-
Notifications
You must be signed in to change notification settings - Fork 536
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
Adds FormControl's "Auto-Wiring" to ActionMenu Component #4372
Adds FormControl's "Auto-Wiring" to ActionMenu Component #4372
Conversation
🦋 Changeset detectedLatest commit: 14f60fe The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
size-limit report 📦
|
…_formcontrollabel
Thanks for creating a PR! Leaving rewatch link for myself to catch up: https://github.rewatch.com/video/2xqmd8rdinwuuedx-accessibility-team-eng-office-hours-march-11-2024?t=60.69 |
}: ActionMenuProps) => { | ||
const [combinedOpenState, setCombinedOpenState] = useProvidedStateOrCreate(open, onOpenChange, false) | ||
const onOpen = React.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]) | ||
const onClose = React.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]) | ||
const inputProps = useFormControlForwardedProps(externalInputProps) |
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.
Using the hook recently created by this PR: #3632. This hook is also being used in the InlineAutocomplete
draft component:
const inputProps = useFormControlForwardedProps(externalInputProps) |
@@ -69,7 +72,7 @@ const Menu: React.FC<React.PropsWithChildren<ActionMenuProps>> = ({ | |||
renderAnchor = anchorProps => { | |||
// We need to attach the anchor props to the tooltip trigger (ActionMenu.Button's grandchild) not the tooltip itself. | |||
const triggerButton = React.cloneElement(anchorChildren, {...anchorProps}) | |||
return React.cloneElement(child, {children: triggerButton, ref: anchorRef}) | |||
return React.cloneElement(child, {children: triggerButton, ref: anchorRef, ...inputProps}) |
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.
Followed the pattern suggested in this slack thread: https://github.slack.com/archives/CSGAVNZ19/p1709843761424779?thread_ts=1709836721.563139&cid=CSGAVNZ19
@@ -22,20 +22,6 @@ exports[`Token components AvatarToken renders all sizes 1`] = ` | |||
border-width: 0; | |||
} | |||
|
|||
.c3 { |
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 updated snapshots as detailed in the contributor docs: https://github.com/primer/react/blob/cb54f4298700d369e616aaefb2e7df4830231736/contributor-docs/testing.md#snapshots
Not sure why these classes had to be rearranged as it's not clear to me how Token
relates to my ActionMenu
changes at all
</FormControl> | ||
) | ||
} | ||
|
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 tried adding a test case for TooltipV2
function ExampleWithTooltipV2WithForm(): JSX.Element {
return (
<FormControl>
<FormControl.Label>Action Menu Label</FormControl.Label>
<ThemeProvider theme={theme}>
<SSRProvider>
<BaseStyles>
<ActionMenu>
<TooltipV2 text="Additional context about the menu button" direction="s">
<ActionMenu.Button>Toggle Menu</ActionMenu.Button>
</TooltipV2>
<ActionMenu.Overlay>
<ActionList>
<ActionList.Item>New file</ActionList.Item>
</ActionList>
</ActionMenu.Overlay>
</ActionMenu>
</BaseStyles>
</SSRProvider>
</ThemeProvider>
</FormControl>
)
}
it('MenuButton wrapped by TooltipV2 within FormControl should be labelled by FormControl.Label', async () => {
const component = HTMLRender(<ExampleWithTooltipV2WithForm />)
const button = component.getByLabelText('Action Menu Label')
expect(button).toBeVisible()
const buttonByRole = component.getByRole('button')
expect(button.id).toBe(buttonByRole.id)
})
But I got this error because the FormControl.Label
ended up labelling the TooltipV2
instead of the ActionMenu.Button
(presumably since the tooltip is wrapping the button).
If I try to force the TooltipV2
to act similarly to Tooltip
(v1) and wrap the entire ActionMenu
function ExampleWithTooltipV2WithForm(): JSX.Element {
return (
<FormControl>
<FormControl.Label>Action Menu Label</FormControl.Label>
<ThemeProvider theme={theme}>
<SSRProvider>
<BaseStyles>
<TooltipV2 text="Additional context about the menu button" direction="s">
<ActionMenu>
<ActionMenu.Button>Toggle Menu</ActionMenu.Button>
<ActionMenu.Overlay>
<ActionList>
<ActionList.Item>New file</ActionList.Item>
</ActionList>
</ActionMenu.Overlay>
</ActionMenu>
</TooltipV2>
</BaseStyles>
</SSRProvider>
</ThemeProvider>
</FormControl>
)
}
I get this error since that's not how TooltipV2
is supposed to be used.
Either way I'm not concerned about not having a test including TooltipV2
since I can't imagine a valid use case for having an ActionMenu
within a FormControl
being labelled by a FormControl.Label
and then also adding a tooltip on top. Furthermore our Primer a11y guidelines advise against using tooltips in most circumstances: https://primer.style/guides/accessibility/tooltip-alternatives#why.
Instead of auto-wiring the ActionMenu component, I wrote #4389 to auto-wire the SelectPanel v2 component since it's more fitting to be used in forms: https://github.slack.com/archives/C01L618AEP9/p1710345435224569?thread_ts=1710344884.849579&cid=C01L618AEP9 |
Followup to previous discussions:
Changelog
New
Changed
Made use of the the new
useFormControlForwardedProps
hook (introduced by #3632) to automatically wire theActionMenu
component to the accessibility and validation provided by theFormControl
component it's nested within. IfActionMenu
isn't nested withinFormControl
the hook has no effect.react/packages/react/src/FormControl/_FormControlContext.tsx
Lines 24 to 39 in f7dcae9
Within a form the accessible name is now the text within the corresponding
FormControl.Label
tagOutside of a form the accessible name is still the text within the
ActionMenu.Button
itselfI also updated Jest snapshots for the
Token
component (all it did was rearrange class names). I'm unsure why it did this since it seems unrelated to the changes I made, but I'm not too concerned about it since we seem to be moving away from snapshot testing: https://github.com/primer/react/blob/cb54f4298700d369e616aaefb2e7df4830231736/contributor-docs/testing.md#snapshots.Removed
Rollout strategy
Testing & Reviewing
Merge checklist