---
name: autocomplete
title: Autocomplete
url: https://ui.frontic.com/components/ui/autocomplete.md
tier: ui
install: npx @frontic/ui add autocomplete
files:
  - components/ui/autocomplete/Autocomplete.vue
  - components/ui/autocomplete/AutocompleteAnchor.vue
  - components/ui/autocomplete/AutocompleteCancel.vue
  - components/ui/autocomplete/AutocompleteEmpty.vue
  - components/ui/autocomplete/AutocompleteGroup.vue
  - components/ui/autocomplete/AutocompleteInput.vue
  - components/ui/autocomplete/AutocompleteItem.vue
  - components/ui/autocomplete/AutocompleteList.vue
  - components/ui/autocomplete/AutocompleteSeparator.vue
  - components/ui/autocomplete/AutocompleteTrigger.vue
  - components/ui/autocomplete/AutocompleteViewport.vue
  - components/ui/autocomplete/index.ts
registryDependencies:
  - input-group
dependencies:
  - "@lucide/vue"
  - "@vueuse/core"
  - reka-ui
---

# Autocomplete

An input with suggestions that accepts free-form text; the value is the text itself.

## Install

```sh
npx @frontic/ui add autocomplete
```

Built from: [Input Group](https://ui.frontic.com/components/ui/input-group.md)

npm packages: `@lucide/vue`, `@vueuse/core`, `reka-ui`

## Examples

```vue
<script setup lang="ts">
import { MapPinIcon } from '@lucide/vue'
import { InputGroupAddon } from '@/components/ui/input-group'
import { Autocomplete, AutocompleteAnchor, AutocompleteCancel, AutocompleteEmpty, AutocompleteInput, AutocompleteItem, AutocompleteList, AutocompleteViewport } from '@/components/ui/autocomplete'
import { ref, watch } from 'vue'

const addresses = [
  'Hauptstraße 12, 80331 Munich',
  'Hauptstraße 48, 50667 Cologne',
  'Hauptstraße 7, 10115 Berlin',
  'Bergstraße 3, 80333 Munich',
  'Bahnhofstraße 21, 20095 Hamburg',
  'Bahnhofstraße 5, 70173 Stuttgart',
]

/** Stands in for a places API: the server decides what matches, so the list changes with every request. */
async function suggest(query: string) {
  await new Promise((resolve) => setTimeout(resolve, 200))
  return addresses.filter((address) => address.toLowerCase().includes(query.toLowerCase()))
}

const query = ref('')
const suggestions = ref<string[]>([])

// A slower answer to an older query must not replace the newer one's.
watch(query, async (value, _old, onCleanup) => {
  let stale = false
  onCleanup(() => (stale = true))
  const result = value.length < 2 ? [] : await suggest(value)
  if (!stale) suggestions.value = result
})
</script>

<template>
  <Autocomplete v-model="query" ignore-filter>
    <AutocompleteAnchor>
      <InputGroupAddon>
        <MapPinIcon data-icon />
      </InputGroupAddon>
      <AutocompleteInput placeholder="Delivery address or postcode" />
      <InputGroupAddon align="inline-end">
        <AutocompleteCancel :class="{ invisible: !query }" />
      </InputGroupAddon>
    </AutocompleteAnchor>
    <AutocompleteList hide-when-empty>
      <AutocompleteViewport>
        <AutocompleteEmpty>No address found.</AutocompleteEmpty>
        <AutocompleteItem v-for="address in suggestions" :key="address" :value="address">{{ address }}</AutocompleteItem>
      </AutocompleteViewport>
    </AutocompleteList>
  </Autocomplete>
</template>
```

## Anatomy

```vue
<Autocomplete>
  <AutocompleteAnchor>
    <AutocompleteInput />
    <AutocompleteCancel />
  </AutocompleteAnchor>
  <AutocompleteList>
    <AutocompleteViewport>
      <AutocompleteEmpty />
      <AutocompleteItem />
    </AutocompleteViewport>
  </AutocompleteList>
</Autocomplete>
```

## API reference

### Autocomplete

Groups all parts of the autocomplete, which lets the user type freely and pick from suggestions.

`data-slot="autocomplete"` · `Autocomplete.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `modelValue` | `string` |  | The controlled value of the Autocomplete (the input text). Can be bound with `v-model`. |
| `defaultValue` | `string` |  | The value of the autocomplete when initially rendered. Use when you do not need to control the state. |
| `open` | `boolean` |  | The controlled open state of the Autocomplete. Can be bound with `v-model:open`. |
| `defaultOpen` | `boolean` | `false` | The open state of the autocomplete when it is initially rendered. Use when you do not need to control its open state. |
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with autocomplete |
| `dir` | `Direction`: `'ltr' \| 'rtl'` |  | The reading direction of the autocomplete when applicable. |
| `name` | `string` |  | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `required` | `boolean` | `false` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `resetSearchTermOnBlur` | `boolean` | `false` | Whether to reset the searchTerm when the Autocomplete input blurred |
| `openOnFocus` | `boolean` | `false` | Whether to open the autocomplete when the input is focused |
| `openOnClick` | `boolean` | `false` | Whether to open the autocomplete when the input is clicked |
| `ignoreFilter` | `boolean` | `false` | When `true`, disable the default filters |
| `highlightOnHover` | `boolean` | `true` | When `true`, hover over item will trigger highlight |
| `loop` | `boolean` | `false` | When `true`, keyboard navigation will loop from last item to first, and vice versa. |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `value: string` | Event handler called when the value changes. |
| `update:open` | `value: boolean` | Event handler called when the open state of the autocomplete changes. |
| `highlight` | `payload: { ref: HTMLElement; value: string; } \| undefined` | Event handler when highlighted element changes. |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ open: boolean; modelValue: string; }` | Holds the autocomplete's parts; gets whether the suggestions are open and the text typed so far. |

### AutocompleteAnchor

Frames the input and its buttons as one field, and marks where the suggestion list attaches.

`data-slot="autocomplete-anchor"` · `AutocompleteAnchor.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `reference` | `ReferenceElement`: `Element \| VirtualElement` |  | The reference (or anchor) element that is being referred to for positioning.<br><br>If not provided will use the current component as anchor. |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-size` |  | The size the part is drawn at. |

### AutocompleteCancel

Clears the text the user has typed. Renders a `<button>`.

`data-slot="autocomplete-cancel"` · `AutocompleteCancel.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'button'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `label` | `string` | `'Clear'` | Accessible name of the button. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-color` |  | The colour the part is drawn in. |
| `data-variant` |  | The variant the part is drawn with. |

### AutocompleteEmpty

Shows a message when no suggestion matches the text.

`data-slot="autocomplete-empty"` · `AutocompleteEmpty.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

### AutocompleteGroup

Groups related suggestions under an optional heading.

`data-slot="autocomplete-group"` · `AutocompleteGroup.vue`

Styling: `autocomplete-label`, which extends [`menu-label`](https://ui.frontic.com/DESIGN.md#menu-label). Change it there and every part that extends it follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `heading` | `string` |  | Text shown above the group's suggestions. |

### AutocompleteInput

Takes the text the user types; the suggestions filter as it changes. Renders a `<input>`.

`data-slot="autocomplete-input"` · `AutocompleteInput.vue`

Styling: `autocomplete-input`, which extends [`control`](https://ui.frontic.com/DESIGN.md#control) and [`control-line`](https://ui.frontic.com/DESIGN.md#control-line). Change them there and every part that extends them follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `modelValue` | `string` |  | The controlled value of the filter. Can be binded with v-model. |
| `autoFocus` | `boolean` | `false` | Focus on element when mounted. |
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with item |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'input'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `string` | Fires with the new value when `modelValue` changes; `v-model` binds it. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-disabled` |  | Present while the part is disabled. |

### AutocompleteItem

Holds one suggestion; picking it fills the input with its text.

`data-slot="autocomplete-item"` · `AutocompleteItem.vue`

Styling: `autocomplete-item`, which extends [`option-item`](https://ui.frontic.com/DESIGN.md#option-item). Change it there and every part that extends it follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `textValue` | `string` |  | A string representation of the item contents.<br><br>If the children are not plain text, then the `textValue` prop must also be set to a plain text representation, which will be used for autocomplete in the ComboBox. |
| `value` (required) | `AcceptableValue`: `null \| string \| number \| bigint \| Record<string, any>` |  | The value given as data when submitted with a `name`. |
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with the item. |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Event | Payload | Description |
| --- | --- | --- |
| `select` | `event: SelectEvent<AcceptableValue>` | Event handler called when the selecting item.<br><br>It can be prevented by calling `event.preventDefault`. |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ selected: boolean; }` | Holds the suggestion's content; gets whether it is the selected one. |

### AutocompleteList

Holds the suggestions while the autocomplete is open.

`data-slot="autocomplete-content"` · `AutocompleteList.vue`

Styling: `autocomplete-content`, which extends [`overlay`](https://ui.frontic.com/DESIGN.md#overlay). Change it there and every part that extends it follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `forceMount` | `boolean` | `false` | Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. |
| `position` | `'popper' \| 'inline'` | `'popper'` | The positioning mode to use,<br><br>`inline` is the default and you can control the position using CSS.<br><br>`popper` positions content in the same way as our other primitives, for example `Popover` or `DropdownMenu`. |
| `bodyLock` | `boolean` | `false` | The document.body will be lock, and scrolling will be disabled. |
| `hideWhenEmpty` | `boolean` | `false` | When `true`, hides the content when there are no items matching the filter. |
| `memoDependencies` | `unknown[]` |  | Reactive dependencies that should invalidate the memoized content subtree. |
| `side` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'bottom'` | The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled. |
| `sideOffset` | `number` | `4` | The distance in pixels from the trigger. |
| `sideFlip` | `boolean` | `true` | Flip to the opposite side when colliding with boundary. |
| `align` | `'center' \| 'start' \| 'end'` | `'center'` | The preferred alignment against the trigger. May change when collisions occur. |
| `alignOffset` | `number` | `0` | An offset in pixels from the `start` or `end` alignment options. |
| `alignFlip` | `boolean` | `true` | Flip alignment when colliding with boundary. May only occur when `prioritizePosition` is true. |
| `avoidCollisions` | `boolean` | `true` | When `true`, overrides the side and align preferences to prevent collisions with boundary edges. |
| `collisionBoundary` | `Element \| (Element \| null)[] \| null`: `null \| Element \| (Element \| null)[]` | `[]` | The element used as the collision boundary. By default this is the viewport, though you can provide additional element(s) to be included in this check. |
| `collisionPadding` | `number \| Partial<Record<'top' \| 'right' \| 'bottom' \| 'left', number>>` | `0` | The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { top: 20, left: 20 }. |
| `arrowPadding` | `number` | `0` | The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. |
| `hideShiftedArrow` | `boolean` | `true` | When `true`, hides the arrow when it cannot be centered to the reference element. |
| `sticky` | `'partial' \| 'always'` | `'partial'` | The sticky behavior on the align axis. `partial` will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless. |
| `hideWhenDetached` | `boolean` | `false` | Whether to hide the content when the trigger becomes fully occluded. |
| `positionStrategy` | `'absolute' \| 'fixed'` |  | The type of CSS position property to use. |
| `updatePositionStrategy` | `'always' \| 'optimized'` | `'optimized'` | Strategy to update the position of the floating element on every animation frame. |
| `disableUpdateOnLayoutShift` | `boolean` | `false` | Whether to disable the update position for the content when the layout shifted. |
| `prioritizePosition` | `boolean` | `false` | Force content to be position within the viewport.<br><br>Might overlap the reference element, which may not be desired. |
| `reference` | `ReferenceElement`: `Element \| VirtualElement` |  | The custom element or virtual element that will be set as the reference to position the floating element.<br><br>If provided, it will replace the default anchor element. |
| `dir` | `Direction`: `'ltr' \| 'rtl'` |  | The reading direction of the popper content when applicable.<br><br>If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `disableOutsidePointerEvents` | `boolean` | `false` | When `true`, hover/focus/click interactions will be disabled on elements outside the `DismissableLayer`. Users will need to click twice on outside elements to interact with them: once to close the `DismissableLayer`, and again to trigger the element. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Event | Payload | Description |
| --- | --- | --- |
| `escapeKeyDown` | `event: KeyboardEvent` | Event handler called when the escape key is down. Can be prevented. |
| `pointerDownOutside` | `event: PointerDownOutsideEvent` | Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
| `focusOutside` | `event: FocusOutsideEvent` | Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented. |
| `interactOutside` | `event: PointerDownOutsideEvent \| FocusOutsideEvent` | Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown` event happens outside or focus moves outside of it. Can be prevented. |

### AutocompleteSeparator

Separates groups of suggestions in the list.

`data-slot="autocomplete-separator"` · `AutocompleteSeparator.vue`

Styling: `autocomplete-separator`, which extends [`divider`](https://ui.frontic.com/DESIGN.md#divider). Change it there and every part that extends it follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

### AutocompleteTrigger

Opens and closes the suggestion list. Renders a `<button>`.

`data-slot="autocomplete-trigger"` · `AutocompleteTrigger.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with item |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'button'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `label` | `string` | `'Show suggestions'` | Accessible name of the button. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-color` |  | The colour the part is drawn in. |
| `data-variant` |  | The variant the part is drawn with. |

### AutocompleteViewport

Scrolls the suggestions when the list is longer than the space available.

`data-slot="autocomplete-viewport"` · `AutocompleteViewport.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `nonce` | `string` |  | Will add `nonce` attribute to the style tag which can be used by Content Security Policy.<br><br>If omitted, inherits globally from `ConfigProvider`. |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` |  | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

## Styling

| Part | Recipe |
| --- | --- |
| `input` | [`autocomplete-input`](https://ui.frontic.com/DESIGN.md#autocomplete-input) |
| `viewport` | [`autocomplete-viewport`](https://ui.frontic.com/DESIGN.md#autocomplete-viewport) |
| `content` | [`autocomplete-content`](https://ui.frontic.com/DESIGN.md#autocomplete-content) |
| `item` | [`autocomplete-item`](https://ui.frontic.com/DESIGN.md#autocomplete-item) |
| `label` | [`autocomplete-label`](https://ui.frontic.com/DESIGN.md#autocomplete-label) |
| `empty` | [`autocomplete-empty`](https://ui.frontic.com/DESIGN.md#autocomplete-empty) |
| `separator` | [`autocomplete-separator`](https://ui.frontic.com/DESIGN.md#autocomplete-separator) |
| `disabled` | [`disabled`](https://ui.frontic.com/DESIGN.md#disabled) |

States with a look of their own: focus, disabled and invalid.

## Source

`components/ui/autocomplete/Autocomplete.vue`

```vue
<script lang="ts">
/** Groups all parts of the autocomplete, which lets the user type freely and pick from suggestions. */
export default {}
</script>

<script setup lang="ts">
import type { AutocompleteRootEmits, AutocompleteRootProps } from 'reka-ui'
import { AutocompleteRoot, injectFieldRootContext, useForwardPropsEmits } from 'reka-ui'
import { computed } from 'vue'

const props = defineProps<AutocompleteRootProps>()
const emits = defineEmits<AutocompleteRootEmits>()

defineSlots<{
  /** Holds the autocomplete's parts; gets whether the suggestions are open and the text typed so far. */
  default?: (props: { open: boolean; modelValue: string }) => unknown
}>()

const forwarded = useForwardPropsEmits(props, emits)

// Takes the disabled state of a Field around it; AutocompleteInput joins the Field as its control. Delete once Reka's Autocomplete reads the Field itself.
const field = injectFieldRootContext(null)
const joined = computed(() => (field ? { ...forwarded.value, disabled: props.disabled || field.disabled.value } : forwarded.value))
</script>

<template>
  <AutocompleteRoot v-slot="slotProps" data-slot="autocomplete" v-bind="joined">
    <slot v-bind="slotProps" />
  </AutocompleteRoot>
</template>
```

`components/ui/autocomplete/AutocompleteAnchor.vue`

```vue
<script lang="ts">
/** Frames the input and its buttons as one field, and marks where the suggestion list attaches. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxAnchorProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteAnchor, useForwardProps } from 'reka-ui'
import { InputGroup } from '@library/components/ui/input-group'

const props = defineProps<ComboboxAnchorProps & { class?: HTMLAttributes['class'] }>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteAnchor as-child data-slot="autocomplete-anchor" v-bind="forwarded">
    <InputGroup :class="props.class">
      <slot />
    </InputGroup>
  </AutocompleteAnchor>
</template>
```

`components/ui/autocomplete/AutocompleteCancel.vue`

```vue
<script lang="ts">
/** Clears the text the user has typed. */
export default {}
</script>

<script setup lang="ts">
import { XIcon } from '@lucide/vue'

import type { ComboboxCancelProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteCancel, useForwardProps } from 'reka-ui'
import { InputGroupButton } from '@library/components/ui/input-group'

const props = withDefaults(
  defineProps<
    ComboboxCancelProps & {
      class?: HTMLAttributes['class']
      /** Accessible name of the button. */
      label?: string
    }
  >(),
  {
    label: 'Clear',
  },
)

const delegatedProps = reactiveOmit(props, 'class', 'label')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteCancel as-child data-slot="autocomplete-cancel" v-bind="forwarded">
    <InputGroupButton size="icon-xs" :aria-label="props.label" :class="props.class">
      <slot>
        <XIcon data-icon />
      </slot>
    </InputGroupButton>
  </AutocompleteCancel>
</template>
```

`components/ui/autocomplete/AutocompleteEmpty.vue`

```vue
<script lang="ts">
/** Shows a message when no suggestion matches the text. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxEmptyProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteEmpty, useForwardProps } from 'reka-ui'

const props = defineProps<ComboboxEmptyProps & { class?: HTMLAttributes['class'] }>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteEmpty data-slot="autocomplete-empty" v-bind="forwarded" :class="['fui-autocomplete-empty', props.class]">
    <slot />
  </AutocompleteEmpty>
</template>
```

`components/ui/autocomplete/AutocompleteGroup.vue`

```vue
<script lang="ts">
/** Groups related suggestions under an optional heading. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxGroupProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteGroup, AutocompleteLabel, useForwardProps } from 'reka-ui'

const props = defineProps<
  ComboboxGroupProps & {
    class?: HTMLAttributes['class']
    /** Text shown above the group's suggestions. */
    heading?: string
  }
