-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Toolbar component #5080
Toolbar component #5080
Conversation
# Conflicts: # packages/react-aria-components/stories/index.stories.tsx
Build successful! 🎉 |
Build successful! 🎉 |
# Conflicts: # packages/react-aria-components/src/index.ts # packages/react-aria-components/stories/index.stories.tsx
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
// Any reason not to include ref? i feel like we've been sad about not including it down the line | ||
// same with state... | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function useToolbar(props: ToolbarProps & {isInsideAToolbar: boolean}, ref: ForwardedRef<HTMLDivElement>) { |
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.
Any reason not to put this in a @react-aria/toolbar
package?
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.
previously you and @dannify had been on the fence about it, happy to move it
<Radio className={styles.radio} value="right">Right</Radio> | ||
</RadioGroup> | ||
*/} | ||
{/* disabled buttons do not work in toolbar yet, the buttons cannot be focused |
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.
cannot be? isn't that correct?
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.
based off the aria example, some of the disabled buttons are still focusable for screenreaders
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.
and specifically it says this a little further down the page
While they are HTML button elements, as described in the accessibility features section above, in order to remain focusable when disabled, they have aria-disabled instead of the HTML disabled attribute.
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.
hmm that's very subjective. I would expect to skip over them by default, otherwise that is inconsistent with everything else we currently implement.
<Button isDisabled>Cut</Button> | ||
</Toolbar> | ||
*/} | ||
{/* select does not work in toolbar yet, focus can't move "Right Arrow" past it |
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.
if our listeners are capturing seems like it should?
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.
Determined what happened, I wasn't specifying to the focusmanager to move to the next tabbable element, so focus was going to the hidden select and then right back to the select button, forever
it brings up a bigger issue though, we have some components with non-tabble elements, radio group, which should be navigable by arrow key, and then we have some components with non-tabbable elements, select, which should not be navigable by arrow key (there is a hidden input)
I'm not sure how to distinguish between the two. Any thoughts?
I tried using our accept
function in createFocusManager, but ActionGroup isn't implemented as a radiogroup all the time and its button can look very similar to NumberField's increment/decrement buttons...
I don't want to use the context I introduced here because I'm still hoping to find a way to get rid of it
Maybe we could use the FocusScope context to declare if a particular scope intends to control certain keys for navigation within the scope? Problematic that hooks don't have access to our context.
Or we could put a data-attribute on elements like the NumberField increment button that's like, data-reallyNotTabbable
... so i'd have something to filter on, hahaha
</ListBox> | ||
</Popover> | ||
</Select>*/} | ||
{/* numberfield does not work in toolbar yet, focus stops on the stepper buttons |
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
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.
Initial review, will wrap up after lunch
EDIT: nothing else to comment on that hasn't been touched on by other reviews
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
@@ -45,7 +45,8 @@ export interface FocusManagerOptions { | |||
/** Whether focus should wrap around when it reaches the end of the scope. */ | |||
wrap?: boolean, | |||
/** A callback that determines whether the given element is focused. */ | |||
accept?: (node: Element) => boolean | |||
accept?: (node: Element) => boolean, | |||
preview?: boolean |
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.
needed so i could use the same setup and determine where focus would move in both the tabbable and focusable case next before actually committing to it
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
Build successful! 🎉 |
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.
lgtm. let's get this into the next testing session.
toolbarProps: HTMLAttributes<HTMLElement> | ||
} | ||
|
||
// Any reason not to include state? i feel like we've been sad about not including a state arg in the past |
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 can't think of what state a toolbar would have so probably ok. 🤷
|
||
export const ToolbarContext = createContext<ContextValue<ToolbarProps, HTMLDivElement>>({}); | ||
|
||
function Toolbar(props: ToolbarProps, ref: ForwardedRef<HTMLDivElement>) { |
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.
Let's discuss whether we want to temporarily name this UNSTABLE_Toolbar
before the next release.
# Conflicts: # packages/react-aria-components/package.json
Build successful! 🎉 |
## API Changes
unknown top level export { type: 'identifier', name: 'Column' } @react-aria/toolbarAriaToolbarProps-
+AriaToolbarProps {
+ orientation?: Orientation = 'horizontal'
+} it changed:
useToolbarchanged by:
-
+useToolbar {
+ props: AriaToolbarProps
+ ref: RefObject<HTMLDivElement>
+ returnVal: undefined
+} |
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 noticed when using Up/Down arrow on horizontal, focus stays within the groups (and vice versa for vertical). Is this expected?
This is expected https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/ it just happens that ActionGroups use the opposing direction to navigate as well and I just let the child component handle the keys I don't. It's hard to know enough about the children to do anything other than this. For instance, controlling a slider vs navigating a menu vs numberfield spin button. So I think this is an ok interpretation. |
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.
LGTM
Closes
Update: Scope reduced, this only supports children of types: Button, Checkbox, Link, RSP ActionGroup
Guidance from accessibility:
I've tested this out. If the toolbars are nested, then the outermost label is not read. If the inner toolbars are groups, then both labels are read as expected. This can be seen simply in this demo. I recommend popping out into a new window before using VO.
https://codesandbox.io/s/sleepy-northcutt-hfhwnr?file=/src/App.js
Implementing a subset of https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/examples/toolbar/
Open questions, do we need the RSP component?
Answer: Not at the moment, we don't want this held up by a design review.
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: