Skip to content
ARC UI ARC Reactive Components
Docs Components Tokens Synthesizer
v2.1.0
Getting Started Frameworks Design Tokens Theming Theme Synthesizer Accessibility Browser Support Changelog Contributing All Components App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageInfinite ScrollMarqueeScroll AreaSeparatorSkeletonSpinnerStackVirtual List Animated NumberBadgeComparisonCountdown TimerData TableDescription ListDiffKey ValueListMeterSparklineStatStepperTableTagTimelineValue Card BlockquoteCode BlockGradient TextHighlightKbdMarkdownNumber FormatProseTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerFieldsetFile UploadFormHotkeyIcon ButtonInputInput GroupLabelMulti SelectNumber InputOTP InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSliderSortable ListSwitch GroupTextareaTheme ToggleTime PickerToggle AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
Components Select
input interactive
<arc-select>

Overview

Guidelines

When to use

  • Always provide a visible label so users understand what they are selecting
  • Use a meaningful placeholder like "Choose a team member..." rather than generic "Select..."
  • Keep option labels concise — ideally under 40 characters
  • Order options logically (alphabetical, by frequency, or by workflow step)
  • Pre-select a sensible default when one exists to reduce interaction cost
  • Use the disabled state to indicate temporarily unavailable choices (e.g., permissions)

When not to use

  • Don't use Select for fewer than 3 options — use RadioGroup for better scannability
  • Don't nest selects inside other selects — flatten the hierarchy or use a staged flow
  • Don't rely solely on placeholder text as a label — placeholders disappear once a value is chosen
  • Don't use Select for navigation — use NavigationMenu or tabs for moving between views
  • Don't disable the component without explaining why — pair disabled state with a tooltip or helper text

Features

  • Type-ahead search filtering narrows options as the user types
  • Full keyboard navigation: Arrow keys, Home, End, Enter, Escape
  • ARIA listbox role with active-descendant tracking for screen readers
  • Supports placeholder text for empty-state guidance
  • Controlled and uncontrolled value modes
  • Disabled state prevents interaction and conveys unavailability visually
  • Automatic scroll-into-view for the highlighted option in long lists
  • Works with dynamic option lists — update the options array at any time
  • Consistent styling across browsers via Shadow DOM encapsulation

Preview

Alice Chen Bob Martinez Carol Nguyen David Okafor Eva Johansson

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<script type="module" src="@arclux/arc-ui"></script>

<!-- Basic select -->
<arc-select label="Assign to team member" placeholder="Choose a person...">
  <arc-option value="alice-chen">Alice Chen</arc-option>
  <arc-option value="bob-martinez">Bob Martinez</arc-option>
  <arc-option value="carol-nguyen">Carol Nguyen</arc-option>
  <arc-option value="david-okafor">David Okafor</arc-option>
  <arc-option value="eva-johansson">Eva Johansson</arc-option>
</arc-select>

<!-- Pre-selected value -->
<arc-select label="Status" value="in-progress">
  <arc-option value="open">Open</arc-option>
  <arc-option value="in-progress">In Progress</arc-option>
  <arc-option value="review">In Review</arc-option>
  <arc-option value="done">Done</arc-option>
</arc-select>

<!-- In a native form -->
<form action="/api/assign" method="post">
  <arc-select name="assignee" label="Assignee" placeholder="Pick someone...">
    <arc-option value="alice">Alice</arc-option>
    <arc-option value="bob">Bob</arc-option>
  </arc-select>
  <button type="submit">Save</button>
</form>

<script>
  document.querySelector('arc-select')
    .addEventListener('arc-change', (e) => {
      console.log('Selected:', e.detail.value, e.detail.label);
    });
</script>
import { Select, Option } from '@arclux/arc-ui-react';
import { useState } from 'react';

function TeamAssigner() {
  const [assignee, setAssignee] = useState('');

  return (
    <Select
      label="Assign to team member"
      placeholder="Choose a person..."
      value={assignee}
      onArcChange={(e) => setAssignee(e.detail.value)}
    >
      <Option value="alice-chen">Alice Chen</Option>
      <Option value="bob-martinez">Bob Martinez</Option>
      <Option value="carol-nguyen">Carol Nguyen</Option>
      <Option value="david-okafor">David Okafor</Option>
      <Option value="eva-johansson">Eva Johansson</Option>
    </Select>
  );
}

