Skip to content
Kappa
Native Select
@dicehub/kappav0.4.2

Native Select

A styled native select for simple choices, platform menus, and direct form submission.

Selected: eu-central

<script setup>
import { ref } from "vue";
import { Label } from "@dicehub/kappa/components/label";
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const region = ref("eu-central");
</script>

<template>
  <Label for="native-select-preview-region">Deployment region</Label>
  <NativeSelect
    id="native-select-preview-region"
    v-model="region"
    name="region"
    aria-describedby="native-select-preview-help"
  >
    <NativeSelectOption value="us-east">US East</NativeSelectOption>
    <NativeSelectOption value="eu-central">EU Central</NativeSelectOption>
    <NativeSelectOption value="ap-southeast">Asia Pacific</NativeSelectOption>
  </NativeSelect>
  <p id="native-select-preview-help">Selected: {{ region }}</p>
</template>

Installation

Native Select is part of the main Kappa package. It uses the browser select element and adds no state-machine dependency.

Barrel

import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@dicehub/kappa";

Granular

import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

Usage

Add an accessible name, then use v-model or a native initialvalue. Native form attributes and event listeners pass to the select.

<script setup>
import { ref } from "vue";
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const strategy = ref("balanced");
</script>

<template>
  <NativeSelect v-model="strategy" aria-label="Release strategy">
    <NativeSelectOption value="safe">Safe</NativeSelectOption>
    <NativeSelectOption value="balanced">Balanced</NativeSelectOption>
    <NativeSelectOption value="fast">Fast</NativeSelectOption>
  </NativeSelect>
</template>

Composition

Typical part hierarchy
NativeSelect.Root <span>
├── native <select>
│   ├── NativeSelect.Option
│   └── NativeSelect.OptGroup
│       └── NativeSelect.Option
└── decorative chevron <svg>

Kappa styles a native select control. The browser owns menu behavior, keyboard input, and platform presentation.

  • Use Native Select for short, fixed choice lists and standard form behavior.
  • Use Select for a fully styled Ark UI popup, custom placement, or richer option content.
  • Use Field.Select when Ark UI must connect the label, helper text, required state, and error message.

Examples

Sizes

Four control densities align Native Select with Kappa inputs and buttons.

xs
sm
base
lg
<script setup>
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";
</script>

<template>
  <NativeSelect size="xs" aria-label="Extra-small unit" value="metric">
    <NativeSelectOption value="metric">Metric units</NativeSelectOption>
    <NativeSelectOption value="imperial">Imperial units</NativeSelectOption>
  </NativeSelect>
  <NativeSelect size="sm" aria-label="Small unit" value="metric">
    <NativeSelectOption value="metric">Metric units</NativeSelectOption>
    <NativeSelectOption value="imperial">Imperial units</NativeSelectOption>
  </NativeSelect>
  <NativeSelect size="base" aria-label="Base unit" value="metric">
    <NativeSelectOption value="metric">Metric units</NativeSelectOption>
    <NativeSelectOption value="imperial">Imperial units</NativeSelectOption>
  </NativeSelect>
  <NativeSelect size="lg" aria-label="Large unit" value="metric">
    <NativeSelectOption value="metric">Metric units</NativeSelectOption>
    <NativeSelectOption value="imperial">Imperial units</NativeSelectOption>
  </NativeSelect>
</template>

Option Groups

Use native option groups to name related choices.

<script setup>
import { ref } from "vue";
import { Label } from "@dicehub/kappa/components/label";
import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const office = ref("london");
</script>

<template>
  <Label for="native-select-office">Office</Label>
  <NativeSelect id="native-select-office" v-model="office">
    <NativeSelectOptGroup label="Europe">
      <NativeSelectOption value="berlin">Berlin</NativeSelectOption>
      <NativeSelectOption value="london">London</NativeSelectOption>
    </NativeSelectOptGroup>
    <NativeSelectOptGroup label="Asia Pacific">
      <NativeSelectOption value="singapore">Singapore</NativeSelectOption>
      <NativeSelectOption value="sydney">Sydney</NativeSelectOption>
    </NativeSelectOptGroup>
  </NativeSelect>
