Skip to content

feat(selector): add search adornment slots to Selector & MultiSelector - #4598

Closed
freddymeta wants to merge 1 commit into
mainfrom
feat/selector-search-adornments
Closed

feat(selector): add search adornment slots to Selector & MultiSelector#4598
freddymeta wants to merge 1 commit into
mainfrom
feat/selector-search-adornments

Conversation

@freddymeta

Copy link
Copy Markdown
Contributor

What

Adds searchStartContent / searchEndContent slots to Selector and MultiSelector for decorative adornments beside the dropdown search input (only in hasSearch mode) — most commonly a leading search/magnifier Icon.

<Selector hasSearch searchStartContent={<Icon icon="search" size="sm" />}  />

Why

The search input had no adornment slot, so a leading magnifier could only be a CSS pseudo-element (::before with an inline-SVG mask) — which can't be a real icon component and can't carry a handler. This is the composition-friendly fix: pass a real <Icon>.

How (accessibility)

The adornments render inside the search row wrapped aria-hidden and are non-interactive, so:

  • the search input keeps its role="combobox", focus, and keyboard behavior (unchanged),
  • the adornments never surface as extra controls inside the listbox.

The search wrapper becomes a flex row; the input fills the remaining space. Interactive clear-style affordances still belong on the value via onChange — these slots are decorative and deliberately not wired to the search query.

Scope

Part of the EPS-on-Astryx upstreaming (paired with the theme-target PR). This is the piece that genuinely needed component API rather than a theme hook. A full renderSearch override was considered but rejected — it would let a consumer break the combobox/aria-activedescendant contract the component carefully maintains; adornment slots give the needed flexibility (the magnifier) without that risk.

Testing

  • Selector 79 + MultiSelector 74 = 153 tests pass, incl. new ones: both slots render aria-hidden beside the input (both components) and don't render without hasSearch.
  • typecheck:docs, check-sync, sync-exports --check, changeset check, eslint — all green.

Non-breaking; default appearance unchanged (no adornments unless provided).

The searchable dropdown's search input had no way to add a leading
magnifier (or any adornment) without CSS that paints a pseudo-element —
which can't hold a real icon component or a handler.

Add `searchStartContent` / `searchEndContent` slots (only in `hasSearch`
mode) rendered beside the search input. They're wrapped `aria-hidden` and
are non-interactive, so the input keeps its combobox role, focus, and
keyboard behavior, and the adornments never appear as extra controls in
the listbox. The search wrapper becomes a flex row; the input fills it.

This is the composition-friendly alternative to the EPS POC's inline-SVG
`mask` magnifier: a consumer passes a real `<Icon icon="search" />`.
Interactive clear-style affordances still belong on the value via
`onChange` — these slots are decorative and not wired to the query.

Tests assert the slots render aria-hidden beside the input (both
components) and don't render without `hasSearch`; docs list both props.
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview Jul 31, 2026 1:30pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 31, 2026
@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:design-review Affects visuals — Design should review labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

MultiSelector (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 1365 -
Complexity N/A Very High (153) -
Selector (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 1348 -
Complexity N/A Very High (114) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.7KB 1.2KB

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

github-actions Bot added a commit that referenced this pull request Jul 31, 2026
@freddymeta

Copy link
Copy Markdown
Contributor Author

Closing in favor of #4596.

The driving use case here — a decorative leading magnifier in the search input — is covered by the selector-search / selector-search-input theme targets added in #4596: a theme can draw the magnifier via a ::before on the search wrapper (defineTheme), app-wide, without adding component props.

Since these adornment slots were scoped as decorative/non-interactive/aria-hidden, a theme target fully serves the need and avoids adding four new props (searchStartContent/searchEndContent across both Selector and MultiSelector). If a genuinely interactive search adornment is needed later, that can be a single, scoped prop at that point.

@freddymeta freddymeta closed this Aug 1, 2026
@github-actions
github-actions Bot deleted the feat/selector-search-adornments branch August 1, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant