feat(react-aria): creates ARIAButtonComponent type
Current Behavior
At the moment main usages for ARIAButton are:
-
Buttoncomponent itself -
AccordionHeaderbutton slot - Triggers (
PopoverTrigger,MenuTrigger,DialogTrigger)
When those usages are combined (which is the case for Triggers + Button normally), it means that multiple invocations of useARIAButtonProps hook will be provided (one from the Button itself, and one from the trigger that encapsulates the Button)
{/* There's no way, currently, to `MenuTrigger` to know that its children component properly implements button behaviour */}
<MenuTrigger>
<Button>Open Menu</Button>
</MenuTrigger>
New Behavior
Inspired on FluentTriggerComponent
https://github.com/microsoft/fluentui/blob/92bc886e6e3e5ec43847752941456666eb69d32b/packages/react-components/react-utilities/src/trigger/types.ts#L15-L17
This PR Provides proper flag mechanism to ensure that useARIAButtonProps doesn't need to add more handlers on elements that already handle button properties correctly by adding proper type ARIAButtonComponent.
Main usage for this will be to ensure that a given component already implements all the proper behaviours of an ARIAButton, this follows the same idea provided on Trigger components, here's MenuTrigger as an example:
https://github.com/microsoft/fluentui/blob/92bc886e6e3e5ec43847752941456666eb69d32b/packages/react-components/react-menu/src/components/MenuTrigger/MenuTrigger.tsx#L7-L18
This isFluentTriggerComponent = true indicates to other triggers that that specific element is a trigger and can be properly concatenated, allowing the usage of multiple trigger in a single child without causing conflict.
Following this approach Button will be like:
/**
* Buttons give people a way to trigger an action.
*/
export const Button: ForwardRefComponent<ButtonProps> & ARIAButtonComponent = React.forwardRef((props, ref) => {
const state = useButton_unstable(props, ref);
useButtonStyles_unstable(state);
return renderButton_unstable(state);
// Casting is required due to lack of distributive union to support unions on @types/react
}) as ForwardRefComponent<ButtonProps>;
Button.displayName = 'Button';
Button.isARIAButtonComponent = true // this will ensure that `useARIAButtonProps` doesn't repeat itself
📊 Bundle size report
| Package & Exports | Baseline (minified/GZIP) | PR | Change |
|---|---|---|---|
| react-accordion Accordion (including children components) |
78.914 kB24.06 kB |
78.958 kB24.093 kB |
44 B 33 B |
| react-alert Alert |
83.511 kB20.921 kB |
83.561 kB20.955 kB |
50 B 34 B |
| react-button Button |
36.119 kB9.647 kB |
36.167 kB9.674 kB |
48 B 27 B |
| react-button CompoundButton |
43.144 kB10.86 kB |
43.194 kB10.881 kB |
50 B 21 B |
| react-button MenuButton |
38.813 kB10.551 kB |
38.863 kB10.579 kB |
50 B 28 B |
| react-button SplitButton |
46.228 kB11.933 kB |
46.278 kB11.967 kB |
50 B 34 B |
| react-button ToggleButton |
51.888 kB11.127 kB |
51.938 kB11.156 kB |
50 B 29 B |
| react-components react-components: Accordion, Button, FluentProvider, Image, Menu, Popover |
188.672 kB52.359 kB |
188.717 kB52.384 kB |
45 B 25 B |
| react-dialog Dialog (including children components) |
82.755 kB24.581 kB |
82.8 kB24.605 kB |
45 B 24 B |
| react-menu Menu (including children components) |
116.572 kB35.778 kB |
116.617 kB35.803 kB |
45 B 25 B |
| react-menu Menu (including selectable components) |
119.641 kB36.297 kB |
119.686 kB36.322 kB |
45 B 25 B |
| react-popover Popover |
102.963 kB31.553 kB |
103.008 kB31.573 kB |
45 B 20 B |
Unchanged fixtures
| Package & Exports | Size (minified/GZIP) |
|---|---|
| react-avatar Avatar |
48.381 kB13.696 kB |
| react-avatar AvatarGroup |
14.95 kB5.989 kB |
| react-avatar AvatarGroupItem |
68.349 kB19.039 kB |
| react-card Card - All |
67.002 kB19.261 kB |
| react-card Card |
62.684 kB18.177 kB |
| react-card CardFooter |
8.561 kB3.601 kB |
| react-card CardHeader |
9.604 kB3.94 kB |
| react-card CardPreview |
8.662 kB3.656 kB |
| react-components react-components: FluentProvider & webLightTheme |
33.394 kB11.007 kB |
| react-portal-compat PortalCompatProvider |
5.851 kB1.964 kB |
This pull request is automatically built and testable in CodeSandbox.
To see build info of the built libraries, click here or the icon next to each commit SHA.
Latest deployment of this branch, based on commit bf82641578a7fd316d3c4c0f85c0f2a4ae8d6f7b:
| Sandbox | Source |
|---|---|
| @fluentui/react 8 starter | Configuration |
| @fluentui/react-components 9 starter | Configuration |
Asset size changes
Size Auditor did not detect a change in bundle size for any component!
Baseline commit: 92bc886e6e3e5ec43847752941456666eb69d32b (build)
Perf Analysis (@fluentui/react-components)
No significant results to display.
All results
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| Avatar | mount | 1333 | 1342 | 5000 | |
| Button | mount | 953 | 965 | 5000 | |
| FluentProvider | mount | 1577 | 1582 | 5000 | |
| FluentProviderWithTheme | mount | 631 | 647 | 10 | |
| FluentProviderWithTheme | virtual-rerender | 591 | 601 | 10 | |
| FluentProviderWithTheme | virtual-rerender-with-unmount | 635 | 635 | 10 | |
| MakeStyles | mount | 1901 | 1923 | 50000 | |
| SpinButton | mount | 2550 | 2544 | 5000 |
Blocked by #24960
