multiple is enabled — from a predefined list. It pairs a styled trigger with a floating panel of bq-option elements and integrates with native HTML forms.
When to use
Use Select when
- The option list contains more than five items and a radio group would take too much space
- Users need to choose from a predefined set of values in a form
- Multiple selection from a long list is required and a checkbox group would be impractical
- The available choices are dynamic or loaded from an external source
Patterns
Single select
Single Select allows the user to pick one option from a menu.
Multiple select
Multiple Select allows the user to pick multiple options from a menu via checkboxes. Once selected, the items are shown as dismissible tags in the input field above.
Anatomy
| Part | Element | Description |
|---|---|---|
| 1 | Label | The descriptive label rendered above the input control |
| 2 | Input field | The control area that displays the selected value or placeholder |
| 3 | Leading icon | Optional prefix icon displayed at the start of the input field |
| 4 | Placeholder | The hint text shown inside the input when no value is selected |
| 5 | Dropdown panel | The floating container that opens below the input and holds the option list |
| 6 | Menu | The list of selectable bq-option items inside the dropdown panel |
| 7 | Scroll | The scrollbar that appears when the option list overflows the panel height |
| 8 | Dropdown icon | The chevron caret at the end of the input that indicates the open/closed state |
| 9 | Field status label (optional) | Helper text below the input providing guidance or validation feedback |
| 10 | Info label (icon) | Optional icon accompanying the field status label for additional context |
Design guidelines
Single vs. multiple selection
Validation states
Usage
Default
Enhance user interaction by implementing the default select variant. Perfect for scenarios where you want users to choose from a list of options within a dropdown.Open
Use theopen attribute to display the select dropdown by default, offering users quick access to the available options without additional clicks. Use autofocus to keep the input focused on render.
Initial value
Set an initialvalue for the select component to preselect an option, providing a streamlined user experience and minimizing manual input.
Display value
ThedisplayValue property (display-value attribute) on bq-option overrides the value shown inside the input after selection. Use it when the full option content (e.g., multi-line layout) should not be collapsed into the input field.
Disabled
Employ thedisabled attribute to restrict user interaction with the select component temporarily, useful for scenarios where certain options are unavailable.
Multiple
Use themultiple property to enable multiple selections. Use keep-open-on-select to keep the panel open while the user selects options. The max-tags-visible attribute controls how many tags are shown before a +N overflow tag appears.
Options
Prefix
Use theprefix slot to include additional visual elements or context, such as an icon, to provide users with extra visual cues about the field’s purpose.
Suffix
Leverage thesuffix slot to enhance the select component with extra elements. The default suffix is a rotating chevron caret; replace it with any icon to match your design context.
Validation
Usevalidation-status to signal the validation state (error, warning, or success) of the select component, ensuring accurate data input and real-time feedback.
Label with “Optional”
Choose this style when you want to include an optional label for additional context, providing users with guidance while maintaining a clean and unobtrusive design.Label with “Info Tooltip”
Enhance user understanding by incorporating abq-tooltip alongside the label, offering additional information or clarification about the select.
Panel placement
Adjust the panel placement to suit your layout. Use theplacement attribute to position the dropdown relative to the input — useful when the select is near the bottom of the viewport.
With no label
Use this style when you prefer a minimal look and the field’s purpose is conveyed by surrounding context — for example, inside a table or toolbar where a visible label would be redundant.With no Helper Text
Select this variant when you don’t need additional helper text, giving users a straightforward and uncluttered experience.Readonly
A readonly select shows the current value but prevents the panel from opening. Use it in review or summary screens where the displayed value is informational and should not be changed.Without clear button
Setdisable-clear to hide the clear button and prevent one-click deselection. Use this when selecting a value is required and removing it should not be trivially easy.
Custom behavior
CallpreventDefault() on the bqInput event to take full control of option filtering. This lets you implement async filtering, loading states, empty-state messages, and matched-text highlighting entirely in your own code.
Best practices
DoAlways populate the
label slot so the select has an accessible name visible to all users, not just those relying on assistive technology.Don’tLeave the
label slot empty and rely solely on placeholder text — placeholder disappears once a value is selected and is not announced reliably by screen readers.DoWrite a clear, neutral placeholder such as “Choose a country” so users understand the field is interactive and what kind of value they are selecting.
Don’tUse the placeholder as a label substitute or write a directive like “Select” without context — this gives users no information about what the field is for.
DoUse
validation-status and the helper-text slot together when the field is required or has a validation error, so users understand exactly what is wrong and how to fix it.Don’tApply
validation-status="error" without a helper text message — a red border alone does not tell users what is wrong or how to correct it.DoProvide meaningful option labels that describe the value clearly — e.g., “Europe” instead of “EU”, “Pro plan ($49/mo)” instead of “pro”.
Don’tUse internal codes, abbreviations, or IDs as the visible option labels — what is meaningful in your database is not necessarily meaningful to users.
Accessibility
- Built in: the native
<input>inside the control hasrole="combobox",aria-haspopup="listbox",aria-expanded(toggled when the panel opens and closes), andaria-controlspointing to thebq-option-listbyid. - Built in:
aria-disabled="true"is applied on the input whendisabledis set. - Built in: the component is form-associated via
ElementInternals, so it works with native<form>elements,requiredvalidation, andformResetCallback. - Built in: keyboard navigation —
Tabmoves focus to the input;Enter/Spaceopens the panel;ArrowDown/ArrowUpmove between options;Enterselects the focused option;Escapecloses the panel. - Built in: in multi-select mode,
Backspaceon an empty input removes the most recently added tag. - Your responsibility: always provide a visible label via the
labelslot. Thearia-labelledbyon the combobox role relies on the label element being present. - Your responsibility: when
validation-statusis"error", populate thehelper-textslot with a clear error description soaria-describedbycan link the input to the explanation. - Your responsibility: if options are loaded asynchronously, provide a loading indicator in the panel slot so users know content is arriving.
API reference
Properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
autofocus | autofocus | If true, the Select input will be focused on component render | boolean | — |
clearButtonLabel | clear-button-label | The aria label for the clear button | string | 'Clear value' |
debounceTime | debounce-time | Milliseconds to wait before emitting bqInput after typing | number | 0 |
disableClear | disable-clear | If true, the clear button is hidden | boolean | false |
disabled | disabled | If true, the select cannot be interacted with | boolean | false |
disableScrollLock | disable-scroll-lock | If true, the page body scroll will not be locked when the panel is open | boolean | false |
distance | distance | Gap in pixels between the panel and the input element | number | 8 |
form | form | The id of the <form> element this select belongs to | string | — |
keepOpenOnSelect | keep-open-on-select | If true, the panel stays open after a selection | boolean | false |
maxTagsVisible | max-tags-visible | Maximum number of tags shown in multi-select mode before a +N tag appears | number | 2 |
multiple | multiple | If true, the select allows multiple selections | boolean | false |
name | name | The form control name, submitted as part of a name/value pair. Required for form submission | string | — |
open | open | If true, the panel is visible | boolean | false |
panelHeight | panel-height | Overrides the default height of the Select panel | string | — |
placeholder | placeholder | Placeholder text shown when no value is selected | string | — |
placement | placement | Position of the Select panel relative to the input | 'bottom' | 'bottom-end' | 'bottom-start' | 'left' | 'left-end' | 'left-start' | 'right' | 'right-end' | 'right-start' | 'top' | 'top-end' | 'top-start' | 'bottom' |
readonly | readonly | If true, the option list cannot be opened or filtered | boolean | — |
required | required | If true, a value must be selected before the form can be submitted | boolean | — |
sameWidth | same-width | If true, the panel matches the width of the input element | boolean | true |
skidding | skidding | Offset in pixels along the input element axis | number | 0 |
strategy | strategy | CSS position strategy used to place the panel | 'fixed' | 'absolute' | 'fixed' |
validationStatus | validation-status | Visual validation state of the select | 'error' | 'none' | 'success' | 'warning' | 'none' |
value | value | The currently selected value; can be a string or array of strings in multi-select mode | string | string[] | — |
Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
clear() | — | Promise<void> | Clears the selected value and resets the input |
reset(value) | value: string | string[] | Promise<void> | Resets the select to the supplied value |
Events
| Event | Description |
|---|---|
bqBlur | Emitted when the Select input loses focus |
bqClear | Emitted when the selected value has been cleared |
bqFocus | Emitted when the Select input receives focus |
bqInput | Emitted when the input value changes while typing; detail is { value: string | number | string[] } |
bqSelect | Emitted when the selected value changes; detail is { value: string | number | string[]; item: HTMLBqOptionElement } |
Slots
| Slot | Description |
|---|---|
| (default) | The bq-option elements that make up the option list |
label | The label displayed above the input |
prefix | Content shown before the value text inside the control |
tags | Replaces the auto-generated tag list in multi-select mode |
clear-icon | Replaces the default clear icon inside the clear button |
suffix | Content shown after the value text; defaults to a chevron caret |
helper-text | Text shown below the input for guidance or validation messages |
Shadow parts
| Part | Description |
|---|---|
base | The component’s root wrapper <div> |
button | The native <button> inside the clear button |
clear-btn | The bq-button used as the clear button |
control | The input control wrapper <div> |
input-outline | The inner <div> that holds the tags and the native input |
helper-text | The helper text slot container |
input | The native <input> element |
label | The label slot container |
panel | The floating panel container |
prefix | The prefix slot container |
suffix | The suffix slot container |
tags | The tag container <span> for multi-selection |
tag | Each individual tag wrapper |
tag__base | The base wrapper of each bq-tag |
tag__prefix | The prefix slot container of each bq-tag |
tag__text | The text slot container of each bq-tag |
tag__btn-close | The close button of each bq-tag |
option-list | The bq-option-list container |
CSS custom properties
Resources
Interactive playground
Explore Select variants and states in Storybook
Source code
View the component source on GitHub