Datepicker

The <nys-datepicker> component lets users select a single date by typing into the input field or choosing from a calendar popup. On Safari and mobile devices, it falls back to the native date picker.

Copy Code
<nys-datepicker
  id="appointment-date"
  name="appointment-date"
  label="Schedule your DMV appointment"
  description="Enter in MM/DD/YYYY format"
  required
></nys-datepicker>

Can't use NYS Design System web components in your project? Try using the CSS Variables instead.


Accessibility

The <nys-datepicker> component includes the following accessibility features:

  • Built on a native <input type="date">, so screen readers announce the field correctly

  • The calendar button has aria-haspopup="dialog" and aria-expanded to communicate popup state

  • The calendar popup uses role="dialog" with aria-modal and traps focus when open

  • Press Space on the input to open the calendar; press Escape to close it and return focus to the input

  • Tab and Shift+Tab cycle through focusable elements inside the calendar without escaping

  • When required is set, aria-required="true" is applied and validation fires on blur

  • Error messages are rendered via <nys-errormessage> and associated with the input for assistive technology

    Additional accessibility test and build content is coming soon, in a new format.


Options

The calendar popup does not appear in Safari or mobile browsers (iOS and Android). In those environments, users enter dates manually or use the native date picker provided by the operating system.

Value and form output

The value prop accepts a Date object or an ISO date string (YYYY-MM-DD). The input displays the date in MM/DD/YYYY format. Internally, the component stores and submits the value as a string in ISO format (YYYY-MM-DD).

Passing new Date("YYYY-MM-DD") to value can result in an off-by-one-day error due to UTC versus local time conversion. The component handles this internally when you pass an ISO string attribute.
Why this happens

Prefer setting the value as an ISO string attribute: <nys-datepicker value="2025-06-01">. If you must use a Date object in JavaScript, construct it with explicit year/month/day to avoid UTC shifting: new Date(2025, 5, 1).

Valid value examples

Copy Code
// Using a Date object (month is 0-indexed)
datepicker.value = new Date(2025, 5, 1); // June 1, 2025
// Using an ISO string (recommended)
datepicker.value = "2025-06-01";
Copy Code
<nys-datepicker
  label="Benefits enrollment deadline"
  value="2025-06-01"
></nys-datepicker>
Copy Code
// FormData submits the value as a string in YYYY-MM-DD format
// e.g. "2025-06-01"

Width

Set the width prop to adjust the width of the input field. Supported values:

  • md: 200px (default)
  • lg: 384px
  • full: takes the full width of the parent container
Copy Code
<div style="display: flex; flex-direction: column; gap: 16px;">
  <nys-datepicker label="Medium width" width="md"></nys-datepicker>
  <nys-datepicker label="Large width" width="lg"></nys-datepicker>
  <nys-datepicker label="Full width" width="full"></nys-datepicker>
</div>

Custom Start Date

Set startDate to open the calendar to a specific month. This is helpful when the expected date is far from today, such as a fiscal year start or a future project deadline. The value must be in YYYY-MM-DD format.

Copy Code
<nys-datepicker
  label="Fiscal year start date"
  description="Select the first day of the fiscal year"
  startDate="2026-04-01"
></nys-datepicker>

Hiding Buttons

The calendar popup includes "Today" and "Clear" buttons by default. Hide them with hideTodayButton and hideClearButton when you need users to intentionally select a specific date.

Copy Code
<nys-datepicker
  label="Court appearance date"
  hideTodayButton
  hideClearButton
></nys-datepicker>

Required

Set required to make the date field mandatory. The component displays a "Required" flag next to the label and validates on blur.

Copy Code
<nys-datepicker
  label="Application submission date"
  description="Only dates within April 4/5/2026 - 4/15/2026 are selectable"
  minDate="2026-04-05"
  maxDate="2026-04-15"
></nys-datepicker>

Optional

Set optional to display an "Optional" flag. Use this when most fields in the form are required and you need to call out the few that are not.

