Date Range Field

PohonGitHub
Allows users to input a range of dates within a designated field.
mm
dd
yyyy
-
mm
dd
yyyy
<script setup lang="ts">
import { ADateRangeFieldInput, ADateRangeFieldRoot, ALabel } from 'akar';
</script>

<template>
  <div class="flex flex-col gap-2">
    <ALabel
      class="text-sm"
      for="birthday"
    >
      Booking
    </ALabel>
    <ADateRangeFieldRoot
      id="booking"
      v-slot="{ segments }"
      :is-date-unavailable="date => date.day === 19"
      class="group text-sm color-text-highlighted px-2.5 py-1.5 rounded-md bg-background inline-flex gap-0.5 select-none ring ring-ring-accented ring-inset transition-colors items-center relative focus-visible:(ring-2 ring-primary ring-inset)"
    >
      <template
        v-for="item in segments.start"
        :key="item.part"
      >
        <ADateRangeFieldInput
          type="start"
          :part="item.part"
          class="text-center outline-hidden rounded transition-colors-280 data-[placeholder]:color-text-dimmed data-[segment=literal]:color-text-muted focus:bg-background-elevated"
          :class="{
            'w-11': item.part === 'year',
            'w-7': item.part === 'month' || item.part === 'day',
          }"
        >
          {{ item.value }}
        </ADateRangeFieldInput>
      </template>

      <span class="mx-2">
        -
      </span>

      <template
        v-for="item in segments.end"
        :key="item.part"
      >
        <ADateRangeFieldInput
          type="end"
          :part="item.part"
          class="text-center outline-hidden rounded transition-colors-280 data-[placeholder]:color-text-dimmed data-[segment=literal]:color-text-muted focus:bg-background-elevated"
          :class="{
            'w-11': item.part === 'year',
            'w-7': item.part === 'month' || item.part === 'day',
          }"
        >
          {{ item.value }}
        </ADateRangeFieldInput>
      </template>
    </ADateRangeFieldRoot>
  </div>
</template>

Features

  • Full keyboard navigation.
  • Can be controlled or uncontrolled.
  • Focus is fully managed.
  • Localization support.
  • Highly composable.
  • Accessible by default.
  • Supports both date and date-time formats.

Preface

The component depends on the @internationalized/date package, which solves a lot of the problems that come with working with dates and times in JavaScript.

We highly recommend reading through the documentation for the package to get a solid feel for how it works, and you'll need to install it in your project to use the date-related components.

Installation

Install the date package.

pnpm add @internationalized/date

Anatomy

Import all parts and piece them together.

<script setup>
import {
  ADateRangeFieldInput,
  ADateRangeFieldRoot,
} from 'akar';
</script>

<template>
  <ADateRangeFieldRoot>
    <ADateRangeFieldInput />
  </ADateRangeFieldRoot>
</template>

Pohon

One benefit of using Akar is its flexibility and low-level control over the components. However, this also means that you may need to manually construct more complex UI elements by combining multiple Akar components together.

If you feel there's a lot of elements that needs to be constructed manually using Akar, consider using Pohon UI instead. It provides a higher-level abstraction over Akar components with pre-defined styles and behaviors that can help you build UIs faster.

API Reference

Root

Contains all the parts of a date field

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

defaultPlaceholderDateValue

The default placeholder date

defaultValueDateRange

The default value for the calendar

dir'ltr' | 'rtl'

The reading direction of the date field when applicable.
If omitted, inherits globally from AConfigProvider or assumes LTR (left-to-right) reading mode.

disabledfalseboolean

Whether or not the date field is disabled

granularity'day' | 'hour' | 'minute' | 'second'

The granularity to use for formatting times. Defaults to day if a CalendarDate is provided, otherwise defaults to minute. The field will render segments for each part of the date up to and including the specified granularity

hideTimeZoneboolean

Whether or not to hide the time zone segment of the field

hourCycle12 | 24

The hour cycle used for formatting times. Defaults to the local preference

idstring

Id of the element

isDateUnavailableDateMatcher

A function that returns whether or not a date is unavailable

localestring

The locale to use for formatting dates

maxValueDateValue

The maximum date that can be selected

minValueDateValue

The minimum date that can be selected

modelValueDateRange | null

The controlled checked state of the calendar. Can be bound as v-model.

namestring

The name of the field. Submitted with its owning form as part of a name/value pair.

placeholderDateValue

The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view

readonlyfalseboolean

Whether or not the date field is readonly

requiredboolean

When true, indicates that the user must set the value before the owning form can be submitted.

stepDateStep

The stepping interval for the time fields. Defaults to 1.

Emits

Event Type
update:modelValue[DateRange]

Event handler called whenever the model value changes

update:placeholder[date: DateValue]

Event handler called whenever the placeholder value changes

Slots

Slot Type
modelValueDateRange | null
segments{ start: { part: SegmentPart; value: string; }[]; end: { part: SegmentPart; value: string; }[]; }

Input

Contains the date field segments

Props

Prop Default Type
as'div'APrimitiveAsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChildboolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

part*'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'dayPeriod' | 'literal' | 'timeZoneName'

The part of the date to render

type*'start' | 'end'

The type of field to render (start or end)

Data Attributes

Attribute Value
[data-disabled]Present when disabled
[data-invalid]Present when invalid
[data-placeholder]Present when no value is set

Accessibility

Keyboard Interactions

Key Description
Tab

When focus moves onto the date field, focuses the first segment.

ArrowLeftArrowRight

Navigates between the date field segments.

ArrowUpArrowDown

Increments/changes the value of the segment.

0-9

When the focus is on a numeric ADateFieldInput, it types in number and focuses the next segment if the next input would result in an invalid value.

Backspace

Deletes a digit from the focused numeric segments.

AP

When the focus is on the day period, it sets it to AM or PM.