feat(selector): add search adornment slots to Selector & MultiSelector - #4598
feat(selector): add search adornment slots to Selector & MultiSelector#4598freddymeta wants to merge 1 commit into
Conversation
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR Modified ComponentsMultiSelector (@astryxdesign/core) · View in Storybook
Selector (@astryxdesign/core) · View in Storybook
Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
|
Closing in favor of #4596. The driving use case here — a decorative leading magnifier in the search input — is covered by the Since these adornment slots were scoped as decorative/non-interactive/ |
What
Adds
searchStartContent/searchEndContentslots to Selector and MultiSelector for decorative adornments beside the dropdown search input (only inhasSearchmode) — most commonly a leading search/magnifierIcon.Why
The search input had no adornment slot, so a leading magnifier could only be a CSS pseudo-element (
::beforewith an inline-SVGmask) — 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-hiddenand are non-interactive, so:role="combobox", focus, and keyboard behavior (unchanged),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
renderSearchoverride 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
aria-hiddenbeside the input (both components) and don't render withouthasSearch.typecheck:docs,check-sync,sync-exports --check, changeset check, eslint — all green.Non-breaking; default appearance unchanged (no adornments unless provided).