Skip to content
Aihio v2.3.0
Search
GitHub
Search Describe what you are building, or name a component, intent, or token. Components and patterns are ranked the way the MCP server's find tool ranks them for an agent.

<aihio-combobox> v1.0.0 Markdown for agents

Combobox

A text field for picking one option from a long list: typing filters the options, and the chosen option's value submits with the form. Use it when there are too many options to scan comfortably (roughly more than ten), or when the options come from a search.

Intents form-field selection text-entry

Variants

Every value of the attributes that change how it looks. The values come from the schema.

size

Field size, matching aihio-input.

Finland
size="sm"
Finland
size="md"
Finland
size="lg"

Examples

Each one rendered live, over the markup that produces it.

A searchable list

Typing filters without regard to case or accents.

Finland France Germany Iceland Norway Sweden Åland Islands Type to filter. Accents are optional.
<aihio-field>
  <label slot="label">Country</label>
  <aihio-combobox name="country" placeholder="Search countries">
    <aihio-option value="fi">Finland</aihio-option>
    <aihio-option value="fr">France</aihio-option>
    <aihio-option value="de">Germany</aihio-option>
    <aihio-option value="is">Iceland</aihio-option>
    <aihio-option value="no">Norway</aihio-option>
    <aihio-option value="se">Sweden</aihio-option>
    <aihio-option value="ax">Åland Islands</aihio-option>
  </aihio-combobox>
  <span slot="description">Type to filter. Accents are optional.</span>
</aihio-field>

Rich options and a preset value

label sets the text shown once an option is chosen; a disabled option cannot be.

Ada Lovelace Engineering Grace Hopper Compilers Alan Turing On leave
<aihio-field>
  <label slot="label">Assignee</label>
  <aihio-combobox name="assignee" value="ada">
    <aihio-option value="ada" label="Ada Lovelace">Ada Lovelace <small>Engineering</small></aihio-option>
    <aihio-option value="grace" label="Grace Hopper">Grace Hopper <small>Compilers</small></aihio-option>
    <aihio-option value="alan" label="Alan Turing" disabled>Alan Turing <small>On leave</small></aihio-option>
  </aihio-combobox>
</aihio-field>

Free text allowed

allow-custom keeps text that matches no option.

bug design documentation
<aihio-field>
  <label slot="label">Tag</label>
  <aihio-combobox name="tag" allow-custom placeholder="Pick or type a tag">
    <aihio-option>bug</aihio-option>
    <aihio-option>design</aihio-option>
    <aihio-option>documentation</aihio-option>
  </aihio-combobox>
</aihio-field>

Options from a server

filter="none" leaves filtering to you: listen for aihio-search and replace the options.

<aihio-combobox aria-label="Search users" name="user" filter="none" empty-text="Type to search"></aihio-combobox>

Mistakes

Each one beside its fix, with what aihio lint says about it. The prompt fragment gives agents the same pairs, and the build fails if the linter stops catching one or a fix stops passing.

Placeholder is not a label.

Wrap it in aihio-field with a label slot, or add aria-labelledby or aria-label.

Don't

<aihio-combobox placeholder="Country">
  <aihio-option value="fi">Finland</aihio-option>
</aihio-combobox>

aihio lint reports

  • combobox-label error Label it with aria-labelledby pointing at visible text, or aria-label. Placeholder is not a label, and a wrapping <label> would fold the option text into the field's name.

Do

Finland
<aihio-field>
  <label slot="label">Country</label>
  <aihio-combobox name="country">
    <aihio-option value="fi">Finland</aihio-option>
  </aihio-combobox>
</aihio-field>

A wrapping <label> takes its name from all of its text, so an open list's options become part of the field's name.

Use aihio-field instead.

Don't

<label>
  Country
  <aihio-combobox>
    <aihio-option value="fi">Finland</aihio-option>
  </aihio-combobox>
</label>

aihio lint reports

  • combobox-label error Label it with aria-labelledby pointing at visible text, or aria-label. Placeholder is not a label, and a wrapping <label> would fold the option text into the field's name.

Do

Finland
<aihio-field>
  <label slot="label">Country</label>
  <aihio-combobox name="country">
    <aihio-option value="fi">Finland</aihio-option>
  </aihio-combobox>
</aihio-field>

Native <option> elements are not read.

Use aihio-option.

Don't

<aihio-combobox aria-label="Size">
  <option value="s">Small</option>
  <option value="m">Medium</option>
</aihio-combobox>

aihio lint reports

  • invalid-child error child <option> is not allowed here. Expected: aihio-option.
  • invalid-child error child <option> is not allowed here. Expected: aihio-option.

Do

Small Medium
<aihio-combobox aria-label="Size">
  <aihio-option value="s">Small</aihio-option>
  <aihio-option value="m">Medium</aihio-option>
</aihio-combobox>

An option without a value uses its label as its value, so both options have the value "Pro" and the second can never be told apart from the first.

Don't

<aihio-combobox aria-label="Plan">
  <aihio-option>Pro</aihio-option>
  <aihio-option value="Pro">Pro (annual)</aihio-option>
</aihio-combobox>

aihio lint reports

  • combobox-option-values error Give every option a distinct value; the value is how the chosen option is found again.

Do

Pro Pro (annual)
<aihio-combobox aria-label="Plan">
  <aihio-option value="pro">Pro</aihio-option>
  <aihio-option value="pro-annual">Pro (annual)</aihio-option>
</aihio-combobox>

API

Every attribute, property, method, and event the schema declares for aihio-combobox.

Attributes

