Every prop, hook, and type — distilled.
<AIAutocomplete />
The full drop-in component. Owns the input, dropdown, and pills.
| Prop | Type | Default | Description |
|---|---|---|---|
onSubmitRequired | (result: AutocompleteResult) => void | — | Called on Enter or submit. Receives an AutocompleteResult. |
onError | (error: Error) => void | — | Called when a fetch fails. |
apiConfig | APIConfig | — | Runtime API configuration (key or token). |
additionalContext | Record<string, unknown> | — | Optional user context. Include whatever you know about the user (a profile, preferences, workspace, anything) to personalize suggested parameters and options to them. |
className | string | — | Class applied to the container. |
columns | number | 2 | Number of columns in the dropdown grid. |
pillPlacement | "inline" | "dropdown" | "hidden" | "dropdown" | Where unfilled pills render. inline lives in the input; dropdown places them with options. |
mode | "light" | "dark" | "auto" | "auto" | Color mode. auto follows prefers-color-scheme. |
optionsPosition | "above" | "below" | "below" | Where the dropdown opens relative to the input. |
animations | boolean | true | Enable selection streak + new-param shimmer. |
dropdownTrigger | "auto" | "manual" | "hidden" | "auto" | When the dropdown appears. auto = when options available; manual = only on pill tap. |
closeDropdownOnBlur | boolean | true | When false, the dropdown stays open even when the input loses focus. |
showNonTappableOptions | boolean | true | When false, options the server marked is_tappable: false (hint rows like "or type something else…") are hidden instead of rendered alongside the selectable ones. |
submitButton | ReactNode | null | — | Custom submit button. Pass any node to replace the built-in arrow button, or null to render none. Leaving it undefined keeps the default. The library wraps your node so clicks bubble up and trigger submit. |
autoFocus | boolean | true | Focus the input on mount. Set to false to leave focus to the consumer. |
onFocus | () => void | — | Called when the input gains focus. |
onBlur | () => void | — | Called when the input loses focus. |
maskCompletedText | boolean | false | Strip completed-param text from network requests (PII masking). |
optionOverrides | Record<string, (query) => SuggestionOption[]> | — | Override option lists per suggestion type. |
value | string | — | Controlled text value. |
completedParams | CompletedParamState[] | — | Controlled completed params. |
onChange | (value: string) => void | — | Called when text changes (controlled mode). |
onParamsChange | (params: CompletedParamState[]) => void | — | Called when params change (controlled mode). |
showProducts | boolean | true | Render the product strip below the options whenever there are products to show: by default the items the /suggest response reports as matching the query, or the results of a custom products search. Set to false to render no strip and run no custom search. |
products | ProductsConfig | — | Custom source for the product strip. Omit it and the strip shows the items the /suggest response itself reports as matching the query, with no extra request. Set it and the strip is fed by your own search endpoint on the SDK's existing fetch cadence instead; the server's items are then not rendered. The object may be re-created on every render: only setting or removing the config reaches the core, so swapping one live config for another leaves the current cards up until the next request, and a config set mid-session shows nothing until the next request fires. |
productsLayout | "row" | "list" | "row" | How the product strip lays its cards out. "row" is a horizontally scrolling shelf. "list" stacks the same cards as full-width rows (thumbnail on the left, title, vendor and price on the right) for results that read as a list, such as courses, listings or documents, rather than products on a shelf. The list scrolls vertically inside --aia-product-list-max-height, 320px by default. Changing the prop re-lays the strip out at once. |
onProductSelect | (product: Product) => void | — | Called when the user activates a product card. The SDK does not navigate — you decide what a selection means. Modifier and middle clicks are left to the browser (so cmd-click still opens a tab) and don't fire this. |
ref | Ref<AIAutocompleteHandle> | — | Imperative handle: focus(), blur(), reset(), setMode(). |
useAIAutocomplete()
Use the hook for custom rendering. Same options as <AIAutocomplete /> minus the rendering-only props (className, mode, optionsPosition, animations, pillPlacement, autoFocus). The hook doesn't own the textarea — onFocus and onBlur fire when the consumer-owned textarea's focus changes.
State
| Prop | Type | Description |
|---|---|---|
completedParams | CompletedParamState[] | Filled parameters. |
skippedParams | SkippedParamState[] | Suggestions the user dismissed with the skip key (→). Nothing renders them — pass them to buildSubmitResult (or read them for your own telemetry) so a hand-rolled submit carries the same text: "skipped" entries the SDK's own requests do. |
suggestionPills | Suggestion[] | Unfilled suggestions (pills). First item is the active pill. |
segments | Segment[] | Input text split into typed text vs completed segments. |
newParamId | string | null | ID of the most recently added param (for shimmer). |
suggestions | Suggestion[] | All suggestions from server (including placeholder type). |
activeIndex | number | Highlighted option index. -1 = none. |
isLoading | boolean | Fetch in progress. |
isReady | boolean | Server indicates query is complete. |
isDropdownOpen | boolean | Whether the dropdown should be visible. Drive your own dropdown's visibility with this in Tier 3. |
isFocused | boolean | Whether the input currently has focus, as last reported through inputProps or setFocused(). |
isActivePillSelected | boolean | Whether the leading pill should render selected (full opacity) rather than de-emphasized. True while a tappable dropdown option is highlighted; in "manual" trigger mode, true once the pill has been tapped. |
products | Product[] | What the product strip shows: the items the latest /suggest response reported as matching the query, or the results of a custom products search. Already spread into dropdownProps, so read it directly only when you render your own strip. |
customFields | CustomFieldsReport | null | The catalog report the latest response carried, or null when it carried none. See CustomFieldsReport below. |
listboxId | string | Generated id shared by the input's aria-controls and your dropdown's listbox element. Use it when you render your own dropdown so the combobox stays correctly wired for screen readers. |
placeholderText | string | Suggested placeholder text for the current step. |
error | Error | null | Last fetch error. |
Input forwarding (custom inputs)
| Prop | Type | Description |
|---|---|---|
handleTextChange | (text: string) => void | Forward the input's current plain text to the engine on every edit. Custom inputs only — textareas use inputProps. |
handleKeyDown | (e: KeyboardEvent) => void | Forward a keyboard event so the engine can handle Arrow/Enter/Tab/Escape while the dropdown is open. Check event.defaultPrevented to see if it was consumed. Custom inputs only. |
setFocused | (focused: boolean) => void | Tell the engine the input gained or lost focus. Custom inputs only. |
handleCaretMove | (offset: number) => void | Report the caret position (plain-text offset) so arrow keys can move into the dropdown. Call on selection changes. Custom inputs only. |
Actions
| Prop | Type | Description |
|---|---|---|
setActivePill | (index: number) => void | Move the pill at index to front (active). |
removeLastParam | () => void | Remove last completed param, restore as a pill. |
clearNewParamId | () => void | Clear shimmer animation state. |
reset | () => void | Clear all state, re-fetch. |
selectProduct | (product: Product) => void | Announce a product-card activation, firing onProductSelect. The built-in dropdown calls this for you; hand-rolled strips call it themselves. The SDK never navigates. |
Spread props
| Prop | Type | Description |
|---|---|---|
inputProps | TextareaHTMLAttributes | Spread onto a <textarea>. Includes value, placeholder, onChange, onKeyDown, and ARIA attributes. |
dropdownProps | AIAutocompleteDropdownProps | Spread onto <AIAutocompleteDropdown />. Its shape is exactly the <AIAutocompleteDropdown /> props documented below — in Tier 3, read suggestions, activeIndex, isOpen, onSelect, and onHighlight from it to render your own dropdown. |
inputProps fields
What inputProps contains, for when you want to add a handler or wire a non-textarea input. Spread it onto a <textarea>; for a contentEditable or rich-text input, skip it and use the input-forwarding actions above.
| Prop | Type | Description |
|---|---|---|
value | string | Current input text — render it as the textarea's value. |
placeholder | string | undefined | Suggested placeholder for the active step (may be undefined). |
onChange | (e: ChangeEvent<HTMLTextAreaElement>) => void | Forwards edits to the engine (also handles autocapitalize). |
onKeyDown | (e: KeyboardEvent<HTMLTextAreaElement>) => void | Routes Arrow / Enter / Tab / Escape to the dropdown while it's open. |
onFocus / onBlur | () => void | Notify the engine when the input gains or loses focus. |
role + aria-* | ARIA attributes | Combobox accessibility wiring: role="combobox", aria-expanded, aria-activedescendant, aria-autocomplete, aria-controls. |
<AIAutocompleteDropdown />
Spread dropdownProps from useAIAutocomplete.
| Prop | Type | Default | Description |
|---|---|---|---|
suggestionsRequired | Suggestion[] | — | Suggestions to display. |
activeIndexRequired | number | — | Highlighted option index. |
onSelectRequired | (option: SuggestionOption) => void | — | Called when an option is selected. |
onHighlightRequired | (index: number) => void | — | Called on mouse hover. |
isOpenRequired | boolean | — | Whether the dropdown is visible. |
idRequired | string | — | Listbox ID for ARIA. |
pills | Suggestion[] | — | Pills to render inside the dropdown. |
onPillClick | (index: number) => void | — | Called when a pill is clicked. |
showPills | boolean | true | Whether to render pills. |
productsLayout | "row" | "list" | "row" | How the product strip lays its cards out. Same values and default as the <AIAutocomplete /> prop. |
optionsPosition | "above" | "below" | "below" | Where the dropdown opens relative to the input — "above" or "below". Default "below". |
mode | "light" | "dark" | "auto" | — | Color mode for a standalone dropdown — self-scopes the SDK tokens so no .magicx-aia wrapper is needed. Leave unset when nested inside a .magicx-aia ancestor. |
className | string | — | CSS class applied to the dropdown. |
AutocompleteResult
The shape of the object passed to onSubmit.
| Prop | Type | Description |
|---|---|---|
query | string | Plain text as the user sees it. |
raw_query | string | Text with placeholder tokens (e.g. "Create a {{TASK_1}}"). |
completed_params | CompletedParam[] | Filled parameter values. |
custom_fields | CustomFieldsReport | The catalog report for this response, when it carried one. Omitted, not null, when no catalog was read. See CustomFieldsReport below. |
CustomFieldsReport
The catalog report. Every response that read your product catalog also says what it did with the query. The hook returns it as customFields, and it rides on AutocompleteResult as custom_fields.
| Prop | Type | Description |
|---|---|---|
applied_filters | ExpressedFilter[] | Constraints the server read out of the query and the catalog answered, each { param, value, op } with op one of eq, ne, lt, lte, gt, gte. Always an array. |
dropped_filters | ExpressedFilter[] | Constraints the query expressed that the catalog could not answer: a parameter it does not have, a bound that is not a number, or a value no item carries. The items were narrowed without them, so this list is what tells "87 black t-shirts" from "no black item, so here are t-shirts". Always an array. |
items.total | number | How many items the applied filters left standing. Also counts what the query's own words matched, so it drops as a typed word starts matching a title. |
items.matched | MatchedItem[] | The items themselves, capped by the server. This is the list the product strip renders. Empty with a non-zero total when nothing narrowed the catalog, since naming arbitrary items as matches would mislead. |
null (no custom_fields key on the result) means the response carried no report: no catalog was read for it, such as a product with no catalog, the starting state, or a response with no option-bearing parameter to offer. That is "no news", not an empty catalog. The strip clears on such a response rather than keeping an older query's items, and the report stays readable while showProducts is false.