md-date-picker spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
A Material Design 3 date picker implementing the MD3 Date Pickers specification:
Pick a single calendar date through one of three presentations:
modal-input (default) — outlined text field with a trailing calendar
icon that opens a modal calendar dialog. Best for typed-or-pointed entry on
any viewport.modal — a bare modal dialog with no inline trigger; surface it from
your own button via el.show() or two-way open binding.docked — outlined text field that pops a calendar directly beneath the
input. Best for desktop forms where the calendar can stay on screen. Its header
uses month and year dropdown menu buttons, each flanked by prev/next
chevron icon buttons (‹ [Aug ▾] › ‹ [2025 ▾] ›), and a Cancel / OK action
row commits the staged selection.Inside the modal, a header toggle flips the calendar to a typed date-input view (the MD3 “modal date input” pattern), which parses and validates entered dates and shows inline errors.
Calendar navigation is keyboard-first, fully ARIA-labelled, locale-aware via the
Intl.DateTimeFormat / Intl.Locale APIs (including locale-driven
first-day-of-week), and renders correctly in RTL.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker style="min-width: 280px;"></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker style={{ minWidth: '280px' }}></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker style="min-width: 280px;"></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker style="min-width: 280px;"></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<md-date-picker style="min-width: 280px;"></md-date-picker>
Already installed? See the
Installation guide for one-time package setup
(core + tokens, fonts). Each tab below shows two patterns for using
md-date-picker in your project: Option A registers every AWC UI
component at once (simplest), Option B imports only this component for
tree-shake-friendly bundles.
<!-- ─── Option A: global registration (all components) ─── -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- ─── Option B: single import (tree-shake only md-date-picker) ─── -->
<script type="module">
import '@awc-ui/core/components/md-date-picker';
</script>
<md-date-picker></md-date-picker>// ─── Option A: typed React wrapper (registers all components) ───
// Importing from '@awc-ui/react' calls defineCustomElements() as a
// side effect, so every md-* element becomes available in the browser.
import { MdDatePicker } from '@awc-ui/react';
export function Example() {
return <MdDatePicker></MdDatePicker>;
}
// ─── Option B: single import (tree-shake to only md-date-picker) ───
// Skip the wrapper and use the raw custom element. Smallest bundle,
// but you lose typed props/events on JSX.
import '@awc-ui/core/components/md-date-picker';
export function ExampleTreeShaken() {
return <md-date-picker></md-date-picker>;
}// ─── Option A: schema module (any md-* element accepted) ───
// Pair with `defineCustomElements(window)` in main.ts.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<md-date-picker></md-date-picker>`,
})
export class ExampleComponent {}
// ─── Option B: typed directive (tree-shake friendly) ───
// Pair with `import '@awc-ui/core/components/md-date-picker'` in main.ts.
import { Component } from '@angular/core';
import { MdDatePicker } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [MdDatePicker],
template: `<md-date-picker></md-date-picker>`,
})
export class ExampleTreeShakenComponent {}<!-- ─── Option A: typed Vue wrapper (registers all components) ─── -->
<script setup lang="ts">
import { MdDatePicker } from '@awc-ui/vue';
</script>
<template>
<MdDatePicker></MdDatePicker>
</template>
<!-- ─── Option B: single import (tree-shake to only md-date-picker) ─── -->
<script setup lang="ts">
import '@awc-ui/core/components/md-date-picker';
</script>
<template>
<md-date-picker></md-date-picker>
</template><!-- ─── Option A: global registration (done once in main entry) ─── -->
<!-- main.ts: -->
<!-- import { defineCustomElements } from '@awc-ui/svelte'; -->
<!-- defineCustomElements(window); -->
<md-date-picker></md-date-picker>
<!-- ─── Option B: single import (tree-shake to only md-date-picker) ─── -->
<script lang="ts">
import '@awc-ui/core/components/md-date-picker';
</script>
<md-date-picker></md-date-picker>| Situation | Use instead |
|---|---|
| A time of day | md-time-picker |
| A date very close to today | A few md-chip shortcuts (“Today”, “Tomorrow”) |
| A free-form string | md-text-field |
| Choosing from a fixed list | md-select |
| Need | Setting |
|---|---|
| Field plus modal calendar | variant="modal-input" (default) |
| A bare dialog you open yourself | variant="modal" + show() |
| Calendar under the field, desktop forms | variant="docked" |
| Restrict the range | min / max, or isDateDisabled for gaps |
| A clear affordance | clearable |
| Filled field instead of outlined | field-variant="filled" |
| Force a locale | locale, else the document’s |
| Compact panel | density="-1…-4" |
| One-click picking, no confirm step | commit-on-select |
| Keep a docked panel open on click-away | outside-click-dismissible="false" |
| Keep a modal open when the scrim is clicked | scrim-dismissible="false" |
| Variant | Trigger | Surface | Commit behavior | Use case |
|---|---|---|---|---|
modal-input | Outlined text field | Centered modal dialog | OK button | General-purpose date entry |
modal | None (show()) | Centered modal dialog | OK button | Surfaced from a custom trigger |
docked | Outlined text field | Popup beneath the field | OK button | Desktop forms |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker label="Due date"></md-date-picker>
<md-date-picker variant="docked" label="Due date"></md-date-picker>
<md-date-picker field-variant="filled" label="Due date"></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker label="Due date"></MdDatePicker>
<MdDatePicker variant="docked" label="Due date"></MdDatePicker>
<MdDatePicker fieldVariant="filled" label="Due date"></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker label="Due date"></md-date-picker>
<md-date-picker variant="docked" label="Due date"></md-date-picker>
<md-date-picker field-variant="filled" label="Due date"></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker label="Due date"></md-date-picker>
<md-date-picker variant="docked" label="Due date"></md-date-picker>
<md-date-picker field-variant="filled" label="Due date"></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<md-date-picker label="Due date"></md-date-picker>
<md-date-picker variant="docked" label="Due date"></md-date-picker>
<md-date-picker field-variant="filled" label="Due date"></md-date-picker>The docked variant follows the MD3 docked date-picker anatomy:
md-text-field
(variant="outlined", label="Date", supporting text MM/DD/YYYY) with a
trailing md-icon-button calendar toggle that opens the calendar.month-menu-button) — opens a baseline md-menu
with md-menu-item radio checks on the left; the day grid is hidden until
a month is chosen.year-menu-button) — same pattern for years in the
min/max range; scrollable list, day grid hidden while open.md-icon-button prev/next chevrons flank each menu button
(prev-month-button / next-month-button, prev-year-button /
next-year-button) and step the view by one month / year. Chevrons mirror in
RTL. Each chevron is wrapped in md-tooltip showing the action and its
keyboard shortcut (e.g. “Previous year (Shift+Page Up)”). The tooltip sets
aria-description on the trigger so screen readers announce the shortcut on
focus. The menu buttons expose Shift+M / Shift+Y shortcuts (via
md-tooltip) to jump from the day grid into the month / year listboxes.
Each unit is both cyclable (chevrons) and selectable (dropdown).day-unselected) — plain in-month day text.day-today) — outlined circle ring.day-outside) — muted adjacent-month day.day-selected) — filled circle.panel) — corner-large elevated surface.<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker
variant="docked"
label="Date"
supporting-text="MM/DD/YYYY"
></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker
variant="docked"
label="Date"
supportingText="MM/DD/YYYY"
></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker
variant="docked"
label="Date"
supporting-text="MM/DD/YYYY"
></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker
variant="docked"
label="Date"
supporting-text="MM/DD/YYYY"
></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<md-date-picker
variant="docked"
label="Date"
supporting-text="MM/DD/YYYY"
></md-date-picker>Month/year selection uses the shared md-menu / md-menu-item baseline
menu (type="radio", check-position="start"). Arrow keys, Home/End, Enter,
and Space follow md-menu roving focus; Escape closes the menu and restores
the day grid.
error + error-text paint the field and helper text with the
error color; the input is marked aria-invalid.disabled removes the field from the tab order and blocks
interaction.<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Empty" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Populated" value="2026-08-17" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Supporting" supporting-text="DD/MM/YYYY" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Error" error error-text="Date is in the past" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Disabled" disabled style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Clearable" value="2026-08-17" clearable style="min-width: 220px;"></md-date-picker>
</div>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdDatePicker label="Empty" style={{ minWidth: '220px' }}></MdDatePicker>
<MdDatePicker label="Populated" value="2026-08-17" style={{ minWidth: '220px' }}></MdDatePicker>
<MdDatePicker label="Supporting" supportingText="DD/MM/YYYY" style={{ minWidth: '220px' }}></MdDatePicker>
<MdDatePicker label="Error" error errorText="Date is in the past" style={{ minWidth: '220px' }}></MdDatePicker>
<MdDatePicker label="Disabled" disabled style={{ minWidth: '220px' }}></MdDatePicker>
<MdDatePicker label="Clearable" value="2026-08-17" clearable style={{ minWidth: '220px' }}></MdDatePicker>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Empty" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Populated" value="2026-08-17" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Supporting" supporting-text="DD/MM/YYYY" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Error" error error-text="Date is in the past" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Disabled" disabled style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Clearable" value="2026-08-17" clearable style="min-width: 220px;"></md-date-picker>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Empty" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Populated" value="2026-08-17" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Supporting" supporting-text="DD/MM/YYYY" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Error" error error-text="Date is in the past" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Disabled" disabled style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Clearable" value="2026-08-17" clearable style="min-width: 220px;"></md-date-picker>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Empty" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Populated" value="2026-08-17" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Supporting" supporting-text="DD/MM/YYYY" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Error" error error-text="Date is in the past" style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Disabled" disabled style="min-width: 220px;"></md-date-picker>
<md-date-picker label="Clearable" value="2026-08-17" clearable style="min-width: 220px;"></md-date-picker>
</div>Typed entry (no input masks) — modal-input and docked text fields do
not insert separators or reformat while typing. The raw characters you type are
preserved until you commit with Enter or by leaving the field (blur).
On commit the value is parsed flexibly (slashes, dashes, dots, or spaces when
date-separator is unset; only the configured separator when set; optional
leading zeros; compact digit strings such as 06122025 or 6122025) and
reformatted for the configured locale and date-separator. Ambiguous
month/day order (e.g. 06/12/2025 or 12062025) is resolved with day-first
heuristics when a segment exceeds 12, otherwise the locale hint applies. The
value prop and mdChange / mdSelected events always use ISO
YYYY-MM-DD. This avoids mid-keystroke mutations that confuse screen readers
and voice dictation.
Trigger input exposes aria-haspopup="dialog" and aria-expanded.
Dialog uses role="dialog" + aria-modal="true", traps Tab focus, closes on
Escape, and restores focus to the trigger on close.
Calendar uses role="grid" with a presentational weekday row (aria-hidden)
and role="gridcell" day buttons using roving tabindex; each day
exposes a full localized aria-label and aria-selected. Today is
aria-current="date". Weekday abbreviations rely on locale convention for
assistive technology; sighted users see the full weekday name in an
md-tooltip on hover (weekdays are not focusable).
Day-grid keyboard shortcuts (modal, modal-input, and docked variants):
| Key | Action |
|---|---|
| Arrow keys | Move one day (left/right) or one week (up/down) |
| Home | First day of the focused month |
| End | Last day of the focused month |
| Page Up / Page Down | Same calendar day in the previous / next month (clamped, e.g. Jan 31 → Feb 28) |
| Shift+Page Up / Shift+Page Down | Same calendar day in the previous / next year |
| Shift+M (docked only) | Open the month list and move focus into it |
| Shift+Y (docked only) | Open the year list and move focus into it |
| Enter | Select the focused day, commit, and close (single variants) |
| Space | Select the focused day (staged until OK in single variants) |
| Escape | Dismiss without committing |
Shortcuts are handled at the panel level while the picker is open, so they work when focus is anywhere inside the calendar panel (day grid, nav chevrons, docked month/year buttons, or action row) — not only on a focused day cell.
On keyboards without dedicated Page Up / Page Down keys (many Mac laptops),
use Fn+↑ / Fn+↓ for Page Up / Page Down (browsers report these as
PageUp / PageDown). Some Mac layouts also emit Option+↑ /
Option+↓ instead — the picker maps those to the same month navigation.
Tooltips and aria-description text use the Page Up / Page Down labels
per the MD3 spec. Shift+M / Shift+Y use Shift + the letter key
(m / y, case-insensitive); they work from the day grid, nav controls, and
the docked trigger field while the panel is open.
Month/year nav chevrons (docked and modal) expose md-tooltip hints on
hover and focus with the matching shortcut: Page Up / Page Down for
month, Shift+Page Up / Shift+Page Down for year. Screen readers receive
the shortcut via aria-description on the trigger (set by md-tooltip).
Docked month/year menu buttons expose Shift+M / Shift+Y via
md-tooltip aria-description. The truncated month label (e.g. Aug)
shows the full month name in the tooltip on hover and keyboard focus.
Docked month/year dropdown menus use the shared md-menu baseline list;
Arrow Up/Down, Home/End, Enter/Space to select, and Escape to close
(returning focus to the menu button).
Tested with axe-core — zero WCAG 2.1 AA violations.
The locale prop drives Intl formatting only — month and weekday names,
date display order, first day of week, and typed-input format hints. It does
not auto-translate button labels, headlines, tooltips, or other static UI
copy; pass explicit *-label attributes for non-English locales.
| UI string | Prop | HTML attribute |
|---|---|---|
| Field / dialog label | label | label |
| Header supporting text | headline | headline |
| Large headline (no date staged) | selectDateLabel | select-date-label |
| Large headline (typed-entry mode) | enterDatesLabel | enter-dates-label |
| Cancel button | cancelLabel | cancel-label |
| OK button | okLabel | ok-label |
| Invalid typed date error | invalidDateLabel | invalid-date-label |
md-tooltip)Tooltip visible text reuses the same *-label props as aria-label on each
control. Keyboard shortcut suffixes (Page Up, Shift+M, etc.) are appended
in English and are not localized.
| Control | aria-label prop | Tooltip pattern |
|---|---|---|
| Previous / next month chevron | previousMonthLabel / nextMonthLabel | {label} (Page Up) or (Page Down) |
| Previous / next year chevron (docked) | previousYearLabel / nextYearLabel | {label} (Shift+Page Up) or (Shift+Page Down) |
| Docked month menu button | chooseMonthLabel | {fullMonth} · {label} (Shift+M) |
| Docked year menu button | chooseYearLabel | {label} (Shift+Y) |
| Modal month/year toggle | chooseMonthYearLabel | {monthYear} · {chooseMonthAndYearLabel} |
| Calendar / text mode toggle | toggleCalendarLabel / toggleTextLabel | Same as aria-label |
| Calendar trigger icon | openCalendarLabel / closeCalendarLabel | aria-label only (no tooltip) |
Weekday column headers show locale-formatted full weekday names via
md-tooltip (derived from locale, not overridable).
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker
label="日付"
locale="ja-JP"
headline="日付を選択"
select-date-label="日付を選択"
enter-dates-label="日付を入力"
cancel-label="キャンセル"
ok-label="OK"
previous-month-label="前の月"
next-month-label="次の月"
previous-year-label="前の年"
next-year-label="次の年"
choose-month-label="月を選択"
choose-year-label="年を選択"
choose-month-year-label="月と年を選択"
choose-month-and-year-label="月と年を選択"
toggle-calendar-label="カレンダー入力に切り替え"
toggle-text-label="テキスト入力に切り替え"
open-calendar-label="カレンダーを開く"
close-calendar-label="カレンダーを閉じる"
year-grid-label="年"
value="2025-06-15"
></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker
label="日付"
locale="ja-JP"
headline="日付を選択"
selectDateLabel="日付を選択"
enterDatesLabel="日付を入力"
cancelLabel="キャンセル"
okLabel="OK"
previousMonthLabel="前の月"
nextMonthLabel="次の月"
previousYearLabel="前の年"
nextYearLabel="次の年"
chooseMonthLabel="月を選択"
chooseYearLabel="年を選択"
chooseMonthYearLabel="月と年を選択"
chooseMonthAndYearLabel="月と年を選択"
toggleCalendarLabel="カレンダー入力に切り替え"
toggleTextLabel="テキスト入力に切り替え"
openCalendarLabel="カレンダーを開く"
closeCalendarLabel="カレンダーを閉じる"
yearGridLabel="年"
value="2025-06-15"
></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker
label="日付"
locale="ja-JP"
headline="日付を選択"
select-date-label="日付を選択"
enter-dates-label="日付を入力"
cancel-label="キャンセル"
ok-label="OK"
previous-month-label="前の月"
next-month-label="次の月"
previous-year-label="前の年"
next-year-label="次の年"
choose-month-label="月を選択"
choose-year-label="年を選択"
choose-month-year-label="月と年を選択"
choose-month-and-year-label="月と年を選択"
toggle-calendar-label="カレンダー入力に切り替え"
toggle-text-label="テキスト入力に切り替え"
open-calendar-label="カレンダーを開く"
close-calendar-label="カレンダーを閉じる"
year-grid-label="年"
value="2025-06-15"
></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker
label="日付"
locale="ja-JP"
headline="日付を選択"
select-date-label="日付を選択"
enter-dates-label="日付を入力"
cancel-label="キャンセル"
ok-label="OK"
previous-month-label="前の月"
next-month-label="次の月"
previous-year-label="前の年"
next-year-label="次の年"
choose-month-label="月を選択"
choose-year-label="年を選択"
choose-month-year-label="月と年を選択"
choose-month-and-year-label="月と年を選択"
toggle-calendar-label="カレンダー入力に切り替え"
toggle-text-label="テキスト入力に切り替え"
open-calendar-label="カレンダーを開く"
close-calendar-label="カレンダーを閉じる"
year-grid-label="年"
value="2025-06-15"
></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<md-date-picker
label="日付"
locale="ja-JP"
headline="日付を選択"
select-date-label="日付を選択"
enter-dates-label="日付を入力"
cancel-label="キャンセル"
ok-label="OK"
previous-month-label="前の月"
next-month-label="次の月"
previous-year-label="前の年"
next-year-label="次の年"
choose-month-label="月を選択"
choose-year-label="年を選択"
choose-month-year-label="月と年を選択"
choose-month-and-year-label="月と年を選択"
toggle-calendar-label="カレンダー入力に切り替え"
toggle-text-label="テキスト入力に切り替え"
open-calendar-label="カレンダーを開く"
close-calendar-label="カレンダーを閉じる"
year-grid-label="年"
value="2025-06-15"
></md-date-picker>RTL — every box metric is a logical property. The previous/next month and year chevrons mirror automatically, and the docked month/year menus anchor to the inline-start edge of their buttons. See RTL.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<div dir="ltr"><md-date-picker label="Date" style="min-width: 240px;"></md-date-picker></div>
<div dir="rtl"><md-date-picker locale="ar" label="التاريخ" style="min-width: 240px;"></md-date-picker></div>
</div>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<div dir="ltr"><MdDatePicker label="Date" style={{ minWidth: '240px' }}></MdDatePicker></div>
<div dir="rtl"><MdDatePicker locale="ar" label="التاريخ" style={{ minWidth: '240px' }}></MdDatePicker></div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<div dir="ltr"><md-date-picker label="Date" style="min-width: 240px;"></md-date-picker></div>
<div dir="rtl"><md-date-picker locale="ar" label="التاريخ" style="min-width: 240px;"></md-date-picker></div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<div dir="ltr"><md-date-picker label="Date" style="min-width: 240px;"></md-date-picker></div>
<div dir="rtl"><md-date-picker locale="ar" label="التاريخ" style="min-width: 240px;"></md-date-picker></div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<div dir="ltr"><md-date-picker label="Date" style="min-width: 240px;"></md-date-picker></div>
<div dir="rtl"><md-date-picker locale="ar" label="التاريخ" style="min-width: 240px;"></md-date-picker></div>
</div>Density — density="-1…-4" compacts the field and the panel, and locally
overrides an inherited data-density rung. See Density.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker density="0" label="0" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-1" label="-1" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-2" label="-2" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-3" label="-3" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-4" label="-4" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
</div>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdDatePicker density="0" label="0" value="2026-08-17" style={{ minWidth: '170px' }}></MdDatePicker>
<MdDatePicker density="-1" label="-1" value="2026-08-17" style={{ minWidth: '170px' }}></MdDatePicker>
<MdDatePicker density="-2" label="-2" value="2026-08-17" style={{ minWidth: '170px' }}></MdDatePicker>
<MdDatePicker density="-3" label="-3" value="2026-08-17" style={{ minWidth: '170px' }}></MdDatePicker>
<MdDatePicker density="-4" label="-4" value="2026-08-17" style={{ minWidth: '170px' }}></MdDatePicker>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker density="0" label="0" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-1" label="-1" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-2" label="-2" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-3" label="-3" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-4" label="-4" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker density="0" label="0" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-1" label="-1" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-2" label="-2" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-3" label="-3" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-4" label="-4" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker density="0" label="0" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-1" label="-1" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-2" label="-2" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-3" label="-3" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
<md-date-picker density="-4" label="-4" value="2026-08-17" style="min-width: 170px;"></md-date-picker>
</div>i18n — see Localization above: the locale drives month and
weekday names, the first day of the week, and the parse/format order, while
every user-facing string (headline, cancel-label, ok-label,
invalid-date-label, the nav labels…) is a prop you must translate.
Override these on the host element for per-instance theming:
| Property | Description | Default |
|---|---|---|
--md-date-picker-container-color | Dialog / popup background | --md-sys-color-surface-container-high |
--md-date-picker-container-shape | Dialog / popup corner radius | --md-sys-shape-corner-extra-large |
--md-date-picker-field-color | Text-field outline / active indicator color | --md-sys-color-outline |
--md-date-picker-field-text-color | Text-field input text color | --md-sys-color-on-surface |
--md-date-picker-field-container-color | Filled-field container background | --md-sys-color-surface-container-highest |
--md-date-picker-field-container-shape | Text-field corner radius | --md-sys-shape-corner-extra-small |
--md-date-picker-field-filled-pill | Filled field: 1 rounds all corners (capsule); omit for MD3 top-only | 0 |
--md-date-picker-field-supporting-color | Supporting text below the field | --md-sys-color-on-surface-variant |
--md-date-picker-label-color | Floating label color | --md-sys-color-on-surface-variant |
--md-date-picker-headline-color | Modal headline (selected date) color | --md-sys-color-on-surface |
--md-date-picker-supporting-color | Header supporting-text color | --md-sys-color-on-surface-variant |
--md-date-picker-weekday-color | Weekday column-header color | --md-sys-color-on-surface-variant |
--md-date-picker-day-color | Day cell text color | --md-sys-color-on-surface |
--md-date-picker-day-selected-color | Selected day text color | --md-sys-color-on-primary |
--md-date-picker-day-selected-bg | Selected day container color | --md-sys-color-primary |
--md-date-picker-today-outline-color | Today’s outline ring color | --md-sys-color-primary |
--md-date-picker-day-outline-color | Deprecated (unselected days are plain text) | — |
--md-date-picker-action-color | Cancel / OK action label color | --md-sys-color-primary |
--md-date-picker-menu-color | Docked month/year menu surface | --md-sys-color-surface-container-high |
--md-date-picker-scrim-color | Modal scrim color | --md-sys-color-scrim |
--md-date-picker-icon-color | Trailing / nav icon color | --md-sys-color-on-surface-variant |
--md-date-picker-panel-width | Modal / docked popup panel width | 360px |
--md-date-picker-panel-max-block-size | Modal / docked popup max height | 524px |
--md-date-picker-docked-panel-width | Docked popup width override | --md-date-picker-panel-width |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.dp-brand {
--md-date-picker-day-selected-bg: #7c4dff;
--md-date-picker-headline-color: #7c4dff;
--md-date-picker-today-outline-color: #7c4dff;
--md-date-picker-action-color: #7c4dff;
--md-date-picker-container-shape: 12px;
}
.dp-tonal {
--md-date-picker-container-color: var(--md-sys-color-secondary-container);
--md-date-picker-day-selected-bg: var(--md-sys-color-tertiary);
--md-date-picker-day-selected-color: var(--md-sys-color-on-tertiary);
--md-date-picker-weekday-color: var(--md-sys-color-on-secondary-container);
}
.dp-squared {
--md-date-picker-day-selected-shape: 6px;
--md-date-picker-day-today-shape: 6px;
--md-date-picker-panel-width: 320px;
}
</style>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker class="dp-brand" variant="docked" label="Branded" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-tonal" variant="docked" label="Tonal" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-squared" variant="docked" label="Squared days" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
</div>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.dp-brand {
--md-date-picker-day-selected-bg: #7c4dff;
--md-date-picker-headline-color: #7c4dff;
--md-date-picker-today-outline-color: #7c4dff;
--md-date-picker-action-color: #7c4dff;
--md-date-picker-container-shape: 12px;
}
.dp-tonal {
--md-date-picker-container-color: var(--md-sys-color-secondary-container);
--md-date-picker-day-selected-bg: var(--md-sys-color-tertiary);
--md-date-picker-day-selected-color: var(--md-sys-color-on-tertiary);
--md-date-picker-weekday-color: var(--md-sys-color-on-secondary-container);
}
.dp-squared {
--md-date-picker-day-selected-shape: 6px;
--md-date-picker-day-today-shape: 6px;
--md-date-picker-panel-width: 320px;
}
</style>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdDatePicker className="dp-brand" variant="docked" label="Branded" value="2026-08-17" style={{ minInlineSize: '230px' }}></MdDatePicker>
<MdDatePicker className="dp-tonal" variant="docked" label="Tonal" value="2026-08-17" style={{ minInlineSize: '230px' }}></MdDatePicker>
<MdDatePicker className="dp-squared" variant="docked" label="Squared days" value="2026-08-17" style={{ minInlineSize: '230px' }}></MdDatePicker>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.dp-brand {
--md-date-picker-day-selected-bg: #7c4dff;
--md-date-picker-headline-color: #7c4dff;
--md-date-picker-today-outline-color: #7c4dff;
--md-date-picker-action-color: #7c4dff;
--md-date-picker-container-shape: 12px;
}
.dp-tonal {
--md-date-picker-container-color: var(--md-sys-color-secondary-container);
--md-date-picker-day-selected-bg: var(--md-sys-color-tertiary);
--md-date-picker-day-selected-color: var(--md-sys-color-on-tertiary);
--md-date-picker-weekday-color: var(--md-sys-color-on-secondary-container);
}
.dp-squared {
--md-date-picker-day-selected-shape: 6px;
--md-date-picker-day-today-shape: 6px;
--md-date-picker-panel-width: 320px;
}
</style>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker class="dp-brand" variant="docked" label="Branded" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-tonal" variant="docked" label="Tonal" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-squared" variant="docked" label="Squared days" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<style>
.dp-brand {
--md-date-picker-day-selected-bg: #7c4dff;
--md-date-picker-headline-color: #7c4dff;
--md-date-picker-today-outline-color: #7c4dff;
--md-date-picker-action-color: #7c4dff;
--md-date-picker-container-shape: 12px;
}
.dp-tonal {
--md-date-picker-container-color: var(--md-sys-color-secondary-container);
--md-date-picker-day-selected-bg: var(--md-sys-color-tertiary);
--md-date-picker-day-selected-color: var(--md-sys-color-on-tertiary);
--md-date-picker-weekday-color: var(--md-sys-color-on-secondary-container);
}
.dp-squared {
--md-date-picker-day-selected-shape: 6px;
--md-date-picker-day-today-shape: 6px;
--md-date-picker-panel-width: 320px;
}
</style>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker class="dp-brand" variant="docked" label="Branded" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-tonal" variant="docked" label="Tonal" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-squared" variant="docked" label="Squared days" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<style>
.dp-brand {
--md-date-picker-day-selected-bg: #7c4dff;
--md-date-picker-headline-color: #7c4dff;
--md-date-picker-today-outline-color: #7c4dff;
--md-date-picker-action-color: #7c4dff;
--md-date-picker-container-shape: 12px;
}
.dp-tonal {
--md-date-picker-container-color: var(--md-sys-color-secondary-container);
--md-date-picker-day-selected-bg: var(--md-sys-color-tertiary);
--md-date-picker-day-selected-color: var(--md-sys-color-on-tertiary);
--md-date-picker-weekday-color: var(--md-sys-color-on-secondary-container);
}
.dp-squared {
--md-date-picker-day-selected-shape: 6px;
--md-date-picker-day-today-shape: 6px;
--md-date-picker-panel-width: 320px;
}
</style>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker class="dp-brand" variant="docked" label="Branded" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-tonal" variant="docked" label="Tonal" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
<md-date-picker class="dp-squared" variant="docked" label="Squared days" value="2026-08-17" style="min-inline-size: 230px;"></md-date-picker>
</div>Every default resolves through an md-sys-color role, so a picker that sets no
custom properties follows the theme on its own:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Untouched defaults" value="2026-08-17" clearable style="min-width: 240px;"></md-date-picker>
<md-date-picker variant="docked" label="Docked" value="2026-08-17" style="min-width: 240px;"></md-date-picker>
</div>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdDatePicker label="Untouched defaults" value="2026-08-17" clearable style={{ minWidth: '240px' }}></MdDatePicker>
<MdDatePicker variant="docked" label="Docked" value="2026-08-17" style={{ minWidth: '240px' }}></MdDatePicker>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Untouched defaults" value="2026-08-17" clearable style="min-width: 240px;"></md-date-picker>
<md-date-picker variant="docked" label="Docked" value="2026-08-17" style="min-width: 240px;"></md-date-picker>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Untouched defaults" value="2026-08-17" clearable style="min-width: 240px;"></md-date-picker>
<md-date-picker variant="docked" label="Docked" value="2026-08-17" style="min-width: 240px;"></md-date-picker>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:flex-start;">
<md-date-picker label="Untouched defaults" value="2026-08-17" clearable style="min-width: 240px;"></md-date-picker>
<md-date-picker variant="docked" label="Docked" value="2026-08-17" style="min-width: 240px;"></md-date-picker>
</div>Style internal elements through the shadow boundary:
| Part | Element |
|---|---|
field | Text-field container (trigger) |
leading-icon | Slotted leading-icon wrapper |
label | Floating field label |
input | Field text input |
calendar-button | Trailing calendar toggle button |
supporting-text | Helper / error text below the field |
modal / scrim | Modal wrapper / scrim overlay |
panel | Dialog / docked popup surface |
header | Modal header region |
supporting | Header supporting text |
headline | Large selected-date headline |
mode-toggle | Calendar / text-input switch button |
body | Calendar / year / input body region |
nav | Month label + prev/next nav row (also docked nav) |
month-toggle | Month-year label button (year grid; modal) |
prev-button / next-button | Month navigation buttons (modal) |
month-menu-button / year-menu-button | Docked month / year dropdown buttons |
prev-month-button / next-month-button | Docked month chevron icon buttons |
prev-year-button / next-year-button | Docked year chevron icon buttons |
selection-divider | Divider between docked nav and month/year menu |
month-menu / year-menu | Docked inline baseline month / year menus |
month-option / month-option-selected | Month menu option / selected |
year-option / year-option-selected | Year menu option / selected |
calendar | Calendar grid wrapper |
weekdays / weekday | Weekday header row / single column header |
grid | Day-cell grid |
day | A day cell button |
day-unselected / day-selected / day-today / day-disabled / day-outside | Day cell state parts |
year-grid / year / year-selected | Year selection grid + options |
entry / entry-input | In-dialog typed date-entry region |
actions | Cancel / OK action row |
cancel-button / ok-button | Action buttons |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.parts-dp::part(field) { --md-date-picker-field-color: var(--md-sys-color-primary); }
.parts-dp::part(day-selected) { border-radius: 6px; }
.parts-dp::part(day-today) { outline-width: 2px; }
.parts-dp::part(weekday) { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.parts-dp::part(headline) { font-style: italic; }
.parts-dp::part(ok-button) { font-weight: 700; }
</style>
<md-date-picker class="parts-dp" variant="docked" label="Styled parts" value="2026-08-17" style="min-width: 260px;"></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.parts-dp::part(field) { --md-date-picker-field-color: var(--md-sys-color-primary); }
.parts-dp::part(day-selected) { border-radius: 6px; }
.parts-dp::part(day-today) { outline-width: 2px; }
.parts-dp::part(weekday) { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.parts-dp::part(headline) { font-style: italic; }
.parts-dp::part(ok-button) { font-weight: 700; }
</style>
<MdDatePicker className="parts-dp" variant="docked" label="Styled parts" value="2026-08-17" style={{ minWidth: '260px' }}></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.parts-dp::part(field) { --md-date-picker-field-color: var(--md-sys-color-primary); }
.parts-dp::part(day-selected) { border-radius: 6px; }
.parts-dp::part(day-today) { outline-width: 2px; }
.parts-dp::part(weekday) { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.parts-dp::part(headline) { font-style: italic; }
.parts-dp::part(ok-button) { font-weight: 700; }
</style>
<md-date-picker class="parts-dp" variant="docked" label="Styled parts" value="2026-08-17" style="min-width: 260px;"></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<style>
.parts-dp::part(field) { --md-date-picker-field-color: var(--md-sys-color-primary); }
.parts-dp::part(day-selected) { border-radius: 6px; }
.parts-dp::part(day-today) { outline-width: 2px; }
.parts-dp::part(weekday) { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.parts-dp::part(headline) { font-style: italic; }
.parts-dp::part(ok-button) { font-weight: 700; }
</style>
<md-date-picker class="parts-dp" variant="docked" label="Styled parts" value="2026-08-17" style="min-width: 260px;"></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<style>
.parts-dp::part(field) { --md-date-picker-field-color: var(--md-sys-color-primary); }
.parts-dp::part(day-selected) { border-radius: 6px; }
.parts-dp::part(day-today) { outline-width: 2px; }
.parts-dp::part(weekday) { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.parts-dp::part(headline) { font-style: italic; }
.parts-dp::part(ok-button) { font-weight: 700; }
</style>
<md-date-picker class="parts-dp" variant="docked" label="Styled parts" value="2026-08-17" style="min-width: 260px;"></md-date-picker>| Slot | Description |
|---|---|
leading-icon | Custom leading icon for the field |
header | Replaces the entire modal header |
actions | Replaces the Cancel / OK action row |
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker label="Custom icon">
<span slot="leading-icon" class="material-symbols-outlined">event</span>
</md-date-picker>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker label="Custom icon">
<span slot="leading-icon" className="material-symbols-outlined">event</span>
</MdDatePicker>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker label="Custom icon">
<span slot="leading-icon" class="material-symbols-outlined">event</span>
</md-date-picker><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker label="Custom icon">
<span slot="leading-icon" class="material-symbols-outlined">event</span>
</md-date-picker>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<md-date-picker label="Custom icon">
<span slot="leading-icon" class="material-symbols-outlined">event</span>
</md-date-picker>| Event | Cancelable | Detail | Fires |
|---|---|---|---|
mdInput | no | { value: string } | Every keystroke in the text field |
mdSelected | no | MdDatePickerSelectedDetail | A day cell is picked — staged, not committed |
mdChange | no | MdDatePickerChangeDetail | The value commits — OK, Enter, or a docked pick |
mdOpen / mdClose | no | void | The panel opened / closed |
mdCancel | no | void | Dismissed without committing — Cancel, Escape, the scrim, or a click outside a docked panel |
mdViewChange | no | MdDatePickerViewChangeDetail | The calendar moved month or year, or switched to the year grid |
mdMenuOpen / mdMenuSelect | no | MdDatePickerMenu*Detail | The docked month / year dropdowns |
mdModeChange | no | MdDatePickerModeChangeDetail | The calendar ⇄ text-input toggle |
Set commit-on-select and a day click stages and commits: mdSelected then
mdChange fire together, the panel dismisses, and the built-in Cancel / OK row
is not rendered — there is nothing left for it to confirm.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- default: a day click only stages; OK commits -->
<md-date-picker label="Due date" value="2026-08-10"></md-date-picker>
<!-- one click, no confirm step, no action row -->
<md-date-picker label="Due date" value="2026-08-10" commit-on-select></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<!-- default: a day click only stages; OK commits -->
<MdDatePicker label="Due date" value="2026-08-10"></MdDatePicker>
<!-- one click, no confirm step, no action row -->
<MdDatePicker label="Due date" value="2026-08-10" commit-on-select></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<!-- default: a day click only stages; OK commits -->
<md-date-picker label="Due date" value="2026-08-10"></md-date-picker>
<!-- one click, no confirm step, no action row -->
<md-date-picker label="Due date" value="2026-08-10" commit-on-select></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<!-- default: a day click only stages; OK commits -->
<md-date-picker label="Due date" value="2026-08-10"></md-date-picker>
<!-- one click, no confirm step, no action row -->
<md-date-picker label="Due date" value="2026-08-10" commit-on-select></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<!-- default: a day click only stages; OK commits -->
<md-date-picker label="Due date" value="2026-08-10"></md-date-picker>
<!-- one click, no confirm step, no action row -->
<md-date-picker label="Due date" value="2026-08-10" commit-on-select></md-date-picker>A modal puts a scrim between the panel and the page, and clicking it
dismisses — scrim-dismissible turns that off. A docked panel has no scrim,
so the click that lands outside it is caught on the document instead;
outside-click-dismissible is its opt-out.
Either way the dismissal is a cancel: mdCancel fires and anything staged is
discarded. Set outside-click-dismissible="false" when a stray click must not
throw away a half-made choice, or when the picker sits inside another popup whose
own click-away handling would otherwise close both at once.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker variant="docked" label="Start"></md-date-picker>
<md-date-picker
variant="docked"
label="Start"
outside-click-dismissible="false"
></md-date-picker>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdDatePicker variant="docked" label="Start"></MdDatePicker>
<MdDatePicker
variant="docked"
label="Start"
outsideClickDismissible="false"
></MdDatePicker>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-date-picker variant="docked" label="Start"></md-date-picker>
<md-date-picker
variant="docked"
label="Start"
outside-click-dismissible="false"
></md-date-picker><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-date-picker variant="docked" label="Start"></md-date-picker>
<md-date-picker
variant="docked"
label="Start"
outside-click-dismissible="false"
></md-date-picker>
</template><script>
import '@awc-ui/core/define';
</script>
<md-date-picker variant="docked" label="Start"></md-date-picker>
<md-date-picker
variant="docked"
label="Start"
outside-click-dismissible="false"
></md-date-picker><!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-date-picker id="demo"></md-date-picker>
<script type="module">
import { defineCustomElements } from '@awc-ui/core/loader';
defineCustomElements(window);
const el = document.querySelector('#demo');
el.addEventListener('mdChange', (event) => {
// e.detail: MdDatePickerChangeDetail
console.log('mdChange', event.detail);
});
el.addEventListener('mdSelected', (event) => {
// e.detail: MdDatePickerSelectedDetail
console.log('mdSelected', event.detail);
});
el.addEventListener('mdInput', (event) => {
// e.detail: { value: string }
console.log('mdInput', event.detail);
});
el.addEventListener('mdOpen', (event) => {
console.log('mdOpen', event.detail);
});
el.addEventListener('mdClose', (event) => {
console.log('mdClose', event.detail);
});
el.addEventListener('mdCancel', (event) => {
console.log('mdCancel', event.detail);
});
el.addEventListener('mdViewChange', (event) => {
// e.detail: MdDatePickerViewChangeDetail
console.log('mdViewChange', event.detail);
});
el.addEventListener('mdMenuOpen', (event) => {
// e.detail: MdDatePickerMenuOpenDetail
console.log('mdMenuOpen', event.detail);
});
el.addEventListener('mdMenuSelect', (event) => {
// e.detail: MdDatePickerMenuSelectDetail
console.log('mdMenuSelect', event.detail);
});
el.addEventListener('mdModeChange', (event) => {
// e.detail: MdDatePickerModeChangeDetail
console.log('mdModeChange', event.detail);
});
</script>import { MdDatePicker } from '@awc-ui/react';
export function Demo() {
return (
<MdDatePicker
onMdChange={(event) => {
// e.detail: MdDatePickerChangeDetail
console.log('mdChange', event.detail);
}}
onMdSelected={(event) => {
// e.detail: MdDatePickerSelectedDetail
console.log('mdSelected', event.detail);
}}
onMdInput={(event) => {
// e.detail: { value: string }
console.log('mdInput', event.detail);
}}
onMdOpen={(event) => {
console.log('mdOpen', event.detail);
}}
onMdClose={(event) => {
console.log('mdClose', event.detail);
}}
onMdCancel={(event) => {
console.log('mdCancel', event.detail);
}}
onMdViewChange={(event) => {
// e.detail: MdDatePickerViewChangeDetail
console.log('mdViewChange', event.detail);
}}
onMdMenuOpen={(event) => {
// e.detail: MdDatePickerMenuOpenDetail
console.log('mdMenuOpen', event.detail);
}}
onMdMenuSelect={(event) => {
// e.detail: MdDatePickerMenuSelectDetail
console.log('mdMenuSelect', event.detail);
}}
onMdModeChange={(event) => {
// e.detail: MdDatePickerModeChangeDetail
console.log('mdModeChange', event.detail);
}}
/>
);
}// app.module.ts — register once
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<md-date-picker (mdChange)="onChange($event)" (mdSelected)="onSelected($event)" (mdInput)="onInput($event)" (mdOpen)="onOpen($event)" (mdClose)="onClose($event)" (mdCancel)="onCancel($event)" (mdViewChange)="onViewChange($event)" (mdMenuOpen)="onMenuOpen($event)" (mdMenuSelect)="onMenuSelect($event)" (mdModeChange)="onModeChange($event)"></md-date-picker>
`,
})
export class AppComponent {
onChange(event: CustomEvent<MdDatePickerChangeDetail>) {
console.log('mdChange', event.detail);
}
onSelected(event: CustomEvent<MdDatePickerSelectedDetail>) {
console.log('mdSelected', event.detail);
}
onInput(event: CustomEvent<{ value: string }>) {
console.log('mdInput', event.detail);
}
onOpen(event: CustomEvent<void>) {
console.log('mdOpen', event.detail);
}
onClose(event: CustomEvent<void>) {
console.log('mdClose', event.detail);
}
onCancel(event: CustomEvent<void>) {
console.log('mdCancel', event.detail);
}
onViewChange(event: CustomEvent<MdDatePickerViewChangeDetail>) {
console.log('mdViewChange', event.detail);
}
onMenuOpen(event: CustomEvent<MdDatePickerMenuOpenDetail>) {
console.log('mdMenuOpen', event.detail);
}
onMenuSelect(event: CustomEvent<MdDatePickerMenuSelectDetail>) {
console.log('mdMenuSelect', event.detail);
}
onModeChange(event: CustomEvent<MdDatePickerModeChangeDetail>) {
console.log('mdModeChange', event.detail);
}
}<script setup>
import '@awc-ui/core/define';
function onMdChange(event) {
// e.detail: MdDatePickerChangeDetail
console.log('mdChange', event.detail);
}
function onMdSelected(event) {
// e.detail: MdDatePickerSelectedDetail
console.log('mdSelected', event.detail);
}
function onMdInput(event) {
// e.detail: { value: string }
console.log('mdInput', event.detail);
}
function onMdOpen(event) {
console.log('mdOpen', event.detail);
}
function onMdClose(event) {
console.log('mdClose', event.detail);
}
function onMdCancel(event) {
console.log('mdCancel', event.detail);
}
function onMdViewChange(event) {
// e.detail: MdDatePickerViewChangeDetail
console.log('mdViewChange', event.detail);
}
function onMdMenuOpen(event) {
// e.detail: MdDatePickerMenuOpenDetail
console.log('mdMenuOpen', event.detail);
}
function onMdMenuSelect(event) {
// e.detail: MdDatePickerMenuSelectDetail
console.log('mdMenuSelect', event.detail);
}
function onMdModeChange(event) {
// e.detail: MdDatePickerModeChangeDetail
console.log('mdModeChange', event.detail);
}
</script>
<template>
<md-date-picker @md-change="onMdChange" @md-selected="onMdSelected" @md-input="onMdInput" @md-open="onMdOpen" @md-close="onMdClose" @md-cancel="onMdCancel" @md-view-change="onMdViewChange" @md-menu-open="onMdMenuOpen" @md-menu-select="onMdMenuSelect" @md-mode-change="onMdModeChange" />
</template><script>
import '@awc-ui/core/define';
function onMdChange(event) {
// e.detail: MdDatePickerChangeDetail
console.log('mdChange', event.detail);
}
function onMdSelected(event) {
// e.detail: MdDatePickerSelectedDetail
console.log('mdSelected', event.detail);
}
function onMdInput(event) {
// e.detail: { value: string }
console.log('mdInput', event.detail);
}
function onMdOpen(event) {
console.log('mdOpen', event.detail);
}
function onMdClose(event) {
console.log('mdClose', event.detail);
}
function onMdCancel(event) {
console.log('mdCancel', event.detail);
}
function onMdViewChange(event) {
// e.detail: MdDatePickerViewChangeDetail
console.log('mdViewChange', event.detail);
}
function onMdMenuOpen(event) {
// e.detail: MdDatePickerMenuOpenDetail
console.log('mdMenuOpen', event.detail);
}
function onMdMenuSelect(event) {
// e.detail: MdDatePickerMenuSelectDetail
console.log('mdMenuSelect', event.detail);
}
function onMdModeChange(event) {
// e.detail: MdDatePickerModeChangeDetail
console.log('mdModeChange', event.detail);
}
</script>
<md-date-picker on:mdChange={onMdChange} on:mdSelected={onMdSelected} on:mdInput={onMdInput} on:mdOpen={onMdOpen} on:mdClose={onMdClose} on:mdCancel={onMdCancel} on:mdViewChange={onMdViewChange} on:mdMenuOpen={onMdMenuOpen} on:mdMenuSelect={onMdMenuSelect} on:mdModeChange={onMdModeChange} />| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
valueMissingLabel | value-missing-label | string | 'Please choose a date.' | — |
reserveSupportingSpace | reserve-supporting-space | boolean | false | — |
variant | variant | 'modal' | 'modal-input' | 'docked' | 'modal-input' | Yes |
value | value | string | '' | Yes |
label | label | string | 'Date' | — |
placeholder | placeholder | string | '' | — |
min | min | string | '' | — |
max | max | string | '' | — |
open | open | boolean | false | Yes |
disabled | disabled | boolean | false | Yes |
required | required | boolean | false | Yes |
clearable | clearable | boolean | false | Yes |
clearLabel | clear-label | string | 'Clear date' | — |
error | error | boolean | false | Yes |
errorText | error-text | string | '' | — |
supportingText | supporting-text | string | '' | — |
locale | locale | string | '' | — |
dateSeparator | date-separator | string | '' | — |
fieldVariant | field-variant | 'outlined' | 'filled' | 'outlined' | — |
firstDayOfWeek | first-day-of-week | number | -1 | — |
headline | headline | string | 'Select date' | — |
cancelLabel | cancel-label | string | 'Cancel' | — |
okLabel | ok-label | string | 'OK' | — |
selectDateLabel | select-date-label | string | 'Select date' | — |
enterDatesLabel | enter-dates-label | string | 'Enter dates' | — |
invalidDateLabel | invalid-date-label | string | 'Invalid date' | — |
previousMonthLabel | previous-month-label | string | 'Previous month' | — |
nextMonthLabel | next-month-label | string | 'Next month' | — |
previousYearLabel | previous-year-label | string | 'Previous year' | — |
nextYearLabel | next-year-label | string | 'Next year' | — |
chooseMonthLabel | choose-month-label | string | 'Choose month' | — |
chooseYearLabel | choose-year-label | string | 'Choose year' | — |
chooseMonthYearLabel | choose-month-year-label | string | 'Choose a different month and year' | — |
chooseMonthAndYearLabel | choose-month-and-year-label | string | 'Choose month and year' | — |
toggleCalendarLabel | toggle-calendar-label | string | 'Switch to calendar input' | — |
toggleTextLabel | toggle-text-label | string | 'Switch to text input' | — |
openCalendarLabel | open-calendar-label | string | 'Open calendar' | — |
closeCalendarLabel | close-calendar-label | string | 'Close calendar' | — |
calendarIcon | calendar-icon | string | 'calendar_today' | — |
yearGridLabel | year-grid-label | string | 'Year' | — |
scrimDismissible | scrim-dismissible | boolean | true | — |
outsideClickDismissible | outside-click-dismissible | boolean | true | — |
commitOnSelect | commit-on-select | boolean | false | Yes |
name | name | string | '' | — |
isDateDisabled | JS only | (date: Date) => boolean | — | — |
density | density | 0 | -1 | -2 | -3 | -4 | 0 | Yes |
| Method | Parameters |
|---|---|
show() | none |
close() | none |
clear() | none |
focusInput() | none |
getValidity() | none |
checkValidity() | none |
reportValidity() | none |
setCustomValidity() | message: string |
| Slot | Description |
|---|---|
leading-icon | Custom leading icon for the field |
calendar-icon | Custom trailing calendar toggle icon (replaces calendar-icon prop) |
header | Replaces the entire modal header |
actions | Replaces the Cancel / OK action row |
Override on the host element for per-instance theming:
| Property | Description |
|---|---|
--md-date-picker-container-color | Dialog / popup body background |
--md-date-picker-header-color | Modal header background |
--md-date-picker-container-shape | Dialog / popup corner radius |
--md-date-picker-field-color | Text-field resting outline color |
--md-date-picker-field-focus-color | Text-field focused outline / label color |
--md-date-picker-field-text-color | Text-field input text color |
--md-date-picker-field-filled-pill | Filled field: 1 for capsule/pill (all corners) |
--md-date-picker-field-supporting-color | Supporting text below the field |
--md-date-picker-label-color | Floating label color |
--md-date-picker-headline-color | Modal headline (selected date) color |
--md-date-picker-supporting-color | Header supporting-text color |
--md-date-picker-weekday-color | Weekday column-header color |
--md-date-picker-day-color | Day cell text color |
--md-date-picker-day-selected-color | Selected day text color |
--md-date-picker-day-selected-bg | Selected day container color |
--md-date-picker-day-selected-shape | Selected day corner radius (overrides morph) |
--md-date-picker-day-today-shape | Today ring corner radius |
--md-date-picker-today-outline-color | Today's outline ring color |
--md-date-picker-day-outline-color | Deprecated — unselected days are plain text |
--md-date-picker-action-color | Cancel / OK action label color |
--md-date-picker-menu-color | Docked month/year menu surface |
--md-date-picker-selection-bloom-duration | Docked month/year menu bloom-in duration |
--md-date-picker-selection-bloom-easing | Docked month/year menu bloom-in easing |
--md-date-picker-selection-bloom-out-duration | Docked menu bloom-out on pick (default short4) |
--md-date-picker-calendar-bloom-duration | Docked day grid bloom-in after pick (default medium2) |
--md-date-picker-grid-slide-duration | Day grid month/year slide duration |
--md-date-picker-panel-bloom-out-duration | Panel bloom-out on dismiss (default short4) |
--md-date-picker-scrim-color | Modal scrim color |
--md-date-picker-icon-color | Trailing / nav icon color |
--md-date-picker-panel-width | Modal / docked popup panel inline size |
--md-date-picker-panel-max-block-size | Modal / docked popup panel max block size |
--md-date-picker-docked-panel-width | Docked popup panel inline size (overrides panel-width) |
--md-date-picker-year-inline-size | Year grid cell inline size (modal) |
--md-date-picker-year-block-size | Year grid cell block size (modal) |
--md-date-picker-year-grid-gap | Year grid row/column gap (modal) |
--md-date-picker-year-grid-padding-inline | Year grid inline padding (modal) |
--md-date-picker-year-grid-viewport-block-size | Year grid scroll viewport block size (modal) |
--md-date-picker-day-outside-color | — |
--md-date-picker-icon-size | — |
Style internal elements through shadow DOM with ::part():
| Part | Description |
|---|---|
menu-caret | — |
year-grid-wrap | Animated wrapper for modal year grid |
month-menu | Docked inline baseline md-menu (month selection) |
year-menu | Docked inline baseline md-menu (year selection) |
entry-input | In-dialog outlined md-text-field (single modal input) |
field | Text-field container (trigger) |
clear-button | — |
calendar-button | Trailing calendar toggle button |
month-toggle | Month-year menu button (opens year grid; modal; same as menu-button) |
nav | Month label + prev/next nav row (also docked nav row) |
month-menu-button | Docked month dropdown menu button ("Aug ▾") |
year-menu-button | Docked year dropdown menu button ("2025 ▾") |
selection-divider | Divider between docked nav and month/year menu |
month-menu-wrap | — |
year-menu-wrap | — |
calendar | Calendar grid wrapper |
weekdays | Weekday header row |
weekday | A single weekday column header |
grid | Day-cell grid |
week | — |
year-grid-scroll year-grid-viewport | — |
year-grid | Year-selection grid (modal) |
year-row | — |
entry | In-dialog text-entry region |
header | Modal header region |
supporting | Header supporting text |
headline | Large selected-date headline |
mode-toggle | Calendar / text-input switch button |
actions | Cancel / OK action row |
cancel-button | Cancel action |
ok-button | Confirm action |
body | Calendar / year / input body region |
docked-below-nav | — |
panel | Dialog / docked popup surface |
modal | Modal wrapper (scrim + panel) |
scrim | Modal scrim overlay |
month-menu-viewport | — |
year-menu-viewport | — |
md-time-picker ·
md-text-field ·
md-select ·
md-menu ·
md-dialog ·
md-icon-button
md-date-pickerTwo artefacts to give your AI agent so it generates correct UI with this component. The per-component spec answers "how do I use this exact tag?". The main-llm spec answers "which tag should I pick in the first place?".
md-date-picker spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
System-prompt preamble · decision matrix · token reference · page recipes · anti-patterns. Paste into the system prompt at the start of a piece of work.