Copy Code
<nys-datepicker
  label="Preferred callback date"
  optional
></nys-datepicker>

Tooltip

Set tooltip to display an info icon with hover text that provides additional context about the field.

Copy Code
<nys-datepicker
  label="Inspection date"
  tooltip="The date your vehicle was last inspected by an authorized station"
></nys-datepicker>

Error Message

Set errorMessage to define custom error text. The message only appears when showError is also set. When used with required, the component automatically validates on blur and shows errors after the first interaction.

Copy Code
<nys-datepicker
  label="Permit expiration date"
  showError
  errorMessage="A valid expiration date is required to continue"
></nys-datepicker>

Disabled

Set disabled to prevent interaction. The calendar button and input are both disabled, and the field is excluded from form submission.

Copy Code
<nys-datepicker
  label="Registration date"
  disabled
  value="2025-01-15"
></nys-datepicker>

Usage

When to use this component

  • When users need to select a single calendar date, such as scheduling an appointment or choosing a filing deadline
  • When the day of the week matters and a calendar view helps users orient themselves
  • When a form requires consistent date formatting across browsers

When to consider something else

  • For familiar dates where users already know the value without a calendar, such as date of birth or document issue dates. Consider memorable date fields (currently under proposal).
  • When users need to select multiple dates or a span of time. Consider a date range component (possible version 2 of nys-datepicker).
  • When time selection is required alongside the date.

Do

  • Set the label property to clearly describe what date is being collected
  • Add description text to specify the expected format or provide context
  • Set required when the date is mandatory for form submission
  • Use startDate to open the calendar to a relevant month when the expected date is far from today
  • Pass date values as ISO strings ("YYYY-MM-DD") rather than Date objects to avoid timezone issues

Don't

  • Don't omit the label -- every datepicker needs one for accessibility
  • Don't use this component for dates users know from memory, like date of birth. A text input with separate month/day/year fields is more efficient.
  • Don't rely on the calendar popup alone -- Safari and mobile browsers use the native date picker instead
  • Don't set both required and optional on the same component
  • Don't use hideTodayButton and hideClearButton together unless users must select a specific date and should not be able to clear it

Properties

Property Type Default
id string "" (auto-generated)
name string ""
label string ""
description string ""
value string | Date | undefined undefined
width "md" | "lg" | "full" "md"
startDate string (format YYYY-MM-DD) ""
required boolean false
optional boolean false
disabled boolean false
showError boolean false
errorMessage string ""
tooltip string ""
inverted boolean false
hideTodayButton boolean false
hideClearButton boolean false
form string | null null

Form Prop

The form property associates this component with a <form> element by ID, even if the component is not a descendant of that form. See Form Patterns for details on form association and ElementInternals.


Style Overrides

There are no existing CSS variables for this component. Explore existing options, or propose a new one with a Component Proposal.


Events

The <nys-datepicker> component emits two custom JavaScript events:

  1. nys-input -- Fired when the user selects or types a valid date.
  2. nys-blur -- Fired when the input or calendar loses focus. Triggers validation.

Event details

The nys-input event includes a detail object with the following properties:

  • id (string): The id of the datepicker component.
  • value (Date): The selected date as a Date object.

The nys-blur event is a plain Event with no additional detail.

You can listen to these events using JavaScript:

Copy Code
// Select the datepicker component
const datepicker = document.querySelector("nys-datepicker");

// Listen for date selection datepicker.addEventListener("nys-input", (event) => { const { id, value } = event.detail; console.log(</span><span class="token string">Datepicker (</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">) date selected:</span><span class="token template-punctuation string">, value); });

// Listen for blur (triggers validation) datepicker.addEventListener("nys-blur", () => { console.log("Datepicker lost focus"); });

Suggest a New Component

Do you have an idea for a new NYS Design System web component? Look through the existing proposals in our GitHub discussions board to see if someone already proposed something similar. If not, feel free to submit one.