---
name: date-picker
title: Date Picker
url: https://ui.frontic.com/components/ui/date-picker.md
tier: ui
install: npx @frontic/ui add date-picker
files:
  - components/ui/date-picker/DatePicker.vue
  - components/ui/date-picker/DatePickerCalendar.vue
  - components/ui/date-picker/DatePickerContent.vue
  - components/ui/date-picker/DatePickerTrigger.vue
  - components/ui/date-picker/index.ts
registryDependencies:
  - calendar
  - date-field
  - popover
dependencies:
  - "@internationalized/date"
  - "@lucide/vue"
  - "@vueuse/core"
  - reka-ui
---

# Date Picker

A date typed segment by segment or picked from a calendar the button beside it opens; joins a Field around it.

## Install

```sh
npx @frontic/ui add date-picker
```

Built from: [Calendar](https://ui.frontic.com/components/ui/calendar.md), [Date Field](https://ui.frontic.com/components/ui/date-field.md), [Popover](https://ui.frontic.com/components/ui/popover.md)

Used by: [Date Range Picker](https://ui.frontic.com/components/ui/date-range-picker.md)

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

## Examples

```vue
<script setup lang="ts">
import { getLocalTimeZone, isWeekend, today } from '@internationalized/date'
import type { DateValue } from 'reka-ui'
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { DatePicker } from '@/components/ui/date-picker'

const tomorrow = today(getLocalTimeZone()).add({ days: 1 })
const closed = (date: DateValue) => isWeekend(date, 'de-DE')
</script>

<template>
  <Field name="pickup" class="w-xs max-w-full">
    <FieldLabel :native-label="false">Pick up at the Basecamp store</FieldLabel>
    <DatePicker :min-value="tomorrow" :is-date-unavailable="closed" />
    <FieldDescription>Open Monday to Friday; from tomorrow.</FieldDescription>
  </Field>
</template>
```

The example also uses `field`, which `add date-picker` leaves out: `npx @frontic/ui add field`.

## Anatomy

```vue
<DatePicker>
  <DatePickerTrigger />
  <DatePickerContent />
</DatePicker>
```

## API reference

### DatePicker

Lets the user type a date, or pick it from a calendar the button beside it opens.

`data-slot="date-picker"` · `DatePicker.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `disabled` | `boolean` | `false` | Whether or not the date field is disabled |
| `dir` | `Direction`: `'ltr' \| 'rtl'` |  | The reading direction of the date field when applicable.<br><br>If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. |
| `modelValue` | `DateValue \| null`: `null \| CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The controlled value of the field. Can be bound as `v-model`. |
| `defaultValue` | `DateValue`: `CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The default value for the calendar |
| `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. |
| `defaultPlaceholder` | `DateValue`: `CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The default placeholder date |
| `placeholder` | `DateValue`: `CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view |
| `maxValue` | `DateValue`: `CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The maximum date that can be selected |
| `minValue` | `DateValue`: `CalendarDate \| CalendarDateTime \| ZonedDateTime` |  | The minimum date that can be selected |
| `locale` | `string` |  | The locale to use for formatting dates |
| `readonly` | `boolean` | `false` | Whether or not the date field is readonly |
| `isDateUnavailable` | `Matcher`: `(date: DateValue): boolean` |  | A function that returns whether or not a date is unavailable |
| `id` | `string` |  | Id of the element |
| `hourCycle` | `HourCycle`: `12 \| 24` |  | The hour cycle used for formatting times. Defaults to the local preference |
| `step` | `DateStep` |  | The stepping interval for the time fields. Defaults to `1`. |
| `stepSnapping` | `boolean` | `false` | Whether to enforce snapping the time value to the nearest step increment after input. Defaults to `false`. |
| `granularity` | `Granularity`: `'day' \| 'hour' \| 'minute' \| 'second'` |  | The granularity to use for formatting times. Defaults to day if a CalendarDate is provided, otherwise defaults to minute. The field will render segments for each part of the date up to and including the specified granularity |
| `hideTimeZone` | `boolean` | `false` | Whether or not to hide the time zone segment of the field |
| `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` | `false` | 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. |
| `pagedNavigation` | `boolean` | `false` | This property causes the previous and next buttons to navigate by the number of months displayed at once, rather than one month |
| `preventDeselect` | `boolean` | `false` | Whether or not to prevent the user from deselecting a date without selecting another date first |
| `weekStartsOn` | `WeekStartsOn`: `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6` |  | The day of the week to start the calendar on |
| `weekdayFormat` | `WeekDayFormat`: `'narrow' \| 'short' \| 'long'` |  | The format to use for the weekday strings provided via the weekdays slot prop |
| `fixedWeeks` | `boolean` | `false` | Whether or not to always display 6 weeks in the calendar |
| `numberOfMonths` | `number` |  | The number of months to display at once |
| `isDateDisabled` | `Matcher`: `(date: DateValue): boolean` |  | A function that returns whether or not a date is disabled |
| `closeOnSelect` | `boolean` | `true` | Whether or not to close the popover on date select |
| `class` | `ClassValue` |  | Classes added to the part's own element, after its recipe classes. |
| `layout` | `LayoutTypes`: `'month-and-year' \| 'month-only' \| 'year-only'` |  | Replaces the calendar's month heading with month and/or year dropdowns. |
| `triggerLabel` | `string` | `'Open calendar'` | Names the calendar button for screen readers. |

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `date: DateValue \| undefined` | Event handler called whenever the model value changes |
| `update:open` | `value: boolean` | Event handler called when the open state of the popover changes. |
| `update:placeholder` | `date: DateValue` | Event handler called whenever the placeholder value changes |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ segments: Segment[]; modelValue: DateValue \| undefined; }` | Replaces the segments; gets them and the date, to lay out with DateFieldInput. |

### DatePickerContent

The popover a DatePicker's or DateRangePicker's calendar opens in, lined up with the field.

`data-slot="date-picker-content"` · `DatePickerContent.vue`

| 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. |

### DatePickerTrigger

The calendar button at the end of a DatePicker's or DateRangePicker's field.

`data-slot="date-picker-trigger"` · `DatePickerTrigger.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | `'Open calendar'` | Names the button for screen readers. |

## Styling

| Part | Recipe |
| --- | --- |
| `trigger` | [`date-picker-trigger`](https://ui.frontic.com/DESIGN.md#date-picker-trigger) |
| `content` | [`date-picker-content`](https://ui.frontic.com/DESIGN.md#date-picker-content) |
| `focus-ring` | [`focus-ring`](https://ui.frontic.com/DESIGN.md#focus-ring) |

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

## Source

`components/ui/date-picker/DatePicker.vue`

```vue
<script lang="ts">
/** Lets the user type a date, or pick it from a calendar the button beside it opens. */
export default {}
</script>

<script setup lang="ts">
import type { DatePickerRootEmits, DatePickerRootProps, DateValue, SegmentPart } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import type { LayoutTypes } from '@library/components/ui/calendar'
import { reactiveOmit } from '@vueuse/core'
import { DatePickerAnchor, DatePickerRoot, useForwardPropsEmits } from 'reka-ui'
import { DateField } from '@library/components/ui/date-field'
import DatePickerCalendar from './DatePickerCalendar.vue'
import DatePickerContent from './DatePickerContent.vue'
import DatePickerTrigger from './DatePickerTrigger.vue'

type Segment = { part: SegmentPart; value: string }

const props = withDefaults(
  defineProps<
    DatePickerRootProps & {
      class?: HTMLAttributes['class']
      /** Replaces the calendar's month heading with month and/or year dropdowns. */
      layout?: LayoutTypes
      /** Names the calendar button for screen readers. */
      triggerLabel?: string
    }
  >(),
  { triggerLabel: 'Open calendar', closeOnSelect: true },
)
defineOptions({ inheritAttrs: false })

const emits = defineEmits<DatePickerRootEmits>()

const forwarded = useForwardPropsEmits(reactiveOmit(props, 'class', 'layout', 'triggerLabel'), emits)

defineSlots<{
  /** Replaces the segments; gets them and the date, to lay out with DateFieldInput. */
  default?: (props: { segments: Segment[]; modelValue: DateValue | undefined }) => unknown
}>()
</script>

<template>
  <DatePickerRoot v-bind="forwarded">
    <DatePickerAnchor as-child>
      <DateField v-bind="$attrs" data-slot="date-picker" :class="props.class">
        <template v-if="$slots.default" #default="slotProps">
          <slot v-bind="slotProps as { segments: Segment[]; modelValue: DateValue | undefined }" />
        </template>
        <template #end>
          <DatePickerTrigger :label="triggerLabel" />
        </template>
      </DateField>
    </DatePickerAnchor>
    <DatePickerContent>
      <DatePickerCalendar :layout="layout" />
    </DatePickerContent>
  </DatePickerRoot>
</template>
```

`components/ui/date-picker/DatePickerCalendar.vue`

```vue
<script lang="ts">
/** The calendar a date picker opens: our Calendar, driven by the picker's date and settings. */
export default {}
</script>

<script setup lang="ts">
import type { DateValue } from 'reka-ui'
import type { LayoutTypes } from '@library/components/ui/calendar'
import { isEqualDay } from '@internationalized/date'
import { injectDatePickerRootContext } from 'reka-ui'
import { Calendar } from '@library/components/ui/calendar'

defineProps<{
  /** Replaces the month heading with month and/or year dropdowns. */
  layout?: LayoutTypes
}>()

const picker = injectDatePickerRootContext()

function pick(date: DateValue | undefined) {
  if (date && picker.modelValue.value && isEqualDay(date, picker.modelValue.value)) return
  picker.onDateChange(date)
}

function page(date: DateValue) {
  if (!isEqualDay(date, picker.placeholder.value)) picker.onPlaceholderChange(date)
}
</script>

<template>
  <Calendar
    :model-value="picker.modelValue.value"
    :placeholder="picker.placeholder.value"
    :layout="layout"
    :is-date-disabled="picker.isDateDisabled"
    :is-date-unavailable="picker.isDateUnavailable"
    :min-value="picker.minValue.value"
    :max-value="picker.maxValue.value"
    :locale="picker.locale.value"
    :disabled="picker.disabled.value"
    :paged-navigation="picker.pagedNavigation.value"
    :week-starts-on="picker.weekStartsOn.value"
    :weekday-format="picker.weekdayFormat.value"
    :fixed-weeks="picker.fixedWeeks.value"
    :number-of-months="picker.numberOfMonths.value"
    :readonly="picker.readonly.value"
    :prevent-deselect="picker.preventDeselect.value"
    :dir="picker.dir.value"
    @update:model-value="pick"
    @update:placeholder="page"
  />
</template>
```

`components/ui/date-picker/DatePickerContent.vue`

```vue
<script lang="ts">
/** The popover a DatePicker's or DateRangePicker's calendar opens in, lined up with the field. */
export default {}
</script>

<script setup lang="ts">
import { PopoverContent } from '@library/components/ui/popover'

/** Opens the calendar on the picked day, else today, else its first day that can be picked. */
function focusDay(event: Event) {
  const calendar = event.target as HTMLElement
  const day =
    calendar.querySelector<HTMLElement>('[data-selected]') ??
    calendar.querySelector<HTMLElement>('[data-today]:not([data-disabled])') ??
    calendar.querySelector<HTMLElement>('[data-value]:not([data-outside-view]):not([data-disabled])')
  if (!day) return
  event.preventDefault()
  day.focus()
}
</script>

<template>
  <PopoverContent data-slot="date-picker-content" align="start" class="fui-date-picker-content" @open-auto-focus="focusDay">
    <slot />
  </PopoverContent>
</template>
```

`components/ui/date-picker/DatePickerTrigger.vue`

```vue
<script lang="ts">
/** The calendar button at the end of a DatePicker's or DateRangePicker's field. */
export default {}
</script>

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

import { DatePickerTrigger, DateRangePickerTrigger, injectDateRangePickerRootContext } from 'reka-ui'

withDefaults(
  defineProps<{
    /** Names the button for screen readers. */
    label?: string
  }>(),
  { label: 'Open calendar' },
)

const range = injectDateRangePickerRootContext(null)
</script>

<template>
  <component
    :is="range ? DateRangePickerTrigger : DatePickerTrigger"
    data-slot="date-picker-trigger"
    :aria-label="label"
    class="fui-date-picker-trigger outline-none transition-colors focus-visible:fui-focus-ring disabled:pointer-events-none"
  >
    <CalendarIcon data-icon />
  </component>
</template>
```

## API of the items the example uses

### Field

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

#### Field

Groups a label, an input, a description and an error of one form field, and validates its input.

`data-slot="field"` · `Field.vue`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` |  | The name of the field. Submitted with its owning form as part of a name/value pair, and used to match server `errors` on a `FormRoot`. Takes precedence over the `name` of the control. |
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with the field's control. Takes precedence over the `disabled` of the control. |
| `required` | `boolean` | `false` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `invalid` | `boolean` |  | When `true`, marks the field invalid regardless of its own validation. Useful when the field state is controlled by an external library. |
| `dirty` | `boolean` |  | Whether the field's value has changed from its initial value. Useful when the field state is controlled by an external library. |
| `touched` | `boolean` |  | Whether the field has been touched (its control blurred). Useful when the field state is controlled by an external library. |
| `validate` | `FieldValidateFn`: `(value: unknown, formValues: Record<string, unknown>): FieldValidateResult \| Promise<FieldValidateResult>` |  | Custom validation function. Return an error message (or array of messages) when invalid, or `null`/`undefined` when valid. Receives the control's value and the values of every named field in the owning form.<br><br>Can be async, but an async `validate` does not prevent form submission when `validationMode` is `onSubmit`. |
| `validationMode` | `FieldValidationMode`: `'onBlur' \| 'onChange' \| 'onSubmit'` | `'onSubmit'` | When the field (re-)runs validation. Takes precedence over the `validationMode` of an ancestor `FormRoot`.<br>- `onSubmit`: when the form is submitted, then on every change after that.<br>- `onBlur`: when the control loses focus.<br>- `onChange`: on every change to the control's value. |
| `validationDebounceTime` | `number` |  | How long to wait (in ms) between `validate` calls when validating on change. |
| `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. |
| `orientation` | `FieldOrientation`: `'vertical' \| 'horizontal' \| 'responsive'` | `'vertical'` | Label above the control, beside it, or `responsive`: beside it once the field group is wide enough. |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ invalid: boolean; errors: string[]; }` | The label, control, description and error; gets `invalid` and the current `errors`. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-horizontal` |  | Present when the part is laid out horizontally. |
| `data-orientation` | `'vertical' \| 'horizontal' \| 'responsive'` | Carries the `orientation` prop. |

#### FieldContent

Groups the label and description that sit beside the control of a field. Renders a `<div>`.

`data-slot="field-content"` · `FieldContent.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. |

#### FieldDescription

Gives help text for a field, such as what to enter.

`data-slot="field-description"` · `FieldDescription.vue`

Styling: `field-description`, which extends [`hint`](https://ui.frontic.com/DESIGN.md#hint) and [`link-primary`](https://ui.frontic.com/DESIGN.md#link-primary). Change them there and every part that extends them follows.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  | Id of the element. Auto-generated when not provided. |
| `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. |

#### FieldError

Shows why the input of a field is invalid, from its own validation, from the server or from a form library.

`data-slot="field-error"` · `FieldError.vue`

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

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  | Id of the element. Auto-generated when not provided. |
| `match` | `boolean \| keyof ValidityState`: `boolean \| 'badInput' \| 'customError' \| 'patternMismatch' \| 'rangeOverflow' \| 'rangeUnderflow' \| 'stepMismatch' \| 'tooLong' \| 'tooShort' \| 'typeMismatch' \| 'valid' \| 'valueMissing'` |  | Restricts when this error renders:<br>- a `ValidityState` key (e.g. `"valueMissing"`) — renders when that constraint fails.<br>- `true` — always renders, letting an external library control visibility.<br>- omitted — renders whenever the field is invalid. |
| `forceMount` | `boolean` | `false` | Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. |
| `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. |
| `errors` | `(string \| { message: string \| undefined; } \| undefined)[]` |  | Messages from outside the Field, such as vee-validate's or TanStack Form's; shown instead of the Field's own, duplicates dropped. |

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ errors: string[]; }` | Replaces the messages; gets the current `errors`. |

#### FieldGroup

Stacks several fields of a form together. Renders a `<div>`.

`data-slot="field-group"` · `FieldGroup.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. |

#### FieldLabel

Labels the input of a field.

`data-slot="field-label"` · `FieldLabel.vue`

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

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `nativeLabel` | `boolean` | `true` | Whether the label renders a native `label` element. Set to `false` when rendering another element (e.g. `as="div"`): it then drops `for`, focuses the control on click, and relies on the control's `aria-labelledby`.<br><br>Useful for button controls like `SelectTrigger`, where a native label would forward clicks and `:hover` to the button. |
| `for` | `string` |  | The id of the element the label is associated with. |
| `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. |

#### FieldLegend

Titles a set of related fields. Renders a `<legend>`.

`data-slot="field-legend"` · `FieldLegend.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` | `'legend'` | 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. |
| `variant` | `'label' \| 'legend'` | `'legend'` | Whether the legend reads as a section heading or as a field label. |

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-variant` | `'label' \| 'legend'` | Carries the `variant` prop. |

#### FieldSeparator

Separates fields of a form, optionally with a short text in between. Renders a `<div>`.

`data-slot="field-separator"` · `FieldSeparator.vue`

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

| Data attribute | Values | Description |
| --- | --- | --- |
| `data-content` | `'true' \| 'false'` | `true` when the separator has text in it. |

#### FieldSet

Groups related fields under one legend. Renders a `<fieldset>`.

`data-slot="field-set"` · `FieldSet.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` | `'fieldset'` | 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. |

#### FieldTitle

Shows the title of a field next to its description. Renders a `<div>`.

`data-slot="field-title"` · `FieldTitle.vue`

Styling: `field-label`, 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` | `'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. |

#### FieldValidity

Renders from the validation state of a field, such as a custom message or a strength meter.

| Slot | Slot props | Description |
| --- | --- | --- |
| `default` | `{ validity: Omit<Record<keyof ValidityState, boolean>, "valid"> & { valid: boolean \| null; }; errors: string[]; error: string; value: unknown; initialValue: unknown; }` | Gets the field's `validity` (`valid` is `null` until there is one), its `errors`, the first `error`, the `value` validated last and the `initialValue`. |