>()

const delegatedProps = reactiveOmit(props, 'class', 'heading')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteGroup data-slot="autocomplete-group" v-bind="forwarded" :class="['overflow-hidden', props.class]">
    <AutocompleteLabel v-if="heading" class="fui-autocomplete-label">
      {{ heading }}
    </AutocompleteLabel>
    <slot />
  </AutocompleteGroup>
</template>
```

`components/ui/autocomplete/AutocompleteInput.vue`

```vue
<script lang="ts">
/** Takes the text the user types; the suggestions filter as it changes. */
export default {}
</script>

<script setup lang="ts">
import type { AutocompleteInputEmits, AutocompleteInputProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteInput, FieldControl, injectAutocompleteRootContext, injectFieldRootContext, Slot, useForwardPropsEmits } from 'reka-ui'

defineOptions({
  inheritAttrs: false,
})

const props = defineProps<AutocompleteInputProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<AutocompleteInputEmits>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardPropsEmits(delegatedProps, emits)

// Joins a Field around it through FieldControl, as Input does. Delete once Reka's Autocomplete reads the Field itself.
const field = injectFieldRootContext(null)
const autocomplete = injectAutocompleteRootContext()
</script>

<template>
  <component :is="field ? FieldControl : Slot" v-bind="field ? { asChild: true, modelValue: autocomplete.modelValue.value } : {}">
    <AutocompleteInput
      data-slot="autocomplete-input"
      v-bind="{ ...$attrs, ...forwarded }"
      :class="[
        'fui-autocomplete-input border-0 focus-visible:border-b-0 bg-transparent outline-none transition-colors disabled:pointer-events-none disabled:cursor-not-allowed disabled:fui-disabled group-has-[>[data-align=inline-start]]/input-group:ps-2 group-has-[>[data-align=inline-end]]/input-group:pe-2',
        props.class,
      ]"
    />
  </component>
