Skip to main content

Date and Time Picker

Allows users to select a date, time, or combined date-time value from a structured input. Use in forms wherever a precise date or time value is required. Don't use for simple date-only input where time is irrelevant.

OverviewStyleAccessibility

Description

Anatomy

PartRequired?Notes
Field label Required Visible label associated via for/id. Must describe the expected value — for example, 'Consultation close date' or 'Meeting start time'. Do not rely on placeholder text as a label.
Date input segment Required Structured text input or segmented day/month/year fields. Accepts keyboard entry and is connected to the calendar popover.
Time input segment Optional Hour and minute fields, with optional AM/PM toggle for 12-hour format. Only present in date-time or time-only variants.
Calendar trigger button Recommended Icon button (calendar icon) that opens the calendar popover. Must be keyboard-accessible and labelled with aria-label.
Calendar popover Recommended Floating panel containing a month grid. Includes previous/next month navigation and today highlight. Dismissed on selection or Escape.
Month/year navigation Required Controls inside the calendar popover for stepping through months and years. Must be operable by keyboard.
Helper text Optional Supplementary guidance below the input, such as expected format ('DD/MM/YYYY') or constraints ('Must be a future date').
Error message Recommended Replaces or follows helper text when validation fails. Must be linked to the input via aria-describedby.
Clear button Optional Allows the user to remove a selected value. Only shown when a value is present and the field is not required.

Variants

States

State Behaviour
Default Input is empty and ready for interaction. Label and optional helper text are visible.
Focused 3px focus ring using --op-color-interactive-focus appears on the active input segment or trigger button. Calendar popover opens when the trigger button receives focus and Enter/Space is pressed, or on click.
Filled A selected value is displayed in the input. The clear button appears if the field is clearable.
Open (calendar popover visible) The calendar popover is displayed. The trigger button is in a pressed state (aria-expanded='true'). Focus moves into the popover grid.
Disabled Input and trigger button are non-interactive. Text renders at reduced opacity using --op-color-text-disabled. Not submitted with the form.
Read-only Value is displayed but cannot be changed. Input has readonly attribute. Trigger button is hidden or non-interactive. Value is submitted with the form.
Error Border changes to --op-color-status-error. Error message appears below the input, linked via aria-describedby. The error persists until a valid value is entered.
Loading Used when available dates are fetched asynchronously (for example, checking consultant availability). A spinner replaces or overlays the calendar while data loads.

Usage guidelines

Do / Don't

Do

Label the field with specific, plain-language text that describes the value being captured, such as 'Consultation open date' or 'Meeting start time'.

Don't

Use generic labels like 'Date' or 'Pick a date' that leave users uncertain about what value is expected.

Do

Show the expected format in helper text when using a text-entry date input, for example 'DD/MM/YYYY'.

Don't

Rely on placeholder text alone to communicate the expected format — placeholder text disappears on focus and is not reliably read by screen readers.

Do

Set sensible min and max date constraints to prevent invalid input — for example, preventing a consultation close date from being set in the past.

Don't

Allow users to select dates outside a valid range and then surface a validation error after submission.

Do

For date-time fields, confirm the user's timezone where it is relevant to the action, particularly for scheduled notifications or cross-jurisdiction consultations.

Don't

Silently assume server timezone without surfacing it to the user, which can cause missed meetings or incorrectly timed notifications.

Do

Preserve a partially entered value when the user navigates away and returns, where the form supports draft saving.

Don't

Clear the field silently if the user opens and closes the popover without selecting a date — this is disorienting.

Layout & Spacing

Field label: margin-bottom --op-space-4 (4px) Input container: min-height 44px; padding-inline --op-space-12 (12px); padding-block --op-space-8 (8px) Helper text / error message: margin-top --op-space-4 (4px) Calendar popover: margin-top --op-space-4 (4px) from the input; padding --op-space-16 (16px) Calendar day cell: min-width 36px; min-height 36px; gap --op-space-4 (4px) between cells Month navigation buttons: min 44x44px touch target Time input segments: min-width 48px; gap --op-space-8 (8px) between hour and minute

Tokens

PartTokenValue
Input border (default) --op-color-border-default 1px solid. Increases to 2px on focus.
Input border (error) --op-color-status-error 1px solid; replaces default border when field is in error state.
Input background --op-color-bg-primary White/surface background. Does not change on focus.
Input text --op-color-text-primary Primary text colour for entered values.
Placeholder / helper text --op-color-text-secondary Used for format hints and supplementary guidance.
Error message text --op-color-status-error Matches border colour to reinforce the error state visually.
Focus ring --op-color-interactive-focus 3px solid outline, 2px offset. Applied to input segments and trigger button.
Calendar trigger button icon --op-color-interactive-default Icon colour for the calendar trigger. Uses --op-color-interactive-hover on hover.
Calendar popover background --op-color-bg-primary Surface colour for the floating calendar panel.
Calendar popover border --op-color-border-default 1px solid border on the popover container.
Selected date cell background --op-color-interactive-default Filled background on the selected day. Text uses --op-color-text-on-interactive.
Today highlight --op-color-interactive-default Underline or dot indicator only (not filled) to differentiate from selected state.
Disabled input --op-color-text-disabled Reduced-opacity text. Background uses --op-color-bg-disabled.
Date range in-range highlight --op-color-interactive-default At 15% opacity for cells between start and end dates.

