MultiAutoCompleteInput
Select several suggestions, create new tokens and keep a structured list separate from the current query.
MultiAutoCompleteInputTag a release
Choose suggestions, type a new tag and press Enter, or paste comma-separated values. The Documentation tag is locked; remove other tags individually or clear them together.
<RegorApp id="multi-auto-complete-input-demo" src="./playground.ts"/> import {
type AutoCompleteOption,
defineButtonComponents,
defineFlexComponents,
defineFormComponents,
defineIconComponents,
defineMultiAutoCompleteInputComponents,
type MultiAutoCompleteItem,
} from '@purestack/ts-components'
import {
lucide_chevron_down,
lucide_loader_circle,
lucide_x,
} from '@purestack/ts-svg-icons'
import {
createApp,
defineComponent,
html,
type Ref,
ref,
type SRef,
sref,
} from 'regor'
export interface MultiAutoCompleteInputExample {
selectedTags: SRef<MultiAutoCompleteItem[]>
tagQuery: Ref<string>
tagOptions: AutoCompleteOption[]
customAllowed: Ref<boolean>
duplicatesAllowed: Ref<boolean>
pending: Ref<boolean>
locked: Ref<boolean>
clear: () => void
}
const multiAutoCompleteInputExampleTemplate = html`<Flex direction="column">
<MultiAutoCompleteInput
id="multi-tags"
label="Release tags"
placeholder="Choose or type a tag"
name="tags"
:items="selectedTags"
:model="tagQuery"
:options="tagOptions"
:allowCustomValues="customAllowed"
:allowDuplicates="duplicatesAllowed"
:loading="pending"
:disabled="locked"
separators=",;"
/>
<Flex wrap="true">
<FormCheck id="multi-custom" label="Allow new tags" :checked="customAllowed" />
<FormCheck
id="multi-duplicates"
label="Allow duplicates"
:checked="duplicatesAllowed"
/>
<FormCheck id="multi-loading" label="Loading state" :checked="pending" />
<FormCheck id="multi-disabled" label="Disabled" :checked="locked" />
</Flex>
<Btn variant="link" @click="clear">Clear editable tags</Btn>
<FormStatus>
{{ selectedTags.length }} tags selected. Query: {{ tagQuery || 'Empty' }}
</FormStatus>
<ul>
<li r-for="tag in selectedTags">{{ tag.label }} · {{ tag.value }}</li>
</ul>
</Flex>`
function createMultiAutoCompleteInputExample(): MultiAutoCompleteInputExample {
const requiredTag: MultiAutoCompleteItem = {
label: 'Documentation',
value: 'docs',
disabled: true,
}
const selectedTags = sref<MultiAutoCompleteItem[]>([
requiredTag,
{ label: 'Needs review', value: 'review', tone: 'warning' },
])
return {
selectedTags,
tagQuery: ref(''),
tagOptions: [
{ label: 'TypeScript', value: 'ts', keywords: ['typed'] },
{ label: 'Accessibility', value: 'a11y' },
{ label: 'Performance', value: 'perf' },
{ label: 'Internal · unavailable', value: 'internal', disabled: true },
],
customAllowed: ref(true),
duplicatesAllowed: ref(false),
pending: ref(false),
locked: ref(false),
clear: () => selectedTags([requiredTag]),
}
}
const component = defineComponent<MultiAutoCompleteInputExample>(
multiAutoCompleteInputExampleTemplate,
{
context: createMultiAutoCompleteInputExample,
},
)
const icons: Record<string, string> = {
'lucide:loader-circle': lucide_loader_circle,
'lucide:x': lucide_x,
'lucide:chevron-down': lucide_chevron_down,
}
createApp(
{
components: {
MultiAutoCompleteInputExample: component,
...defineMultiAutoCompleteInputComponents(),
...defineFlexComponents(),
...defineFormComponents(),
...defineButtonComponents(),
...defineIconComponents((name) => icons[name] ?? ''),
},
},
{
selector: 'app#multi-auto-complete-input-demo',
template: html`<MultiAutoCompleteInputExample />`,
},
) Invalid and disabled tokens
Token state can express validation results supplied by your application.
<RegorApp id="multi-auto-complete-input-states-demo" src="./states.ts"/> import {
defineIconComponents,
defineMultiAutoCompleteInputComponents,
type MultiAutoCompleteItem,
} from '@purestack/ts-components'
import { lucide_chevron_down, lucide_x } from '@purestack/ts-svg-icons'
import { createApp, defineComponent, html, type SRef, sref } from 'regor'
export interface MultiAutoCompleteInputStates {
recipients: SRef<MultiAutoCompleteItem[]>
}
const multiAutoCompleteInputStatesTemplate = html`<MultiAutoCompleteInput
id="multi-token-states"
label="Example recipients"
:items="recipients"
placeholder="Add a recipient"
/>`
function createMultiAutoCompleteInputStates(): MultiAutoCompleteInputStates {
return {
recipients: sref<MultiAutoCompleteItem[]>([
{ label: 'Required reviewer', value: 'reviewer', disabled: true },
{
label: 'Invalid address',
value: 'invalid',
invalid: true,
tone: 'danger',
},
]),
}
}
const component = defineComponent<MultiAutoCompleteInputStates>(
multiAutoCompleteInputStatesTemplate,
{
context: createMultiAutoCompleteInputStates,
},
)
const icons: Record<string, string> = {
'lucide:x': lucide_x,
'lucide:chevron-down': lucide_chevron_down,
}
createApp(
{
components: {
MultiAutoCompleteInputStates: component,
...defineMultiAutoCompleteInputComponents(),
...defineIconComponents((name) => icons[name] ?? ''),
},
},
{
selector: 'app#multi-auto-complete-input-states-demo',
template: html`<MultiAutoCompleteInputStates />`,
},
) Behavior and accessibility
Arrow keys and Enter select suggestions; Escape closes the popup. Backspace on an empty query removes the last removable token. Each selected item produces a hidden field when name is supplied. required applies to the query input, so validate selected items explicitly when requiring at least one token.
API reference
MultiAutoCompleteInput contract
Props below are the public template API. RefOrValue accepts a literal or a reactive ref; bind refs with a colon-prefixed attribute. Native attributes and events can be passed through the component root.
id
RefOrValue<string> - Default
generated
Unique control ID. Supply an explicit value when help text or another element needs to reference this control.
label
RefOrValue<string> - Default
not set
Visible label. Use language that describes the control or value in its surrounding context.
tone
RefOrValue<SemanticTone> - Default
inherited
Semantic intent: neutral, accent, secondary, info, success, warning, danger, feature, custom or ghost. The active skin supplies the colors.
variant
RefOrValue<ComponentVariant> - Default
surfaceAlt
Visual treatment. Accepts solid, surface, surfaceAlt, spotlight, glass, flat, flatAlt, flatSolid, outlineFill, outline, subtle, subtleBtn, link, sheen, underline, rail, bracket or none.
items
SRef<MultiAutoCompleteItem[]> - Default
sref([])
Writable shallow ref of MultiAutoCompleteItem[]. Each item supports label, value, disabled, invalid, tone and keywords.
model
Ref<string> - Default
ref('')
Two-way value ref. Pass the ref itself with :model="fieldValue" so edits update application state.
name
RefOrValue<string> - Default
not set
Native form field name used during FormData serialization.
required
RefOrValue<boolean> - Default
false
Native required constraint. Validate the owning form before accepting its data.
autocomplete
RefOrValue<string> - Default
off
Native browser autofill hint, such as name, email or current-password.
placeholder
RefOrValue<string> - Default
not set
A short input hint shown while empty. Keep a separate visible label.
disabled
RefOrValue<boolean> - Default
false
Disables interaction. Use a bound boolean, for example :disabled="isLocked".
icon
RefOrValue<string> - Default
not set
Registered SVG icon name. In browser apps, include the icon in the resolver passed to defineIconComponents.
iconEnd
RefOrValue<string> - Default
lucide:chevron-down; loader-circle while loading
Trailing input icon. Include both default icons in the browser resolver when the loading state is used. An explicit iconEnd overrides both.
removeIcon
RefOrValue<string> - Default
lucide:x
Registered icon on each removable token button.
options
RefOrValue<AutoCompleteOption[]> - Default
[]
Suggestion or select data. Each option has a label, an optional value and an optional disabled flag. Omitted values use the label.
rowComponent
RefOrValue<string> - Default
MultiAutoCompleteOptionRow
Registered row presentation. The input supplies option semantics and keyboard selection.
minLength
RefOrValue<number | string> - Default
0
Minimum trimmed query length before suggestions may open.
maxResults
RefOrValue<number | string> - Default
10
Maximum number of matching suggestions rendered.
openOnFocus
RefOrValue<boolean> - Default
true
Opens suggestions on focus when the minimum query length is met.
allowCustomValues
RefOrValue<boolean> - Default
true
Allows Enter and separators to create tokens from query text.
allowDuplicates
RefOrValue<boolean> - Default
false
Allows repeated selected values when true.
separators
RefOrValue<string> - Default
,;
Characters that commit query fragments; newline also splits pasted input.
loading
RefOrValue<boolean> - Default
false
Shows a loading state. Your application supplies options and manages any asynchronous request.
emptyText
RefOrValue<string> - Default
No suggestions
Message displayed when the query has no matching suggestions.
loadingText
RefOrValue<string> - Default
Loading suggestions
Status message while loading is true.
onCreateItem
RefOrValue<MultiAutoCompleteCreateItem> - Default
not set
Maps query text to a MultiAutoCompleteItem, or null/undefined to reject it.
onOptionToItem
RefOrValue<MultiAutoCompleteOptionToItem> - Default
not set
Maps a resolved suggestion to an item, or null/undefined to reject it.
onSplitInput
RefOrValue<MultiAutoCompleteSplitInput> - Default
not set
Custom text splitter returning string fragments. Replaces default separator splitting.
onItemsChange
RefOrValue<MultiAutoCompleteItemsChange> - Default
not set
Receives the updated selected-item array.
onSelect
RefOrValue<MultiAutoCompleteSelect> - Default
not set
Receives the resolved option and the item created from it.
onSearch
RefOrValue<MultiAutoCompleteSearch> - Default
not set
Callback receiving the query string after an edit. Use it to load or filter application data.
Composition
No slots. Register defineMultiAutoCompleteInputComponents and defineIconComponents. Use sref for items and ref for the current text model.
Events and item data
The input emits itemschange, itemremove, itemcreate, optionselect and querychange. Each item can carry label, value, disabled, invalid, tone and keywords. Keep persistence and domain validation in the owning app.