Skip to contentAsheeUIAsheeUI

Calendar

A date field with a month grid, a typed path, and a value that is a Date.

Calendar is a date field: an input that accepts a typed date and a panel with the month grid beside it. It collects a day, a time or both, mode decides which, and in the default date mode one press on a day is the whole interaction, because the panel closes with the choice. It is a field first: label, description, message and status behave as they do everywhere in the field family.

Usage

import { Calendar } from "@asheeui/web";

<Calendar label="Delivery date" selected={date} onChange={setDate} />

The value is a Date, and null means nothing is chosen. selected reads it, onChange reports it, and the field writes it into the input as dd/mm/yyyy, one format whatever the reader's locale, so a value that is typed, re-read and compared is always written the same way.

Modes

mode states what the field collects. date shows the month grid and closes the panel when a day is chosen; datetime shows the grid and the time spinners together and keeps the panel open, because a reader choosing both has not finished after the day; time shows only the spinners and applies the time to the day the field already holds.

The time is reported as it changes, spinner by spinner, and Done closes the panel in the two modes that keep it open. Typing is a real second path in every mode: the digits are read in the order the field writes them, day, month, year, then hours, minutes, seconds, and the field reformats as you go. A typed time keeps the day the field already holds, so adding an hour does not move the day.

Constraints

disableFuture refuses any day after today, and stops the forward control from moving past the month that holds today, a month whose every day would be refused is not worth opening. isClearable adds a clear control to the field and a Clear to the panel once something is chosen.

Validation is the family's: status and message on the field, announced the same way every other field announces them. Typed input is forgiving rather than strict, a part out of range is clamped to the month's own answer, so 31 in a thirty-day month gives you the 30th, which is a value you can correct instead of a field that appears to ignore you.

Props

mode is registered as date, size as md and variant as bordered, because the component registers the field family's web defaults; radius follows the application's defaultRadius and the accent follows its defaultColor. isClearable and disableFuture are both off, and picker carries the panel's own settings: portal (true) and portalTarget (rendered into document.body by default) decide where it lives, and lockScroll (true) whether the page behind it moves. Pass placeholder to replace the wording the field supplies for the mode.

Accessibility

  • The input announces a dialog: it carries aria-haspopup="dialog" and aria-expanded, so the panel is not a surprise and its closing is not either.
  • The month is a table with role="grid", named by its month and year. Each day is a gridcell that states whether it is selected, and today is marked with aria-current="date".
  • The grid is one tab stop, not thirty-one: when it opens, only one day is in the tab order, the chosen day, or today when the field is empty, and the arrow keys move it by a day and by a week, Home and End go to the first and last day of the focused week, and PageUp and PageDown move thirty days either way. Focus follows the navigated day across a month boundary.
  • The month controls are labelled (Previous month, Next month) and the next one is disabled rather than hidden when disableFuture forbids it, the field's clear control is labelled Clear selection, and opening the panel does not move focus, it stays in the input, so typing keeps working while the grid is open and an outside press or Escape closes it.