Date Picker
Form-associated date input wrapping the native calendar UI. A Lit Web Component migrated from the Angular esa-date-picker.
Preview
<esa-date-picker label="Event date" help-text="Pick any day"></esa-date-picker> Sizes
<esa-date-picker label="Extra small" size="xs"></esa-date-picker>
<esa-date-picker label="Small" size="sm"></esa-date-picker>
<esa-date-picker label="Medium" size="md"></esa-date-picker>
<esa-date-picker label="Large" size="lg"></esa-date-picker> States
Constrain selectable days with min/max. Preset, required, error, and disabled states are attribute-driven.
<esa-date-picker label="Within 2026" min="2026-01-01" max="2026-12-31"></esa-date-picker>
<esa-date-picker label="Preset value" value="2026-06-03"></esa-date-picker>
<esa-date-picker label="Required" required></esa-date-picker>
<esa-date-picker label="Error" error-text="Date is required"></esa-date-picker>
<esa-date-picker label="Disabled" disabled value="2026-06-03"></esa-date-picker> API
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | '' | Field label above the input. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'md' | Control size (reflected attribute). |
value | string | '' | ISO date value (YYYY-MM-DD). |
min | string | '' | Earliest selectable date (YYYY-MM-DD). |
max | string | '' | Latest selectable date (YYYY-MM-DD). |
placeholder | string | 'Select date...' | Placeholder text. |
help-text | string | '' | Helper text below the input. |
error-text | string | '' | Error message; sets the error state when present. |
required | boolean | false | Marks the field required (renders a * after the label). |
disabled | boolean | false | Disables interaction (reflected attribute). |
Events
| Event | Type | Default | Description |
|---|---|---|---|
change | CustomEvent<{ value: string }> | — | Fired on input. Value is an ISO YYYY-MM-DD string. Composed and bubbles. |
Accessibility
- Renders a native
<input type="date">— the browser supplies the calendar and full keyboard handling. - The input is labelled via
aria-label(falls back to "Date" when no label is set). min/maxmap to native input bounds, blocking out-of-range selection.- Form-associated via
ElementInternals— value submits with the enclosing form.
Theming surface
Every public token this component reads, extracted from its source at build time.
The Resolves to column walks each token's real lineage —
component → semantic → primitive → raw value — so you
can see exactly where re-pointing it lands. A spoke re-skins by overriding these in
its theme-<slug>.css; component internals are never edited. No
hook for what you need? File it with /request-lego.
| Token | Tier | Resolves to |
|---|---|---|
--focus-ring-color | component | #65ba74 via --color-border-focus → --color-grass-8 |
--focus-ring-width | component | 2px |
--form-bg | component | #fcfcfc via --color-surface → --color-gray-1 |
--form-bg-disabled | component | #f0f0f0 via --color-disabled-bg → --color-gray-3 |
--form-border-color | component | #cecece via --color-border → --color-gray-7 |
--form-border-color-error | component | #e5484d via --color-danger → --color-red-9 |
--form-border-color-focus | component | #65ba74 via --color-border-focus → --color-grass-8 |
--form-border-width | component | 1px |
--form-error-color | component | #ce2c31 via --color-danger-strong → --color-red-11 |
--form-font-size-lg | component | clamp(0.875rem, 0.77rem + 0.52vw, 1.125rem) via --type-size-300 |
--form-font-size-md | component | clamp(0.75rem, 0.66rem + 0.44vw, 0.9375rem) via --type-size-200 |
--form-font-size-sm | component | clamp(0.625rem, 0.56rem + 0.32vw, 0.75rem) via --type-size-100 |
--form-font-size-xs | component | clamp(0.5rem, 0.44rem + 0.3vw, 0.625rem) via --type-size-050 |
--form-height-lg | component | 48px |
--form-height-md | component | 40px |
--form-height-sm | component | 32px |
--form-height-xs | component | 28px |
--form-help-color | component | #838383 via --color-text-muted → --color-gray-10 |
--form-label-color | component | #646464 via --color-text-secondary → --color-gray-11 |
--form-padding-x-lg | component | 1rem via --spacing-400 |
--form-padding-x-md | component | 0.75rem via --spacing-300 |
--form-padding-x-sm | component | 0.625rem via --spacing-250 |
--form-padding-x-xs | component | 0.5rem via --spacing-200 |
--form-padding-y-lg | component | 0.75rem via --spacing-300 |
--form-padding-y-md | component | 0.5rem via --spacing-200 |
--form-padding-y-sm | component | 0.375rem via --spacing-150 |
--form-padding-y-xs | component | 0.25rem via --spacing-100 |
--form-radius-lg | component | 0.5rem via --radius-200 |
--form-radius-md | component | 0.5rem via --radius-200 |
--form-radius-sm | component | 0.25rem via --radius-100 |
--form-radius-xs | component | 0.25rem via --radius-100 |
--form-text-color | component | #202020 via --color-text-primary → --color-gray-12 |
--color-danger | semantic | #e5484d via --color-red-9 |
--color-danger-border | semantic | #fdbdbe via --color-red-6 |
--font-sans | semantic | 'DM Sans', sans-serif |
--transition-fast | semantic | 150ms ease |
--type-size-150 | semantic | clamp(0.6875rem, 0.61rem + 0.38vw, 0.875rem) |
--font-weight-medium | primitive | 500 |
--spacing-100 | primitive | 0.25rem |