---
name: popover
title: Popover
url: https://ui.frontic.com/components/ui/popover.md
tier: ui
install: npx @frontic/ui add popover
files:
  - components/ui/popover/Popover.vue
  - components/ui/popover/PopoverAnchor.vue
  - components/ui/popover/PopoverContent.vue
  - components/ui/popover/PopoverDescription.vue
  - components/ui/popover/PopoverHeader.vue
  - components/ui/popover/PopoverTitle.vue
  - components/ui/popover/PopoverTrigger.vue
  - components/ui/popover/index.ts
dependencies:
  - "@vueuse/core"
  - reka-ui
---

# Popover

A small panel that opens from a trigger and stays until dismissed, with a title and description, such as delivery details or a size guide.

## Install

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

Used by: [Date Picker](https://ui.frontic.com/components/ui/date-picker.md), [Filter](https://ui.frontic.com/components/ui/filter.md), [Cart Minimal](https://ui.frontic.com/components/templates/cart-minimal.md), [Filter Toolbar](https://ui.frontic.com/components/templates/filter-toolbar.md)

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

## Examples

```vue
<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger } from '@/components/ui/popover'

const sizes = [
  { size: 'S', chest: '88–96', waist: '76–84' },
  { size: 'M', chest: '96–104', waist: '84–92' },
  { size: 'L', chest: '104–112', waist: '92–100' },
  { size: 'XL', chest: '112–120', waist: '100–108' },
]
</script>

<template>
  <Popover default-open>
    <PopoverTrigger as-child><Button variant="outline" color="neutral">Size guide</Button></PopoverTrigger>
    <PopoverContent>
      <PopoverHeader>
        <PopoverTitle>Jacket sizes</PopoverTitle>
        <PopoverDescription>Body measurements in centimetres.</PopoverDescription>
      </PopoverHeader>
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Size</TableHead>
            <TableHead class="text-end">Chest</TableHead>
            <TableHead class="text-end">Waist</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          <TableRow v-for="row in sizes" :key="row.size">
            <TableCell>{{ row.size }}</TableCell>
            <TableCell class="text-end">{{ row.chest }}</TableCell>
            <TableCell class="text-end">{{ row.waist }}</TableCell>
          </TableRow>
        </TableBody>
      </Table>
    </PopoverContent>
  </Popover>
</template>
```

The example also uses `button` and `table`, which `add popover` leaves out: `npx @frontic/ui add button table`.

## Anatomy

```vue
<Popover>
  <PopoverTrigger />
  <PopoverContent>
    <PopoverHeader>
      <PopoverTitle />
      <PopoverDescription />
    </PopoverHeader>
  </PopoverContent>
</Popover>
```

## API reference

### Popover

Groups all parts of the popover.

`data-slot="popover"` · `Popover.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `defaultOpen` | `boolean` | `false` | The open state of the popover when it is initially rendered. Use when you do not need to control its open state. |
| `open` | `boolean` |  | The controlled open state of the popover. |
| `modal` | `boolean` | `false` | The modality of the popover. When set to true, interaction with outside elements will be disabled and only popover content will be visible to screen readers. |

| Event | Payload | Description |
| --- | --- | --- |
| `update:open` | `value: boolean` | Event handler called when the open state of the popover changes. |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ open: boolean; close: () => void; }` | Holds the popover's trigger and content; gets whether it is open and a function that closes it. |

### PopoverAnchor

Sets the element the popover content is positioned against.

`data-slot="popover-anchor"` · `PopoverAnchor.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`. |

### PopoverContent

Holds what the popover shows while open.

`data-slot="popover-content"` · `PopoverContent.vue`

Styling: `popover-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. |
| `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. |
| `openAutoFocus` | `event: Event` | Event handler called when auto-focusing on open. Can be prevented. |
| `closeAutoFocus` | `event: Event` | Event handler called when auto-focusing on close. Can be prevented. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-align` | `'start' \| 'center' \| 'end'` | How the content lines up with its trigger: as `align` asks, unless there was no room. |
| `data-dismissable-layer` |  | Marks a layer that closes on Escape or a click outside it. |
| `data-side` | `'top' \| 'right' \| 'bottom' \| 'left'` | The side the content opened on: the one `side` asks for, unless there was no room. |
| `data-state` | `'open' \| 'closed'` | The state the part is in, one value per state. |

| CSS variable | Description |
| --- | --- |
| `--reka-popover-content-available-height` | The height the content has between its trigger and the edge of the screen. |
| `--reka-popover-content-available-width` | The width the content has between its trigger and the edge of the screen. |
| `--reka-popover-content-transform-origin` | The point the content grows from, on the side facing its trigger, for its open and close animation. |
| `--reka-popover-trigger-height` | The trigger's height. |
| `--reka-popover-trigger-width` | The trigger's width, to size the content to match. |

### PopoverDescription

Explains the popover in a short text below its title. Renders a `<p>`.

`data-slot="popover-description"` · `PopoverDescription.vue`

Styling: `popover-description`, which extends [`part-description`](https://ui.frontic.com/DESIGN.md#part-description). 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` | `'p'` | 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. |

### PopoverHeader

Groups the title and description at the top of the popover. Renders a `<div>`.

`data-slot="popover-header"` · `PopoverHeader.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`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

### PopoverTitle

Names what the popover is about. Renders a `<div>`.

`data-slot="popover-title"` · `PopoverTitle.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`. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

### PopoverTrigger

Opens and closes the popover. Renders a `<button>`.

`data-slot="popover-trigger"` · `PopoverTrigger.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`. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-state` | `'open' \| 'closed'` | The state the part is in, one value per state. |

## Styling

| Part | Recipe |
| --- | --- |
| `content` | [`popover-content`](https://ui.frontic.com/DESIGN.md#popover-content) |
| `header` | [`popover-header`](https://ui.frontic.com/DESIGN.md#popover-header) |
| `title` | [`popover-title`](https://ui.frontic.com/DESIGN.md#popover-title) |
| `description` | [`popover-description`](https://ui.frontic.com/DESIGN.md#popover-description) |

## Source

`components/ui/popover/Popover.vue`

```vue
<script lang="ts">
/** Groups all parts of the popover. */
export default {}
</script>

<script setup lang="ts">
import type { PopoverRootEmits, PopoverRootProps } from 'reka-ui'
import { PopoverRoot, useForwardPropsEmits } from 'reka-ui'

const props = defineProps<PopoverRootProps>()
const emits = defineEmits<PopoverRootEmits>()

const forwarded = useForwardPropsEmits(props, emits)

defineSlots<{
  /** Holds the popover's trigger and content; gets whether it is open and a function that closes it. */
  default?: (props: { open: boolean; close: () => void }) => unknown
}>()
</script>

<template>
  <PopoverRoot v-slot="slotProps" data-slot="popover" v-bind="forwarded">
    <slot v-bind="slotProps" />
  </PopoverRoot>
</template>
```

`components/ui/popover/PopoverAnchor.vue`

```vue
<script lang="ts">
/** Sets the element the popover content is positioned against. */
export default {}
</script>

<script setup lang="ts">
import type { PopoverAnchorProps } from 'reka-ui'
import { PopoverAnchor, useForwardProps } from 'reka-ui'

const props = defineProps<PopoverAnchorProps>()
const forwarded = useForwardProps(props)
</script>

<template>
  <PopoverAnchor data-slot="popover-anchor" v-bind="forwarded">
    <slot />
  </PopoverAnchor>
</template>
```

`components/ui/popover/PopoverContent.vue`

```vue
<script lang="ts">
/** Holds what the popover shows while open. */
export default {}
</script>

<script setup lang="ts">
import type { PopoverContentEmits, PopoverContentProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { PopoverContent, PopoverPortal, useForwardPropsEmits } from 'reka-ui'

defineOptions({
  inheritAttrs: false,
})

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

const delegatedProps = reactiveOmit(props, 'class')

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

<template>
  <PopoverPortal>
    <PopoverContent
      data-slot="popover-content"
      v-bind="{ ...$attrs, ...forwarded }"
      :class="[
        'fui-popover-content 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-popover-content-transform-origin)',
        props.class,
      ]"
    >
      <slot />
    </PopoverContent>
  </PopoverPortal>
</template>
```

`components/ui/popover/PopoverDescription.vue`

```vue
<script lang="ts">
/** Explains the popover in a short text below its title. */
export default {}
</script>

<script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui'
import { Primitive } from 'reka-ui'
import type { HTMLAttributes } from 'vue'

const props = withDefaults(
  defineProps<
    PrimitiveProps & {
      class?: HTMLAttributes['class']
    }
  >(),
  { as: 'p' },
)
</script>

<template>
  <Primitive :as="props.as" :as-child="props.asChild" data-slot="popover-description" :class="['fui-popover-description', props.class]">
    <slot />
  </Primitive>
</template>
```

`components/ui/popover/PopoverHeader.vue`

```vue
<script lang="ts">
/** Groups the title and description at the top of the popover. */
export default {}
</script>

<script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui'
import { Primitive } from 'reka-ui'
import type { HTMLAttributes } from 'vue'

const props = withDefaults(
  defineProps<
    PrimitiveProps & {
      class?: HTMLAttributes['class']
    }
  >(),
  { as: 'div' },
)
</script>

<template>
  <Primitive :as="props.as" :as-child="props.asChild" data-slot="popover-header" :class="['fui-popover-header', props.class]">
    <slot />
  </Primitive>
</template>
```

`components/ui/popover/PopoverTitle.vue`

```vue
<script lang="ts">
/** Names what the popover is about. */
export default {}
</script>

<script setup lang="ts">
import type { PrimitiveProps } from 'reka-ui'
import { Primitive } from 'reka-ui'
import type { HTMLAttributes } from 'vue'

const props = withDefaults(
  defineProps<
    PrimitiveProps & {
      class?: HTMLAttributes['class']
    }
  >(),
  { as: 'div' },
)
</script>

<template>
  <Primitive :as="props.as" :as-child="props.asChild" data-slot="popover-title" :class="['fui-popover-title', props.class]">
    <slot />
  </Primitive>
</template>
```

`components/ui/popover/PopoverTrigger.vue`

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

<script setup lang="ts">
import type { PopoverTriggerProps } from 'reka-ui'
import { PopoverTrigger, useForwardProps } from 'reka-ui'

const props = defineProps<PopoverTriggerProps>()
const forwarded = useForwardProps(props)
</script>

<template>
  <PopoverTrigger data-slot="popover-trigger" v-bind="forwarded">
    <slot />
  </PopoverTrigger>
</template>
```

## API of the items the example uses

### Button

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

#### Button

Lets the user trigger an action, such as adding a product to the cart. Renders a `<button>`.

`data-slot="button"` · `Button.vue`

Styling: `button`, which extends [`action`](https://ui.frontic.com/DESIGN.md#action). 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` | `'button'` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `variant` | `'solid' \| 'outline' \| 'soft' \| 'ghost' \| 'link'` | `'solid'` | The visual style: a filled, outlined, tinted, background-free or text-link button. |
| `color` | `'neutral' \| 'primary' \| 'destructive' \| 'buy' \| 'checkout' \| 'inverse'` | `'primary'` | The colour role, e.g. primary for the brand colour, buy for add-to-cart, checkout for the checkout step, destructive for removing. |
| `size` | `'md' \| 'xs' \| 'sm' \| 'lg' \| 'icon-xs' \| 'icon-sm' \| 'icon-md' \| 'icon-lg'` | `'md'` | The button's height and padding; the `icon-*` sizes make a square, icon-only button. |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |

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

### Table

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

#### Table

Groups all parts of the table, which shows data in rows and columns. Renders a `<table>`.

`data-slot="table"` · `Table.vue`

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

#### TableBody

Holds the data rows of the table. Renders a `<tbody>`.

`data-slot="table-body"` · `TableBody.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` | `'tbody'` | 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. |

#### TableCaption

Describes in a short line what the table shows. Renders a `<caption>`.

`data-slot="table-caption"` · `TableCaption.vue`

Styling: `table-caption`, which extends [`hint`](https://ui.frontic.com/DESIGN.md#hint). 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` | `'caption'` | 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. |

#### TableCell

Holds one value in a row of the table. Renders a `<td>`.

`data-slot="table-cell"` · `TableCell.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` | `'td'` | 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. |

#### TableEmpty

Shows a message in place of rows when the table has no data. Renders a `<td>`.

`data-slot="table-empty"` · `TableEmpty.vue`

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

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `colspan` | `number` | `1` | The number of columns the empty row spans; set it to the table's column count. |

#### TableFooter

Holds the summary rows at the bottom of the table, such as totals. Renders a `<tfoot>`.

`data-slot="table-footer"` · `TableFooter.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` | `'tfoot'` | 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. |

#### TableHead

Labels one column of the table. Renders a `<th>`.

`data-slot="table-head"` · `TableHead.vue`

Styling: `table-head`, which extends [`label`](https://ui.frontic.com/DESIGN.md#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` | `'th'` | 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. |

#### TableHeader

Holds the row of column labels at the top of the table. Renders a `<thead>`.

`data-slot="table-header"` · `TableHeader.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` | `'thead'` | 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. |

#### TableRow

Groups the cells that belong to one entry of the table. Renders a `<tr>`.

`data-slot="table-row"` · `TableRow.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` | `'tr'` | 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-selected` |  | Present while the item is selected. |
