Select

Selects one option from an overlay. The closed trigger carries a chevron.

Alkmaar
Amsterdam

Face

The only face

Inter, or Inter. Weight and size do the rest.

Use it for

  • One choice from a list of five or more when the labels are short.
  • Lists that benefit from type-ahead and a consistent overlay across platforms.
  • Use fullWidth in compound field layouts. name and form support native submission; required uses native validation and reset restores uncontrolled defaults. readOnly preserves the submitted selection.
  • Mark unavailable options disabled; they stay visible and are skipped by keyboard navigation.

Not for

  • Free text or filtering; use Combobox.
  • A platform picker when it is specifically preferred; use NativeSelect.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { Select } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/select.

2. Vendor the source

npx @noorddev/vlak-cli add select

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/select.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { useState } from "react";
import { Select } from "@noorddev/vlak-react";

const [city, setCity] = useState("alkmaar");

<Select
  aria-label="City"
  options={[
    { value: "alkmaar", label: "Alkmaar" },
    { value: "amsterdam", label: "Amsterdam" },
    { value: "rotterdam", label: "Rotterdam" },
  ]}
  value={city}
  onValueChange={setCity}
/>

Select

Select-only combobox: the trigger holds focus and points at the active option with aria-activedescendant; the listbox overlays.

PropTypeDefaultDescription
optionsrequiredSelectOption[]
valuestring
defaultValuestring
placeholderReactNode"Select…"
onValueChange(value: string) => void
disabledboolean
fullWidthbooleanfalseFill a compound field without imposing a minimum column width.
namestring
formstring
requiredbooleanfalse
readOnlybooleanfalse

Also accepts Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue">.

KeysDoes
Arrow down, Arrow up, Enter, SpaceOpens the list on the selected option
Home, EndOpens on the first or last option; moves there when open
Type lettersJumps to the next matching option, open or closed
Arrow down, Arrow upMoves the active option
Page up, Page downMoves ten options
Enter, SpaceSelects the active option and closes
EscapeCloses and returns focus to the trigger
TabCloses and moves on
<button class="rs-dropdown" role="combobox" aria-haspopup="listbox" aria-expanded="true"><span>Alkmaar</span></button>
<div class="rs-menu rs-select-list" role="listbox"><div class="rs-menu-item rs-menu-item-active" role="option" aria-selected="true">Alkmaar</div><div class="rs-menu-item" role="option" aria-selected="false">Amsterdam</div></div>
.rs-select.rs-select-list.rs-select-fluid.rs-select-native.rs-select-feedback