Date Picker
A date input component with an integrated calendar popup for selecting single dates.
Overview
Date pickers allow users to select dates through multiple input methods. They combine a text input field with a calendar dropdown, giving users the flexibility to either manually type familiar dates or visually select dates from a calendar view. The component automatically handles date formatting and validation for manual entries, making it versatile for both quick familiar date entry and visual date selection.
Usage
forge-date-picker wraps a child text field and adds a calendar dropdown, through min/max/disabledDates/disabledDaysOfWeek, masked/maskFormat/showMaskFormat, dateFormat, shortcuts, showToday, and showClear. Use it for a single, specific date; for a start and end date together, use a date range picker instead, and for a time instead of a date, use a time picker.
Rules
Basic usage
A date picker’s text field accepts typed input and its trailing icon button opens a calendar dropdown for picking a date instead.
A date picker combining a text field with a calendar dropdown.
<forge-date-picker>
<forge-text-field>
<label for="date-picker" slot="label">
Date
</label>
<input aria-label="Pick a date" type="text" id="date-picker" autocomplete="off" placeholder autocorrect="off" autocapitalize="off" role="combobox" aria-live="assertive" aria-atomic aria-haspopup aria-owns="forge-date-picker-jrl2d" aria-controls="forge-aria-controls-placeholder">
<forge-icon-button aria-label="Toggle calendar" slot="end" density="medium">
<forge-icon name="insert_invitation">
</forge-icon>
</forge-icon-button>
</forge-text-field>
</forge-date-picker>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconInsertInvitation } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconInsertInvitation]);
</script>Date format
Set dateFormat to control how a typed or selected date is displayed in the field, independent of the calendar’s own locale. The default is MM/DD/YYYY; the built-in formats are:
MM/DD/YYYYMM/DD/YYDD/MMM/YYYYMM-DD-YYYYMM-DD-YYDD-MMM-YYYYYYYY-MM-DDYYYY-MMM-DDDD.MM.YYYYDD.MM.YY
Changing dateFormat automatically updates the input mask to match, and handles parsing/formatting for you.
A date picker with an explicit date format.
<forge-date-picker date-format="MM/DD/YYYY">
<forge-text-field>
<label for="date-picker-date-formats" slot="label">
MM/DD/YYYY
</label>
<input type="text" id="date-picker-date-formats" autocomplete="off" autocorrect="off" autocapitalize="off" role="combobox" aria-live="assertive" aria-atomic aria-haspopup aria-owns="forge-date-picker-38u9l" aria-controls="forge-aria-controls-placeholder">
<forge-icon-button aria-label="Toggle calendar" slot="end" density="medium">
<forge-icon name="insert_invitation">
</forge-icon>
</forge-icon-button>
</forge-text-field>
</forge-date-picker>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconInsertInvitation } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconInsertInvitation]);
</script>Custom mask
Set maskFormat for a non-default input mask, pair it with showMaskFormat to display that mask as a placeholder, and set shortcuts="off" to remove the default quick-entry shortcuts when they don’t make sense for a custom format.
A custom mask format shown as a placeholder, with support text describing it.
<forge-date-picker mask-format="Mmm DD, YYYY" shortcuts="off">
<forge-text-field>
<label for="date-picker" slot="label">
Date
</label>
<input type="text" id="date-picker" autocomplete="off" placeholder="Mmm DD, YYYY" autocorrect="off" autocapitalize="off" role="combobox" aria-live="assertive" aria-atomic aria-haspopup aria-owns="forge-date-picker-q1x73" aria-controls="forge-aria-controls-placeholder">
<span slot="support-text">
Enter a date in the format Mmm DD, YYYY (e.g., Jul 08, 2025)
</span>
<forge-icon-button aria-label="Toggle calendar" slot="end" density="medium">
<forge-icon name="insert_invitation">
</forge-icon>
</forge-icon-button>
</forge-text-field>
</forge-date-picker>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconInsertInvitation } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconInsertInvitation]);
const monthMap = {
Jan: 0,
Feb: 1,
Mar: 2,
Apr: 3,
May: 4,
Jun: 5,
Jul: 6,
Aug: 7,
Sep: 8,
Oct: 9,
Nov: 10,
Dec: 11
};
function parseCallback(str) {
if (!str) {
return null;
}
const match = str.match(/(\w{3}) (\d{2}), (\d{4})/);
if (!match || match.length !== 4) {
return null;
}
const monthStr = match[1];
const day = parseInt(match[2], 10);
const year = parseInt(match[3], 10);
const month = monthMap[monthStr];
if (isNaN(day) || isNaN(month) || isNaN(year)) {
return null;
}
const date = new Date(year, month, day);
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
return null;
}
return date;
}
function formatCallback(date) {
if (!date) {
return "";
}
return new Intl.DateTimeFormat("en-US", { month: "short", day: "2-digit", year: "numeric" }).format(date);
}
const datePicker = document.querySelector("forge-date-picker");
if (datePicker) {
datePicker.parseCallback = parseCallback;
datePicker.formatCallback = formatCallback;
}
</script>For a format that isn’t one of the built-in options, pair maskFormat with parseCallback/formatCallback to take over parsing and formatting entirely. maskFormat supports these segment tokens: Mmm (Jan), MMM (JAN), DD, YYYY, and YY.
dateInput.maskFormat = "Mmm DD, YYYY";
dateInput.parseCallback = (str) => {
const match = str.match(/(\w{3}) (\d{2}), (\d{4})/);
if (!match) return null;
const [, monthStr, day, year] = match;
const month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].indexOf(monthStr);
return new Date(Number(year), month, Number(day));
};
dateInput.formatCallback = (date) =>
date ? new Intl.DateTimeFormat("en-US", { month: "short", day: "2-digit", year: "numeric" }).format(date) : "";
Constraints
Set min, max, and disabledDaysOfWeek to bound selectable dates and exclude specific days, such as weekends.
A date picker bounded to a range, with weekends disabled.
<forge-date-picker min="2026-01-01" max="2026-12-31" disabled-days-of-week="0,6">
<forge-text-field>
<label for="date-picker-constrained">
Appointment date
</label>
<input type="text" id="date-picker-constrained" />
</forge-text-field>
</forge-date-picker>Shortcuts, today, and clear
Set showToday and showClear to add dedicated shortcuts to the calendar dropdown, alongside the default quick-entry shortcuts.
Shortcuts for today and a clear button, alongside the default quick-entry shortcuts.
<forge-date-picker show-today show-clear>
<forge-text-field>
<label for="date-picker-shortcuts">
Choose date
</label>
<input type="text" id="date-picker-shortcuts" />
</forge-text-field>
</forge-date-picker>The date picker ships one default quick-entry shortcut — typing t jumps to today. Set shortcuts="off" to remove it, or set the shortcuts property to your own map of key names to callbacks that return a Date given the current date:
dateInput.shortcuts = {
t: (currentDate) => new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()),
y: (currentDate) => new Date(currentDate.getFullYear(), 0, 1),
e: (currentDate) => new Date(currentDate.getFullYear(), 11, 31),
};
Disabled
Set disabled to prevent typing or opening the calendar dropdown.
A disabled date picker.
<forge-date-picker disabled>
<forge-text-field disabled>
<label for="date-picker-disabled">
Choose date
</label>
<input type="text" id="date-picker-disabled" />
</forge-text-field>
</forge-date-picker>A date input component with an integrated calendar popup for selecting single dates.
import "@tylertech/forge/date-picker";| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value | value | string | — | The value of the date picker. |
min | min | string | — | The minimum date the calendar will allow. |
max | max | string | — | The maximum date the calendar will allow. |
disabledDates | — | Date | Date[] | null | undefined | — | The dates that are restricted from being selected. |
open | open | boolean | false | Whether the calendar dropdown is open. |
popupClasses | popup-classes | string | — | The CSS classes that are applied to the popup element. |
disabled | disabled | boolean | false | Whether the date picker is disabled or not. |
masked | masked | boolean | false | Whether the input mask is applied or not. |
maskFormat | mask-format | string | MM/DD/YYYY | The mask format that displayed in the input. |
showMaskFormat | show-mask-format | boolean | false | Whether the mask format is displayed in the input or not. Only applies if `masked` is `true`. |
dateFormat | date-format | DatePickerDateFormat | MM/DD/YYYY | The date format to use for the date picker. |
valueMode | value-mode | DatePickerValueMode | string | The type for the `value` property and `forge-date-picker-change` event. |
shortcuts | shortcuts | DatePickerShortcuts | — | When specifies as an attribute you can only use the `off` value to disable shortcuts. Otherwise, you can use the `shortcuts` property to set your own shortcuts. |
notifyInputValueChanges | — | boolean | false | Whether the native input will be notified of value changes via the `input` and `change` events. |
allowInvalidDate | allow-invalid-date | boolean | false | Whether to allow an invalid date to be input. When true, the date picker will not clear out the value of the input if the date was invalid (i.e. could not be parsed). |
showToday | show-today | boolean | false | Whether the today button is visible in the popup. |
showClear | show-clear | boolean | false | Whether the clear button is visible in the popup. |
parseCallback | — | DatePickerParseCallback | — | The callback to use for parsing a date value string to a `Date` object. |
formatCallback | — | DatePickerFormatCallback | — | The callback to use for formatting `Date` value to a custom string format. |
prepareMaskCallback | — | DatePickerPrepareMaskCallback | — | The callback to use when altering default mask entry. |
disabledDaysOfWeek | disabled-days-of-week | string | — | The days of the week to disable from selection. |
disableDayCallback | — | (date: Date) => boolean | — | The callback to use for testing whether a specific date should be disabled or not. |
yearRange | year-range | string | — | The year range. |
locale | locale | string | — | The locale to use. |
calendarText | calendar-text | DatePickerCalendarDropdownText | — | Customized strings to display in the calendar dropdown UI. |
| Name | Type | Description |
|---|---|---|
forge-date-picker-change | CustomEvent<Date | string | null> | Emits when the value of the date picker changes. |
forge-date-picker-open | CustomEvent<void> | Emits when the date picker opens. |
forge-date-picker-close | CustomEvent<void> | Emits when the date picker closes. |
forge-date-picker-input | CustomEvent<string> | Emits when the user inputs a value into the date picker. |
Screen reader behavior
Verify that keyboard navigation within the calendar popup is announced by a screen reader as the user moves between days.
The date picker automatically applies aria-live, aria-atomic, aria-haspopup, aria-expanded, aria-owns, and aria-disabled to its <input> for you. You’re still responsible for adding an aria-label to the input if it doesn’t have an associated <label> element.