Date and date-range entry: a text field that parses typed dates, plus a calendar popover.
The qds-date-picker is designed for as-of dates, effective dates, reporting periods, and date ranges in financial applications. Typing is the primary input method; the calendar is an aid, not the input method. The value is always an ISO date string (YYYY-MM-DD), never a Date object – a Date drags a timezone into a field that has no time, and an as-of date that shifts a day in UTC is a reporting defect.
The text field accepts the display format (derived from the locale) plus unambiguous shorthand. The field shows its expected format as the placeholder (MM/DD/YYYY in en-US), so 3/7 is never a guess.
Do NOT use this component for a birth date or any date far from today – three text inputs or a typed field with no calendar is faster than paging a calendar back forty years. Do NOT use it for month or quarter selection; that wants a period picker.
<qds-date-picker label="As-of date" value="2026-03-07"></qds-date-picker>
Range mode:
<qds-date-picker
label="Reporting period"
range
min="2026-01-01"
max="2026-12-31"
name="period"
></qds-date-picker>
With shortcuts and week numbers:
<script type="module">
const dp = document.querySelector('qds-date-picker');
dp.shortcuts = [
{ label: 'Prior month end', value: '2026-02-28' },
{ label: 'YTD', value: '2026-01-01,2026-03-07' },
];
</script>
<qds-date-picker
label="As-of date"
show-week-numbers
first-day-of-week="1"
></qds-date-picker>
The text field accepts the following input formats. All are parsed on blur and the field re-renders with the canonical display format.
Type a date in the format shown by the placeholder. In en-US this is MM/DD/YYYY. In other locales the order and separator follow Intl.DateTimeFormat.
03/07/2026 – full date in display format3/7 – month/day, year defaults to the current year3/7/26 – two-digit year (00-49 = 20xx, 50-99 = 19xx)2026-03-07 – unambiguous, locale-independent03072026 – 8 digits, MMDDYYYY in en-US (or DDMMYYYY in day-first locales)7 Mar 2026 – day, abbreviated month name, year. Locale month names are tried first, English month names as a fallback.| Token | Meaning | Example (today = 2026-06-15) |
|---|---|---|
t |
Today | 2026-06-15 |
t+N |
Today plus N days | t+30 = 2026-07-15 |
t-N |
Today minus N days | t-1 = 2026-06-14 |
eom |
End of current month | 2026-06-30 |
eoq |
End of current quarter | 2026-06-30 (Q2) |
eoy |
End of current year | 2026-12-31 |
In range mode, type two dates separated by - or to:
03/07/2026 - 03/31/20263/7 to 3/31value - string, default ''. ISO date string YYYY-MM-DD.end-value - string, default ''. Range mode only; second date as YYYY-MM-DD.range - boolean, default false. Two dates in one field.min - string. ISO date; days before are disabled.max - string. ISO date; days after are disabled.first-day-of-week - number, default locale. 0 = Sunday, 1 = Monday, etc.display-format - string, default locale short. Pattern like MM/DD/YYYY.locale - string. BCP 47 locale tag.show-week-numbers - boolean, default false. ISO week numbers in a leading column.open - boolean, default false. Reflected; calendar popover visibility.placement - 'auto' | 'bottom' | 'top', default auto.name - string. Form field name.label - string. Label text.hint - string. Helper text below the field.error-text - string. Error message shown when invalid is true.size - 'sm' | 'md' | 'lg', default md.disabled - boolean, default false. Disables interaction.readonly - boolean, default false. Field holds value; no pointer or key response.required - boolean, default false. Must have a value.invalid - boolean, default false. Author-forced invalid state.clearable - boolean, default false. Renders a clear button when non-empty.validate-on - 'blur' | 'input' | 'submit', default blur.disabledDates - (iso: string) => boolean, property only. Predicate; matching days are disabled and blocked from selection.shortcuts - {label: string, value: string}[], property only. Shortcut buttons rendered in the calendar. Value can be a single ISO date or start,end for range mode.validity - QdsValidity. Read-only validity state.checkValidity() - () => boolean.reportValidity() - () => boolean.setCustomValidity(msg) - (string) => void. Empty string clears.container - Outer wrapper.label - Label text.wrapper - Input wrapper (control surface).input - The text input.calendar-button - Calendar toggle button.clear-button - Clear value button.panel - Calendar popover panel.panel-header - Calendar header (nav + label).nav-prev - Previous navigation button.nav-next - Next navigation button.month-label - Month/year label (clickable for drill-down).shortcut - A shortcut button.weekday - A weekday header cell.week-number - A week number cell.day - A day cell.day-today - Today’s day cell.day-selected - Selected day cell.day-in-range - In-range day cell (range mode).day-disabled - Disabled day cell.month-grid - Month selection grid.year-grid - Year selection grid.hint - Helper text.error - Error message.--qds-control-height-sm - Small control height. Default 32px.--qds-control-height-md - Medium control height. Default 40px.--qds-control-height-lg - Large control height. Default 48px.--qds-popover-z - Popover z-index. Default 1000.change - Date committed (typed or picked). Detail: { component, value, endValue }.input - Same moment as change; native parity. Detail: { component, value, endValue }.qds-open - Calendar opened. Detail: { component }.qds-close - Calendar closed. Detail: { component }.qds-month-change - Visible month changed. Detail: { component, year, month }.qds-validity-change - Validity transition. Detail: { component, valid, validity, message }.valueMissing when required and empty.typeMismatch when typed text does not parse.rangeUnderflow / rangeOverflow against min / max.customError for a date rejected by disabled-dates or for an inverted range – message: “End date must be on or after the start date.”One field, two dates. The display shows 03/07/2026 - 03/31/2026. First click sets the start and arms the end; second click sets the end. A second click before the start restarts the selection rather than producing an inverted range. Two months are shown side by side at 600px or wider, stacked below that. Paging moves both months by one. Hovering a candidate end previews the range.
| Key | Field | Calendar open |
|---|---|---|
| Typing | Enters a date | Passes through to the field |
ArrowDown |
Opens the calendar | +1 week |
ArrowUp |
Opens | -1 week |
ArrowLeft / ArrowRight |
Caret movement | -1 / +1 day |
PageUp / PageDown |
– | -1 / +1 month |
Shift + PageUp / PageDown |
– | -1 / +1 year |
Home / End |
Caret | First / last day of month |
Enter |
Commits typed text | Selects focused day, closes (single mode) |
Escape |
– | Closes, keeps the field value |
<qds-field label="As-of date" required hint="Enter or pick a date">
<qds-date-picker
name="asOf"
required
min="2026-01-01"
max="2026-12-31"
clearable
></qds-date-picker>
</qds-field>