Skip to content

Adds FormControl's "Auto-Wiring" to ActionMenu Component - #4372

Closed
JeffreyKozik wants to merge 6 commits into
mainfrom
jeffreykozik/autolinking_actionmenubutton_to_formcontrollabel
Closed

Adds FormControl's "Auto-Wiring" to ActionMenu Component#4372
JeffreyKozik wants to merge 6 commits into
mainfrom
jeffreykozik/autolinking_actionmenubutton_to_formcontrollabel

Conversation

@JeffreyKozik

@JeffreyKozikJeffreyKozik commented Mar 8, 2024

Copy link
Copy Markdown
Contributor

Followup to previous discussions:

Changelog

New

Changed

Made use of the the new useFormControlForwardedProps hook (introduced by #3632) to automatically wire the ActionMenu component to the accessibility and validation provided by the FormControl component it's nested within. If ActionMenu isn't nested within FormControl the hook has no effect.

/**
* Make any component compatible with `FormControl`'s automatic wiring up of accessibility attributes & validation by
* reading the props from this hook and merging them with the passed-in props. If used outside of `FormControl`, this
* hook has no effect.
*
* @param externalProps The external props passed to this component. If provided, these props will be merged with the
* `FormControl` props, with external props taking priority.
*/
exportfunctionuseFormControlForwardedProps<P>(externalProps: P): P&FormControlForwardedProps
/**
* Make any component compatible with `FormControl`'s automatic wiring up of accessibility attributes & validation by
* reading the props from this hook and handling them / assigning them to the underlying form control. If used outside
* of `FormControl`, this hook has no effect.
*/
exportfunctionuseFormControlForwardedProps(): FormControlForwardedProps
exportfunctionuseFormControlForwardedProps(externalProps: FormControlForwardedProps={}){

Within a form the accessible name is now the text within the corresponding FormControl.Label tag
Screenshot as evidence for the statement above
Outside of a form the accessible name is still the text within the ActionMenu.Button itself
Screenshot as evidence for the statement above

I 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

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

Merge checklist

@JeffreyKozik
JeffreyKozik requested a review from a team as a code ownerMarch 8, 2024 21:57
@changeset-bot

changeset-botBot commented Mar 8, 2024

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 14f60fe

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@primer/reactMinor

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

@github-actions

github-actionsBot commented Mar 8, 2024

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize
packages/react/dist/browser.esm.js87.51 KB (-0.08% 🔽)
packages/react/dist/browser.umd.js87.93 KB (-0.03% 🔽)

@github-actions
github-actionsBottemporarily deployed to storybook-preview-4372 March 8, 2024 22:01 Inactive
@JeffreyKozikJeffreyKozik self-assigned this Mar 11, 2024
@JeffreyKozikJeffreyKozik changed the title adds automatic wiring of a11y attributes to ActionMenu.Buttonadds automatic wiring of a11y attributes to ActionMenu.Button primer changeMar 11, 2024
@github-actions
github-actionsBottemporarily deployed to storybook-preview-4372 March 11, 2024 21:26 Inactive
@JeffreyKozikJeffreyKozik changed the title adds automatic wiring of a11y attributes to ActionMenu.Button primer changeAdds FormControl's "Auto-Wiring" to ActionMenu ComponentMar 12, 2024
@JeffreyKozikJeffreyKozik added the skip changeset This change does not need a changelog label Mar 12, 2024
@siddharthkp

siddharthkp commented Mar 13, 2024

Copy link
Copy Markdown
Member

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

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)

Copy link
Copy Markdown
ContributorAuthor

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:

constinputProps=useFormControlForwardedProps(externalInputProps)

// 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})

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

border-width: 0;
}

.c3 {

Copy link
Copy Markdown
ContributorAuthor

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>
)
}

@JeffreyKozikJeffreyKozikMar 13, 2024

Copy link
Copy Markdown
ContributorAuthor

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

functionExampleWithTooltipV2WithForm(): JSX.Element{return(<FormControl><FormControl.Label>Action Menu Label</FormControl.Label><ThemeProvidertheme={theme}><SSRProvider><BaseStyles><ActionMenu><TooltipV2text="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()=>{constcomponent=HTMLRender(<ExampleWithTooltipV2WithForm/>)constbutton=component.getByLabelText('Action Menu Label')expect(button).toBeVisible()constbuttonByRole=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).
image

If I try to force the TooltipV2 to act similarly to Tooltip (v1) and wrap the entire ActionMenu

functionExampleWithTooltipV2WithForm(): JSX.Element{return(<FormControl><FormControl.Label>Action Menu Label</FormControl.Label><ThemeProvidertheme={theme}><SSRProvider><BaseStyles><TooltipV2text="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.
image

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.

@JeffreyKozik

JeffreyKozik commented Mar 13, 2024

Copy link
Copy Markdown
ContributorAuthor

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

@jonrohan
jonrohan deleted the jeffreykozik/autolinking_actionmenubutton_to_formcontrollabel branch May 9, 2025 18:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@JeffreyKozik@siddharthkp