value
string
Value of the initially chosen option, and the value a form reset returns to. The value property carries the live choice.
name
string
Form field name. The chosen option's value (not its label) is submitted under it. Without it the field submits nothing.
form
string
Id of an external form that owns the field.
placeholder
string
Placeholder text. It is not a label.
disabled
boolean default false
Disables the field. A disabled field submits nothing.
readonly
boolean default false
Shows the chosen option without letting it change. The value still submits.
required
boolean default false
Requires a choice for native constraint validation.
error
boolean default false
Shows error styling and sets aria-invalid. aihio-field sets this from its error slot.
size
one of smmdlg default md
Field size, matching aihio-input.
filter
one of containsstarts-withnone default contains
How typing filters the options. contains ranks prefix matches first, then word-start matches, then any match. none shows every option as given, for lists filtered by a server.
allow-custom
boolean default false
Accepts typed text that matches no option; the text becomes the value. Without it, leaving the field reverts unmatched text to the chosen option.
loading
boolean default false
Shows a loading row and marks the list busy while options are being fetched.
empty-text
string default No results
Shown and announced when no option matches.
loading-text
string default Loading…
Shown and announced while loading is set.
results-text
string
Result-count announcement with a {count} placeholder, for localisation (e.g. "{count} tulosta"). Defaults to "1 result" / "N results".
open
boolean default false
Reflects whether the list is showing. Set or remove it to open or close the list.

Properties

value
string
Get or set the chosen option's value (or the free text, with allow-custom). Setting it does not fire aihio-change.
defaultValue
string
Get or set the reset value reflected by the value attribute
selectedOption
HTMLElement | null read-only
The chosen aihio-option, or null
control
HTMLInputElement | null read-only
The native text input carrying role="combobox"
form
HTMLFormElement | null read-only
The owning form, or null outside one
validity
ValidityState | null read-only
Native constraint validation state
validationMessage
string read-only
Native validation message
willValidate
boolean read-only
Whether the field participates in constraint validation

Methods

open(): void
Opens the list showing every option, with the chosen one highlighted.
close(): void
Closes the list, reverting unconfirmed text to the chosen option.
toggle(): void
Opens or closes the list.
focus(options?: FocusOptions): void
Moves focus to the text input.
checkValidity(): boolean
Runs native constraint validation and returns whether the field is valid.
reportValidity(): boolean
Runs native constraint validation and shows the browser message if invalid.
setCustomValidity(message: string): void
Sets a custom validation message.

Events

aihio-change
detail { value: string, label: string }
Fired when the person commits a different choice, or when a form reset changes it. Not fired for programmatic value changes.
aihio-search
detail { query: string }
Fired on every keystroke with the typed text. Use it to fetch options for filter="none".
aihio-open
Fired after the list opens.
aihio-close
detail { reason: string }
Fired after the list closes.

Composition

Allowed children
aihio-option

Sub-components

Used only inside aihio-combobox, which gives them their roles and keyboard behaviour.

<aihio-option>

One choice in an aihio-combobox. Its text (or label attribute) is what typing matches and what the field shows once chosen.

Attributes

value
string
Submitted value. Defaults to the label.
label
string
Text matched against and shown in the field when the content is richer than a plain label (an icon, a secondary line).
disabled
boolean default false
Shown but cannot be chosen, and skipped by the arrow keys.

Properties

value
string
The value attribute, or the label when it is absent
label
string
The label attribute, or the normalised text content
disabled
boolean
Reflects the disabled attribute
selected
boolean read-only
Whether the owning combobox has this option chosen

Accessibility

What you have to provide, and what the component already does. The obligations with a rule are checked by aihio lint and by the dev build's console warnings.

Your obligations

  • error When the combobox is not inside an aihio-field

    Label it with aria-labelledby pointing at visible text, or aria-label. Placeholder is not a label, and a wrapping <label> would fold the option text into the field's name.

    Checked as combobox-label

  • error When two aihio-option children share a value

    Give every option a distinct value; the value is how the chosen option is found again.

    Checked as combobox-option-values

  • warn When the combobox is inside a <form> and its value should be submitted

    Set name. A combobox without a name is omitted from FormData.

    Checked as combobox-form-name

Handled for you

  • A real <input role="combobox"> with aria-autocomplete="list", aria-expanded, and aria-controls pointing at the listbox
  • DOM focus stays in the input; aria-activedescendant follows the highlighted option, in the same tree as the options it names
  • Options render as role="option" inside role="listbox"; the chosen option has aria-selected="true" and a check mark, disabled options have aria-disabled
  • ArrowDown/ArrowUp open the list and move through enabled options (wrapping); Alt+ArrowDown opens without moving; Alt+ArrowUp accepts and closes; PageDown/PageUp jump ten
  • Enter chooses the highlighted option; Escape closes and reverts unconfirmed text, and is left alone when the list is closed so a surrounding dialog still closes
  • Tab accepts the highlighted option and moves on; leaving the field any other way keeps the previous choice unless the text matches an option exactly
  • Typing filters case- and accent-insensitively ("aland" finds "Åland"), ranks prefix matches first, highlights the first match, and sets the matched text in bold
  • A polite status region announces the result count, the empty message, or the loading message once typing pauses
  • The toggle button is out of the tab order, carries the field's label, and exposes aria-expanded
  • Keys pressed while an IME is composing are left to the IME
  • The chosen value submits through a hidden input under name; required, form reset, <fieldset disabled>, and the form attribute behave natively
  • The list renders in the top layer, flips above the field when there is more room there, and fits the visual viewport above an on-screen keyboard
  • Forced colours restate the highlighted and disabled states with system colours; reduced motion removes the open animation and spinner