Skip to content

[combobox][autocomplete][select] Fix listbox separator semantics - #5399

Merged
atomiks merged 5 commits into
mui:masterfrom
sarthakmalik0810:codex/listbox-context-separators
Aug 3, 2026
Merged

[combobox][autocomplete][select] Fix listbox separator semantics#5399
atomiks merged 5 commits into
mui:masterfrom
sarthakmalik0810:codex/listbox-context-separators

Conversation

@sarthakmalik0810

@sarthakmalik0810 sarthakmalik0810 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Select.Separator, Combobox.Separator, and Autocomplete.Separator currently reuse Separator, which exposes role="separator" when rendered inside a listbox. This is flagged by axe DevTools and ARC Toolkit.

Changes

  • Render listbox separators with role="presentation".
  • Share the implementation across Select, Combobox, and Autocomplete.
  • Preserve the existing public props, types, orientation, and data-orientation.

Note for reviewers: This does not remove or change any public props and is not a breaking change. The orientation prop remains supported and is not deprecated. If reviewers prefer deprecating it for listbox separators, we can address that in this PR.

Fixes #5398

@pkg-pr-new

pkg-pr-new Bot commented Aug 2, 2026

Copy link
Copy Markdown

commit: de2664d

@code-infra-dashboard

code-infra-dashboard Bot commented Aug 2, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+198B(+0.04%) 🔺+63B(+0.04%)

Details of bundle changes

Performance

Total duration: 1,159.50 ms ▼-325.25 ms(-21.9%) | Renders: 78 (+0) | Paint: 1,820.06 ms ▼-497.54 ms(-21.5%)

Test Duration Renders
Tabs mount (200 instances) 178.69 ms ▼-76.31 ms(-29.9%) 3 (+0)
Select mount (200 instances) 143.72 ms ▼-43.94 ms(-23.4%) 3 (+0)
Scroll Area mount (300 instances) 80.46 ms ▼-34.50 ms(-30.0%) 3 (+0)
Dialog mount (300 instances) 46.94 ms ▼-20.70 ms(-30.6%) 1 (+0)
Popover mount (300 instances) 67.16 ms ▼-19.82 ms(-22.8%) 1 (+0)

…and 4 more (+6 within noise) — details


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Aug 2, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit de2664d
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a7127e64559cf0008e967e5
😎 Deploy Preview https://deploy-preview-5399--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@sarthakmalik0810
sarthakmalik0810 marked this pull request as ready for review August 2, 2026 13:07
@sarthakmalik0810
sarthakmalik0810 force-pushed the codex/listbox-context-separators branch from 1b344c9 to 80f2c77 Compare August 2, 2026 13:13
@sarthakmalik0810 sarthakmalik0810 changed the title [combobox] [autocomplete] [select] Fix listbox separator semantics [combobox][autocomplete][select] Fix listbox separator semantics Aug 2, 2026
@sarthakmalik0810
sarthakmalik0810 force-pushed the codex/listbox-context-separators branch from 80f2c77 to 4b0fc02 Compare August 2, 2026 18:05
@atomiks

atomiks commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR review

Nothing is merge-blocking: the semantic fix is valid, role="presentation" correctly suppresses both the default <div> and implicit semantics from replacement elements such as <hr>, and removing aria-orientation is correct once the divider is absent from the accessibility tree. The orientation prop should remain as visual state, and the focused Select and Combobox tests adequately cover the shared Autocomplete behavior. The remaining issues are small implementation and documentation nits.

Simplifications (1)

1. 🟡 Share the listbox separator implementation

Location: packages/react/src/select/separator/SelectSeparator.tsx:1 and packages/react/src/combobox/separator/ComboboxSeparator.tsx:1

export const SelectSeparator = React.forwardRef(function SelectSeparator(
  componentProps: SelectSeparator.Props,
  forwardedRef: React.ForwardedRef<HTMLDivElement>,
) {

SelectSeparator and ComboboxSeparator are effectively identical runtime components with different names and documentation links. The bundle report shows +360 B parsed / +100 B gzip, which is small but avoidable for a purely semantic correction.

Failure scenario: Each listbox primitive ships and maintains a duplicate component body, adding bundle bytes and allowing the implementations to drift even though their behavior is identical.

Fix: Extract one internal ListboxSeparator implementation and alias it from Select, Combobox, and Autocomplete, while retaining the component-specific exported type aliases.

Docs (1)

1. 🟡 Make the shared separator description neutral

Location: packages/react/src/combobox/separator/ComboboxSeparator.tsx:6

/**
 * A visual separator between combobox items.
 * Renders a `<div>` element.
 */

Autocomplete reuses ComboboxSeparator, so its generated API currently describes Autocomplete.Separator as being “between combobox items.” That leaks the implementation source into a different public component namespace.

Failure scenario: A reader of the Autocomplete API sees Combobox-specific terminology and may reasonably wonder whether the documented component or generated API mapping is incorrect.

Fix: Use a neutral shared description such as “A visual separator between items.”

Verdict

Approve after nits - the accessibility approach is correct; only the duplicated runtime implementation and shared wording should be cleaned up before merging.


🤖 Review generated with Codex

@sarthakmalik0810
sarthakmalik0810 force-pushed the codex/listbox-context-separators branch from 4b0fc02 to a3f8d1d Compare August 3, 2026 07:12
@sarthakmalik0810
sarthakmalik0810 force-pushed the codex/listbox-context-separators branch from a3f8d1d to d956016 Compare August 3, 2026 07:13
@sarthakmalik0810

Copy link
Copy Markdown
Contributor Author

@atomiks Thanks for the review. I extracted the shared listbox separator implementation into packages/react/src/utils/listbox-separator. Select, Combobox, and Autocomplete now expose it through their own Separator parts while preserving their existing public props and types.

@zannager zannager added the component: combobox Changes related to the combobox component. label Aug 3, 2026
@atomiks atomiks added component: select Changes related to the select component. type: bug It doesn't behave as expected. component: autocomplete Changes related to the autocomplete component. labels Aug 3, 2026

@atomiks atomiks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the fix @sarthakmalik0810

@atomiks
atomiks merged commit becc19a into mui:master Aug 3, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: autocomplete Changes related to the autocomplete component. component: combobox Changes related to the combobox component. component: select Changes related to the select component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[combobox] [autocomplete] [select] Avoid exposing role="separator" inside listboxes

3 participants