</template>
```

`components/ui/autocomplete/AutocompleteItem.vue`

```vue
<script lang="ts">
/** Holds one suggestion; picking it fills the input with its text. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxItemEmits, ComboboxItemProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteItem, useForwardPropsEmits } from 'reka-ui'

const props = defineProps<ComboboxItemProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<ComboboxItemEmits>()

defineSlots<{
  /** Holds the suggestion's content; gets whether it is the selected one. */
  default?: (props: { selected: boolean }) => unknown
}>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>

<template>
  <AutocompleteItem
    v-slot="slotProps"
    data-slot="autocomplete-item"
    v-bind="forwarded"
    :class="[
      'fui-autocomplete-item relative cursor-default outline-hidden select-none data-disabled:pointer-events-none data-disabled:fui-disabled **:data-icon:pointer-events-none **:data-icon:shrink-0',
      props.class,
    ]"
  >
    <slot v-bind="slotProps" />
  </AutocompleteItem>
</template>
```

`components/ui/autocomplete/AutocompleteList.vue`

```vue
<script lang="ts">
/** Holds the suggestions while the autocomplete is open. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteContent, AutocompletePortal, useForwardPropsEmits } from 'reka-ui'

defineOptions({
  inheritAttrs: false,
})

const props = withDefaults(defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'] }>(), {
  position: 'popper',
  align: 'center',
  sideOffset: 4,
})
const emits = defineEmits<ComboboxContentEmits>()

const delegatedProps = reactiveOmit(props, 'class')
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>

<template>
  <AutocompletePortal>
    <AutocompleteContent
      data-slot="autocomplete-content"
      v-bind="{ ...$attrs, ...forwarded }"
      :class="[
        'fui-autocomplete-content max-h-(--reka-combobox-content-available-height) z-50 data-open:animate-in data-closed:animate-out data-open:fade-in-0 data-closed:fade-out-0 data-open:zoom-in-95 data-closed:zoom-out-95 data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 duration-100 origin-(--reka-combobox-content-transform-origin) overflow-hidden',
        props.class,
      ]"
    >
      <slot />
    </AutocompleteContent>
  </AutocompletePortal>
</template>
```

`components/ui/autocomplete/AutocompleteSeparator.vue`

```vue
<script lang="ts">
/** Separates groups of suggestions in the list. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxSeparatorProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteSeparator, useForwardProps } from 'reka-ui'

const props = defineProps<ComboboxSeparatorProps & { class?: HTMLAttributes['class'] }>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteSeparator data-slot="autocomplete-separator" v-bind="forwarded" :class="['fui-autocomplete-separator', props.class]" />
</template>
```

`components/ui/autocomplete/AutocompleteTrigger.vue`

```vue
<script lang="ts">
/** Opens and closes the suggestion list. */
export default {}
</script>

