Date Picker
Date Picker selects a single calendar day, a date range (type="daterange"), a date-time (type="datetime"), a date-time range (type="datetimerange"), a calendar month (type="month"), or a calendar year (type="year"). The trigger matches Input sizing and chrome and uses a fixed width so empty and filled text do not resize the control (14rem for date / month / year, 16.5rem for datetime, 22rem for daterange, 28rem for datetimerange; overflow ellipsizes). The panel portals to document.body. At viewport widths of 640px or less, the panel opens as a bottom sheet with a backdrop instead of an anchored popup. Day panels show an editable date field. Datetime types use a time button that opens an hour, then minute, then second grid (the same drill-down as year / month, not scroll columns). Each day-calendar header’s year and month labels open those panels: picking a year continues to months, and picking a month returns to the day grid. On type="month", the year label opens the year panel, then a month cell commits. Range types use dual-month calendars (left month = view; right = next month) with << / < / year / month / > / >> navigation per calendar.
type="date" commits on day click (Clear / Now). daterange and datetimerange commit and close when the end date is picked (order is normalized); Confirm remains for typed date fields but is not required after the second click. datetime stays a draft until Confirm (Clear / Now commit immediately). Default range display separator is → (override with separator).
Breaking changes
- Trigger width is fixed per
type, so the input no longer grows or shrinks with the value. daterange/datetimerange: the second day click commits the range and closes. Confirm is optional.- Year / month: click the header year or month to open that panel and finish the pick.
- Datetime time: click the time field to open the time panel (hour → minute → second).
separatordefault:' → '.
Demos
Basic
value (ISO YYYY-MM-DD) and listen for input with e.detail.value. The panel shows an editable date field plus a single-month calendar; clicking a day commits and closes. Use Clear and Now in the panel footer. Value: 2026-09-17
Range
type="daterange" and bind :value to [start, end] | null. The panel shows start/end date fields and **dual-month** calendars. Two clicks pick start then end (order is normalized) and the range **fills in without Confirm**. Footer: Clear + optional Confirm (no Now). Trigger display uses the default separator → between dates. [ "2026-09-01", "2026-09-17" ]
Datetime
type="datetime" and bind value as local YYYY-MM-DD HH:mm:ss (or empty). The date field and calendar edit a draft; click the time field to open the time panel (hour, then minute, then second). Confirm commits (Clear / Now commit immediately). Value: 2026-09-17 08:00:00
Datetimerange
type="datetimerange" and bind :value to [start, end] | null (each string YYYY-MM-DD HH:mm:ss). **Dual-month** calendars plus start/end dates; time fields open the same time panel. The second day click commits and closes (no Confirm required). Footer: Clear + optional Confirm. [ "2026-09-01 09:00:00", "2026-09-17 18:00:00" ]
Month
type="month" and bind value as YYYY-MM (or empty). The panel shows a 12-month grid; click the year label to open the year panel, then pick a month to commit and close. Default display format is yyyy-MM. Panel actions: Clear / Now (no Confirm). Value: 2026-09
Year
type="year" and bind value as four-digit YYYY (or empty). The panel shows a page of years with prev/next page controls; picking a year commits and closes. Default format is yyyy. Panel actions: Clear / Now. Value: 2026
Size
sm, md, and lg. Clearable
clearable shows a clear control on the trigger when the value is non-empty and the field is interactive. The panel footer also exposes Clear (and Now or Confirm depending on type). Status / round
status; set round for a pill trigger. Disabled / isDateDisabled
disabled blocks the whole control. isDateDisabled is a JS property (iso: string) => boolean that greys out days (and can block Now). API
Date Picker Props
| Prop | Type | Default |
|---|---|---|
type | 'date' | 'daterange' | 'datetime' | 'datetimerange' | 'month' | 'year' | 'date' |
value | string | [string, string] | null | '' / null |
format | string | 'yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss' (datetime types), 'yyyy-MM' (month), or 'yyyy' (year) |
separator | string | ' → ' |
start-placeholder | string | '' |
end-placeholder | string | '' |
size | 'sm' | 'md' | 'lg' | 'md' |
placeholder | string | '' |
disabled | boolean | false |
clearable | boolean | false |
round | boolean | false |
status | 'success' | 'warning' | 'error' | '' | '' |
open | boolean | false |
locale | 'en' | 'zh-TW' | 'en' |
isDateDisabled | (iso: string) => boolean | — |
For type="date", value is ISO YYYY-MM-DD or empty string. For type="daterange", value is [start, end] | null (each YYYY-MM-DD). For type="datetime", value is local YYYY-MM-DD HH:mm:ss or empty string. For type="datetimerange", value is [start, end] | null (each YYYY-MM-DD HH:mm:ss). For type="month", value is YYYY-MM or empty string. For type="year", value is four-digit YYYY or empty string. Prefer :value property binding; range attributes may be a JSON array. format only affects trigger display: date types use yyyy MM dd; datetime types also support HH mm ss; month uses yyyy MM; year uses yyyy. Default format is coerced when type changes: yyyy-MM-dd HH:mm:ss for datetime / datetimerange, yyyy-MM for month, yyyy for year (from the date default yyyy-MM-dd). separator (default ' → ') and start-placeholder / end-placeholder apply to range trigger display and panel field separators (placeholders fall back to placeholder when empty). isDateDisabled is property-only (not an HTML attribute): for day types it receives YYYY-MM-DD; for month, YYYY-MM; for year, YYYY. Date panel fields parse on blur/Enter (YYYY-MM-DD); invalid text reverts. Header year / month open drill-down panels. The datetime time control opens an hour → minute → second panel. daterange / datetimerange commit when the end day is picked. Confirm still commits a datetime draft (and typed range fields). Now and Clear commit immediately where shown. date / month / year commit on cell click (plus Clear / Now in the footer). Footer actions: date / month / year → Clear / Now; datetime → Clear / Now / Confirm; daterange / datetimerange → Clear / Confirm. The trigger width is fixed per type so empty and filled values do not change layout.
Date Picker Events
| Name | Description |
|---|---|
input | Value changed (select / clear / now / confirm); bubbles; composed: true; detail.value is string for date, datetime, month, and year, [string, string] | null for daterange and datetimerange |
change | Same commits as input; bubbles; composed: true; detail.value matches input |
gk-open-change | Panel open state changed; bubbles; composed: true; detail: { open: boolean } |
CSS Parts
Trigger parts are exposable via gk-date-picker::part(...). The panel is portaled to document.body, so panel / calendar / actions are not reachable as gk-date-picker::part(panel) (etc.). Style the popup with .gk-date-picker-panel and its descendants (those nodes may still carry part attributes for targeting under that class).
| Part | Description |
|---|---|
base | Trigger surface (::part) |
input | Readonly display text (::part) |
suffix | Clear + calendar icon area (::part) |
clear | Trigger clear button (::part) |
panel | Portaled popup root — style via .gk-date-picker-panel |
panel-fields | Date inputs and time buttons at the top of day panels — under .gk-date-picker-panel |
calendar | Month grid region (dual grids for range types) — under .gk-date-picker-panel |
confirm | Confirm button — under .gk-date-picker-panel |
actions | Clear / Now / Confirm row (varies by type) — under .gk-date-picker-panel |