fluentui icon indicating copy to clipboard operation
fluentui copied to clipboard

feat(react-aria): creates ARIAButtonComponent type

Open bsunderhus opened this issue 3 years ago • 4 comments

Current Behavior

At the moment main usages for ARIAButton are:

  1. Button component itself
  2. AccordionHeader button slot
  3. 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

bsunderhus avatar Sep 21 '22 14:09 bsunderhus

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-accordion
Accordion (including children components)
78.914 kB
24.06 kB
78.958 kB
24.093 kB
44 B
33 B
react-alert
Alert
83.511 kB
20.921 kB
83.561 kB
20.955 kB
50 B
34 B
react-button
Button
36.119 kB
9.647 kB
36.167 kB
9.674 kB
48 B
27 B
react-button
CompoundButton
43.144 kB
10.86 kB
43.194 kB
10.881 kB
50 B
21 B
react-button
MenuButton
38.813 kB
10.551 kB
38.863 kB
10.579 kB
50 B
28 B
react-button
SplitButton
46.228 kB
11.933 kB
46.278 kB
11.967 kB
50 B
34 B
react-button
ToggleButton
51.888 kB
11.127 kB
51.938 kB
11.156 kB
50 B
29 B
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
188.672 kB
52.359 kB
188.717 kB
52.384 kB
45 B
25 B
react-dialog
Dialog (including children components)
82.755 kB
24.581 kB
82.8 kB
24.605 kB
45 B
24 B
react-menu
Menu (including children components)
116.572 kB
35.778 kB
116.617 kB
35.803 kB
45 B
25 B
react-menu
Menu (including selectable components)
119.641 kB
36.297 kB
119.686 kB
36.322 kB
45 B
25 B
react-popover
Popover
102.963 kB
31.553 kB
103.008 kB
31.573 kB
45 B
20 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-avatar
Avatar
48.381 kB
13.696 kB
react-avatar
AvatarGroup
14.95 kB
5.989 kB
react-avatar
AvatarGroupItem
68.349 kB
19.039 kB
react-card
Card - All
67.002 kB
19.261 kB
react-card
Card
62.684 kB
18.177 kB
react-card
CardFooter
8.561 kB
3.601 kB
react-card
CardHeader
9.604 kB
3.94 kB
react-card
CardPreview
8.662 kB
3.656 kB
react-components
react-components: FluentProvider & webLightTheme
33.394 kB
11.007 kB
react-portal-compat
PortalCompatProvider
5.851 kB
1.964 kB
🤖 This report was generated against 92bc886e6e3e5ec43847752941456666eb69d32b

fabricteam avatar Sep 21 '22 14:09 fabricteam

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

codesandbox-ci[bot] avatar Sep 21 '22 14:09 codesandbox-ci[bot]

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 92bc886e6e3e5ec43847752941456666eb69d32b (build)

size-auditor[bot] avatar Sep 21 '22 14:09 size-auditor[bot]

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

fabricteam avatar Sep 21 '22 15:09 fabricteam

Blocked by #24960

bsunderhus avatar Sep 27 '22 19:09 bsunderhus