microsoft / fluentui

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.
https://react.fluentui.dev
Other
17.87k stars 2.66k forks source link

fix: standalone Listbox updates activedescendant correctly #31415

Open smhigley opened 2 weeks ago

smhigley commented 2 weeks ago

Related to #31140 and #31235

Essentially this moves the initial activeDescendantController setting logic from useComboboxBaseState to useListbox, so it runs when the listbox is first renders instead of based on the change in open state.

That both makes combobox/dropdown aria-activedescendant logic a bit more straightforward (the attribute is set if the referenced option exists), and also makes a standalone listbox work.

It also moves a couple option lookup functions to the context, so that Listbox can access them (previously the getOptionById logic in onFocus wasn't working when not a standalone widget, since it didn't have access to the parent combobox's option collection).

Previous Behavior

The original issue was that listbox did not set the initial activedescendant. The first fix to that issue did so on focus, but that caused issues when clicking also set focus (and reset the activedescendant, potentially causing scroll & jumping).

New Behavior

There's no reason Listbox should not always have aria-activedescendant set while it's present on the page, so this change moves the initial activedescendant logic from the combobox (which handled it when opened) to the listbox (which handles it when initially rendered).

There is a very subtle difference between the two, since the Listbox is rendered when the Combobox/Dropdown trigger gains focus, but before it is opened. This causes a minor difference in when aria-activedescendant is set, but does not cause any practical drawbacks to screen reader users. Some early ARIA combobox pattern work was based around the idea that aria-activedescendant would always be set, so screen readers already handle logic on whether to read the activedescendant based on aria-expanded.

fabricteam commented 2 weeks ago

šŸ“Š Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-combobox
Combobox (including child components)
100.496 kB
33.156 kB
101.45 kB
33.342 kB
954 B
186 B
react-combobox
Dropdown (including child components)
101.129 kB
33.096 kB
102.088 kB
33.285 kB
959 B
189 B
react-timepicker-compat
TimePicker
103.487 kB
34.632 kB
104.444 kB
34.803 kB
957 B
171 B
Unchanged fixtures | Package & Exports | Size (minified/GZIP) | | ----------------- | -------------------: | | react-accordion
Accordion (including children components) | `100.003 kB`
`30.524 kB` | | react-alert
Alert | `78.817 kB`
`22.543 kB` | | react-avatar
Avatar | `49.299 kB`
`15.837 kB` | | react-avatar
AvatarGroup | `20.107 kB`
`7.973 kB` | | react-avatar
AvatarGroupItem | `63.316 kB`
`20.017 kB` | | react-breadcrumb
@fluentui/react-breadcrumb - package | `114.486 kB`
`31.821 kB` | | react-button
Button | `37.103 kB`
`10.784 kB` | | react-button
CompoundButton | `43.514 kB`
`12.074 kB` | | react-button
MenuButton | `41.884 kB`
`12.132 kB` | | react-button
SplitButton | `49.896 kB`
`13.724 kB` | | react-button
ToggleButton | `53.03 kB`
`12.543 kB` | | react-card
Card - All | `101.184 kB`
`29.049 kB` | | react-card
Card | `94.218 kB`
`27.333 kB` | | react-card
CardFooter | `14.354 kB`
`5.795 kB` | | react-card
CardHeader | `16.618 kB`
`6.555 kB` | | react-card
CardPreview | `14.418 kB`
`5.931 kB` | | react-datepicker-compat
DatePicker Compat | `220.038 kB`
`62.373 kB` | | react-dialog
Dialog (including children components) | `99.303 kB`
`29.994 kB` | | react-menu
Menu (including children components) | `152.023 kB`
`45.98 kB` | | react-menu
Menu (including selectable components) | `154.709 kB`
`46.477 kB` | | react-message-bar
MessageBar (all components) | `24.411 kB`
`9.114 kB` | | react-persona
Persona | `56.19 kB`
`17.726 kB` | | react-popover
Popover | `127.766 kB`
`40.096 kB` | | react-toast
Toast (including Toaster) | `99.625 kB`
`30.033 kB` |

šŸ¤– This report was generated against 8820c131f5b6d0509c2781f741b07932f37a4ff5

fabricteam commented 2 weeks ago

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 634 653 5000
Button mount 282 309 5000
Field mount 1139 1144 5000
FluentProvider mount 695 697 5000
FluentProviderWithTheme mount 83 84 10
FluentProviderWithTheme virtual-rerender 36 34 10
FluentProviderWithTheme virtual-rerender-with-unmount 73 76 10
MakeStyles mount 855 850 50000
Persona mount 1745 1696 5000
SpinButton mount 1359 1365 5000
SwatchPicker mount 1489 1540 5000