Props
| Name | Type | Default | Description |
|---|---|---|---|
adaptive | boolean | undefined | `config.adaptive` (`true`) | When Set it per instance only to disagree with the app-wide |
append:icon | string | undefined | the chevron-down glyph | Name of the icon to be added at the end of the input. Replaces the chevron rather than sitting next to it. v3 removed both the |
autocomplete | string | undefined | - | Guides to the browser as to the type of information expected in the field. |
autofocus | Booleanish | undefined | - | Sets autofocus on page load. |
clearable | boolean | undefined | false | Displays a clear button when the input has a value and is being interacted with. |
comma | boolean | undefined | false | Sets the display model for selected values to a list of comma separated string. In this mode the user cannot deselect an option by pressing the close button. A display mode, and it costs the per-value close button: in |
compact | boolean | undefined | false | Sets the component in a compact mode. |
dependencies | unknown[] | undefined | - | Defines an array of dependencies that will trigger actions in the component upon change. Compared by value hash, not by reference, so an array rebuilt on every render does not refetch. Coherence is lazy: a select with a provider and an empty model ignores changes here until its first load. See example |
depsDebounceTime | number | undefined | 0 | Timeout used to debounce response to changes to dependencies. Defaults to |
description | string | undefined | - | Descriptive text displayed below the label and above the input. Unlike the hint it is always
visible, and it is linked to the input via |
direction | InputDirection | undefined | - | Direction of the layout of the component. Can either be a predefined value or a
pattern separated by a space like |
disabled | boolean | undefined | false | Disables the component. |
disableWriting | boolean | "auto" | "mobile" | "desktop" | undefined | 'auto' | Controls whether the search input is shown inside the dropdown panel.
Also the supported way to switch filtering off, and it takes |
enforceCoherence | boolean | undefined | false | If coherence is enforced the input cannot have a modelValue that is incoherent with its current items. modelValue will be reset upon incoherence. Reach for it when |
errors | string | string[] | undefined | - | Can be a string or an array of string containing the messages to display.
They render in an |
filterBy | string[] | undefined | [] | Property paths used to filter options when the user types in the search input.
When empty (default) options are matched against their display text.
When non-empty the provided paths are searched instead of the display text.
To disable filtering entirely set Replaces the match against the display text rather than adding to it, and every listed path must exist on every item or matching throws. With a provider it still applies, on top of the response — a server match whose text does not contain the query is hidden by this local pass. See example |
groupBy | string | ((item: T) => string | number | symbol) | undefined | - | Path to item property for grouping options. Grouping changes how the list virtualises: a flat list windows per row, a grouped list windows per group, so one group with thousands of options mounts in full. Keep such lists flat, or chunk them. See example |
hasErrors | boolean | undefined | false | Define if the component should be in an error state. It usually attaches a CSS class for styling purposes. |
hasWarnings | boolean | undefined | false | Define if the component should be in a warning state.
Same chrome as errors with |
headerHeight | number | undefined | - | Height of group headers in the listbox (px). Defaults to 32px (24px
compact; 36px / 32px on mobile viewports). Only applies when Defaults to 32px (24px compact, 36px in the mobile sheet). Set it in the prop and not in CSS — the number also feeds the virtualiser, so a stylesheet override desynchronises the paint from the scroll maths. See example |
hideLabel | boolean | undefined | false | Visually hides the label of the input while maintaining accessibility. |
hint | string | undefined | - | Text box to be displayed near the input, usually to indicate instructions. |
id | string | undefined | - | The identifier of the component. |
itemHeight | number | undefined | 28 | Height of the options in the listbox (px). Defaults to 28px (24px compact; 44px / 36px on mobile viewports). An explicit value wins on every viewport. Defaults to 28px (24px compact, 44px in the mobile sheet). Raise it to match taller |
itemProps | BbSelectItemProps<T> | undefined | - | ADDITIONAL row fields resolved from each item — never its text or value
(those stay on |
itemsrequired | T[] | ((query: string, prefill: boolean, modelValue: any) => Promise<T[]>) | ((query: string, prefill: boolean, modelValue: any) => T[]) | - | Used to retrieve items; can be an array or a function. Pass your domain objects as they are and describe them with |
itemText | ItemAccessor<T, string> | undefined | - | Defines a path that returns a property of the object to use as text or a function that returns a string. |
itemValue | ItemAccessor<T> | undefined | - | Defines a path that returns a property of the object to use as value or a function that returns any value. Prefer a primitive id: stable, unique, cheap to submit. Omit it and the whole object becomes the value; matching still uses its value hash, but the model then carries the full object. See example |
labelrequired | string | - | Text content of the label of the element. |
labelMode | "outside" | "floating" | "inside" | undefined | - | Label rendering mode. |
labelPosition | "left" | "center" | "right" | undefined | - | Sets the text alignment of the label. |
loading | boolean | undefined | false | Sets the component in a loading state, usually triggering some visual styles. External pending state only — a parent form saving, say. Fetching through a provider drives its own loading state, so mirroring it here does nothing but hide bugs. See example |
loadingText | string | undefined | - | String displayed while items are being loaded. |
max | number | undefined | - | Maximum number of selectable items when the multiple flag is set. Applies to |
maxSelectedLabels | number | undefined | Infinity | Maximum number of labels shown before collapsing to a count summary. Unset, the labels collapse only when they overflow the field. Applies to |
modelValuerequired | any | - | Used by v-model. Can be any serializable type. |
modelValueDebounceTime | number | undefined | 0 | Timeout used to debounce response to changes to modelValue. |
multiple | boolean | undefined | false | Allows the selection of multiple items. The model must already be an array on the first render. A scalar or an unseeded |
name | string | undefined | - | Defines the name of the input. Renders one hidden input per value, JSON-stringifying anything that is not a string. In v3 an empty selection posts no field at all, like a native |
noDataText | string | undefined | - | String displayed when there are no items to display. |
offCanvasProps | Partial<BbOffCanvasProps> | undefined | - | Props for the phone sheet. A |
persistentHint | boolean | undefined | false | Keeps the hint displayed. |
placeholder | string | undefined | - | String displayed when there's no data. Single mode only. An empty |
prefill | boolean | "interaction" | undefined | 'interaction' | Controls when items are pre-loaded.
Defaults to |
prepend:icon | string | undefined | - | Name of the icon to be added at the start of the input. |
pt | PtItemMap<BbSelectPtPart, BbSelectOptionPtPart, BbSelectPtState, T> | undefined | - | Passthrough, object form: the same keys as the |
pt:box | PtValue | undefined | - | |
pt:box:disabled | PtValue | undefined | - | |
pt:box:errors | PtValue | undefined | - | |
pt:box:has-value | PtValue | undefined | - | |
pt:box:loading | PtValue | undefined | - | |
pt:box:open | PtValue | undefined | - | |
pt:box:readonly | PtValue | undefined | - | |
pt:box:selected | PtValue | undefined | - | |
pt:box:warnings | PtValue | undefined | - | |
pt:clear | PtValue | undefined | - | |
pt:clear:disabled | PtValue | undefined | - | |
pt:clear:errors | PtValue | undefined | - | |
pt:clear:has-value | PtValue | undefined | - | |
pt:clear:loading | PtValue | undefined | - | |
pt:clear:open | PtValue | undefined | - | |
pt:clear:readonly | PtValue | undefined | - | |
pt:clear:selected | PtValue | undefined | - | |
pt:clear:warnings | PtValue | undefined | - | |
pt:description | PtValue | undefined | - | |
pt:description:disabled | PtValue | undefined | - | |
pt:description:errors | PtValue | undefined | - | |
pt:description:has-value | PtValue | undefined | - | |
pt:description:loading | PtValue | undefined | - | |
pt:description:open | PtValue | undefined | - | |
pt:description:readonly | PtValue | undefined | - | |
pt:description:selected | PtValue | undefined | - | |
pt:description:warnings | PtValue | undefined | - | |
pt:hint | PtValue | undefined | - | |
pt:hint:disabled | PtValue | undefined | - | |
pt:hint:errors | PtValue | undefined | - | |
pt:hint:has-value | PtValue | undefined | - | |
pt:hint:loading | PtValue | undefined | - | |
pt:hint:open | PtValue | undefined | - | |
pt:hint:readonly | PtValue | undefined | - | |
pt:hint:selected | PtValue | undefined | - | |
pt:hint:warnings | PtValue | undefined | - | |
pt:icon | PtValue | undefined | - | |
pt:icon:disabled | PtValue | undefined | - | |
pt:icon:errors | PtValue | undefined | - | |
pt:icon:has-value | PtValue | undefined | - | |
pt:icon:loading | PtValue | undefined | - | |
pt:icon:open | PtValue | undefined | - | |
pt:icon:readonly | PtValue | undefined | - | |
pt:icon:selected | PtValue | undefined | - | |
pt:icon:warnings | PtValue | undefined | - | |
pt:input | PtValue | undefined | - | |
pt:input:disabled | PtValue | undefined | - | |
pt:input:errors | PtValue | undefined | - | |
pt:input:has-value | PtValue | undefined | - | |
pt:input:loading | PtValue | undefined | - | |
pt:input:open | PtValue | undefined | - | |
pt:input:readonly | PtValue | undefined | - | |
pt:input:selected | PtValue | undefined | - | |
pt:input:warnings | PtValue | undefined | - | |
pt:item-description | PtValue | ((ctx: PtItemCtx<T, BbSelectPtState>) => PtItemResult) | undefined | - | |
pt:item-description:disabled | PtValue | undefined | - | |
pt:item-description:errors | PtValue | undefined | - | |
pt:item-description:has-value | PtValue | undefined | - | |
pt:item-description:loading | PtValue | undefined | - | |
pt:item-description:open | PtValue | undefined | - | |
pt:item-description:readonly | PtValue | undefined | - | |
pt:item-description:selected | PtValue | undefined | - | |
pt:item-description:warnings | PtValue | undefined | - | |
pt:item-icon | PtValue | ((ctx: PtItemCtx<T, BbSelectPtState>) => PtItemResult) | undefined | - | |
pt:item-icon:disabled | PtValue | undefined | - | |
pt:item-icon:errors | PtValue | undefined | - | |
pt:item-icon:has-value | PtValue | undefined | - | |
pt:item-icon:loading | PtValue | undefined | - | |
pt:item-icon:open | PtValue | undefined | - | |
pt:item-icon:readonly | PtValue | undefined | - | |
pt:item-icon:selected | PtValue | undefined | - | |
pt:item-icon:warnings | PtValue | undefined | - | |
pt:item-text | PtValue | ((ctx: PtItemCtx<T, BbSelectPtState>) => PtItemResult) | undefined | - | |
pt:item-text:disabled | PtValue | undefined | - | |
pt:item-text:errors | PtValue | undefined | - | |
pt:item-text:has-value | PtValue | undefined | - | |
pt:item-text:loading | PtValue | undefined | - | |
pt:item-text:open | PtValue | undefined | - | |
pt:item-text:readonly | PtValue | undefined | - | |
pt:item-text:selected | PtValue | undefined | - | |
pt:item-text:warnings | PtValue | undefined | - | |
pt:label | PtValue | undefined | - | |
pt:label:disabled | PtValue | undefined | - | |
pt:label:errors | PtValue | undefined | - | |
pt:label:has-value | PtValue | undefined | - | |
pt:label:loading | PtValue | undefined | - | |
pt:label:open | PtValue | undefined | - | |
pt:label:readonly | PtValue | undefined | - | |
pt:label:selected | PtValue | undefined | - | |
pt:label:warnings | PtValue | undefined | - | |
pt:list | PtValue | undefined | - | |
pt:list:disabled | PtValue | undefined | - | |
pt:list:errors | PtValue | undefined | - | |
pt:list:has-value | PtValue | undefined | - | |
pt:list:loading | PtValue | undefined | - | |
pt:list:open | PtValue | undefined | - | |
pt:list:readonly | PtValue | undefined | - | |
pt:list:selected | PtValue | undefined | - | |
pt:list:warnings | PtValue | undefined | - | |
pt:message | PtValue | undefined | - | |
pt:message:disabled | PtValue | undefined | - | |
pt:message:errors | PtValue | undefined | - | |
pt:message:has-value | PtValue | undefined | - | |
pt:message:loading | PtValue | undefined | - | |
pt:message:open | PtValue | undefined | - | |
pt:message:readonly | PtValue | undefined | - | |
pt:message:selected | PtValue | undefined | - | |
pt:message:warnings | PtValue | undefined | - | |
pt:option | PtValue | ((ctx: PtItemCtx<T, BbSelectPtState>) => PtItemResult) | undefined | - | |
pt:option:disabled | PtValue | undefined | - | |
pt:option:errors | PtValue | undefined | - | |
pt:option:has-value | PtValue | undefined | - | |
pt:option:loading | PtValue | undefined | - | |
pt:option:open | PtValue | undefined | - | |
pt:option:readonly | PtValue | undefined | - | |
pt:option:selected | PtValue | undefined | - | |
pt:option:warnings | PtValue | undefined | - | |
pt:panel | PtValue | undefined | - | |
pt:panel:disabled | PtValue | undefined | - | |
pt:panel:errors | PtValue | undefined | - | |
pt:panel:has-value | PtValue | undefined | - | |
pt:panel:loading | PtValue | undefined | - | |
pt:panel:open | PtValue | undefined | - | |
pt:panel:readonly | PtValue | undefined | - | |
pt:panel:selected | PtValue | undefined | - | |
pt:panel:warnings | PtValue | undefined | - | |
pt:prefix | PtValue | undefined | - | |
pt:prefix:disabled | PtValue | undefined | - | |
pt:prefix:errors | PtValue | undefined | - | |
pt:prefix:has-value | PtValue | undefined | - | |
pt:prefix:loading | PtValue | undefined | - | |
pt:prefix:open | PtValue | undefined | - | |
pt:prefix:readonly | PtValue | undefined | - | |
pt:prefix:selected | PtValue | undefined | - | |
pt:prefix:warnings | PtValue | undefined | - | |
pt:root | PtValue | undefined | - | |
pt:root:disabled | PtValue | undefined | - | |
pt:root:errors | PtValue | undefined | - | |
pt:root:has-value | PtValue | undefined | - | |
pt:root:loading | PtValue | undefined | - | |
pt:root:open | PtValue | undefined | - | |
pt:root:readonly | PtValue | undefined | - | |
pt:root:selected | PtValue | undefined | - | |
pt:root:warnings | PtValue | undefined | - | |
pt:sheet | PtValue | undefined | - | |
pt:sheet:disabled | PtValue | undefined | - | |
pt:sheet:errors | PtValue | undefined | - | |
pt:sheet:has-value | PtValue | undefined | - | |
pt:sheet:loading | PtValue | undefined | - | |
pt:sheet:open | PtValue | undefined | - | |
pt:sheet:readonly | PtValue | undefined | - | |
pt:sheet:selected | PtValue | undefined | - | |
pt:sheet:warnings | PtValue | undefined | - | |
pt:spinner | PtValue | undefined | - | |
pt:spinner:disabled | PtValue | undefined | - | |
pt:spinner:errors | PtValue | undefined | - | |
pt:spinner:has-value | PtValue | undefined | - | |
pt:spinner:loading | PtValue | undefined | - | |
pt:spinner:open | PtValue | undefined | - | |
pt:spinner:readonly | PtValue | undefined | - | |
pt:spinner:selected | PtValue | undefined | - | |
pt:spinner:warnings | PtValue | undefined | - | |
pt:suffix | PtValue | undefined | - | |
pt:suffix:disabled | PtValue | undefined | - | |
pt:suffix:errors | PtValue | undefined | - | |
pt:suffix:has-value | PtValue | undefined | - | |
pt:suffix:loading | PtValue | undefined | - | |
pt:suffix:open | PtValue | undefined | - | |
pt:suffix:readonly | PtValue | undefined | - | |
pt:suffix:selected | PtValue | undefined | - | |
pt:suffix:warnings | PtValue | undefined | - | |
queryDebounceTime | number | undefined | 500 | Time to wait when the user stops writing in the input before querying data. Defaults to 500ms. The component owns the debounce; a hand-rolled one around the provider fights it. See example |
readonly | boolean | undefined | false | Sets the input in a readonly state. |
required | boolean | undefined | false | Sets the input as required. Marks the field and feeds the asterisk, but does not trigger native constraint validation: the hidden inputs carrying the value are barred from it by the HTML spec. The message a reader sees still comes from |
reverse | boolean | undefined | false | Reverses the layout. Applicable in every direction the order of the label and the input is swapped. |
selectable | boolean | ((item: T) => boolean) | undefined | true | Defines whether options are selectable. Can be a global boolean that affects all options or a function that accepts an item and returns a boolean that only affects that item. Non-selectable options are rendered disabled. The only supported way to disable individual options. A |
selectedLabelsFn | ((count: number) => string) | undefined | - | Function that returns a string to be displayed when the number of selected labels
is greater than |
stash | boolean | undefined | false | Adds a stash to accumulate selected values across searches. Keeps every previously fetched option resolvable, which is what stops a chip losing its text after a later search. The flip side: on a select with |
transitionDuration | number | undefined | 250 | How long the transition has to last in milliseconds. |
variant | InputVariantType | undefined | 'outline' | Visual variant of the field box — the same names and tokens as the
|
warnings | string | string[] | undefined | - | Warning messages to display beneath the field, in their own |
v-model
Values kept in sync through v-model.
| Name | Type | Description |
|---|---|---|
modelValue | any | Holds a single value, or an array of them under |
Events
| Name | Type | Description |
|---|---|---|
active | (e: "active"): void | |
blur | (e: "blur", event: FocusEvent): void | |
change | (e: "change", event: Event): void | |
click | (e: "click", event: MouseEvent): void | |
focus | (e: "focus", event: FocusEvent): void | |
hidden | (e: "hidden"): void | Emitted once the options surface has finished closing. |
hide | (e: "hide"): void | Emitted as soon as the options surface starts to close. |
inactive | (e: "inactive"): void | Validate on this, not on |
input | (e: "input", event: Event): void | |
option:add | (e: "option:add", text: string): void | Fires when the user commits an option the list did not contain. Use it to create the record on your side, then push it into |
show | (e: "show"): void | Emitted as soon as the options surface starts to open (the popover, or the sheet on a phone). |
shown | (e: "shown"): void | Emitted once the options surface is open and its open transition has finished. |
update:modelValue | (e: "update:modelValue", value: any): void |
Slots
The listed properties are the ones exposed to the slot scope.
| Name | Type | Description |
|---|---|---|
append | { query: string; focus: () => void; close: () => Promise<void>; } | Content appended inside the input field, after the value area. |
append-outer | { query: string; close: () => Promise<void>; } | Content appended outside the input field wrapper. |
chip | BbSelectChipSlotProps<T> | Replaces the default badge rendered for each selection in Replaces the badge for each selection in |
description | BbSelectDescriptionSlotProps | Replaces the description text. Provided alone (no |
footer | BbSelectPanelSlotProps | Content pinned to the bottom of the options panel, below the options list. Rendered in both the desktop popover and the adaptive sheet. Renders below the options list in the desktop popover and in the mobile sheet alike. Select-all lives here: the model is yours, so assigning every value to it is the whole implementation. See example |
group | BbSelectGroupSlotProps<T> | Replaces the default group header rendered above grouped options. Styles the group header only. |
header | BbSelectPanelSlotProps | Content pinned to the top of the options panel, above the search field. Rendered in both the desktop popover and the adaptive sheet. Renders above the search field. Derive any summary from your own model rather than from |
label | BbSelectLabelSlotProps | Replaces the default label text rendered above the input. |
loading | { query: string; } | Content shown inside the options dropdown while items are loading. |
no-data | { query: string; focus: () => void; } | Content shown when no options match the query or the list is empty. |
option | BbSelectOptionSlotProps<T> | Replaces the default rendering of each option row in the dropdown. Replaces the row's text, not the selection check — that renders outside the slot and survives any markup. Taller rows need |
prefix | object | Content rendered as an inline prefix inside the input field. |
prepend | { query: string; focus: () => void; close: () => Promise<void>; } | Content prepended inside the input field, before the value area. |
prepend-outer | { query: string; close: () => Promise<void>; } | Content prepended outside the input field wrapper. |
suffix | object | Content rendered as an inline suffix inside the input field. |
Changes from v2
Props removed or renamed in 3.0. If you are coming from v2, the answer is here.
allowWritingdisableWritingfails silentlyhasWarninghasWarningsfails silentlyoffcanvasPropsoffCanvasPropsfails silently