Components / Inputs

MorphSelect

A select whose trigger grows into the list, with a gliding highlight and type-ahead.

Install

npx shadcn@latest add https://irisui.dev/r/morph-select.json
import { MorphSelect } from "@/components/iris/morph-select/morph-select";
Registry item morph-selectBrings in foundationRegistry JSON

Preview

MorphSelect

A select whose trigger grows into its option list, with a gliding highlight, groups, type-ahead and optional search.

When to use

  • Picking one value from a short to medium list: assignee, time zone, model, priority.
  • Lists with icons, avatars or trailing meta (offsets, counts); groups and search kick in for longer lists.
  • Not for multi-select filters; use ChipGroup.
  • Not for two to four always-visible options; use SegmentedControl or RadioCards.

Usage

import { MorphSelect } from "@/components/iris/morph-select/morph-select";

const [zone, setZone] = useState("athens");
h(MorphSelect, {
  label: "Time zone",
  name: "timezone",
  value: zone,
  onValueChange: setZone,
  items: [
    {
      label: "Europe",
      options: [
        { value: "lisbon", label: "Lisbon", meta: "UTC+0" },
        { value: "berlin", label: "Berlin", meta: "UTC+1" },
        { value: "athens", label: "Athens", meta: "UTC+2" },
      ],
    },
  ],
});

Props

Prop Type Default Description
label string required Visible label and accessible name of the trigger and list.
hideLabel boolean false Keeps the label for assistive technology only.
items (MorphSelectOption | MorphSelectGroup)[] required Options { value, label, icon?, meta?, keywords?, disabled? } or groups { label, options }.
value / defaultValue string | null – / null Controlled or initial selection.
onValueChange (value, option) => void – Receives the new value and its option.
placeholder string "Select" Trigger text with no selection.
searchable boolean | "auto" "auto" Search field in place of the trigger; auto turns it on above eight options.
searchPlaceholder string – Search placeholder.
panelWidth number 272 Open surface width in px; never narrower than the trigger.
maxListHeight number 296 Tallest list before it scrolls.
align "start" | "end" "start" Edge that stays put while the surface grows.
name string – Adds a hidden input for form submission.
disabled boolean false Disables the trigger.
className string – Extra class on the root.

Notes

  • Keyboard: Enter, Space or arrows open; arrows skip disabled options; PageUp/PageDown move by eight; Home/End; Alt+ArrowUp picks and closes; typing jumps or filters; Escape closes and returns focus; Tab closes without picking.
  • The trigger is a combobox pointing at the active option; with search on, the input becomes the combobox. A polite live region announces result counts.
  • icon is a 20px mark; pass an avatar or a plain icon.
  • Reduced motion makes size changes instant and replaces the fly and roll with fades.
  • Reads --surface, --hover, --line, --line-strong, --line-soft, --ink-2, --ink-3, --shadow-resting, --shadow-floating.