Skip to the content

ComponentsForm

Autocomplete

A text field that suggests values as people type; they may pick a suggestion or keep their own text.

Import

import { Autocomplete, AutocompleteClear, AutocompleteCollection, AutocompleteContent, AutocompleteEmpty, AutocompleteGroup, AutocompleteInput, AutocompleteItem, AutocompleteLabel, AutocompleteList, AutocompleteSeparator, AutocompleteStatus, AutocompleteTrigger } from "@booleanpress/ui/autocomplete"

Also install @base-ui/react: pnpm add @base-ui/react

Usage

Autocomplete is Base UI's Autocomplete with the library's field and list look. It needs the @base-ui/react peer package. The value is the text in the field: a suggestion only fills it. When the value must be one of the options, use Combobox; for several free values, TagsInput.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const TAGS = ["billing", "bounce", "dkim", "refund"]

export function TagField() {
  return (
    <>
      <Label htmlFor="tag">Ticket tag</Label>
      <Autocomplete items={TAGS}>
        <AutocompleteInput id="tag" placeholder="Type a tag" />
        <AutocompleteContent>
          <AutocompleteList>
            {(tag: string) => (
              <AutocompleteItem key={tag} value={tag}>
                {tag}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </>
  )
}

It is uncontrolled with defaultValue, or controlled with value and onValueChange, which carry the field's text; onValueChange's second argument has a reason ("input-change", "item-press"โ€ฆ). When its form resets (a reset button, or React's reset after a form action), an uncontrolled field goes back to defaultValue and a controlled one is given the text it started with through onValueChange. Base UI filters items as people type; filter={null} shows them as given, for suggestions fetched from a server. mode="both" adds inline completion: the highlighted suggestion is written into the field as you move through the list.

AutocompleteInput is the field, as wide as its container, with size (sm, default, lg) and variant="filled" defaulting to the provider's controlSize and fieldVariant; showClear, showTrigger and loading add a clear button, a chevron cell and a spinner. The list hides while it has no suggestions, unless AutocompleteEmpty ("No results") or AutocompleteStatus has something to say. Inside a Dialog, Sheet or Popover the list works as anywhere else: a click picks and the overlay stays open, and Escape closes the list before the overlay.

Examples

Basic

Free text with suggestions that narrow as you type; text that matches none is kept.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const TAGS = ["billing", "bounce", "dkim", "dmarc", "dns", "feature request", "onboarding", "refund", "spf", "webhook"]

export default function AutocompleteBasic() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-2">
      <Label htmlFor="autocomplete-tag">Ticket tag</Label>
      <Autocomplete items={TAGS}>
        <AutocompleteInput id="autocomplete-tag" placeholder="Type a tag" />
        <AutocompleteContent>
          <AutocompleteList>
            {(tag: string) => (
              <AutocompleteItem key={tag} value={tag}>
                {tag}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Inline completion

mode="both" writes the highlighted suggestion into the field while the arrow keys move through the list.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const ZONES = ["Africa/Cairo", "America/Chicago", "America/New_York", "Asia/Dhaka", "Asia/Tokyo", "Europe/Berlin", "Europe/London", "Europe/Madrid"]

export default function AutocompleteInline() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-2">
      <Label htmlFor="autocomplete-zone">Time zone</Label>
      <Autocomplete items={ZONES} mode="both">
        <AutocompleteInput id="autocomplete-zone" placeholder="Europe/London" />
        <AutocompleteContent>
          <AutocompleteList>
            {(zone: string) => (
              <AutocompleteItem key={zone} value={zone}>
                {zone}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Async

Suggestions load from a stand-in help centre after 600 ms: filter={null}, a spinner and AutocompleteStatus loading; only the latest request fills the list, and a failed one says so.

import { useRef, useState } from "react"
import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
  AutocompleteStatus,
} from "@booleanpress/ui/autocomplete"

const ARTICLES = [
  "Set up SPF for your domain",
  "Set up DKIM signing",
  "Read a bounce report",
  "Rotate an API key",
  "Route email per site",
  "Resend failed emails",
]

// Stands in for a request to the help centre: answers after 600 ms.
function searchArticles(query: string) {
  return new Promise<string[]>((resolve) =>
    setTimeout(() => resolve(ARTICLES.filter((title) => title.toLowerCase().includes(query.toLowerCase()))), 600)
  )
}

export default function AutocompleteAsync() {
  const [results, setResults] = useState<string[]>([])
  const [loading, setLoading] = useState(false)
  const [failed, setFailed] = useState(false)
  // Only the latest request may update the list: an earlier, slower answer is dropped.
  const latest = useRef(0)

  async function search(query: string) {
    const request = ++latest.current
    setFailed(false)
    if (!query.trim()) {
      setResults([])
      setLoading(false)
      return
    }
    setLoading(true)
    try {
      const found = await searchArticles(query)
      if (request === latest.current) setResults(found)
    } catch {
      if (request === latest.current) {
        setResults([])
        setFailed(true)
      }
    } finally {
      if (request === latest.current) setLoading(false)
    }
  }

  return (
    <div className="flex w-full max-w-64 flex-col gap-2">
      <Label htmlFor="autocomplete-help">Search the help centre</Label>
      <Autocomplete items={results} filter={null} onValueChange={(query, { reason }) => reason !== "item-press" && search(query)}>
        <AutocompleteInput id="autocomplete-help" placeholder="e.g. bounce" loading={loading} />
        <AutocompleteContent>
          <AutocompleteStatus loading={loading}>{failed ? "Could not search the help centre. Try again." : null}</AutocompleteStatus>
          <AutocompleteList>
            {(title: string) => (
              <AutocompleteItem key={title} value={title}>
                {title}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Groups

Grouped items with AutocompleteGroup and AutocompleteLabel, and AutocompleteEmpty when nothing matches.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteEmpty,
  AutocompleteGroup,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteLabel,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const GROUPS = [
  { value: "Recent", items: ["invoice overdue", "bounce rate"] },
  { value: "Customers", items: ["Northwind Traders", "Fabrikam Studio", "Contoso Clinics"] },
  { value: "Mailers", items: ["Amazon SES", "Postmark", "SendGrid"] },
]

export default function AutocompleteGroups() {
  return (
    <div className="flex w-full max-w-64 flex-col gap-2">
      <Label htmlFor="autocomplete-search">Search</Label>
      <Autocomplete items={GROUPS}>
        <AutocompleteInput id="autocomplete-search" placeholder="Search everything" />
        <AutocompleteContent>
          <AutocompleteEmpty />
          <AutocompleteList>
            {(group: (typeof GROUPS)[number]) => (
              <AutocompleteGroup key={group.value} items={group.items}>
                <AutocompleteLabel>{group.value}</AutocompleteLabel>
                {group.items.map((entry) => (
                  <AutocompleteItem key={entry} value={entry}>
                    {entry}
                  </AutocompleteItem>
                ))}
              </AutocompleteGroup>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Sizes

sm is 28 px high, default 35 px and lg 42 px.

import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const SIZES = [
  { size: "sm", label: "Small" },
  { size: "default", label: "Default" },
  { size: "lg", label: "Large" },
] as const

const SENDERS = ["Billing team", "Deliverability team", "Support team", "No reply"]

export default function AutocompleteSizes() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-4">
      {SIZES.map(({ size, label }) => (
        <Autocomplete key={size} items={SENDERS}>
          <AutocompleteInput size={size} placeholder={label} aria-label={`Sender name, ${label.toLowerCase()} size`} />
          <AutocompleteContent>
            <AutocompleteList>
              {(sender: string) => (
                <AutocompleteItem key={sender} value={sender}>
                  {sender}
                </AutocompleteItem>
              )}
            </AutocompleteList>
          </AutocompleteContent>
        </Autocomplete>
      ))}
    </div>
  )
}

Filled

variant="filled" fills the field with the grey --field-filled, on hover and focus too.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const SUBJECTS = ["Your receipt", "Your password reset link", "Welcome aboard", "Your invoice is ready"]

export default function AutocompleteFilled() {
  return (
    <div className="flex w-full max-w-64 flex-col gap-2">
      <Label htmlFor="autocomplete-subject">Subject</Label>
      <Autocomplete items={SUBJECTS}>
        <AutocompleteInput id="autocomplete-subject" variant="filled" placeholder="Write a subject" />
        <AutocompleteContent>
          <AutocompleteList>
            {(subject: string) => (
              <AutocompleteItem key={subject} value={subject}>
                {subject}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Disabled

disabled on the root and the input: the text stays, the field fills grey and suggests nothing.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const SENDERS = ["Billing team", "Support team"]

export default function AutocompleteDisabled() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-2">
      <Label htmlFor="autocomplete-sender">Sender name</Label>
      <Autocomplete items={SENDERS} defaultValue="Support team" disabled>
        <AutocompleteInput id="autocomplete-sender" disabled />
        <AutocompleteContent>
          <AutocompleteList>
            {(sender: string) => (
              <AutocompleteItem key={sender} value={sender}>
                {sender}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
    </div>
  )
}

Invalid

aria-invalid draws the error edge and placeholder; aria-describedby reads the message with the name.

import { Label } from "@booleanpress/ui/label"
import {
  Autocomplete,
  AutocompleteContent,
  AutocompleteInput,
  AutocompleteItem,
  AutocompleteList,
} from "@booleanpress/ui/autocomplete"

const DOMAINS = ["example.com", "mail.example.com", "news.example.com"]

export default function AutocompleteInvalid() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-2">
      <Label htmlFor="autocomplete-domain">Sending domain</Label>
      <Autocomplete items={DOMAINS} required>
        <AutocompleteInput
          id="autocomplete-domain"
          placeholder="example.com"
          aria-invalid
          aria-describedby="autocomplete-domain-error"
        />
        <AutocompleteContent>
          <AutocompleteList>
            {(domain: string) => (
              <AutocompleteItem key={domain} value={domain}>
                {domain}
              </AutocompleteItem>
            )}
          </AutocompleteList>
        </AutocompleteContent>
      </Autocomplete>
      <p id="autocomplete-domain-error" className="text-xs text-destructive-strong">
        Enter the domain you send from.
      </p>
    </div>
  )
}

Accessibility

Semantics
The input has role="combobox", aria-autocomplete="list" ("both" with inline completion), aria-expanded and aria-controls pointing at the role="listbox" of suggestions; the highlighted suggestion is its aria-activedescendant. Focus stays in the input.
Labels
Name the input with a Label whose htmlFor is its id (or a label round the field), aria-label or aria-labelledby. While the list is open, Base UI hides everything but the input and the list from assistive technology, the visible label included; so the input also carries its labels' text as its own aria-label, read when it mounts, as the list opens and when the label's text changes, and keeps its name. An input named by aria-label or aria-labelledby keeps that name. The clear button is named "Clear" and the chevron "Show options", from the provider.
Focus
The input is the only tab stop; the clear button and the chevron are pointer targets, since typing and the arrow keys do the same.
Known limits
  • Suggestions are not a selection: nothing is marked chosen in the list.

Keyboard

Keyboard
KeyBehaviour
โ†“Opens the suggestions, then highlights the next one.
โ†‘Highlights the previous suggestion.
EnterFills the field with the highlighted suggestion and closes the list.
EscapeCloses the list and keeps the text; inside a dialog, the dialog stays open.
HomeorEndMove the text cursor to the start or the end of the field.
Aโ€“ZTyping narrows the suggestions; with mode="both" the highlighted one is written in.

API

AutocompleteClear

AutocompleteClear props
PropTypeDefaultDescription
classNamestring
disabledbooleanfalseWhether the component should ignore user interaction.
keepMountedbooleanfalseWhether the component should remain mounted in the DOM when not visible.
nativeButtonbooleantrueWhether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxClearState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxClearState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteCollection

AutocompleteContent

AutocompleteContent props
PropTypeDefaultDescription
align"center" | "start" | "end"startHow to align the popup relative to the specified side.
alignOffsetnumber | OffsetFunction0Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: - data.anchor: the dimensions of the anchor element with properties width and height. - data.positioner: the dimensions of the positioner element with properties width and height. - data.side: which side of the anchor element the positioner is aligned against. - data.align: how the positioner is aligned relative to the specified side.
anchorElement | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null) | nullAn element to position the popup against. By default, the popup will be positioned against the trigger.
classNamestring
containerHTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | nullA parent element to render the portal element into.
finalFocusboolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null)Determines the element to focus when the popup is closed. - false: Do not move focus. - true: Move focus based on the default behavior (trigger or previously focused element). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.
initialFocusboolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | void | HTMLElement | null)Determines the element to focus when the popup is opened. - false: Do not move focus. - true: Move focus based on the default behavior (first tabbable element or popup). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxPopupState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
side"top" | "bottom" | "left" | "right" | "inline-end" | "inline-start"bottomWhich side of the anchor element to align the popup against. May automatically change to avoid collisions.
sideOffsetnumber | OffsetFunction2Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a data object parameter with the following properties: - data.anchor: the dimensions of the anchor element with properties width and height. - data.positioner: the dimensions of the positioner element with properties width and height. - data.side: which side of the anchor element the positioner is aligned against. - data.align: how the positioner is aligned relative to the specified side.
styleCSSProperties | ((state: ComboboxPopupState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteEmpty

AutocompleteEmpty props
PropTypeDefaultDescription
classNamestring
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxEmptyState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxEmptyState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteGroup

AutocompleteGroup props
PropTypeDefaultDescription
classNamestring
itemsreadonly any[]Items to be rendered within this group. When provided, child Collection components will use these items.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxGroupState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxGroupState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteInput

AutocompleteInput props
PropTypeDefaultDescription
classNamestring
disabledbooleanfalseWhether the component should ignore user interaction.
loadingbooleanfalseShows a spinner in the field while suggestions load. Pair it with AutocompleteStatus, which announces it.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxInputState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
showClearbooleanfalseShows a clear button while the field has text; it empties the field and keeps focus in it.
showTriggerbooleanfalseShows a chevron cell at the field's end that opens the whole list of suggestions.
size"default" | "sm" | "lg"28, 35 or 42 px tall. Defaults to the provider's controlSize.
styleCSSProperties | ((state: ComboboxInputState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.
variant"default" | "filled"filled fills the field grey. Defaults to the provider's fieldVariant.

AutocompleteItem

AutocompleteItem props
PropTypeDefaultDescription
classNamestring
descriptionReactNodeA second, muted line under the label.
disabledbooleanfalseWhether the component should ignore user interaction.
iconReactNodeLeading media beside both lines, such as an icon or an avatar.
indexnumberThe index of the item in the list. Improves performance when specified by avoiding the need to calculate the index automatically from the DOM.
nativeButtonbooleantrueWhether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).
onClick((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void)An optional click handler for the item when selected. It fires when clicking the item with the pointer, as well as when pressing Enter with the keyboard if the item is highlighted when the Input or List element has focus.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AutocompleteItemState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: AutocompleteItemState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.
valueanynullA unique value that identifies this item.

AutocompleteLabel

AutocompleteLabel props
PropTypeDefaultDescription
classNamestring
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxGroupLabelState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxGroupLabelState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteList

AutocompleteList props
PropTypeDefaultDescription
classNamestring
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxListState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxListState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteSeparator

AutocompleteSeparator props
PropTypeDefaultDescription
classNamestring
orientation"horizontal" | "vertical"'horizontal'The orientation of the separator.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AutocompleteSeparatorState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: AutocompleteSeparatorState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteStatus

AutocompleteStatus props
PropTypeDefaultDescription
classNamestring
loadingbooleanfalseShows a spinner and the provider's loadingResults string in place of the children.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ComboboxStatusState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: ComboboxStatusState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

AutocompleteTrigger

AutocompleteTrigger props
PropTypeDefaultDescription
classNamestring
disabledbooleanfalseWhether the component should ignore user interaction.
nativeButtonbooleantrueWhether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AutocompleteTriggerState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleCSSProperties | ((state: AutocompleteTriggerState) => CSSProperties)Style applied to the element, or a function that returns a style object based on the component's state.

Also exported: Autocomplete, a helper the parts use; useAutocompleteFilter, a hook for the parts' shared state; call it inside the component's provider.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="autocomplete-clear" (AutocompleteClear), data-slot="autocomplete-collection" (AutocompleteCollection), data-slot="autocomplete-content" (AutocompleteContent), data-slot="autocomplete-empty" (AutocompleteEmpty), data-slot="autocomplete-group" (AutocompleteGroup), data-slot="autocomplete-loading" (AutocompleteInput), data-slot="autocomplete-item" (AutocompleteItem), data-slot="autocomplete-label" (AutocompleteLabel), data-slot="autocomplete-list" (AutocompleteList), data-slot="autocomplete-separator" (AutocompleteSeparator), data-slot="autocomplete-status" (AutocompleteStatus), data-slot="autocomplete-trigger" (AutocompleteTrigger), and data-disabled.

Provider strings: toggleOptions, clear, noResults, loadingResults (BooleanUIProvider's strings).

Theming

The field is InputGroup: --field (--field-filled filled), --control for the edge, --ring on focus, --invalid when invalid, icons in --control-hover. The list uses --popover and --accent for the highlighted suggestion; its motion is set once in theme.css.

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--accentbackground
--accent-foregroundtext
--borderborder, background
--control-hovertext
--foregroundtext
--muted-foregroundtext
--popoverbackground
--popover-foregroundtext