---
title: "DatePicker"
description: "A date selector with a YYYY-MM-DD string value."
category: Form
status: beta
since: 0.3.4
tags: [date-picker, form, calendar]
syncStatus: reviewed
verified: true
---

## Usage

### Popup, Field, and Inline
`v-model:visible` controls the popup, `variant` picks the surface, and `popup="false"` renders inline.
:::TuffDemoWrapper{demo="DatePickerDatePickerDemo" code-lang="vue"}
---
code: |
  <template>
    <TxButton @click="visible = true">Open date picker</TxButton>
    <TxDatePicker
      v-model="releaseDate"
      v-model:visible="visible"
      title="Release date"
      min="2025-01-01"
      max="2030-12-31"
    />

    <TxDatePicker v-model="fieldDate" variant="adaptive" placeholder="Select date" />

    <TxDatePicker
      v-model="inlineDate"
      :visible="true"
      :popup="false"
      :show-toolbar="false"
      min="2026-05-10"
      max="2026-05-31"
    />
  </template>
---
:::

### Best Practices

- Store dates only as `YYYY-MM-DD` strings; the component has no time zone or time of day.
- Use `variant="field"` for dense desktop forms and `variant="picker"` for mobile-first flows; use `adaptive` only after checking both surfaces in the same layout.
- When the surrounding card already handles disclosure and spacing, render the `picker` surface inline with `popup="false"`.
- Set `weekStartsOn` explicitly when locale conventions matter.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|------|
| `modelValue` | `string \| DateRangeValue` | `''` | A `YYYY-MM-DD` date; a `[start, end]` pair under `range`. |
| `visible` | `boolean` | `false` | Popup visibility, bound with `v-model:visible`. |
| `popup` | `boolean` | `true` | Picker surface only: `false` renders it inline. |
| `variant` | `'picker' \| 'field' \| 'adaptive'` | `'picker'` | `picker` is the wheel, `field` the calendar field, `adaptive` switches by viewport width. |
| `title` | `string` | `'Select date'` | Toolbar title, forwarded to `TxPicker`. |
| `placeholder` | `string` | `'Select date'` | Placeholder of the empty field calendar. |
| `min` | `string` | - | Earliest selectable date (`YYYY-MM-DD`); invalid values are ignored. |
| `max` | `string` | - | Latest selectable date (`YYYY-MM-DD`); invalid values are ignored. |
| `disabled` | `boolean` | `false` | Blocks interaction. |
| `showToolbar` | `boolean` | `true` | Shows the picker toolbar. |
| `confirmText` | `string` | `'Confirm'` | Confirm button label, forwarded to `TxPicker`. |
| `cancelText` | `string` | `'Cancel'` | Cancel button label, forwarded to `TxPicker`. |
| `closeOnClickMask` | `boolean` | `true` | Closes the popup when the mask is clicked. |
| `adaptiveBreakpoint` | `number` | `768` | Minimum viewport width at which `adaptive` shows the field calendar. |
| `weekStartsOn` | `0 \| 1` | `0` | First day of the field calendar's week: `0` Sunday, `1` Monday. |
| `range` | `boolean` | `false` | Field calendar only: picks a start and an end date; the wheel ignores it. |
| `rangeSeparator` | `string` | `' → '` | Text between the two dates in the field's display value. |

### Events

| Event | Params | Description |
|------|------|------|
| `update:modelValue` | `(value: string \| DateRangeValue)` | Fires with the formatted value when the date changes. |
| `change` | `(value: string \| DateRangeValue)` | Fires together with `update:modelValue`. |
| `update:visible` | `(visible: boolean)` | Fires when visibility should change. |
| `confirm` | `(value: string)` | Fires with the current date when the user confirms. |
| `cancel` | - | Fires when the user cancels. |
| `open` | - | Fires on open. |
| `close` | - | Fires on close. |

## Overview

- The value is always emitted as `YYYY-MM-DD`; an empty or invalid value starts from local today, clamped to `min` / `max`.
- The `picker` surface opens through `v-model:visible`; the `field` surface renders through `TxPopover` and syncs `update:visible`, `open`, and `close` too.
- Column changes emit `update:modelValue` and `change` live; `confirm` then closes the way the picker does.
- The field calendar is sized to the month grid (280–360px), not the field. Its title zooms out day → month → 12-year block, the arrows step the current view, and closing returns to the day grid.
- `range`: the first click anchors the start and previews the band, the second closes it and emits `[start, end]` in order. Nothing is emitted before both ends exist, and closing mid-pick abandons it.
- The calendar uses `grid` / `gridcell` with `aria-selected`; under reduced motion, slides and zooms collapse to a short fade.

## Technologies

- Days inside a range carry `is-in-range`; the ends carry `is-range-start` / `is-range-end`.
- Source: `packages/tuffex/packages/components/src/date-picker/`.

<TuffDocSourceLink />
