Select
A dropdown with optional groups and a search field, driven by the keyboard, for choices a native select cannot style or filter.
-
<aparte-select> + 2 parts
<aparte-select placeholder="Pick a format" value="md" style="max-width: 16rem">
<aparte-option value="md">Markdown</aparte-option>
<aparte-option value="pdf">PDF</aparte-option>
<aparte-option value="html">Web page</aparte-option>
</aparte-select><aparte-select> is the dropdown the model selector and the
approval mode switch are built on. Its options are
<aparte-option> children, optionally grouped in <aparte-optgroup>. The value is an attribute;
a change fires aparte-select-change with the new value, its label and the previous value.
Variants
Section titled “Variants”Groups and a search field
Section titled “Groups and a search field”<!-- searchable adds a filter field; an optgroup labels a band of options. -->
<aparte-select placeholder="Pick a model" searchable style="max-width: 16rem">
<aparte-optgroup label="Cloud">
<aparte-option value="large">Large</aparte-option>
<aparte-option value="fast">Fast</aparte-option>
</aparte-optgroup>
<aparte-optgroup label="In the browser">
<aparte-option value="small">Small, offline</aparte-option>
<aparte-option value="tiny" disabled>Tiny (not downloaded)</aparte-option>
</aparte-optgroup>
</aparte-select>searchable adds a field that filters the options as you type. A group has a label; it can be
collapsible, and loading adds a spinner row while its options arrive.
<aparte-select disabled=""></aparte-select>el.addEventListener('aparte-select-change', (e) => use(e.detail));<aparte-select disabled=""></aparte-select>The aparte-* tags are typed JSX intrinsics as soon as you import from @aparte/react. A presence attribute takes '', never true — React stringifies it, and disabled={false} would render disabled="false", which hasAttribute reads as on. Events reach you by ref, typed through the DOM.
<template>
<aparte-select disabled=""
@aparte-select-change="(e) => use(e.detail)"
></aparte-select>
</template>Declared through Vue’s GlobalComponents, so vue-tsc checks the tag in any template. A presence attribute takes '' to set and null to remove, never false.
<aparte-select disabled=""
on:aparte-select-change={(e) => use(e.detail)}
></aparte-select>Declared through SvelteHTMLElements, so svelte-check covers the attributes and the on: handlers. A presence attribute takes '', never false.
import { AparteSelectDirective } from '@aparte/angular';<aparte-select [disabled]="true"
(selectChange)="use($event)"></aparte-select>A standalone directive whose selector IS the tag, so the real element sits in the template — @if, @for and content projection all reach it — and no CUSTOM_ELEMENTS_SCHEMA is needed.
Installation and the framework-specific traps: React · Vue · Svelte · Angular.
<aparte-select>
Section titled “<aparte-select>”<aparte-select> · class AparteSelect
Attributes
| Attribute | Description |
|---|---|
value | The selected option’s value. |
placeholder | Shown while nothing is selected. |
disabled | Blocks opening the dropdown. |
searchable | Adds a filter field above the options. Read on the first render only. |
open | Reflects (and controls) whether the dropdown is open. |
Properties
| Property | Type | Description |
|---|---|---|
value | string | |
open | boolean |
Events
| Event | Type | Description |
|---|---|---|
aparte-select-open | CustomEvent | The dropdown opened. No detail. |
aparte-select-close | CustomEvent | The dropdown closed. No detail. |
aparte-select-change | CustomEvent<AparteSelectChangeDetail> | The selection changed; carries the new value, its label and the previous value. |
CSS variables
| Variable | Default | Description |
|---|---|---|
--aparte-select-bg | var(--aparte-surface-1) | Trigger background. (The dropdown panel has its own token, --aparte-select-dropdown-bg, in both themes.) |
--aparte-select-border | var(--aparte-border-control) | Border of the trigger and of the dropdown. |
--aparte-select-border-hover | var(--aparte-border-control) | Trigger border on hover. |
--aparte-radius-select | var(--aparte-radius-md) | Corner radius of the trigger and the dropdown — the theme’s knob, beside --aparte-radius-input and the others. (It used to exist twice, as this and a private --aparte-select-radius with a different value.) |
--aparte-select-text | var(--aparte-text) | Colour of the trigger label (and of the options). |
--aparte-select-chevron | var(--aparte-text-muted) | Colour of the chevron, which rotates 180° while open. |
--aparte-select-dropdown-bg | var(--aparte-surface-1) | Dropdown panel background, in both themes (--aparte-surface-1 is dark-aware). It used to be read in the light theme only, the dark rule taking the TRIGGER’s background instead — so a transparent trigger made the panel see-through in the dark. |
--aparte-select-shadow | 0 1px 3px rgba(0, 0, 0, 0.08), 0 10px 28px rgba(0, 0, 0, 0.16) | Dropdown panel shadow. |
--aparte-select-z | var(--aparte-z-dropdown) | z-index of the dropdown. It is position: fixed, so this is the one knob that decides whether it lands above the rest of your page. |
<aparte-option>
Section titled “<aparte-option>”<aparte-option> · class AparteOption
Attributes
| Attribute | Description |
|---|---|
value | Option value |
disabled | Disabled state |
selected | Selected state |
data-status | Free-form status the host sets; styled, never read by core. |
Properties
| Property | Type | Description |
|---|---|---|
value | string | |
label (readonly) | string | |
disabled | boolean | |
selected | boolean |
CSS variables
| Variable | Default | Description |
|---|---|---|
--aparte-select-text | var(--aparte-text) | Option text colour. |
--aparte-select-option-hover | var(--aparte-surface-2) | Background on hover, and for the keyboard-active row ([data-active]), which adds an inset --aparte-primary ring on top so the two are distinguishable. |
--aparte-select-option-selected | color-mix(in srgb, var(--aparte-primary) var(--aparte-mark-tint), transparent) | Background of the selected row. A tint by default: a solid accent fill with white text failed WCAG AA in both themes. |
--aparte-select-option-selected-text | var(--aparte-select-text, var(--aparte-text)) | Text colour of the selected row. Set both this and the background to go back to a solid fill. |
<aparte-optgroup>
Section titled “<aparte-optgroup>”<aparte-optgroup> · class AparteOptgroup
Attributes
| Attribute | Description |
|---|---|
label | Group label |
collapsible | Adds the chevron and the click handler to the header — so it needs a label, and it is read only when that header is first built. |
collapsed | Collapsed state |
loading | Appends a spinner row to the group; the options stay visible. |
Properties
| Property | Type | Description |
|---|---|---|
label | string | |
collapsible | boolean | |
collapsed | boolean | |
loading | boolean |
Events
| Event | Type | Description |
|---|---|---|
aparte-optgroup-toggle | CustomEvent<AparteOptgroupToggleEventDetail> | The group was collapsed or expanded. |
CSS variables
| Variable | Default | Description |
|---|---|---|
--aparte-text-muted | — | Colour of the group header label and of the loading row. The shared theme token: there is no optgroup-specific override, so restyling one group’s header means setting this on that element. |
Accessibility
Section titled “Accessibility”- The trigger is a combobox (a button when the list is searchable) that opens a list box; the arrow keys move through the options, Enter picks one, Escape closes.
- A group is a labelled group, so a screen reader names it with each option.
- Give the select an
aria-label, or a placeholder that says what it chooses.
Related
Section titled “Related”- Model selector — a select over providers and models.
- Field — the native
<select>with the field recipe. - Menu — a list of commands rather than a value.