nalarx-ui
Components

Picker

A pill that opens a menu of described choices, for switching a model, agent or mode.

bunx shadcn@latest add @nalarx/picker

Usage

The caller owns open. onToggle fires for the trigger, Escape and an outside press. Picking a row does not close the menu on its own: close it in the row's onClick.

<Picker open={open} onToggle={() => setOpen((o) => !o)} icon="sparkle" active={model !== "auto"} label={current.title}>
  <PickerLabel>Model</PickerLabel>
  {models.map((m) => (
    <PickRow key={m.id} active={m.id === model} title={m.title} desc={m.desc}
      onClick={() => { setModel(m.id); setOpen(false); }} />
  ))}
</Picker>

Active with a label, a divider and a disabled row; compact (icon only); disabled:

Choose the model that answers
Choose the model that answers

States

  • Active or open: neutral bg-hover wash and a line-strong hairline; never orange.
  • Label change: the label slides in again (nx-label-swap), off under reduced motion.
  • Compact: icon only; label becomes the accessible name and the tooltip.
  • Disabled: 55%, cannot open.
  • Rows: the active one is washed with a check; descriptions clamp to two lines with the full text on hover; disabled rows are 55% and skipped.
  • Placement: right-aligned under the pill, 260px wide by default, flips up and shrinks to stay inside the screen. It sits on --z-popover, so it opens over dialogs.

Keyboard

Key
Enter, Space, ArrowDown on the pillOpens and highlights the first row.
ArrowDown / ArrowUp, Home / EndMoves between rows.
TypingJumps to the row whose title starts with it.
Enter / SpacePicks the row.
EscapeCloses and returns focus to the pill.

Props

Picker: open, onToggle, icon, active, label, leadingVisual?, menuWidth? (260), compact?, disabled?, describedBy?, descriptionText?, children.

PickRow: active, title, desc, onClick, leading?, disabled?.

Replaces

Web Picker.tsx (Picker, PickRow, MenuLabel → PickerLabel, MenuDivider → PickerDivider; the facade keeps the old names). menuZIndex is gone: the menu always sits above dialogs.

On this page