Engineering notes

  • The date-time picker does not have a native wa-* Web Awesome counterpart. Implement using the browser-native , , or element as the baseline, progressively enhanced with a custom calendar popover for cross-browser consistency and Orbit styling.
  • Always associate the label element with the input using matching for/id attributes. If using a fieldset for a date range pair, use a legend for the group label.
  • Wire aria-describedby on the input to the IDs of both the helper text element and the error message element (space-separated). Toggle the error message element visibility and content in response to validation state.
  • Set aria-expanded='true'/'false' on the calendar trigger button to reflect popover open state. Set aria-haspopup='dialog' on the trigger button.
  • The calendar popover must have role='dialog' with an aria-label such as 'Choose date'. Wrap day cells in a role='grid' with role='gridcell' for individual cells.
  • When the popover opens, move focus to the currently selected date cell, or to today's date if no value is set. When the popover closes (via Escape or date selection), return focus to the trigger button.
  • For date ranges, manage focus order so that the start date input is reached before the end date input. Validate that the end date is not before the start date and surface the error on the end date field.
  • Respect prefers-reduced-motion — suppress any slide/fade animation on the calendar popover open/close if the user has requested reduced motion.
  • For government forms that will be archived or audited, store and display dates in ISO 8601 format (YYYY-MM-DD) internally, while formatting for display according to the locale (DD/MM/YYYY for Australia).
  • When min or max date constraints are applied, mark out-of-range day cells with aria-disabled='true' and prevent selection. Do not remove them from the DOM as this confuses calendar navigation.

Keyboard interaction

KeyAction
Tab Moves focus to the date input segment, then to the time input segment (if present), then to the calendar trigger button, then to the clear button (if visible).
Enter / Space Opens the calendar popover when focus is on the trigger button. Selects the focused day cell when the popover is open.
Escape Closes the calendar popover and returns focus to the trigger button.
Arrow Left / Right Moves focus between day cells within the calendar grid. Wraps to the previous or next month row as needed.
Arrow Up / Down Moves focus between weeks in the calendar grid (7 days per step).
Page Up / Page Down Navigates to the previous or next month in the calendar popover.
Home / End Moves focus to the first or last day of the current week in the calendar grid.
Backspace / Delete Clears the current segment value when focus is in the input. Activates the clear button when focus is on it.

Why it matters

Government forms are frequently used by people with disabilities, including those who use screen readers or keyboard-only navigation. Date and time inputs are particularly error-prone for these users when implemented poorly — missing labels, focus traps in calendar popovers, and inaccessible grid navigation are common failure points. Accessible date pickers reduce barriers to participation in public consultations and government services.

Focus

Focus ring is 3px solid --op-color-interactive-focus with a 2px offset, applied to all interactive elements: input segments, the trigger button, clear button, and calendar day cells. When the calendar popover opens, focus transfers to the selected date cell or to today's date if no value is set. The popover must not create a focus trap — Escape must always return focus to the trigger button. When the popover closes (by selection or Escape), focus returns to the trigger button. In the date range variant, focus moves from the start date trigger to the end date trigger after the start date is selected, guiding the user through the two-step selection.

ARIA

Role or attributeWhen to useExample
aria-label (trigger button) Provides an accessible name for the icon-only calendar trigger button. <button aria-label="Open date picker" aria-haspopup="dialog" aria-expanded="false">
aria-expanded (trigger button) Reflects whether the calendar popover is currently open. <button aria-expanded="true" aria-haspopup="dialog">
role="dialog" + aria-label (popover) Identifies the calendar popover as a dialog and gives it an accessible name. <div role="dialog" aria-label="Choose date" aria-modal="true">
role="grid" (calendar table) Marks the day grid as an interactive grid, enabling grid navigation keys. <table role="grid" aria-labelledby="calendar-month-label">
aria-selected (day cell) Marks the currently selected date in the calendar grid. <td role="gridcell" aria-selected="true" tabindex="0">
aria-disabled (day cell) Marks out-of-range or unavailable dates as non-interactive without removing them from the grid. <td role="gridcell" aria-disabled="true" tabindex="-1">
aria-describedby (input) Links the input to both helper text and error message elements for programmatic description. <input type="text" aria-describedby="dob-hint dob-error">
aria-live="polite" (error message) Announces validation errors to screen reader users without interrupting their current action. <p id="dob-error" aria-live="polite" role="alert">Please enter a valid date.</p>

Contrast

Label text (--op-color-text-primary on --op-color-bg-primary): must meet 4.5:1 minimum ratio. Helper text (--op-color-text-secondary on --op-color-bg-primary): must meet 4.5:1 minimum ratio — verify this token combination in the Orbit token audit, as secondary text tokens can fall below threshold. Error text (--op-color-status-error on --op-color-bg-primary): must meet 4.5:1 minimum ratio. Selected day cell text (--op-color-text-on-interactive on --op-color-interactive-default): must meet 4.5:1 minimum ratio. Disabled input text (--op-color-text-disabled): contrast requirement is relaxed to 3:1 per WCAG 2.1 SC 1.4.3 exception for disabled controls, but aim higher where feasible.

Touch targets

All interactive elements — input segments, the calendar trigger button, clear button, month navigation arrows, and individual day cells — must meet the 44x44px minimum touch target. Day cells in the calendar grid may be visually smaller than 44px but must have padding or invisible hit areas to reach the minimum. This is critical for use on mobile devices in the field (for example, council officers completing forms on tablets).

Things to avoid

  • Do not use placeholder text as a substitute for a visible label. Placeholder text is not reliably exposed to assistive technologies and disappears on input.
  • Do not open the calendar popover automatically on focus of the text input — this interrupts keyboard users who want to type a date directly.
  • Do not prevent text entry in the date input and force popover-only selection — some users find a keyboard-typed date faster and less disruptive.
  • Do not use colour alone to indicate the selected date or today's date — pair colour with a shape, underline, or other visual indicator.
  • Do not dismiss the popover immediately on mouse-down on a date cell — wait for mouse-up/click to confirm selection, to avoid accidental selections during scroll.

Was this page helpful?

Updated 5 October 2026