Components Select <arc-select> 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. |