Skip to content

feat(ui): chonkify segmentedControl #89589

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

Merged
merged 14 commits into from
Apr 15, 2025
Merged

Conversation

TkDodo
Copy link
Contributor

@TkDodo TkDodo commented Apr 15, 2025

No description provided.

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 15, 2025
Comment on lines 53 to +56
export function getChonkButtonStyles(
p: ButtonProps & {theme: DO_NOT_USE_ChonkTheme}
p: Pick<ButtonProps, 'size' | 'priority' | 'busy' | 'disabled' | 'borderless'> & {
theme: DO_NOT_USE_ChonkTheme;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed the interface here to be as minimal as possible - only what gets really used, so that I can re-use it in the segmentgedControl

@@ -150,7 +152,7 @@ export function getChonkButtonStyles(
},
},

'&:active, &[aria-expanded="true"]': {
'&:active, &[aria-expanded="true"], &[aria-checked="true"]': {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

segmentedControl is a checkbox and thus sets aria-checked for “active” elements

@@ -159,7 +161,7 @@ export function getChonkButtonStyles(
},
},

'&:disabled': {
'&:disabled, &[aria-disabled="true"]': {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve set aria-disabled for the element in the segmentedControl that receives styling, so I need to match it here, too.

${p => p.theme.buttonPadding[p.size]}
font-weight: ${p => p.theme.fontWeightNormal};

${p => ({...getChonkButtonStyles({...p, disabled: p.isDisabled, priority: p.isSelected && p.priority === 'primary' ? 'primary' : 'default'})})}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

took me a while to figure out why disabled styles don’t work. disabled vs isDisabled, and no typescript errors because the prop is optional and there is no excess property checking 😭

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my god... we really need to delete these dual props, this is a waste of time + having isDisabled and disabled is just confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we use isDisabled a lot because of “boolean props should start with is”, which is okay, but then we have disabled because the html property is disabled and this gets forwarded to inputs :/

let’s put it on the list to decide for one

Comment on lines +165 to +168
// Once an item is selected, it gets a heavier font weight and becomes slightly
// wider. To prevent layout shifts, we need a hidden container (HiddenLabel) that
// will always have normal weight to take up constant space; and a visible,
// absolutely positioned container (VisibleLabel) that doesn't affect the layout.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

none of this madness is needed in chonk because selected elements don’t get wider so we can get rid of those wrappers and the absolute positioning 🎉

@TkDodo TkDodo marked this pull request as ready for review April 15, 2025 10:09
@TkDodo TkDodo requested a review from a team as a code owner April 15, 2025 10:09
also we need a special handling for when there's only two elements in the segmentedControl
${({theme}) => theme.focusRing};
}

${p => p.isSelected && `z-index: 1;`}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this above under L53 and just do something like z-index: isSelected ? 1 : undefined so that the base rules are somewhat centralized? I hate it when I need to use search inside a css files just to find that one of the rules is defined somewhere totally random, and I've also seen instances where these end up redefining a z-index somewhere else, which also results in duplicate css rules

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally: 4c010d8

this is still a leftover from the existing styles, I don’t even know why we’d need it 🤷‍♂️

Comment on lines +187 to +190
priority={priority}
data-test-id={props.value}
aria-checked={isSelected}
aria-disabled={isDisabled}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@TkDodo TkDodo enabled auto-merge (squash) April 15, 2025 13:40
@TkDodo TkDodo merged commit d1b8e44 into master Apr 15, 2025
41 checks passed
@TkDodo TkDodo deleted the tkdodo/feat/chonkify-segmentedControl branch April 15, 2025 13:54
@github-actions github-actions bot locked and limited conversation to collaborators May 1, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants