Phi
DatePicker
@dicehub/phiv1.0.0-beta.1

DatePicker

A composable date picker for single dates, multiple dates, date ranges, and popup calendars.

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref(new Date(2026, 4, 20));
</script>

<template>
  <DatePicker v-model:selected="selected" inline />
</template>

Installation

Barrel

import { DatePicker } from "@dicehub/phi";

Granular

import { DatePicker } from "@dicehub/phi/components/date-picker";

Usage

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref(new Date(2026, 5, 4));
</script>

<template>
  <DatePicker v-model:selected="selected" placeholder="Pick a date" />
</template>

Examples

Single Date

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref(new Date(2026, 4, 20));
</script>

<template>
  <DatePicker v-model:selected="selected" inline />
</template>

Multiple Dates

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref([
  new Date(2026, 4, 12),
  new Date(2026, 4, 14),
]);
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="multiple"
    inline
  />
</template>

Date Range

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker, type DatePickerDateRange } from "@dicehub/phi/components/date-picker";

const selected = ref<DatePickerDateRange>({
  from: new Date(2026, 4, 12),
  to: new Date(2026, 4, 16),
});
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="range"
    :number-of-months="2"
    inline
  />
</template>

Range Constraints

<script setup lang="ts">
import { ref } from "vue";
import { DatePicker, type DatePickerDateRange } from "@dicehub/phi/components/date-picker";

const selected = ref<DatePickerDateRange>({
  from: new Date(2026, 4, 12),
  to: new Date(2026, 4, 16),
});
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="range"
    :range-min-days="2"
    :range-max-days="6"
    inline
  />
</template>
<script setup lang="ts">
import { ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref<Date>();
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    :positioning="{ placement: 'bottom', gutter: 8 }"
  >
    <DatePicker.Control>
      <DatePicker.Trigger>Pick a date</DatePicker.Trigger>
    </DatePicker.Control>
    <DatePicker.Positioner>
      <DatePicker.Content>
        <DatePicker.Calendar />
      </DatePicker.Content>
    </DatePicker.Positioner>
  </DatePicker>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { DatePicker, type DatePickerDateRange } from "@dicehub/phi/components/date-picker";

const selected = ref<DatePickerDateRange>();
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="range"
    :number-of-months="2"
    :positioning="{ placement: 'bottom', gutter: 8 }"
  >
    <DatePicker.Control>
      <DatePicker.Trigger>Select dates</DatePicker.Trigger>
    </DatePicker.Control>
    <DatePicker.Positioner>
      <DatePicker.Content>
        <DatePicker.Calendar />
      </DatePicker.Content>
    </DatePicker.Positioner>
  </DatePicker>
</template>

Range Presets

<script setup lang="ts">
import { ref } from "vue";
import {
  DatePicker,
  dateToDateValue,
  type DatePickerDateRange,
} from "@dicehub/phi/components/date-picker";

const selected = ref<DatePickerDateRange>();
const firstWeek = [
  dateToDateValue(new Date(2026, 5, 1)),
  dateToDateValue(new Date(2026, 5, 7)),
];
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="range"
    :number-of-months="2"
    :positioning="{ placement: 'bottom', gutter: 8 }"
  >
    <DatePicker.Control>
      <DatePicker.Trigger>Select dates</DatePicker.Trigger>
    </DatePicker.Control>
    <DatePicker.Positioner>
      <DatePicker.Content class="date-picker-demo__preset-popover">
        <div class="date-picker-demo__preset-list">
          <DatePicker.PresetTrigger :value="firstWeek">
            This month
          </DatePicker.PresetTrigger>
        </div>
        <div class="date-picker-demo__calendar-pane">
          <DatePicker.Calendar />
        </div>
      </DatePicker.Content>
    </DatePicker.Positioner>
  </DatePicker>
</template>

Disabled Dates with Usage Limits

<script setup lang="ts">
import { computed, ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref<Date[]>([]);
const maxDays = 5;
const unavailableDays = [5, 12, 18, 25];
const isDateUnavailable = (date: Date) =>
  date.getMonth() === 5 && unavailableDays.includes(date.getDate());
const footer = computed(
  () => `${selected.value.length}/${maxDays} days selected. Grayed dates are unavailable.`,
);
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="multiple"
    :max-selected-dates="maxDays"
    :is-date-disabled="isDateUnavailable"
    fixed-weeks
    inline
  />
  <p>{{ footer }}</p>
</template>

Usage Limits

<script setup lang="ts">
import { computed, ref } from "vue";
import { DatePicker } from "@dicehub/phi/components/date-picker";

const selected = ref<Date[]>([]);
const maxDays = 5;
const unavailableDays = [5, 12, 18, 25];
const isDateUnavailable = (date: Date) =>
  date.getMonth() === 5 && unavailableDays.includes(date.getDate());
const footer = computed(
  () => `${selected.value.length}/${maxDays} days selected. Grayed dates are unavailable.`,
);
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="multiple"
    :max-selected-dates="maxDays"
    :is-date-disabled="isDateUnavailable"
    fixed-weeks
    inline
  />
  <p>{{ footer }}</p>
</template>

Full Popup Example

<script setup lang="ts">
import { ref } from "vue";
import {
  DatePicker,
  dateToDateValue,
  type DatePickerDateRange,
} from "@dicehub/phi/components/date-picker";

const selected = ref<DatePickerDateRange>({
  from: new Date(2026, 5, 10),
  to: new Date(2026, 5, 14),
});

const nextWeek = [
  dateToDateValue(new Date(2026, 5, 15)),
  dateToDateValue(new Date(2026, 5, 19)),
];
</script>

<template>
  <DatePicker
    v-model:selected="selected"
    mode="range"
    :number-of-months="2"
    :positioning="{ placement: 'bottom', gutter: 8 }"
  >
    <DatePicker.Control>
      <DatePicker.Trigger>Select dates</DatePicker.Trigger>
    </DatePicker.Control>
    <DatePicker.Positioner>
      <DatePicker.Content class="date-picker-demo__preset-popover">
        <div class="date-picker-demo__preset-list">
          <DatePicker.PresetTrigger :value="nextWeek">
            Next week
          </DatePicker.PresetTrigger>
        </div>
        <div class="date-picker-demo__calendar-pane">
          <DatePicker.Calendar />
        </div>
      </DatePicker.Content>
    </DatePicker.Positioner>
  </DatePicker>
</template>

Sub-components

ComponentDescription
DatePicker.RootRoot wrapper around Ark UI DatePicker.Root with Phi styling and Date aliases.
DatePicker.ControlInput control wrapper for popup date pickers.
DatePicker.InputDate input. Use index 0 and 1 for range start and end inputs.
DatePicker.TriggerButton that opens the calendar popup.
DatePicker.ContentPositioned popup content surface.
DatePicker.CalendarDay-calendar renderer with month navigation.
DatePicker.PresetTriggerApplies a preset date or date range.
DatePicker.ValueTextDisplays selected date text from Ark state.
DatePicker.RangeTextDisplays the current visible calendar range.

API Reference

DatePicker.Root

PropTypeDefaultDescription
modelValueDateValue[]-Ark-native controlled value. Use v-model for DateValue arrays.
selectedDate | Date[] | { from?: Date; to?: Date }-Date-based controlled value alias. Use v-model:selected.
selectionMode / mode"single" | "multiple" | "range""single"Selection behavior. `mode` is an alias for `selectionMode`.
numOfMonths / numberOfMonthsnumber1Number of calendar months to display.
min / maxDateValue-Ark-native date boundaries.
minDate / maxDateDate-Date-object aliases for date boundaries.
rangeMinDays / rangeMaxDaysnumber-Rejects completed ranges outside day-length limits.
isDateUnavailable(date: DateValue, locale: string) => boolean-Ark-native unavailable date predicate.
isDateDisabled(date: Date, locale: string) => boolean-Date-object alias for unavailable dates.
inlinebooleanfalseRenders the calendar inline instead of in a popup.
startOfWeeknumber1First day of the week. Defaults to Monday.
placeholderstring-Placeholder shown by the default input.

DatePicker.Calendar

PropTypeDefaultDescription
---No custom props. Calendar reads DatePicker root state.

DatePicker.Content

PropTypeDefaultDescription
classstring-Use class or style to customize popup width and layout.