<script setup lang="ts">
import { ChevronDownIcon } from '@lucide/vue'

import type { ComboboxTriggerProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteTrigger, useForwardProps } from 'reka-ui'
import { InputGroupButton } from '@library/components/ui/input-group'

const props = withDefaults(
  defineProps<
    ComboboxTriggerProps & {
      class?: HTMLAttributes['class']
      /** Accessible name of the button. */
      label?: string
    }
  >(),
  {
    label: 'Show suggestions',
  },
)

const delegatedProps = reactiveOmit(props, 'class', 'label')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteTrigger as-child data-slot="autocomplete-trigger" v-bind="forwarded">
    <InputGroupButton size="icon-xs" :aria-label="props.label" :class="props.class">
      <slot>
        <ChevronDownIcon data-icon />
      </slot>
    </InputGroupButton>
  </AutocompleteTrigger>
</template>
```

`components/ui/autocomplete/AutocompleteViewport.vue`

```vue
<script lang="ts">
/** Scrolls the suggestions when the list is longer than the space available. */
export default {}
</script>

<script setup lang="ts">
import type { ComboboxViewportProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { AutocompleteViewport, useForwardProps } from 'reka-ui'

const props = defineProps<ComboboxViewportProps & { class?: HTMLAttributes['class'] }>()

const delegatedProps = reactiveOmit(props, 'class')

const forwarded = useForwardProps(delegatedProps)
</script>

<template>
  <AutocompleteViewport data-slot="autocomplete-viewport" v-bind="forwarded" :class="['fui-autocomplete-viewport max-h-63 scroll-py-1.5 overflow-y-auto', props.class]">
    <slot />
  </AutocompleteViewport>
</template>
```

## API of the items the example uses

### Input Group

[Full docs](https://ui.frontic.com/components/ui/input-group.md) · `npx @frontic/ui add input-group`

#### InputGroup

Groups an input with addons such as icons, buttons or text. Renders a `<div>`.

`data-slot="input-group"` · `InputGroup.vue`

Styling: `input-group`, which extends [`control`](https://ui.frontic.com/DESIGN.md#control). Change it there and every part that extends it follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'div'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `size` | `InputGroupSize`: `'md' \| 'sm'` |  | The height of the group; the input inside it follows. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-size` | `'md' \| 'sm'` | Carries the `size` prop. |

#### InputGroupAddon

Places an icon, text or button beside the input of its group. Renders a `<div>`.

`data-slot="input-group-addon"` · `InputGroupAddon.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'div'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `align` | `InputGroupAddonAlign`: `'inline-start' \| 'inline-end' \| 'block-start' \| 'block-end'` | `'inline-start'` | Where the addon sits: before or after the input on its line, or above or below it. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-align` | `'inline-start' \| 'inline-end' \| 'block-start' \| 'block-end'` | Carries the `align` prop. |

#### InputGroupButton

Lets the user act on the input of its group, such as submit it.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `'solid' \| 'outline' \| 'soft' \| 'ghost' \| 'link'` | `'ghost'` | The button style: solid, outline, soft, ghost or link. |
| `color` | `'neutral' \| 'primary' \| 'destructive' \| 'buy' \| 'checkout' \| 'inverse'` | `'neutral'` | The button colour role, e.g. neutral or brand. |
| `size` | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | `'xs'` | The button's size inside the field; the `icon-*` sizes make a square, icon-only button. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-color` | `'neutral' \| 'primary' \| 'destructive' \| 'buy' \| 'checkout' \| 'inverse'` | Carries the `color` prop. |
| `data-size` | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | Carries the `size` prop. |
| `data-variant` | `'solid' \| 'outline' \| 'soft' \| 'ghost' \| 'link'` | Carries the `variant` prop. |

#### InputGroupInput

Lets the user enter a single line of text inside the group.

`data-slot="input-group-control"` · `InputGroupInput.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

#### InputGroupText

Shows fixed text, such as a unit or prefix, inside the group. Renders a `<span>`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
| `as` | `AsTag \| Component`: `ComponentOptions<any, any, any, ComputedOptions, MethodOptions, any, any, any, string, {}, {}, string, {}, {}, {}, string, ComponentProvideOptions> \| (props: any, ctx: Omit<{ attrs: Attrs; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<string, any>>(exposed?: Exposed \| undefined) => void; }, 'expose'>): any \| ComponentPublicInstanceConstructor<any, any, any, any, ComputedOptions, MethodOptions> \| 'a' \| 'button' \| 'div' \| 'form' \| 'h2' \| 'h3' \| 'img' \| 'input' \| 'label' \| 'li' \| 'nav' \| 'ol' \| 'p' \| 'span' \| 'svg' \| 'ul' \| 'template' \| {} & string` | `'span'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

#### InputGroupTextarea

Lets the user enter several lines of text inside the group.

`data-slot="input-group-control"` · `InputGroupTextarea.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
