Usage
To get started, import the necessary components from the package:
import {
DatePicker,
DatePickerControl,
DatePickerInput,
DatePickerTrigger,
DatePickerClearTrigger,
DatePickerContent,
DatePickerYearSelect,
DatePickerMonthSelect,
DatePickerPrevTrigger,
DatePickerViewTrigger,
DatePickerNextTrigger,
DatePickerGrid,
DatePickerRowHeader,
DatePickerColumnHeader,
DatePickerRowGroup,
DatePickerRow,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
} from '@ark-ui/react'
Here is an example of how to use the Date Picker component:
import { Portal } from '@zag-js/react'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/react'
const Basic = () => (
<DatePicker>
{(api) => (
<>
<DatePickerControl>
<span>View mode: {api.view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<DatePickerYearSelect />
<DatePickerMonthSelect />
<div>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<DatePickerViewTrigger>
{api.view === 'day' && api.visibleRangeText.start}
{api.view === 'month' && api.visibleRange.start.year}
{api.view === 'year' && `${api.getDecade().start} - ${api.getDecade().end}`}
</DatePickerViewTrigger>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
{api.view === 'day' && (
<DatePickerGrid>
<DatePickerRowHeader>
{api.weekDays.map((day, i) => (
<DatePickerColumnHeader key={i} aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
))}
</DatePickerRowHeader>
<DatePickerRowGroup>
{api.weeks.map((week, id) => (
<DatePickerRow key={id}>
{week.map((day, id) => (
<DatePickerDayCell key={id} value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
{api.view === 'month' && (
<DatePickerGrid>
<DatePickerRowGroup>
{api.getMonthsGrid({ columns: 4, format: 'short' }).map((months, row) => (
<DatePickerRow key={row}>
{months.map((month, index) => (
<DatePickerMonthCell key={index} value={month.value}>
<DatePickerMonthCellTrigger>{month.label}</DatePickerMonthCellTrigger>
</DatePickerMonthCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
{api.view === 'year' && (
<DatePickerGrid>
<DatePickerRowGroup>
{api.getYearsGrid({ columns: 4 }).map((years, row) => (
<DatePickerRow key={row}>
{years.map((year, index) => (
<DatePickerYearCell key={index} value={year.value}>
<DatePickerYearCellTrigger>{year.label}</DatePickerYearCellTrigger>
</DatePickerYearCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)}
</DatePicker>
)
import { For, Show } from 'solid-js'
import { Portal } from 'solid-js/web'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/solid'
const Basic = () => (
<DatePicker>
{(api) => (
<>
<DatePickerControl>
<span>View mode: {api().view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<DatePickerYearSelect />
<DatePickerMonthSelect />
<div>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<DatePickerViewTrigger>
<Show when={api().view === 'day'}>{api().visibleRangeText.start}</Show>
<Show when={api().view === 'month'}>{api().visibleRange.start.year}</Show>
<Show when={api().view === 'year'}>
{api().getDecade().start} - {api().getDecade().end}
</Show>
</DatePickerViewTrigger>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
<Show when={api().view === 'day'}>
<DatePickerGrid>
<DatePickerRowHeader>
<For each={api().weekDays}>
{(day) => (
<DatePickerColumnHeader aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
)}
</For>
</DatePickerRowHeader>
<DatePickerRowGroup>
<For each={api().weeks}>
{(week) => (
<DatePickerRow>
<For each={week}>
{(day) => (
<DatePickerDayCell value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
<Show when={api().view === 'month'}>
<DatePickerGrid>
<DatePickerRowGroup>
<For each={api().getMonthsGrid({ columns: 4, format: 'long' })}>
{(months) => (
<DatePickerRow>
<For each={months}>
{(month) => (
<DatePickerMonthCell value={month.value}>
<DatePickerMonthCellTrigger>
{month.label}
</DatePickerMonthCellTrigger>
</DatePickerMonthCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
<Show when={api().view === 'year'}>
<DatePickerGrid>
<DatePickerRowGroup>
<For each={api().getYearsGrid({ columns: 4 })}>
{(years) => (
<DatePickerRow>
<For each={years}>
{(year) => (
<DatePickerYearCell value={year.value}>
<DatePickerYearCellTrigger>{year.label}</DatePickerYearCellTrigger>
</DatePickerYearCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)}
</DatePicker>
)
Story not available
Range Selection with Single Grid
To create a Date Picker that allows a range selection, set the selectionMode
prop to “range”. This renders a single grid view where the user can select a
start and end date:
import { Portal } from '@zag-js/react'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/react'
const RangeWithSingleGrid = () => (
<DatePicker selectionMode="range">
{(api) => (
<>
<DatePickerControl>
<span>View mode: {api.view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<DatePickerYearSelect />
<DatePickerMonthSelect />
<div>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<DatePickerViewTrigger>
{api.view === 'day' && api.visibleRangeText.start}
{api.view === 'month' && api.visibleRange.start.year}
{api.view === 'year' && `${api.getDecade().start} - ${api.getDecade().end}`}
</DatePickerViewTrigger>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
{api.view === 'day' && (
<DatePickerGrid>
<DatePickerRowHeader>
{api.weekDays.map((day, i) => (
<DatePickerColumnHeader key={i} aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
))}
</DatePickerRowHeader>
<DatePickerRowGroup>
{api.weeks.map((week, id) => (
<DatePickerRow key={id}>
{week.map((day, id) => (
<DatePickerDayCell key={id} value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
{api.view === 'month' && (
<DatePickerGrid>
<DatePickerRowGroup>
{api.getMonthsGrid({ columns: 4, format: 'short' }).map((months, row) => (
<DatePickerRow key={row}>
{months.map((month, index) => (
<DatePickerMonthCell key={index} value={month.value}>
<DatePickerMonthCellTrigger>{month.label}</DatePickerMonthCellTrigger>
</DatePickerMonthCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
{api.view === 'year' && (
<DatePickerGrid>
<DatePickerRowGroup>
{api.getYearsGrid({ columns: 4 }).map((years, row) => (
<DatePickerRow key={row}>
{years.map((year, index) => (
<DatePickerYearCell key={index} value={year.value}>
<DatePickerYearCellTrigger>{year.label}</DatePickerYearCellTrigger>
</DatePickerYearCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
)}
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)}
</DatePicker>
)
import { For, Show } from 'solid-js'
import { Portal } from 'solid-js/web'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/solid'
const RangeWithSingleGrid = () => (
<DatePicker selectionMode="range">
{(api) => (
<>
<DatePickerControl>
<span>View mode: {api().view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<div style={{ display: 'flex', 'justify-content': 'space-between' }}>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<DatePickerViewTrigger>
<Show when={api().view === 'day'}>{api().visibleRangeText.start}</Show>
</DatePickerViewTrigger>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
<DatePickerYearSelect />
<DatePickerMonthSelect />
<div>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<DatePickerViewTrigger>
<Show when={api().view === 'day'}>{api().visibleRangeText.start}</Show>
<Show when={api().view === 'month'}>{api().visibleRange.start.year}</Show>
<Show when={api().view === 'year'}>
{api().getDecade().start} - {api().getDecade().end}
</Show>
</DatePickerViewTrigger>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
<Show when={api().view === 'day'}>
<DatePickerGrid>
<DatePickerRowHeader>
<For each={api().weekDays}>
{(day) => (
<DatePickerColumnHeader aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
)}
</For>
</DatePickerRowHeader>
<DatePickerRowGroup>
<For each={api().weeks}>
{(week) => (
<DatePickerRow>
<For each={week}>
{(day) => (
<DatePickerDayCell value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
<Show when={api().view === 'month'}>
<DatePickerGrid>
<DatePickerRowGroup>
<For each={api().getMonthsGrid({ columns: 4, format: 'short' })}>
{(months) => (
<DatePickerRow>
<For each={months}>
{(month) => (
<DatePickerMonthCell value={month.value}>
<DatePickerMonthCellTrigger>
{month.label}
</DatePickerMonthCellTrigger>
</DatePickerMonthCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
<Show when={api().view === 'year'}>
<DatePickerGrid>
<DatePickerRowGroup>
<For each={api().getYearsGrid({ columns: 4 })}>
{(years) => (
<DatePickerRow>
<For each={years}>
{(year) => (
<DatePickerYearCell value={year.value}>
<DatePickerYearCellTrigger>{year.label}</DatePickerYearCellTrigger>
</DatePickerYearCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</Show>
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)}
</DatePicker>
)
Story not available
Range Selection with Two Grids
In some cases, you might want to display two consecutive months at the same time
to facilitate a broader range selection. This can be achieved by setting the
numOfMonths
prop to 2
:
import { Portal } from '@zag-js/react'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/react'
const RangeWithTwoGrids = () => (
<DatePicker selectionMode="range" numOfMonths={2}>
{(api) => {
const offset = api.getOffset(1)
return (
<>
<DatePickerControl>
<span>View mode: {api.view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<time>{api.visibleRangeText.start}</time>
<time>{api.visibleRangeText.end}</time>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', gap: '24px' }}>
<DatePickerGrid>
<DatePickerRowHeader>
{api.weekDays.map((day, i) => (
<DatePickerColumnHeader key={i} aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
))}
</DatePickerRowHeader>
<DatePickerRowGroup>
{api.weeks.map((week, id) => (
<DatePickerRow key={id}>
{week.map((day, id) => (
<DatePickerDayCell key={id} value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
<DatePickerGrid>
<DatePickerRowHeader>
{api.weekDays.map((day, i) => (
<DatePickerColumnHeader key={i} aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
))}
</DatePickerRowHeader>
<DatePickerRowGroup>
{offset.weeks.map((week, id) => (
<DatePickerRow key={id}>
{week.map((day, id) => (
<DatePickerDayCell key={id} value={day} offset={offset}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
))}
</DatePickerRow>
))}
</DatePickerRowGroup>
</DatePickerGrid>
</div>
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)
}}
</DatePicker>
)
import { For, Show } from 'solid-js'
import { Portal } from 'solid-js/web'
import {
DatePicker,
DatePickerClearTrigger,
DatePickerColumnHeader,
DatePickerContent,
DatePickerControl,
DatePickerDayCell,
DatePickerDayCellTrigger,
DatePickerGrid,
DatePickerInput,
DatePickerMonthCell,
DatePickerMonthCellTrigger,
DatePickerMonthSelect,
DatePickerNextTrigger,
DatePickerPositioner,
DatePickerPrevTrigger,
DatePickerRow,
DatePickerRowGroup,
DatePickerRowHeader,
DatePickerTrigger,
DatePickerViewTrigger,
DatePickerYearCell,
DatePickerYearCellTrigger,
DatePickerYearSelect,
} from '@ark-ui/solid'
const RangeWithTwoGrids = () => (
<DatePicker selectionMode="range" numOfMonths={2}>
{(api) => (
<>
<DatePickerControl>
<span>View mode: {api().view}</span>
<DatePickerInput />
<DatePickerTrigger>🗓</DatePickerTrigger>
<DatePickerClearTrigger>Clear</DatePickerClearTrigger>
</DatePickerControl>
<Portal>
<DatePickerPositioner>
<DatePickerContent>
<div style={{ display: 'flex', 'justify-content': 'space-between' }}>
<DatePickerPrevTrigger>Prev</DatePickerPrevTrigger>
<time>{api().visibleRangeText.start}</time>
<time>{api().visibleRangeText.end}</time>
<DatePickerNextTrigger>Next</DatePickerNextTrigger>
</div>
<div style={{ display: 'flex', 'justify-content': 'space-between', gap: '24px' }}>
<DatePickerGrid>
<DatePickerRowHeader>
<For each={api().weekDays}>
{(day) => (
<DatePickerColumnHeader aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
)}
</For>
</DatePickerRowHeader>
<DatePickerRowGroup>
<For each={api().weeks}>
{(week) => (
<DatePickerRow>
<For each={week}>
{(day) => (
<DatePickerDayCell value={day}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
<DatePickerGrid>
<DatePickerRowHeader>
<For each={api().weekDays}>
{(day) => (
<DatePickerColumnHeader aria-label={day.long}>
{day.narrow}
</DatePickerColumnHeader>
)}
</For>
</DatePickerRowHeader>
<DatePickerRowGroup>
<For each={api().getOffset(1).weeks}>
{(week) => (
<DatePickerRow>
<For each={week}>
{(day) => (
<DatePickerDayCell value={day} offset={api().getOffset(1)}>
<DatePickerDayCellTrigger>{day.day}</DatePickerDayCellTrigger>
</DatePickerDayCell>
)}
</For>
</DatePickerRow>
)}
</For>
</DatePickerRowGroup>
</DatePickerGrid>
</div>
</DatePickerContent>
</DatePickerPositioner>
</Portal>
</>
)}
</DatePicker>
)
Story not available
Conclusion
The Date Picker component provides a versatile solution for date selection needs in your applications. With support for different view modes, single and range date selection, and the ability to render multiple grids, it offers a wide range of customization and usability options.