designComponents

Search the design system…

Search the design system…

primitives

EditableSelect

A combobox whose OPTIONS are an editable dictionary — the field IS a search input: type to filter, pick a row, or press Enter to add a new option inline. For a pure picker use `<MultiSelect>` / `<Select>`.

Install

Pull this component (and its dependencies) straight into your app via the shadcn CLI:

npx shadcn@latest add https://design.oapps.io/r/editable-select.json

Or import from the workspace package:

import { EditableSelect } from "@8maverik8/design";

Examples

Editable dictionary (single)

Focus the field and the list drops open; type to filter in place. Pick a row, or — when nothing matches — press Enter (or click the create row) to add the typed value. Each option carries a minimal × delete on hover. The new option auto-selects when the callback returns its value.

const [options, setOptions] = useState([
  { value: "sec", label: "seconds" },
  { value: "count", label: "count" },
  { value: "ms", label: "ms" },
]);
const [value, setValue] = useState<string[]>(["sec"]);

<EditableSelect
  placeholder="Search or add a unit…"
  value={value}
  onChange={setValue}
  options={options}
  createLabel={(q) => `Add "${q}"`}
  onCreateOption={(label) => {
    const v = label.toLowerCase().replace(/[^a-z0-9]+/g, "_");
    setOptions((o) => [...o, { value: v, label }]);
    return v; // auto-selects
  }}
  onDeleteOption={(v) => setOptions((o) => o.filter((x) => x.value !== v))}
/>

Guidelines

  • Use for small, in-place-manageable dictionaries (units, directions, tags, statuses) where a separate CRUD screen would be overkill.
  • Modify `<MultiSelect>` to do this.MultiSelect is a pure picker; EditableSelect is a distinct product (it mutates the option set). Keeping them separate keeps each one's contract clear.
  • Pass `onCreateOption` / `onDeleteOption` to enable creating (Enter / the create row, when the query matches nothing) and the inline × delete. Return the new option's value from `onCreateOption` to auto-select it.
  • Set `multiple` for many-valued fields; leave it off (default single) for single-value dictionaries like a metric's unit.