-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tabs: unify vertical tabs styles #65387
Changes from all commits
1fe9f0b
aa7e9d9
a3e54c5
0b436e8
299d23c
30cda58
4749518
4ba287f
7847ed6
c9e8020
0499718
77ce702
23f5438
5ffc33d
fa2da0a
af857d3
a8a3f3f
9867089
bd0a96c
56989af
517950e
a708e6b
4aa21c8
dcbd6f5
0a65888
f0902e8
e12afb5
535463c
3c43be8
2d4bc91
7f1e764
34cece9
3b82ba0
789545f
094786c
87ce756
9808c75
74851f8
cba3d80
e6b902f
41dc764
cfc7928
d345ebd
9c28772
f831078
b4f5c21
a9b1578
5736e59
f4dbf4f
94f788b
01f31da
4337d49
01cefc9
bb6b4e1
b6710f2
822715b
ece5efc
07069c8
b008f3a
ee8783f
3d9bde2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,18 +9,15 @@ import * as Ariakit from '@ariakit/react'; | |
*/ | ||
import { COLORS, CONFIG } from '../utils'; | ||
import { space } from '../utils/space'; | ||
import Icon from '../icon'; | ||
|
||
export const TabListWrapper = styled.div` | ||
position: relative; | ||
display: flex; | ||
align-items: stretch; | ||
flex-direction: row; | ||
text-align: center; | ||
overflow-x: auto; | ||
|
||
&[aria-orientation='vertical'] { | ||
flex-direction: column; | ||
text-align: start; | ||
} | ||
|
||
:where( [aria-orientation='horizontal'] ) { | ||
|
@@ -40,11 +37,12 @@ export const TabListWrapper = styled.div` | |
|
||
@media not ( prefers-reduced-motion ) { | ||
&[data-indicator-animated]::before { | ||
transition-property: transform; | ||
transition-property: transform, border-radius, border-block; | ||
transition-duration: 0.2s; | ||
transition-timing-function: ease-out; | ||
} | ||
} | ||
position: relative; | ||
&::before { | ||
content: ''; | ||
position: absolute; | ||
|
@@ -59,7 +57,7 @@ export const TabListWrapper = styled.div` | |
/* Using a large value to avoid antialiasing rounding issues | ||
when scaling in the transform, see: https://stackoverflow.com/a/52159123 */ | ||
--antialiasing-factor: 100; | ||
&:not( [aria-orientation='vertical'] ) { | ||
&[aria-orientation='horizontal'] { | ||
--fade-width: 4rem; | ||
--fade-gradient-base: transparent 0%, black var( --fade-width ); | ||
--fade-gradient-composed: var( --fade-gradient-base ), black 60%, | ||
|
@@ -104,65 +102,87 @@ export const TabListWrapper = styled.div` | |
${ COLORS.theme.accent }; | ||
} | ||
} | ||
&[aria-orientation='vertical']::before { | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
height: calc( var( --antialiasing-factor ) * 1px ); | ||
transform: translateY( calc( var( --selected-top, 0 ) * 1px ) ) | ||
scaleY( | ||
&[aria-orientation='vertical'] { | ||
&::before { | ||
/* Adjusting the border radius to match the scaling in the y axis. */ | ||
border-radius: ${ CONFIG.radiusSmall } / | ||
calc( | ||
var( --selected-height, 0 ) / var( --antialiasing-factor ) | ||
) | ||
${ CONFIG.radiusSmall } / | ||
( | ||
var( --selected-height, 0 ) / | ||
var( --antialiasing-factor ) | ||
) | ||
); | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
height: calc( var( --antialiasing-factor ) * 1px ); | ||
transform: translateY( calc( var( --selected-top, 0 ) * 1px ) ) | ||
scaleY( | ||
calc( | ||
var( --selected-height, 0 ) / | ||
var( --antialiasing-factor ) | ||
) | ||
); | ||
background-color: color-mix( | ||
in srgb, | ||
${ COLORS.theme.accent }, | ||
transparent 96% | ||
); | ||
background-color: ${ COLORS.theme.gray[ 100 ] }; | ||
} | ||
&[data-select-on-move='true']:has( | ||
:is( :focus-visible, [data-focus-visible] ) | ||
)::before { | ||
box-sizing: border-box; | ||
border: var( --wp-admin-border-width-focus ) solid | ||
${ COLORS.theme.accent }; | ||
/* Adjusting the border width to match the scaling in the y axis. */ | ||
border-block-width: calc( | ||
var( --wp-admin-border-width-focus, 1px ) / | ||
( | ||
var( --selected-height, 0 ) / | ||
var( --antialiasing-factor ) | ||
) | ||
); | ||
} | ||
} | ||
`; | ||
|
||
export const Tab = styled( Ariakit.Tab )` | ||
& { | ||
scroll-margin: 24px; | ||
flex-grow: 1; | ||
flex-shrink: 0; | ||
display: inline-flex; | ||
align-items: center; | ||
position: relative; | ||
/* Resets */ | ||
border-radius: 0; | ||
height: ${ space( 12 ) }; | ||
background: transparent; | ||
border: none; | ||
box-shadow: none; | ||
|
||
flex: 1 0 auto; | ||
white-space: nowrap; | ||
display: flex; | ||
align-items: center; | ||
cursor: pointer; | ||
line-height: 1.2; // Some languages characters e.g. Japanese may have a native higher line-height. | ||
padding: ${ space( 4 ) }; | ||
margin-left: 0; | ||
font-weight: 500; | ||
text-align: inherit; | ||
line-height: 1.2; // Characters in some languages (e.g. Japanese) may have a native higher line-height. | ||
font-weight: 400; | ||
color: ${ COLORS.theme.foreground }; | ||
|
||
&[aria-disabled='true'] { | ||
cursor: default; | ||
color: ${ COLORS.ui.textDisabled }; | ||
} | ||
|
||
&:not( [aria-disabled='true'] ):hover { | ||
&:not( [aria-disabled='true'] ):is( :hover, [data-focus-visible] ) { | ||
color: ${ COLORS.theme.accent }; | ||
} | ||
|
||
&:focus:not( :disabled ) { | ||
position: relative; | ||
box-shadow: none; | ||
outline: none; | ||
} | ||
|
||
// Focus. | ||
// Focus indicator. | ||
position: relative; | ||
&::after { | ||
content: ''; | ||
position: absolute; | ||
top: ${ space( 3 ) }; | ||
right: ${ space( 3 ) }; | ||
bottom: ${ space( 3 ) }; | ||
left: ${ space( 3 ) }; | ||
pointer-events: none; | ||
|
||
// Draw the indicator. | ||
|
@@ -175,23 +195,69 @@ export const Tab = styled( Ariakit.Tab )` | |
opacity: 0; | ||
|
||
@media not ( prefers-reduced-motion ) { | ||
transition: opacity 0.1s linear; | ||
transition: opacity 0.15s 0.15s linear; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to be sure, is this intentional? This means the duration is 0.15s and the delay is 0.15s. The c7ee84a7135d24ae6cdbc2b1e0360687.mp4There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is: #65387 (comment) I believe the idea is to show the chevron only after the "indicator" has animated to the new selected tab There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw the comment, but isn't that animation only expected for vertical tabs? Additionally, I don't know if it's related to this PR, but I can see that the pattern categories in the block sidebar don't seem to animate properly - they don't have a background color when focused: b98ac34f83e2a4b460f9aff15ddc6803.mp4There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for reporting - I expect @DaniGuardiola to take a look at this when he's back (I don't think he's online today) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This seem like a good point. The delay (and maybe the whole transition) should only be needed for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On my phone, and on sick leave, but just wanted to say that as far as I remember, this transition was only applied to the Chevron in vertical tabs, and only when select on move is enabled and when using the arrow keys. If that's not the case, something got messed up, and that'd be surprising to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #65387 (comment) 😅 Will fix soon. Silly me! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
} | ||
|
||
&:focus-visible::after { | ||
&[data-focus-visible]::after { | ||
opacity: 1; | ||
} | ||
} | ||
|
||
[aria-orientation='horizontal'] & { | ||
padding-inline: ${ space( 4 ) }; | ||
height: ${ space( 12 ) }; | ||
text-align: center; | ||
scroll-margin: 24px; | ||
|
||
&::after { | ||
content: ''; | ||
inset: ${ space( 3 ) }; | ||
} | ||
} | ||
|
||
[aria-orientation='vertical'] & { | ||
min-height: ${ space( | ||
10 | ||
) }; // Avoid fixed height to allow for long strings that go in multiple lines. | ||
padding: ${ space( 2 ) } ${ space( 3 ) }; | ||
min-height: ${ space( 10 ) }; | ||
text-align: start; | ||
|
||
&[aria-selected='true'] { | ||
color: ${ COLORS.theme.accent }; | ||
fill: currentColor; | ||
} | ||
} | ||
[aria-orientation='vertical'][data-select-on-move='false'] &::after { | ||
content: ''; | ||
inset: var( --wp-admin-border-width-focus ); | ||
} | ||
`; | ||
|
||
export const TabChildren = styled.span` | ||
flex-grow: 1; | ||
`; | ||
|
||
export const TabChevron = styled( Icon )` | ||
flex-shrink: 0; | ||
margin-inline-end: ${ space( -1 ) }; | ||
[aria-orientation='horizontal'] & { | ||
justify-content: center; | ||
display: none; | ||
} | ||
opacity: 0; | ||
[role='tab']:is( [aria-selected='true'], [data-focus-visible], :hover ) & { | ||
opacity: 1; | ||
} | ||
// The chevron is transitioned into existence when selectOnMove is enabled, | ||
// because otherwise it looks jarring, as it shows up outside of the focus | ||
// indicator that's being animated at the same time. | ||
@media not ( prefers-reduced-motion ) { | ||
[data-select-on-move='true'] | ||
[role='tab']:is( [aria-selected='true'], ) | ||
& { | ||
transition: opacity 0.3s ease-in; | ||
stokesman marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @t-hamano oof, I accidentally replaced the wrong transition, this is where it should have been replaced. |
||
} | ||
} | ||
&:dir( rtl ) { | ||
rotate: 180deg; | ||
} | ||
`; | ||
|
||
|
@@ -201,7 +267,7 @@ export const TabPanel = styled( Ariakit.TabPanel )` | |
outline: none; | ||
} | ||
|
||
&:focus-visible { | ||
&[data-focus-visible] { | ||
box-shadow: 0 0 0 var( --wp-admin-border-width-focus ) | ||
${ COLORS.theme.accent }; | ||
// Windows high contrast mode. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably fixed by ariakit/ariakit#4094 which is included in
@ariakit/react
0.4.11
.We should follow-up to update ariakit-related dependencies, and consequently we should be able to remove
:focus-visible
🤞