Skip to content
Liquidify
HomeDocsComponentsExamplesPlayground
⌘K
(opens in new tab)
Liquidify

Accessible React controls with a CSS and SVG material engine.

Product

ComponentsExamplesPlaygroundPackages

Learn

DocumentationGetting startedConceptsAI resources

Project

CommunityShowcaseVersionsGitHub

Independent open-source software. Not affiliated with or endorsed by Apple Inc.

LicenseBrand

Component catalog

Browse the public controls by interaction purpose. Every result links to generated API facts, accessibility behavior, source, and exhaustive stories.

Picker

A single-select control that chooses one value from a discrete set of options.

import { Picker } from "@liquidify/react/picker"

Overview

Basic Picker

A focused starting point showing Picker with its essential configuration.

API

PropTypeDefaultDescription
classNamestring | undefined—Optional additional CSS class merged into the glass surface class. The supported per-instance customisation seam: override any `--lq-*` custom property from this class's CSS — the token cascade the engine reads (ADR-0004). No raw inline style is involved, so this stays ADR-0003 clean.
defaultOpenboolean | undefinedfalseUncontrolled seed for the open state of the menu popover panel. Ignored for `segmented` and `wheel` styles. Pass `defaultOpen={true}` in a Storybook story or test to pre-open the listbox panel for visual grading without a user interaction.
defaultValuestring | undefineditems[0].valueUncontrolled seed for the internal selection (ignored once {@link PickerProps.value} is supplied).
disabledboolean | undefined—When `true`, the whole control is dimmed, removed from the tab order, and all interaction is suppressed. Since the roots vary by style (some are `<div>`, some `<button>`), `data-disabled` provides the CSS hook and `aria-disabled` is set on the appropriate ARIA root.
items
required
readonly PickerItem[]—The selectable options, rendered in order. At least one item is required.
labelPropsLabelProps | undefined—Per-instance typography override for the trigger value and the option labels, forwarded to the internal {@link Text} (ADR-0028). Token-backed axes only; the HIG default is `variant="body"` with `color="inherit"`, so each label adopts its host's colour (accent trigger, primary/secondary option, the wheel's selected colour transition). Applies only to string/number labels — an `<Icon>` / element label passes through unwrapped.
onChange((next: string) => void) | undefined—Fires with the next selected item's `value` whenever the selection changes. Always called, in both controlled and uncontrolled modes.
onOpenChange((open: boolean) => void) | undefined—Fires with the next open state on every open/close path of the menu popover panel — trigger click, item selection, Escape, and outside pointer-down. Ignored for `segmented` and `wheel` styles.
openboolean | undefined—Controlled open state of the menu popover panel (ADR-0015 presentation triad, with {@link PickerProps.defaultOpen} / {@link PickerProps.onOpenChange}). Passing it switches the open state to controlled mode: the panel follows this prop and every open/close request only notifies. Ignored for `segmented` and `wheel` styles.
placementPickerPlacement | undefinedtop-leftWhich trigger corner the `menu` panel anchors to — the corner picks the open side (`top-*` below the trigger, `bottom-*` above) and the trigger edge the panel aligns with (`*-left` / `*-right`), so the menu grows away from that corner (see {@link PickerPlacement}). Ignored for `segmented` and `wheel` styles.
refRef<HTMLDivElement> | undefined—Forwarded ref to the rendered element — the component's native root (or the merged child element on a component that opts into {@link SlottableProps}). Generic over `E` (charter `docs/api-conventions.md` §4 rule 1, default `HTMLElement`) so a component with a polymorphic root (Link's navigation / action mode union, Text's `as`) can instantiate the concrete element per variant instead of leaving every consumer with a widened `Ref<HTMLElement>`. A component that does not narrow simply inherits the `HTMLElement` default — source-compatible with every pre-existing non-generic `extends ControlProps`.
valuestring | undefined—Controlled selected value. Passing this switches Picker to controlled mode: the rendered selection always reflects this value and the consumer owns it via {@link PickerProps.onChange}.
variantPickerVariant | undefinedmenuThe visual variant of the picker — maps to SwiftUI `pickerStyle`.

Guidelines

Do
  • Use Picker when its semantics match the content or action.
  • Keep labels concise, specific, and consistent with the surrounding interface.
  • Test the component with keyboard navigation, zoom, and both color schemes.
Don't
  • Do not use Picker as a visual substitute for a different semantic element.
  • Do not rely on color or an icon alone to communicate essential meaning.
  • Do not override the component tokens with fixed values unless the product theme requires it.

Accessibility

Picker supports the documented keyboard interactions below.

Keyboard
  • Press Tab to move focus to the control.
  • Use the control's documented activation keys without trapping focus.
  • Provide an accessible name whenever the visible label is absent.

Tokens

NameValue
--lq-color-#ffffff#f2f2f7#e5e5ea#000000rgba(60, 60, 67, 0.6)rgba(235, 235, 245, 0.6)rgba(60, 60, 67, 0.3)rgba(235, 235, 245, 0.3)rgba(60, 60, 67, 0.18)rgba(235, 235, 245, 0.16)#007affrgba(60, 60, 67, 0.14)
--lq-color-accent#007aff
--lq-color-bg-primary#ffffff
--lq-color-label-primaryComponent-defined value
--lq-color-label-quaternary-darkrgba(235, 235, 245, 0.16)
--lq-color-label-quaternary-lightrgba(60, 60, 67, 0.18)
--lq-color-label-secondaryComponent-defined value
--lq-color-separatorrgba(60, 60, 67, 0.14)
--lq-glass-440.71.15var(--lq-segmented-control-indicator-blur)calc(var(--lq-glass-material-blur) * 8)var(--lq-shadow-presentational)
--lq-hit-target-touch2.75rem
--lq-icon-size-smallComponent-defined value
--lq-lens-progressResolved by the active Liquidify theme
--lq-lens-stretchResolved by the active Liquidify theme
--lq-lens-xResolved by the active Liquidify theme
--lq-picker-indicator-alpha78%
--lq-picker-padvar(--lq-space-4)var(--lq-space-12)
--lq-picker-wheel-band-filllight-dark( var(--lq-color-label-quaternary-light), var(--lq-color-label-quaternary-dark) )
--lq-picker-wheel-band-hvar(--lq-picker-track-h, var(--lq-space-40))
--lq-picker-wheel-band-insetvar(--lq-picker-pad, var(--lq-space-4))
--lq-picker-wheel-band-radiusvar(--lq-radius-pill)
--lq-picker-wheel-hcalc(var(--lq-picker-wheel-pitch) * 5)calc(6 * var(--lq-date-picker-cell) + 5 * var(--lq-date-picker-gap))
--lq-radius-largeComponent-defined value
--lq-radius-pill9999rem
--lq-shadow-ambient-0 0.125rem 0.375rem rgba(0, 0, 0, 0.10)0 0.5rem 1.375rem rgba(0, 0, 0, 0.20)0 0.75rem 1.75rem rgba(0, 0, 0, 0.14)
--lq-space-0.0625rem0.125rem0.25rem0.5rem0.75rem1rem1.25rem1.5rem2rem2.5rem3rem3.5rem

Key features

  • Liquid material

    Uses Liquidify surfaces and theme-aware design tokens.

  • Typed API

    Provides a typed React API with generated prop documentation.

  • Accessible by default

    Preserves semantic structure, focus visibility, and assistive-technology state.

Resources

  • Source
  • Markdown
  • JSON
  • Storybook
Components