codefast/ui

Command Palette

Search for a command to run...

Source
Form

Native Select

Styled HTML select element with option groups. Zero JS — best for mobile forms.

Examples

Disabled

Add the disabled prop to the NativeSelect component to disable the select.

12 lines
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";

export function NativeSelectDisabled() {
  return (
    <NativeSelect disabled>
      <NativeSelectOption value="">Disabled</NativeSelectOption>
      <NativeSelectOption value="apple">Apple</NativeSelectOption>
      <NativeSelectOption value="banana">Banana</NativeSelectOption>
      <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
    </NativeSelect>
  );
}

Groups

Use NativeSelectOptGroup to organize options into categories.

24 lines
import { NativeSelect, NativeSelectOptGroup, NativeSelectOption } from "@codefast/ui/native-select";

export function NativeSelectGroups() {
  return (
    <NativeSelect>
      <NativeSelectOption value="">Select department</NativeSelectOption>
      <NativeSelectOptGroup label="Engineering">
        <NativeSelectOption value="frontend">Frontend</NativeSelectOption>
        <NativeSelectOption value="backend">Backend</NativeSelectOption>
        <NativeSelectOption value="devops">DevOps</NativeSelectOption>
      </NativeSelectOptGroup>
      <NativeSelectOptGroup label="Sales">
        <NativeSelectOption value="sales-rep">Sales Rep</NativeSelectOption>
        <NativeSelectOption value="account-manager">Account Manager</NativeSelectOption>
        <NativeSelectOption value="sales-director">Sales Director</NativeSelectOption>
      </NativeSelectOptGroup>
      <NativeSelectOptGroup label="Operations">
        <NativeSelectOption value="support">Customer Support</NativeSelectOption>
        <NativeSelectOption value="product-manager">Product Manager</NativeSelectOption>
        <NativeSelectOption value="ops-manager">Operations Manager</NativeSelectOption>
      </NativeSelectOptGroup>
    </NativeSelect>
  );
}

Invalid

Use aria-invalid to show validation errors and the data-invalid attribute to the Field component for styling.

12 lines
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";

export function NativeSelectInvalid() {
  return (
    <NativeSelect aria-invalid="true">
      <NativeSelectOption value="">Error state</NativeSelectOption>
      <NativeSelectOption value="apple">Apple</NativeSelectOption>
      <NativeSelectOption value="banana">Banana</NativeSelectOption>
      <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
    </NativeSelect>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

51 lines
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      placeholder: "Select status",
      todo: "Todo",
      inProgress: "In Progress",
      done: "Done",
      cancelled: "Cancelled",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      placeholder: "اختر الحالة",
      todo: "مهام",
      inProgress: "قيد التنفيذ",
      done: "منجز",
      cancelled: "ملغي",
    },
  },
  he: {
    dir: "rtl",
    values: {
      placeholder: "בחר סטטוס",
      todo: "לעשות",
      inProgress: "בתהליך",
      done: "הושלם",
      cancelled: "בוטל",
    },
  },
};

export function NativeSelectRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <NativeSelect dir={dir}>
      <NativeSelectOption value="">{t.placeholder}</NativeSelectOption>
      <NativeSelectOption value="todo">{t.todo}</NativeSelectOption>
      <NativeSelectOption value="in-progress">{t.inProgress}</NativeSelectOption>
      <NativeSelectOption value="done">{t.done}</NativeSelectOption>
      <NativeSelectOption value="cancelled">{t.cancelled}</NativeSelectOption>
    </NativeSelect>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

11 lines
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";

export function NativeSelectUsage() {
  return (
    <NativeSelect defaultValue="apple">
      <NativeSelectOption value="apple">Apple</NativeSelectOption>
      <NativeSelectOption value="banana">Banana</NativeSelectOption>
      <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
    </NativeSelect>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

NativeSelect
└── NativeSelectOption

Features

  • A real native <select> — zero JS, full OS-native keyboard and screen-reader support, and the mobile picker UI.
  • Two sizes (default, sm).
  • NativeSelectOption/NativeSelectOptGroup use the Canvas/CanvasText CSS system colors, so options render correctly inside the browser's native dropdown popup in both light and dark mode.

API reference

Props for each part of the component. All native element props are also forwarded.

NativeSelect

A styled native <select>. Forwards all native select props.

valuestring

The controlled value.

onChangeReact.ChangeEventHandler<HTMLSelectElement>

Called when the selected value changes.

disabledboolean

Disables the control.

Defaultfalse

NativeSelectOptGroup

labelstring

The group heading text.

NativeSelectOption

valuestring

The option’s submitted value.

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

  • It’s a real <select> — full native keyboard and screen-reader support, zero JS.
  • Best for mobile and long lists where the OS picker is ideal.
  • Pair with a Label via htmlFor / id.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use on mobile forms and when you want the native picker.
  • Group long option lists with opt-groups.

Don’t

  • Don’t use it when you need custom option rendering — use Select.
  • Don’t omit a label.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.