---
title: "InputDate"
description: "An input component for date selection."
canonical_url: "https://vinicunca.dev/pohon/components/input-date"
---
# InputDate

> An input component for date selection.

## Usage

Use the `v-model` directive to control the selected date.

```vue
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date'

const value = shallowRef(new CalendarDate(2022, 2, 3))
</script>

<template>
  <PInputDate v-model="value" />
</template>
```

Use the `default-value` prop to set the initial value when you do not need to control its state.

```vue
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date'

const defaultValue = shallowRef(new CalendarDate(2022, 2, 6))
</script>

<template>
  <PInputDate :default-value="defaultValue" />
</template>
```

**Nuxt:**

> [!NOTE]
> See: /pohon/getting-started/integrations/i18n/nuxt#locale
> 
> This component uses the `@internationalized/date` package for locale-aware formatting. The date format is determined by the `locale` prop of the App component.

**Vue:**

> [!NOTE]
> See: /pohon/getting-started/integrations/i18n/vue#locale
> 
> This component uses the `@internationalized/date` package for locale-aware formatting. The date format is determined by the `locale` prop of the App component.

### Range

Use the `range` prop to select a range of dates.

```vue
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date'

const value = shallowRef({ start: new CalendarDate(2022, 2, 3), end: new CalendarDate(2022, 2, 20) })
</script>

<template>
  <PInputDate range v-model="value" />
</template>
```

### Color

Use the `color` prop to change the color of the InputDate.

```vue
<template>
  <PInputDate color="neutral" highlight />
</template>
```

### Variant

Use the `variant` prop to change the variant of the InputDate.

```vue
<template>
  <PInputDate variant="subtle" />
</template>
```

### Size

Use the `size` prop to change the size of the InputDate.

```vue
<template>
  <PInputDate size="xl" />
</template>
```

### Icon