</template>

Form States

Native disabled and required behavior remains authoritative. Connect invalid controls to clear correction text.

Select a priority.

<script setup>
import { ref } from "vue";
import { Label } from "@dicehub/kappa/components/label";
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const priority = ref("");
</script>

<template>
  <Label for="native-select-disabled" data-disabled>Disabled</Label>
  <NativeSelect id="native-select-disabled" disabled value="archived">
    <NativeSelectOption value="archived">Archived</NativeSelectOption>
  </NativeSelect>

  <Label for="native-select-invalid">Priority</Label>
  <NativeSelect
    id="native-select-invalid"
    v-model="priority"
    invalid
    required
    aria-describedby="native-select-error"
  >
    <NativeSelectOption value="" disabled>Select a priority</NativeSelectOption>
    <NativeSelectOption value="normal">Normal</NativeSelectOption>
    <NativeSelectOption value="urgent">Urgent</NativeSelectOption>
  </NativeSelect>
  <p id="native-select-error">Select a priority.</p>
</template>

Multiple

Add multiple and bind an array. The native menu emits all selected values.

Selected: pdf, csv

<script setup>
import { ref } from "vue";
import { Label } from "@dicehub/kappa/components/label";
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const formats = ref(["pdf", "csv"]);
</script>

<template>
  <Label for="native-select-formats">Export formats</Label>
  <NativeSelect id="native-select-formats" v-model="formats" multiple name="formats">
    <NativeSelectOption value="csv">CSV</NativeSelectOption>
    <NativeSelectOption value="json">JSON</NativeSelectOption>
    <NativeSelectOption value="pdf">PDF</NativeSelectOption>
    <NativeSelectOption value="xlsx">Excel</NativeSelectOption>
  </NativeSelect>
  <p>Selected: {{ formats.join(", ") }}</p>
</template>

Right to Left

The chevron and control padding follow the inherited writing direction.

<script setup>
import { ref } from "vue";
import { Label } from "@dicehub/kappa/components/label";
import {
  NativeSelect,
  NativeSelectOption,
} from "@dicehub/kappa/components/native-select";

const region = ref("cairo");
</script>

<template>
  <div dir="rtl" lang="ar">
    <Label for="native-select-region-ar">المنطقة</Label>
    <NativeSelect id="native-select-region-ar" v-model="region">
      <NativeSelectOption value="cairo">القاهرة</NativeSelectOption>
      <NativeSelectOption value="dubai">دبي</NativeSelectOption>
      <NativeSelectOption value="doha">الدوحة</NativeSelectOption>
    </NativeSelect>
  </div>
</template>

Accessibility

  • Give every Native Select a visible Label when the layout permits it.
  • Keep a disabled placeholder option when the first choice is not a valid value.
  • Connect help and error text with aria-describedby.
  • Use option groups only when their labels help users understand the choices.
  • Native keyboard, touch, form, forced-color, and browser zoom behavior stays intact.

API Reference

NativeSelect

Renders one native select. Standard select attributes pass to the same element.

PropTypeDefaultDescription
invalidbooleanfalseSets invalid presentation and aria-invalid=true.
modelValuestring | number | readonly (string | number)[]—Controlled value used by Vue v-model. Multiple selects use an array.
size"xs" | "sm" | "base" | "lg""base"Sets visual density. This replaces the native visible-row size attribute.

Events

EventPayloadDescription
update:modelValuestring | string[]Emitted on native change. Multiple selects emit selected values as an array.
change / inputEventNative listeners pass through to the select element.

Data Attributes

AttributeValueDescription
data-slot"native-select"Stable control selector.
data-size"xs" | "sm" | "base" | "lg"Resolved density.
data-invalid""Present when the control is invalid.

Exports

ExportDescription
NativeSelectStyled native select root with compound aliases.
NativeSelectRootExplicit root alias.
NativeSelectOptionNative option part.
NativeSelectOptGroupNative option-group part.
NativeSelectProps / NativeSelectEmitsPublic prop and event contracts.
NativeSelectModelValue / NativeSelectSizeValue and density types.