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.jsonimport { MorphSelect } from "@/components/iris/morph-select/morph-select";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
SegmentedControlorRadioCards.
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.
iconis 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.