Skip to main content
solution

Completed Design-System API Review

Scenario​

The design-system team proposes a new Combobox primitive used by search, filters, assignment workflows, and GenUI-generated forms. The component must support keyboard navigation, async results, multi-select, grouped options, validation, virtualization, and theming.

Decision​

Approve the component as a headless primitive plus styled product wrappers. Do not expose a single prop-heavy component for all use cases. Require an accessibility contract, state model, async loading contract, and migration plan before broad adoption.

API boundary​

@atlas/ui-primitives/combobox
-> behavior, keyboard, ARIA, state machine, test fixtures

@atlas/design-system/combobox
-> tokens, visual states, density, theming, icons

product wrappers
-> CustomerCombobox, UserAssignCombobox, ReportFilterCombobox

Reviewed API shape​

Required stable concepts:

  • value
  • inputValue
  • options
  • selectedOptions
  • loading
  • disabled
  • invalid
  • onInputChange
  • onSelectionChange
  • getOptionKey
  • getOptionLabel
  • renderOption
  • emptyState
  • loadingState
  • errorState

Rejected API choices:

ProposalReason rejected
any[] options with implicit label fieldbrittle across product domains
built-in data fetchingcouples primitive to app data layer
visual-only invalid stateinaccessible error handling
automatic virtualization always onunnecessary complexity for small lists
generic metadata propencourages hidden product behavior inside primitive

Accessibility contract​

The component must define:

  • label and accessible name requirements
  • keyboard behavior for open, close, navigate, select, clear, and escape
  • focus behavior after selection and validation errors
  • screen-reader announcement for result count, loading, empty, and error states
  • disabled and read-only behavior
  • reduced-motion behavior
  • touch target expectations
  • form integration and error description mapping

State model​

Test matrix​

TestRequired
keyboard open/navigate/select/escapeyes
label and error descriptionyes
async loading and stale response orderingyes
empty stateyes
grouped optionsyes
multi-select chipsyes
virtualization with keyboard navigationyes for large list wrapper
high contrast and forced colorsyes
reduced motionyes
screen-reader smoke testmanual before stable release

Versioning policy​

  • primitive starts at 0.x for two product pilots
  • stable 1.0 requires two successful adoptions and no critical accessibility defects
  • breaking API changes require migration guide and codemod where possible
  • product wrappers can evolve faster than primitive behavior

Adoption plan​

  1. Pilot in report filters and user assignment.
  2. Collect defects, unsupported states, and API friction.
  3. Stabilize primitive behavior and visual wrapper separately.
  4. Migrate legacy select/search components by workflow priority.
  5. Add design-system docs with do/don't examples.
  6. Mark old components deprecated with removal date.

Approval criteria​

  • headless primitive and styled wrapper boundaries are clear
  • accessibility contract is documented and tested
  • async behavior does not own product data fetching
  • product wrappers own domain-specific rendering
  • migration plan exists for legacy select/search components
  • component is compatible with GenUI registry only through validated props

Source lens​

This review is grounded in Part VII design-system architecture, accessibility contracts, the enterprise design-system solution pack, and GenUI registry constraints from Part XIII.