Installation
Complete project setup first. Your configuration
must select vue/reka and include your Design System ID.
pnpm exec frontfriend download date-picker -f vue --primitive rekaReview dependencies reported by the downloader and keep your source changes in version control.
Usage
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": false,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "default",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Behavior
- Single-date, month, and year selections publish immediately.
- Range selection remains an internal draft until Apply.
- Apply is disabled until both range endpoints are selected; same-day ranges are valid.
- Published ranges are always complete and Reset publishes undefined.
- External value changes synchronize immediately while closed and never interrupt an open draft.
- Cancel or outside close discards the draft and adopts the latest external value; Apply publishes the draft and wins over a pending external value.
- An explicit value is authoritative; selectedPreset is descriptive or initializes selection only when no value exists.
Examples
Default
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": false,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "default",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Range
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": true,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "range",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Range Presets
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": true,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "suggestions",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Suggestions Compact
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": true,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "compact",
"preset": "suggestions",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Months
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": false,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "months",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Years
<script setup lang="ts">
import { DatePicker } from "@/components/ui/date-picker";
const args = {
"range": false,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "years",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
</script>
<template>
<DatePicker v-bind="args" />
</template> Formatting and external state
<script setup lang="ts">
import { CalendarDate } from "@internationalized/date";
import { ref } from "vue";
import { DatePicker } from "@/components/ui/date-picker";
import { Button } from "@/components/ui/button";
const args = {
"range": false,
"disabled": false,
"format": "dd/mm/yyyy",
"layout": "relaxed",
"preset": "default",
} satisfies Partial<
InstanceType<typeof DatePicker> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
format?: "dd/mm/yyyy" | "m,d,yyyy" | "locale" | "custom";
layout?: "relaxed" | "compact";
preset?: "default" | "suggestions" | "range" | "months" | "years";
};
const initialRange = {
start: new CalendarDate(2026, 12, 20),
end: new CalendarDate(2026, 12, 31),
};
const replacementRange = {
start: new CalendarDate(2027, 1, 10),
end: new CalendarDate(2027, 1, 20),
};
const range = ref<typeof initialRange | undefined>(initialRange);
const reset = () => {
range.value = undefined;
};
</script>
<template>
<div class="flex max-w-4xl flex-col gap-6">
<div class="flex flex-wrap gap-4">
<DatePicker
:range="false"
:default-value="new CalendarDate(2026, 12, 31)"
locale="it-IT"
format="locale"
:format-options="{ day: '2-digit', month: 'short', year: '2-digit' }"
/>
<DatePicker
:range="false"
:default-value="new CalendarDate(2026, 12, 31)"
locale="en-US"
format="locale"
:format-options="{ day: '2-digit', month: 'short', year: '2-digit' }"
/>
<DatePicker
:range="false"
:default-value="new CalendarDate(2026, 12, 31)"
locale="it-IT"
format="custom"
format-pattern="dd MMM, yy"
/>
</div>
<div class="flex flex-col gap-3">
<p class="text-sm">
Open the range, change its draft, then use the external controls before
choosing Cancel or Apply.
</p>
<DatePicker
v-model="range"
range
preset="suggestions"
selected-preset="thisMonth"
locale="en-GB"
format="locale"
show-reset-button
/>
<div class="flex gap-2">
<Button variant="tertiary" @click="range = replacementRange"
>External replacement</Button
>
<Button variant="tertiary" @click="reset">External reset</Button>
<Button variant="tertiary" @click="range = initialRange"
>Restore explicit range</Button
>
</div>
<pre class="text-xs">{{ JSON.stringify(range, null, 2) }}</pre>
</div>
</div>
</template> API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.
DatePicker
| Prop | Type | Default | Description |
|---|---|---|---|
applyButtonText | string | — | |
cancelButtonText | string | — | |
captionLayout | "default" | "dropdown" | — | |
class | string | string[] | object | — | |
customMonths | string[] | — | |
customPresets | CustomPreset[] | — | |
customYears | number[] | — | |
defaultValue | DateValue | DateRange | — | |
disabled | boolean | — | |
editable | boolean | — | |
format | DatePickerFormat | — | |
formatOptions | Intl.DateTimeFormatOptions | — | |
formatPattern | string | — | |
layout | "compact" | "relaxed" | — | |
placeholder | string | — | |
preset | "default" | "suggestions" | "months" | "years" | "range" | — | |
presetsLabels | string[] | — | |
range | boolean | — | |
resetButtonText | string | — | |
selectedPreset | string | — | |
showHeader | boolean | — | |
showResetButton | boolean | — |
DatePresetsTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
class | HTMLAttributes["class"] | — | |
isSelected | boolean | — | |
preset | { name: string; label: string } | — |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.