Use the `icon` prop to show an [Icon](https://vinicunca.dev/pohon/components/icon) inside the InputDate.

```vue
<template>
  <PInputDate icon="i-lucide-calendar" />
</template>
```

> [!NOTE]
> 
> Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position.

### Separator Icon

Use the `separator-icon` prop to change the [Icon](https://vinicunca.dev/pohon/components/icon) of the range separator. Defaults to `i-lucide-minus`.

```vue
<template>
  <PInputDate range separator-icon="i-lucide-arrow-right" />
</template>
```

**Nuxt:**

> [!TIP]
> See: /pohon/getting-started/integrations/icons/nuxt#theme
> 
> You can customize this icon globally in your `app.config.ts` under `ui.icons.minus` key.

**Vue:**

> [!TIP]
> See: /pohon/getting-started/integrations/icons/vue#theme
> 
> You can customize this icon globally in your `vite.config.ts` under `ui.icons.minus` key.

### Avatar

Use the `avatar` prop to show an [Avatar](https://vinicunca.dev/pohon/components/avatar) inside the InputDate.

```vue
<template>
  <PInputDate :avatar="{
  src: 'https://github.com/vuejs.png',
  loading: 'lazy'
}" size="md" variant="outline" />
</template>
```

### Disabled

Use the `disabled` prop to disable the InputDate.

```vue
<template>
  <PInputDate disabled />
</template>
```

## Examples

### With unavailable dates

Use the `is-date-unavailable` prop with a function to mark specific dates as unavailable.

```vue [InputDateUnavailableDatesExample.vue]
<script setup lang="ts">
import type { DateValue } from '@internationalized/date';
import { CalendarDate } from '@internationalized/date';

const modelValue = shallowRef({
  start: new CalendarDate(2022, 1, 1),
  end: new CalendarDate(2022, 1, 9),
});

function isDateUnavailable(date: DateValue) {
  return date.day >= 10 && date.day <= 16;
}
</script>

<template>
  <PInputDate
    v-model="modelValue"
    :is-date-unavailable="isDateUnavailable"
    range
  />
</template>
```

### With min/max dates

Use the `min-value` and `max-value` props to limit the dates.

```vue [InputDateMinMaxDatesExample.vue]
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date';

const modelValue = shallowRef(new CalendarDate(2023, 9, 10));
const minDate = new CalendarDate(2023, 9, 1);
const maxDate = new CalendarDate(2023, 9, 30);
</script>

<template>
  <PInputDate
    v-model="modelValue"
    :min-value="minDate"
    :max-value="maxDate"
  />
</template>
```

### As a date picker

Use a [Calendar](https://vinicunca.dev/pohon/components/calendar) and a [Popover](https://vinicunca.dev/pohon/components/popover) component to create a date picker.

```vue [InputDateDatePickerExample.vue]
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date';

const inputDate = useTemplateRef('inputDate');

const modelValue = shallowRef(new CalendarDate(2022, 1, 10));
</script>

<template>
  <PInputDate
    ref="inputDate"
    v-model="modelValue"
  >
    <template #trailing>
      <PPopover :reference="inputDate?.inputsRef[3]?.$el">
        <PButton
          color="neutral"
          variant="link"
          size="sm"
          icon="i-lucide-calendar"
          aria-label="Select a date"
          class="px-0"
        />

        <template #content>
          <PCalendar
            v-model="modelValue"
            class="p-2"
          />
        </template>
      </PPopover>
    </template>
  </PInputDate>
</template>
```

### As a date range picker

Use a [Calendar](https://vinicunca.dev/pohon/components/calendar) and a [Popover](https://vinicunca.dev/pohon/components/popover) component to create a date range picker.

```vue [InputDateDateRangePickerExample.vue]
<script setup lang="ts">
import { CalendarDate } from '@internationalized/date';

const inputDate = useTemplateRef('inputDate');

const modelValue = shallowRef({
  start: new CalendarDate(2022, 1, 10),
  end: new CalendarDate(2022, 1, 20),
});
</script>

<template>
  <PInputDate
    ref="inputDate"
    v-model="modelValue"
    range
  >
    <template #trailing>
      <PPopover :reference="inputDate?.inputsRef[0]?.$el">
        <PButton
          color="neutral"
          variant="link"
          size="sm"
          icon="i-lucide-calendar"
          aria-label="Select a date range"
          class="px-0"
        />

        <template #content>
          <PCalendar
            v-model="modelValue"
            class="p-2"
            :number-of-months="2"
            range
          />
        </template>
      </PPopover>
    </template>
  </PInputDate>
</template>
```

## API

### Props

```ts
/**
 * Props for the InputDate component
 */
interface InputDateProps {
}
```

### Slots

```ts
/**
 * Slots for the InputDate component
 */
interface InputDateSlots {
}
```

### Emits

No events available for this component.

## Theme

```ts [app.config.ts]
export default defineAppConfig({
  ui: {
    inputDate: {
      slots: {
        base: [
          'group relative inline-flex items-center rounded-md select-none',
          'transition-colors'
        ],
        leading: 'absolute inset-y-0 start-0 flex items-center',
        leadingIcon: 'shrink-0 color-text-dimmed',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        trailing: 'absolute inset-y-0 end-0 flex items-center',
        trailingIcon: 'shrink-0 color-text-dimmed',
        segment: [
          'data-[placeholder]:color-text-dimmed data-[segment=literal]:color-text-muted data-[invalid]:color-error text-center outline-hidden rounded-sm data-[disabled]:opacity-75 data-[disabled]:cursor-not-allowed',
          'transition-colors'
        ],
        separatorIcon: 'shrink-0 size-4 color-text-muted'
      },
      variants: {
        fieldGroup: {
          horizontal: 'first:not-[*:only-child]:rounded-e-none last:not-[*:only-child]:rounded-s-none not-last:not-first:rounded-none focus-visible:z-1',
          vertical: 'first:not-[*:only-child]:rounded-b-none last:not-[*:only-child]:rounded-t-none not-last:not-first:rounded-none focus-visible:z-1'
        },
        size: {
          xs: {
            base: [
              'px-2 py-1 text-sm/4 gap-1',
              'pohon:gap-0.25'
            ],
            leading: 'ps-2',
            trailing: 'pe-2',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            segment: 'data-[segment=day]:w-8 data-[segment=month]:w-8 data-[segment=year]:w-10'
          },
          sm: {
            base: [
              'px-2.5 py-1.5 text-sm/4 gap-1.5',
              'pohon:gap-0.5'
            ],
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            segment: 'data-[segment=day]:w-8 data-[segment=month]:w-8 data-[segment=year]:w-10'
          },
          md: {
            base: [
              'px-2.5 py-1.5 text-base/5 gap-1.5',
              'pohon:gap-0.5'
            ],
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            segment: 'data-[segment=day]:w-9 data-[segment=month]:w-9 data-[segment=year]:w-11'
          },
          lg: {
            base: [
              'px-3 py-2 text-base/5 gap-2',
              'pohon:gap-0.75'
            ],
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            segment: 'data-[segment=day]:w-9 data-[segment=month]:w-9 data-[segment=year]:w-11'
          },
          xl: {
            base: [
              'px-3 py-2 text-base gap-2',
              'pohon:gap-0.75'
            ],
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-6',
            leadingAvatarSize: 'xs',
            trailingIcon: 'size-6',
            segment: 'data-[segment=day]:w-10 data-[segment=month]:w-10 data-[segment=year]:w-12'
          }
        },
        variant: {
          outline: 'color-text-highlighted bg-background ring ring-inset ring-border-accented',
          soft: 'color-text-highlighted bg-background-elevated/50 hover:bg-background-elevated has-focus:bg-background-elevated disabled:bg-background-elevated/50',
          subtle: 'color-text-highlighted bg-background-elevated ring ring-inset ring-border-accented',
          ghost: 'color-text-highlighted bg-transparent hover:bg-background-elevated has-focus:bg-background-elevated disabled:bg-transparent dark:disabled:bg-transparent',
          none: 'color-text-highlighted bg-transparent has-focus:outline-none'
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        leading: {
          true: ''
        },
        trailing: {
          true: ''
        },
        loading: {
          true: ''
        },
        highlight: {
          true: ''
        },
        fixed: {
          false: ''
        },
        type: {
          file: 'file:me-1.5 file:font-500 file:color-text-muted file:outline-none'
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
        },
        {
          color: 'secondary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-secondary/25 has-focus-visible:outline-3 has-focus-visible:ring-secondary'
        },
        {
          color: 'success',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-success/25 has-focus-visible:outline-3 has-focus-visible:ring-success'
        },
        {
          color: 'info',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-info/25 has-focus-visible:outline-3 has-focus-visible:ring-info'
        },
        {
          color: 'warning',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-warning/25 has-focus-visible:outline-3 has-focus-visible:ring-warning'
        },
        {
          color: 'error',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-error/25 has-focus-visible:outline-3 has-focus-visible:ring-error'
        },
        {
          color: 'primary',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3'
        },
        {
          color: 'secondary',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-secondary/25 has-focus-visible:outline-3'
        },
        {
          color: 'success',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-success/25 has-focus-visible:outline-3'
        },
        {
          color: 'info',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-info/25 has-focus-visible:outline-3'
        },
        {
          color: 'warning',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-warning/25 has-focus-visible:outline-3'
        },
        {
          color: 'error',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-error/25 has-focus-visible:outline-3'
        },
        {
          color: 'primary',
          highlight: true,
          class: 'ring ring-inset pohon:ring-primary'
        },
        {
          color: 'secondary',
          highlight: true,
          class: 'ring ring-inset pohon:ring-secondary'
        },
        {
          color: 'success',
          highlight: true,
          class: 'ring ring-inset pohon:ring-success'
        },
        {
          color: 'info',
          highlight: true,
          class: 'ring ring-inset pohon:ring-info'
        },
        {
          color: 'warning',
          highlight: true,
          class: 'ring ring-inset pohon:ring-warning'
        },
        {
          color: 'error',
          highlight: true,
          class: 'ring ring-inset pohon:ring-error'
        },
        {
          color: 'neutral',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-border-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-border-inverted'
        },
        {
          color: 'neutral',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-border-inverted/25 has-focus-visible:outline-3'
        },
        {
          color: 'neutral',
          highlight: true,
          class: 'ring ring-inset ring-border-inverted'
        },
        {
          leading: true,
          size: 'xs',
          class: 'ps-7'
        },
        {
          leading: true,
          size: 'sm',
          class: 'ps-8'
        },
        {
          leading: true,
          size: 'md',
          class: 'ps-9'
        },
        {
          leading: true,
          size: 'lg',
          class: 'ps-10'
        },
        {
          leading: true,
          size: 'xl',
          class: 'ps-11'
        },
        {
          trailing: true,
          size: 'xs',
          class: 'pe-7'
        },
        {
          trailing: true,
          size: 'sm',
          class: 'pe-8'
        },
        {
          trailing: true,
          size: 'md',
          class: 'pe-9'
        },
        {
          trailing: true,
          size: 'lg',
          class: 'pe-10'
        },
        {
          trailing: true,
          size: 'xl',
          class: 'pe-11'
        },
        {
          loading: true,
          leading: true,
          class: {
            leadingIcon: 'animate-spin'
          }
        },
        {
          loading: true,
          leading: false,
          trailing: true,
          class: {
            trailingIcon: 'animate-spin'
          }
        },
        {
          fixed: false,
          size: 'xs',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'sm',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'md',
          class: 'md:text-sm'
        },
        {
          fixed: false,
          size: 'lg',
          class: 'md:text-sm'
        },
        {
          variant: 'outline',
          class: {
            segment: 'focus:bg-background-elevated'
          }
        },
        {
          variant: 'soft',
          class: {
            segment: 'focus:bg-background-accented/50 group-hover:focus:bg-background-accented'
          }
        },
        {
          variant: 'subtle',
          class: {
            segment: 'focus:bg-background-accented'
          }
        },
        {
          variant: 'ghost',
          class: {
            segment: 'focus:bg-background-elevated group-hover:focus:bg-background-accented'
          }
        },
        {
          variant: 'none',
          class: {
            segment: 'focus:bg-background-elevated'
          }
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
})
```

## Changelog

See commit history for [component](https://github.com/vinicunca/pohon/commits/main/src/runtime/components/InputDate.vue) and [theme](https://github.com/vinicunca/pohon/commits/main/src/theme/input-date.ts).

---

- [DateField](https://vinicunca.dev/akar/components/date-field)
- [GitHub](https://github.com/vinicunca/pohon/blob/main/src/runtime/components/InputDate.vue)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
