---
title: "MazDatePicker"
description: "A powerful and flexible date picker component with support for single dates, date ranges, time selection, and extensive customization options"
package: "maz-ui"
url: "https://maz-ui.com/components/maz-date-picker"
---

# MazDatePicker

> A powerful and flexible date picker component with support for single dates, date ranges, time selection, and extensive customization options

- Package: `maz-ui`
- Import: `import MazDatePicker from 'maz-ui/components/MazDatePicker'`
- Nuxt: auto-imported by `@maz-ui/nuxt`, no import needed in a Nuxt app
- Web: https://maz-ui.com/components/maz-date-picker

> Before use it, you should install the MazUi plugin in your project, follow instructions in [Getting Started](../guide/getting-started.md)

**Tip:**

This component can be translated globally using the [MazUi](https://maz-ui.com/ecosystem/translations.md) plugin.

## Table of Contents

- Basic Usage
- Date Formats
- Date Selection
- Custom Trigger
- Time Selection
- Range Selection
- Internationalization
- Validation & Constraints
- Types
- Props
- Events
- Slots

## Basic Usage

The simplest way to use MazDatePicker:

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Select a date"
    placeholder="Choose your date"
    format="YYYY-MM-DD"
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
</script>
```

## Date Formats

Understanding date formats is crucial for using MazDatePicker effectively. The component uses two different format concepts:

### 1. Data Format (`format` prop)

This controls how dates are stored and transmitted in your `v-model`. Default is `'YYYY-MM-DD'`.

### 2. Display Format (`input-date-format` prop)

This controls how dates appear in the input field using `Intl.DateTimeFormatOptions`.

```vue
<template>
  <!-- ISO Format (recommended) -->
  <MazDatePicker
    v-model="date1"
    label="ISO Format (YYYY-MM-DD)"
    format="YYYY-MM-DD"
    :input-date-format="{ dateStyle: 'medium' }"
  />

  <!-- US Format -->
  <MazDatePicker
    v-model="date2"
    label="US Format (MM/DD/YYYY)"
    format="MM/DD/YYYY"
    :input-date-format="{ dateStyle: 'short' }"
  />

  <!-- European Format -->
  <MazDatePicker
    v-model="date3"
    label="European Format (DD-MM-YYYY)"
    format="DD-MM-YYYY"
    :input-date-format="{ dateStyle: 'medium' }"
  />
</template>

<script setup>
import { ref } from 'vue'

const date1 = ref('2024-03-15')        // ISO format
const date2 = ref('03/15/2024')        // US format
const date3 = ref('15-03-2024')        // European format
</script>
```

### Custom Display Transformation

Use `inputDateTransformer` to completely customize how dates appear in the input:

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Custom Display Format"
    :input-date-transformer="transformDate"
  />
</template>

<script setup>
import { ref } from 'vue'
import dayjs from 'dayjs'

const date = ref()

const transformDate = ({ value }) => {
  return value ? `📅 ${dayjs(value).format('dddd, MMMM Do YYYY')}` : ''
}
</script>
```

## Date Selection

### Standard Date Picker

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Select Date"
    color="primary"
    auto-close
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
</script>
```

### Inline Date Picker

Perfect for dashboards or when you want the calendar always visible:

```vue
<template>
  <MazDatePicker
    v-model="date"
    inline
    color="secondary"
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
</script>
```

### Double Calendar

Show two months at once for better date selection:

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Double Calendar"
    double
    color="success"
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
</script>
```

## Custom Trigger

By default MazDatePicker renders a readonly `MazInput` as the field that opens the calendar. Use the `#trigger` slot to replace it with your own element - a button, a custom input, an icon... Clicking the slotted element opens the calendar automatically (no `@click` needed), and the slot exposes the current open state plus functions for programmatic control.

### Slot bindings

| Binding | Type | Description |
| --- | --- | --- |
| `is-open` | `boolean` | Whether the calendar is currently open |
| `open` | `() => void` | Open the calendar programmatically |
| `close` | `() => void` | Close the calendar programmatically |
| `toggle` | `() => void` | Toggle the calendar programmatically |

```vue
<template>
  <MazDatePicker v-model="date" auto-close>
    <!-- Clicking the button opens the picker automatically. -->
    <template #trigger="{ isOpen }">
      <MazBtn color="secondary" :class="{ 'ring-2 ring-secondary': isOpen }">
        {{ date || 'Pick a date' }}
      </MazBtn>
    </template>
  </MazDatePicker>
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
</script>
```

**Tip:**

The model value is not passed through the slot - use your own `v-model` ref (here `date`) to display the selected value in your custom trigger. The exposed `open` / `close` / `toggle` functions are only needed when you want to drive the picker from your own logic.

> In `inline` mode the calendar is always visible, so the `trigger` slot is not rendered. To open the picker from an element rendered outside the component, use the `custom-element-selector` prop instead.

## Time Selection

### Date + Time (24h format)

```vue
<template>
  <MazDatePicker
    v-model="dateTime"
    label="Date & Time (24h)"
    format="YYYY-MM-DD HH:mm"
    time
    color="info"
  />
</template>

<script setup>
import { ref } from 'vue'

const dateTime = ref()
</script>
```

### Date + Time (12h format)

```vue
<template>
  <MazDatePicker
    v-model="dateTime"
    label="Date & Time (12h)"
    format="YYYY-MM-DD hh:mm a"
    time
    color="warning"
  />
</template>

<script setup>
import { ref } from 'vue'

const dateTime = ref()
</script>
```

### Time Only Selection

```vue
<template>
  <!-- 24h format -->
  <MazDatePicker
    v-model="time24"
    label="Time Only (24h)"
    format="HH:mm"
    only-time
    color="accent"
  />

  <!-- 12h format -->
  <MazDatePicker
    v-model="time12"
    label="Time Only (12h)"
    format="hh:mm a"
    only-time
    color="destructive"
  />
</template>

<script setup>
import { ref } from 'vue'

const time24 = ref('14:30')
const time12 = ref('02:30 pm')
</script>
```

### Custom Minute Intervals

```vue
<template>
  <MazDatePicker
    v-model="time1"
    label="5min intervals"
    format="HH:mm"
    :minute-interval="5"
    only-time
  />

  <MazDatePicker
    v-model="time2"
    label="15min intervals"
    format="HH:mm"
    :minute-interval="15"
    only-time
  />

  <MazDatePicker
    v-model="time3"
    label="30min intervals"
    format="HH:mm"
    :minute-interval="30"
    only-time
  />
</template>

<script setup>
import { ref } from 'vue'

const time1 = ref()
const time2 = ref()
const time3 = ref()
</script>
```

## Range Selection

For selecting date ranges, pass an object with `start` and `end` properties:

```vue
<template>
  <MazDatePicker
    v-model="range"
    label="Select Date Range"
    range
    double
    auto-close
    color="primary"
  />
</template>

<script setup>
import { ref } from 'vue'

const range = ref({
  start: undefined,
  end: undefined
})
</script>
```

### Range with Shortcuts

Provide predefined shortcuts for common date ranges:

```vue
<template>
  <MazDatePicker
    v-model="range"
    label="Range with Shortcuts"
    range
    double
    :shortcuts="shortcuts"
    color="secondary"
  />
</template>

<script setup>
import { ref } from 'vue'
import dayjs from 'dayjs'

const range = ref({
  start: undefined,
  end: undefined
})

const shortcuts = [
  {
    label: 'Today',
    identifier: 'today',
    value: {
      start: dayjs().format('YYYY-MM-DD'),
      end: dayjs().format('YYYY-MM-DD')
    }
  },
  {
    label: 'Last 7 days',
    identifier: 'last7days',
    value: {
      start: dayjs().subtract(6, 'day').format('YYYY-MM-DD'),
      end: dayjs().format('YYYY-MM-DD')
    }
  },
  {
    label: 'This month',
    identifier: 'thisMonth',
    value: {
      start: dayjs().startOf('month').format('YYYY-MM-DD'),
      end: dayjs().endOf('month').format('YYYY-MM-DD')
    }
  }
]
</script>
```

### Property `shortcuts`

#### Model

```ts
interface MazDatePickerShortcut {
  identifier: string // should be uniq
  label: string
  value: {
    start: string
    end: string
  }
}

type MazDatePickerShortcuts = MazDatePickerShortcut[]
```

#### Example

```ts
import type { MazDatePickerShortcut } from 'maz-ui/components'

const shortcuts: MazDatePickerShortcut[] = [{
  label: 'Next month',
  identifier: 'nextMonth',
  value: {
    start: dayjs().add(1, 'month').set('date', 1).format('YYYY-MM-DD'),
    end: dayjs()
      .add(1, 'month')
      .set('date', dayjs().add(1, 'month').daysInMonth())
      .format('YYYY-MM-DD'),
  },
}]
```

**Details: View default shortcuts**

```ts
const shortcuts = [
  {
    label: 'Last 7 days',
    identifier: 'last7Days',
    value: {
      start: dayjs().subtract(6, 'day').format('YYYY-MM-DD'),
      end: dayjs().format('YYYY-MM-DD'),
    },
  },
  {
    label: 'Last 30 days',
    identifier: 'last30Days',
    value: {
      start: dayjs().subtract(29, 'day').format('YYYY-MM-DD'),
      end: dayjs().format('YYYY-MM-DD'),
    },
  },
  {
    label: 'This week',
    identifier: 'thisWeek',
    value: {
      start: dayjs().startOf('week').format('YYYY-MM-DD'),
      end: dayjs().endOf('week').format('YYYY-MM-DD'),
    },
  },
  {
    label: 'Last week',
    identifier: 'lastWeek',
    value: {
      start: dayjs()
        .subtract(1, 'week')
        .startOf('week')
        .format('YYYY-MM-DD'),
      end: dayjs().subtract(1, 'week').endOf('week').format('YYYY-MM-DD'),
    },
  },
  {
    label: 'This month',
    identifier: 'thisMonth',
    value: {
      start: dayjs().set('date', 1).format('YYYY-MM-DD'),
      end: dayjs()
        .set('date', dayjs().daysInMonth())
        .format('YYYY-MM-DD'),
    },
  },
  {
    label: 'This year',
    identifier: 'thisYear',
    value: {
      start: dayjs().startOf('year').format('YYYY-MM-DD'),
      end: dayjs().endOf('year').format('YYYY-MM-DD'),
    },
  },
  {
    label: 'Last year',
    identifier: 'lastYear',
    value: {
      start: dayjs()
        .subtract(1, 'year')
        .startOf('year')
        .format('YYYY-MM-DD'),
      end: dayjs().subtract(1, 'year').endOf('year').format('YYYY-MM-DD'),
    },
  },
]
```

## Validation & Constraints

### Min/Max Dates

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Limited Date Range"
    :min-date="minDate"
    :max-date="maxDate"
    color="info"
  />
</template>

<script setup>
import { ref } from 'vue'
import dayjs from 'dayjs'

const date = ref()
const minDate = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
const maxDate = dayjs().add(30, 'day').format('YYYY-MM-DD')
</script>
```

#### Property `min-max-auto`

Disable min-max auto check to not change the value when it is out of range

```vue
<template>
  <MazDatePicker
    v-model="date"
    label="Not auto date range"
    :min-date="minDate"
    :max-date="maxDate"
    :min-max-auto="false"
  />
</template>

<script setup>
import { ref } from 'vue'
import dayjs from 'dayjs'

const date = ref()
const minDate = dayjs().subtract(30, 'day').format('YYYY-MM-DD')
const maxDate = dayjs().add(30, 'day').format('YYYY-MM-DD')
</script>
```

### Disabled Days & Dates

```vue
<template>
  <!-- Disable weekends -->
  <MazDatePicker
    v-model="date1"
    label="Weekends Disabled"
    :disabled-weekly="[0, 6]"
    color="warning"
  />

  <!-- Disable specific dates -->
  <MazDatePicker
    v-model="date2"
    label="Holidays Disabled"
    :disabled-dates="holidays"
    color="destructive"
  />
</template>

<script setup>
import { ref } from 'vue'

const date1 = ref()
const date2 = ref()

// 0 = Sunday, 6 = Saturday
const weekends = [0, 6]

// Specific holiday dates
const holidays = [
  dayjs().subtract(2, 'day').format('YYYY-MM-DD'),
  dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
  dayjs().format('YYYY-MM-DD'),
  dayjs().add(1, 'day').format('YYYY-MM-DD'),
  dayjs().add(2, 'day').format('YYYY-MM-DD'),
  dayjs().add(3, 'day').format('YYYY-MM-DD'),
  dayjs().add(4, 'day').format('YYYY-MM-DD'),
]
</script>
```

### Disabled Hours

```vue
<template>
  <MazDatePicker
    v-model="dateTime"
    format="YYYY-MM-DD hh:mm a"
    time
    label="Disabled Hours"
    :disabled-hours="disabledHours"
    color="info"
  />

  <MazDatePicker
    v-model="time"
    format="HH:mm"
    only-time
    label="Disabled Hours"
    :disabled-hours="disabledHours"
    color="info"
  />
</template>

<script setup>
import { ref } from 'vue'

const date = ref()
const time = ref()

const disabledHours = [0, 1, 2, 11, 22, 23]
</script>
```

## Internationalization

MazDatePicker supports full internationalization. **By default, it uses the locale from the [MazUiTranslations](https://maz-ui.com/ecosystem/translations.md) plugin**, but you can override it:

```vue
<template>
  <!-- French -->
  <MazDatePicker
    v-model="frenchDate"
    label="French Locale"
    locale="fr-FR"
    :first-day-of-week="1"
    color="primary"
  />

  <!-- German -->
  <MazDatePicker
    v-model="germanDate"
    label="German Locale"
    locale="de-DE"
    :first-day-of-week="1"
    color="secondary"
  />

  <!-- Japanese -->
  <MazDatePicker
    v-model="japaneseDate"
    label="Japanese Locale"
    locale="ja-JP"
    color="accent"
  />

  <!-- Arabic -->
  <MazDatePicker
    v-model="arabicDate"
    label="Arabic Locale"
    locale="ar-SA"
    :first-day-of-week="6"
    color="warning"
  />
</template>

<script setup>
import { ref } from 'vue'

const frenchDate = ref()
const germanDate = ref()
const japaneseDate = ref()
const arabicDate = ref()
</script>
```

## Types

```typescript
// Value types
type MazDatePickerValue = string | undefined | MazDatePickerPartialRangeValue

interface MazDatePickerRangeValue {
  start: string
  end: string
}

type MazDatePickerPartialRangeValue = Partial<MazDatePickerRangeValue>

// Shortcut type
interface MazDatePickerShortcut {
  identifier: string
  label: string
  value: {
    start: string
    end: string
  }
}
```

## Accessibility

- The input is a `combobox` opening a `dialog` (`aria-haspopup="dialog"`, `aria-expanded`, `aria-controls`).
- Each month is a `grid` labelled by the month and the year, the days of the week are its column headers and each day has its full date as label (`aria-current="date"` for today, `aria-selected` on the selected days).
- **Keyboard** in the calendar: only one day is in the tab sequence, the arrows move by day (← →) and by week (↑ ↓), Home / End go to the start / end of the week, Page Up / Page Down to the previous / next month (with Shift: year). Disabled days are skipped and the calendar follows the focus to the displayed month.
- The navigation buttons labels come from `@maz-ui/translations` (`aria` namespace).

## MazDatePicker API

`import MazDatePicker from 'maz-ui/components/MazDatePicker'`

### Props

- `id` (`string`): The unique identifier of the component.
- `input-props` (`MazInputProps<MazInputValue>`): The props to apply to the input component.
- `model-value` (`MazDatePickerValue`, `v-model`): The value of the date picker component If an object is provided, the picker will be a range picker.
- `format` (`string`, default: `"YYYY-MM-DD"`): The format pattern for date display and parsing.
- `open` (`boolean`, default: `false`, `v-model:open`): Controls whether the picker window is open.
- `label` (`string`): The label text displayed above the input field.
- `placeholder` (`string`): The placeholder text shown when no value is selected.
- `input-date-format` (`Intl.DateTimeFormatOptions`, default: `{ dateStyle: "medium", timeStyle: "short" }`): The Intl.DateTimeFormatOptions for styling the input date display.
- `input-date-transformer` (`((payload: { formattedDate?: string | undefined; value?: MazDatePickerValue; locale: string; }) => string)`): Custom function to transform the formatted date display.
- `locale` (`string`, default: `""`, `v-model:locale`): The locale string for date formatting and localization.
- `hide-header` (`boolean`, default: `false`): Controls whether the calendar header is hidden.
- `disabled` (`boolean`, default: `false`): Controls whether the component is disabled.
- `first-day-of-week` (`0 | 1 | 2 | 3 | 4 | 5 | 6`, default: `0`): The first day of the week in the calendar. Values: `'0'`, `'1'`, `'2'`, `'3'`, `'4'`, `'5'`, `'6'` (non exhaustive).
- `auto-close` (`boolean`, default: `false`): Controls whether the picker closes automatically after date selection.
- `custom-element-selector` (`string`): CSS selector for a custom element that triggers the picker.
- `double` (`boolean`, default: `false`): Controls whether the picker displays two months side by side.
- `inline` (`boolean`, default: `false`): Controls whether the picker is displayed inline without input field.
- `color` (`"primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent"`, default: `"primary"`): The color theme of the component.
- `picker-position` (`MazPopoverPosition`, default: `"auto"`): The position where the picker popover should appear. Values: `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-end'`, `'bottom-end'`, `'left-end'`, `'right-end'`, `'top-start'`, `'bottom-start'`, `'left-start'`, `'right-start'` (non exhaustive).
- `picker-prefer-position` (`MazPopoverPreferPosition`, default: `"bottom-start"`): The preferred position of the picker popover. Values: `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-end'`, `'bottom-end'`, `'left-end'`, `'right-end'`, `'top-start'`, `'bottom-start'`, `'left-start'`, `'right-start'` (non exhaustive).
- `picker-fallback-position` (`MazPopoverFallbackPosition`, default: `"top-start"`): The fallback position of the picker popover. Values: `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-end'`, `'bottom-end'`, `'left-end'`, `'right-end'`, `'top-start'`, `'bottom-start'`, `'left-start'`, `'right-start'` (non exhaustive).
- `time` (`boolean`, default: `false`): Controls whether the picker includes a time selector.
- `only-time` (`boolean`, default: `false`): Controls whether the picker shows only time selection (no date).
- `minute-interval` (`number`, default: `5`): The interval in minutes for the time picker minute selection. Values: `'1'`, `'5'`, `'10'`, `'15'`, `'30'` (non exhaustive).
- `use-browser-locale` (`boolean`, default: `true`): Controls whether to automatically detect and use the browser's locale.
- `fetch-local` (`boolean`, default: `true`): Controls whether to fetch locale data dynamically.
- `shortcuts` (`boolean | MazDatePickerShortcut[]`, default: `true`): Array of predefined date range shortcuts or false to disable.
- `shortcut` (`string`): The identifier of the currently selected shortcut.
- `min-date` (`string`): The minimum selectable date in ISO format.
- `max-date` (`string`): The maximum selectable date in ISO format.
- `min-max-auto` (`boolean`, default: `true`): When minDate or maxDate are provided, if the current date is not between minDate and maxDate, the current date will be set to the minDate or maxDate.
- `disabled-weekly` (`number[]`, default: `[]`): Array of weekday numbers to disable (0 = Sunday, 6 = Saturday).
- `disabled-dates` (`string[]`, default: `[]`): Array of specific dates to disable in ISO format.
- `disabled-hours` (`number[]`, default: `[]`): Array of hour numbers to disable in the time picker (0-23).
- `block` (`boolean`, default: `false`): Controls whether the input displays in full width.
- `range` (`boolean`, default: `false`): Controls whether the picker operates in range selection mode.
- `transition` (`string`, default: `"scale-fade"`): The transition name of the popover.

### Events

- `@update:model-value` (payload: `value: MazDatePickerValue`): Emitted when the picker value changes
- `@close` (payload: `(void | undefined)?`): Emitted when the picker closes
- `@update:locale` (payload: `value: string`)
- `@update:open` (payload: `value: boolean`)

### Slots

- `#trigger`: Replace the default input with your own element Bindings: `isOpen: boolean` (Current open state of the popover), `close: () => void` (Function to close the popover), `open: () => void` (Function to open the popover), `toggle: () => void` (Function to toggle the popover).
