PixelCalendarGrid

Standalone month grid for date selection — usable inline or composed inside date pickers and range pickers.

  • Controlled or uncontrolled month navigation: month + onMonthChange (React), v-model:month (Vue), [(month)] (Angular)
  • Min/max date bounds plus custom disabledDates (array or predicate)
  • Optional rangePreview prop highlights start/end + in-range cells
  • Full keyboard nav: Arrows, Home/End, PageUp/PageDown, Enter/Space
  • Surface-aware (pixel / linear) — follows the nearest PxlKitSurfaceProvider
Status
stable
Category
forms
Since
v1.9.0

API

import { PixelCalendarGrid } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
valueDate | null—The picked day, null for none; leave unset for an uncontrolled grid.
defaultValueDate | null—Initial day while uncontrolled.
onChange(date: Date) => void—Called with the day picked, at its start.
minDateDate—First day that can be picked.
maxDateDate—Last day that can be picked.
disabledDatesDate[] | ((d: Date) => boolean)—Days that cannot be picked: a list, or a test of each day.
renderDay(d: Date) => React.ReactNode—Draws a day's cell content in place of its number.
monthDate—The month on show (any day of it); leave unset to start on the picked day's, else today's.
onMonthChange(m: Date) => void—Called with the first day of the month shown next (the navigation buttons, or focus leaving the month).
surface'pixel' | 'linear'—Surface override; defaults to the nearest provider.
rangePreview{ from?: Date; to?: Date; hover?: Date }—A range to highlight: from from to to, or to hover while to is not picked.
data-testidstring—Optional hook for tests.

ref points to <div>.

Accessibility

WCAG target: 2.1 AA

  • grid

role=grid with columnheader weekday cells and gridcell day buttons; aria-selected marks the chosen day, aria-current="date" marks today, and aria-disabled marks out-of-bounds or disabled dates. Moves skip disabled days and stop at min/max. One enabled day is in the tab order. Week start, month and weekday names follow PxlKitLocaleProvider.

Keyboard

KeyActionWhen
ArrowLeftMove focus to previous day—
ArrowRightMove focus to next day—
ArrowUpMove focus to previous week—
ArrowDownMove focus to next week—
HomeMove focus to start of week—
EndMove focus to end of week—
PageUpMove focus to the same day of the previous month (its last day when shorter)—
PageDownMove focus to the same day of the next month (its last day when shorter)—
Shift+PageUpMove focus to the same day of the previous year—
Shift+PageDownMove focus to the same day of the next year—
EnterSelect the focused day—
SpaceSelect the focused day—

Usage

import { useState } from 'react';
import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function Default() {
  const [value, setValue] = useState<Date | null>(null)
  return <PixelCalendarGrid value={value} onChange={setValue} />
}

Examples

Default

Shows the current month and marks today, by the clock of whatever renders it: a server render can differ from the browser's (a page built on another day, another time zone) and fail to hydrate. For a stable server render pass month (and value or defaultValue), or render a current-month calendar in the browser only: next/dynamic with ssr: false (Next.js), ClientOnly (Nuxt), @defer (Angular).

import { useState } from 'react';
import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function Default() {
  const [value, setValue] = useState<Date | null>(null)
  return <PixelCalendarGrid value={value} onChange={setValue} />
}

With Selected Date

import { useState } from 'react';
import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function WithSelectedDate() {
  const [value, setValue] = useState<Date | null>(new Date())
  return <PixelCalendarGrid value={value} onChange={setValue} />
}

With Min/Max Bounds

import { useState } from 'react';
import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function WithMinMax() {
  const today = new Date()
  const min = new Date(today.getFullYear(), today.getMonth(), 1)
  const max = new Date(today.getFullYear(), today.getMonth() + 1, 0)
  const [value, setValue] = useState<Date | null>(null)
  return (
    <PixelCalendarGrid
      value={value}
      onChange={setValue}
      minDate={min}
      maxDate={max}
    />
  )
}

Disabled Weekends

import { useState } from 'react';
import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function WithDisabledWeekends() {
  const [value, setValue] = useState<Date | null>(null)
  return (
    <PixelCalendarGrid
      value={value}
      onChange={setValue}
      disabledDates={(d) => d.getDay() === 0 || d.getDay() === 6}
    />
  )
}

Range Preview

import { PixelCalendarGrid } from '@pxlkit/ui-kit';

export function RangePreview() {
  const from = new Date()
  const to = new Date(from.getFullYear(), from.getMonth(), from.getDate() + 5)
  return <PixelCalendarGrid rangePreview={{ from, to }} />
}

Related