function StatusPicker() {
  return (
    <Select label="Status" value="in-progress">
      <Option value="open">Open</Option>
      <Option value="in-progress">In Progress</Option>
      <Option value="review">In Review</Option>
      <Option value="done">Done</Option>
    </Select>
  );
}
<script setup>
import { Select, Option } from '@arclux/arc-ui-vue';
import { ref } from 'vue';

const assignee = ref('');
</script>

<template>
  <Select
    label="Assign to team member"
    placeholder="Choose a person..."
    :value="assignee"
    @arc-change="assignee = $event.detail.value"
  >
    <Option value="alice-chen">Alice Chen</Option>
    <Option value="bob-martinez">Bob Martinez</Option>
    <Option value="carol-nguyen">Carol Nguyen</Option>
    <Option value="david-okafor">David Okafor</Option>
    <Option value="eva-johansson">Eva Johansson</Option>
  </Select>
</template>
<script>
  import { Select, Option } from '@arclux/arc-ui-svelte';

  let status = 'open';
</script>

<Select label="Task status" value={status}
  on:arc-change={(e) => status = e.detail.value}>
  <Option value="open">Open</Option>
  <Option value="in-progress">In Progress</Option>
  <Option value="review">In Review</Option>
  <Option value="done">Done</Option>
  <Option value="closed">Closed</Option>
</Select>
import { Component } from '@angular/core';
import { Select, Option } from '@arclux/arc-ui-angular';

@Component({
  imports: [Select, Option],
  template: `
    <Select label="Assign to team member" placeholder="Choose a person..."
      [value]="assignee" (arc-change)="assignee = $event.detail.value">
      <Option value="alice-chen">Alice Chen</Option>
      <Option value="bob-martinez">Bob Martinez</Option>
      <Option value="carol-nguyen">Carol Nguyen</Option>
      <Option value="david-okafor">David Okafor</Option>
      <Option value="eva-johansson">Eva Johansson</Option>
    </Select>
  `,
})
export class AssignmentComponent {
  assignee = '';
}
import { Select, Option } from '@arclux/arc-ui-solid';
import { createSignal } from 'solid-js';

function CategoryPicker() {
  const [category, setCategory] = createSignal('');

  return (
    <Select label="Category" placeholder="Choose a category..."
      value={category()} onArcChange={(e) => setCategory(e.detail.value)}>
      <Option value="bug">Bug Report</Option>
      <Option value="feature">Feature Request</Option>
      <Option value="docs">Documentation</Option>
      <Option value="question">Question</Option>
    </Select>
  );
}
import { Select, Option } from '@arclux/arc-ui-preact';
import { useState } from 'preact/hooks';

function LocalePicker() {
  const [locale, setLocale] = useState('en');

  return (
    <Select label="Language" value={locale}
      onArcChange={(e) => setLocale(e.detail.value)}>
      <Option value="en">English</Option>
      <Option value="es">Español</Option>
      <Option value="fr">Français</Option>
      <Option value="de">Deutsch</Option>
      <Option value="ja">日本語</Option>
    </Select>
  );
}

API

Prop Type Default Description
value string The currently selected value. Must match one of the child `arc-option` value attributes. Setting this programmatically updates the displayed label and internal selection state.
placeholder string 'Select...' Hint text displayed inside the trigger button when no option is selected. Use it to communicate what kind of choice the user should make, such as "Choose a team member..." or "Pick a status". The placeholder disappears once a value is chosen.
label string Visible label rendered above the select trigger. Also serves as the accessible name for assistive technologies. Always provide a label for accessibility compliance.
size string 'md' Controls the select trigger size. Options: 'sm', 'md', 'lg'.
name string Form field name submitted with the selected value. Required for native form integration via ElementInternals.
disabled boolean false When true, the select trigger becomes non-interactive: it cannot be opened, focused via keyboard, or clicked. The component renders with reduced opacity to visually convey the unavailable state.
error string '' Error message displayed below the select. When set, the trigger border turns red.
open boolean false Controls whether the dropdown is visible. Set programmatically to open or close the dropdown. Automatically set to `false` when an option is selected or the user clicks outside.

Events

Event Description
arc-change Fired when the selected option changes

Option

<arc-option>

Individual option rendered inside a Select or MultiSelect. Each Option provides a value for form submission and displays its text content as the label in the dropdown.

Prop Type Default Description
value string The value submitted when this option is selected. Must be unique within the parent Select.
disabled boolean false When true, dims this option and prevents it from being selected.

See Also