Date

One date: a native <input type="date"> in a .canon-date box, Text Input's frame. canon.js draws the field (day, month and year, in the order of the reader's language) the same way in every browser, and adds a button that opens a calendar. The input stays underneath with the value (2025-10-10), min, max and required. Without JavaScript it is the browser's date field. Specification: docs/components/date.md

Size

data-size on the field or a container sizes the box and its calendar. Type a date (digits move on by themselves; Up and Down step a part), open the calendar with its button, or press Alt+Down in the field.

Placeholder

placeholder on the input shows while the field is empty and not focused (a native date field has none).

Inline

data-inline on the box: the calendar sits in the page in place of the box, always shown. The title zooms out: days, then months, then years. The input still holds the value the form submits.

Range

Two date inputs in one box: a start and an end, each with its own name and aria-label. The field's label is a <span id> naming the pair (role="group" on the field), as for a Range Slider. The calendar shows two months: the first click picks the start, the second the end (the pointer previews the range in between).

Small
Theme decides
Large

Presets

A <datalist> in the box adds a column of ready ranges. Each option's value is a keyword (all, today, yesterday, this-week, last-week, last-7-days, this-month, last-month, last-30-days, this-year, last-year), named in the reader's language, or a start/end range with a label. The one matching the range is pressed. "All time" is min to max, or empty without them.

Report period

Inline

Stay

Week

An <input type="week"> in the box: the value is an ISO week (2025-W42), weeks start on Monday. The calendar adds a column of week numbers; a click on a number or on any of its days picks the week, and so does Enter on a day. Browsers without week inputs still get the same field and calendar.

Inline

Day strip

data-strip on the box: the date as a row of days in the page, in place of the box (for picking a day close to now: a delivery slot, a booking). As many whole days show as fit, a week at most; previous and next move by the days shown, and the arrow keys move along the days and on past either end. Enter, Space or a click picks a day. The input still holds the value the form submits. Narrow the window to see fewer days.

Dates that can't be chosen

Four ways, combined freely. Such days are greyed in the calendar, can be reached with the keyboard but not chosen, and a typed one makes the field invalid.

data-weekdays="1-5": ISO days, 1 is Monday.

min and max, the browser's own.

data-unavailable: dates and start/end ranges.

The app's function: input.canonUnavailable = (iso) => …

States

Text Input's states: disabled and readonly on the input (the calendar button is off too), an error with aria-invalid="true" and a danger message.

Check-in can't be in the past.

Edge cases

Week start

The week starts on the language's first day (Sunday in US English, Monday in most of Europe). data-week-start (1 is Monday, 7 Sunday) on the box or a container sets it.

Right-to-left

Names come from the language; the grid and the arrows follow the direction.