-
Notifications
You must be signed in to change notification settings - Fork 616
Add selected state to Button #1819
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
Conversation
|
size-limit report 📦
|
1957ea4
to
0e721ba
Compare
@@ -65,6 +65,20 @@ The `invisible` variant of `Button` indicates that the action is a low priority | |||
</> | |||
``` | |||
|
|||
### Selected button | |||
|
|||
`Button` can be set to in a "selected" state in two ways. You can use a `selected` class or set `aria-selected ="true"`. |
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.
Is it worth adding a selected
prop that handles both styling and setting aria attributes? May make consumer-side implementation easier. Also, I don't usually ask for users to set classes elsewhere to enable features, so could this be confusing?
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.
Same! this was the exact confusion I was trying to discuss on slack as well. prop or class? Class is just not how we'd do this in react
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.
Should it bearia-pressed
instead? 🤔
The aria-selected attribute indicates the current "selected" state for gridcell, option, row and tab roles.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-selected
The aria-pressed attribute indicates the current "pressed" state of a toggle button.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed
cc @alliethu - what do you think the correct ARIA attribute might be?
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.
Agreed that we should do it with a prop instead of a class or attribute selector.
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 came up today in the Primer patterns working session. We decided this should be purely visual and not set any ARIA attributes.
In the case where a button controls a dropdown, it would need to be passed aria-haspopup
and aria-expanded
attributes. These attributes would be passed by the component that renders the dropdown button and menu.
cc @langermank
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.
Two questions here
- How do we set the pressed styles in this case?
- How do we support the toggles in the tabs use case in the issue Button state selected #1783 ?
I'm thinking we need to implement aria-pressed
styles and scrap the selected
prop.
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.
The two use cases here:
-
Sounds like Button state selected #1783 is using Button as a "toggle button", which isn't just a visual update but also a semantic change.
From MDN (https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed):
Adding aria-pressed to an element with a role of button turns the button into a toggle button. The aria-pressed attribute is only relevant for toggle buttons. It represents the button's current "pressed" state.
It looks like it makes sense to add
aria-pressed
for toggle button. cc @alliethu for confirmation -
For buttons that open a Menu,
aria-pressed
doens't make sense. Instead, we add the aria attributesaria-haspopup="true" aria-expanded="true"
, we can modify button styles if those are present OR to keep the two concerns independent, we can pass apressed
oractive
prop or className (not aria-pressed) to the Button from the Menu components.
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.
Got it, so @mperrotti @siddharthkp I'm adding a pressed
prop to the component and we can handle the css based on that. This will address both the above use cases.
### Selected button | ||
|
||
`Button` can be set to in a "selected" state in two ways. You can use a `selected` class or set `aria-selected ="true"`. | ||
This is in many cases similar to the active state of the button. Usually used in `ButtonGroup` when like tabs. |
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.
Should this capability be restricted to ButtonGroup
? I can see two risks with enabling this for individual buttons:
- Opens door to misuse of standalone button appearance
- A standalone button shouldn't need to be pre-selected
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.
🤔 I don't understand what misuse of this pattern could look like.
How would you restrict to ButtonGroup
? By parent class?
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.
We talked about this in the Primer React planning meeting.
I don't think we want to restrict it to ButtonGroup
buttons, especially because we use the "selected" styling when a button controls a dropdown and the dropdown is open.
Kapture.2022-01-25.at.13.32.30.mp4
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.
I think what we decided in the meeting is to utilize the active
state for dropdowns (this is all forward thinking, not talking about existing functionality) and restrict aria-pressed
to a future new Segmented Control component (a more specific version of a ButtonGroup). The confusing piece of this is that we are simultaneously updating an existing Button component while refactoring a future Button component.
@pksjce I may have missed this, but do you have the use case that prompted this ask to add selected
? We may need to continue supporting it in the original Button while we redesign the future Button.. but my recommendation there will depend on the use case for adding it now.
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.
@langermank - this was the original issue where this came up #1783
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.
Thanks @rezrah.. that's an interesting use case 🤔 I still think this would be a SegmentedControl
though I imagined that to be two/three options max not six 😆 I guess in that case to unblock them use the aria-selected
styles from Primer CSS but map it to aria-pressed
? But I would only add this to the existing Button component, not the refactor.
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.
We are planning to deprecate the existing component as soon as possible. I think for parity we'd need to have it in the new one as well? The new component is not a refactor in terms of functionality I feel, only the API. Once you are done with primer/css#1874, we'd have to work on absorbing it into primer-react.
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.
@pksjce right, thanks for pointing that out. How do you see the new Button API changes rolling into PRC? In CSS and PVC, I think we'll likely end up creating a new component similar to how you've handled Button2
. If you follow that pattern in PRC, you would end up with Button3
😆 Although, the markup in Button2
is almost identical to where we're going with the Button API changes, so perhaps it wouldn't be a big deal to wrap it into Button2
once Button
is deprecated (this is getting a little confusing!)
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.
Yes, I'm not planning to have a Button3
for sure. I'd just update Button2
which would become the only Button
and release it going forward. I don't think there'd be any major API changes. If any breaking then we'd go for a major version change I believe.
<drafts.Button aria-selected="true">Search</drafts.Button> | ||
<drafts.Button aria-selected="true" variant="danger"> | ||
Delete | ||
</drafts.Button> |
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.
Would be nice to have examples for both ways of doing it :)
<drafts.Button aria-selected="true">Search</drafts.Button> | |
<drafts.Button aria-selected="true" variant="danger"> | |
Delete | |
</drafts.Button> | |
<drafts.Button aria-selected="true">Search</drafts.Button> | |
<drafts.Button className="selected" variant="danger"> | |
Delete | |
</drafts.Button> |
@@ -31,6 +31,11 @@ const Button = styled(ButtonBase)<ButtonBaseProps & SxProp>` | |||
background-color: ${get('colors.btn.bg')}; | |||
border-color: ${get('colors.btn.border')}; | |||
} | |||
&.selected, | |||
&[aria-selected='true'] { |
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.
👍 good call on the =true
! I've done the mistake of just putting aria-selected
in the selector and catching =false
coz react 😅
Describe your changes here.
I have added
selected
state as described in https://primer.style/css/components/buttons#selected. I used the same styles as https://github.com/primer/css/blob/e8d5402a26f0e4428cb0cd0694569da3c2ed505e/src/buttons/button.scss#L86I have implemented this for both
Button
andButton2
.Closes # (https://github.com/github/primer/issues/639)
Screenshots
Checkout the storybook in
Please provide before/after screenshots for any visual changes
Merge checklist
Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.