Date Picker
Type or paste a date, or choose a calendar day to update the field immediately. Date-only selection closes the popup and returns focus to its calendar action. Month and year navigation leaves the value unchanged. Escape or clicking outside closes the popup. The default value is YYYY-MM-DD; explicit local date-time, instant and zoned types preserve their clock precision and bound zone. Date-time popups keep the clock editable, committing each complete valid edit. Native fields remain usable before JavaScript.
Choose a date
Type or paste a date directly, or choose a calendar day to update the field immediately. The native form submits one canonical YYYY-MM-DD value.
Su
M
T
W
Th
F
S
No available dates this month.
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-date-picker/ui-date-picker.html"
>
<ui-date-picker
label="Due date"
name="due"
value="2026-10-30"
locale="en-US"
></ui-date-picker><script setup>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<template>
<UiDatePicker
label="Due date"
name="due"
value="2026-10-30"
locale="en-US"
/>
</template>import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
label="Due date"
name="due"
value="2026-10-30"
locale="en-US"
/>;
}/** @jsxImportSource preact */
import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
label="Due date"
name="due"
value="2026-10-30"
locale="en-US"
/>;
}<script>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<UiDatePicker
label="Due date"
name="due"
value="2026-10-30"
locale="en-US"
/>import { Component } from "@angular/core";
import { UiDatePicker } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiDatePicker],
template: `
<span
ui-date-picker
[label]="'Due date'"
[name]="'due'"
[value]="'2026-10-30'"
[locale]="'en-US'"
></span>
`,
})
export default class Example {}Preserve a local time
Calendar navigation preserves the existing clock and fractional precision. The time blocks and clock choices remain directly editable; the bound value retains its space separator.
Su
M
T
W
Th
F
S
No available dates this month.
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-date-picker/ui-date-picker.html"
>
<ui-date-picker
type="datetime-local"
value-format="space"
label="Date and time"
name="appointment"
value="2026-10-30 14:30:45.125"
locale="en-US"
></ui-date-picker><script setup>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<template>
<UiDatePicker
type="datetime-local"
value-format="space"
label="Date and time"
name="appointment"
value="2026-10-30 14:30:45.125"
locale="en-US"
/>
</template>import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="datetime-local"
valueFormat="space"
label="Date and time"
name="appointment"
value="2026-10-30 14:30:45.125"
locale="en-US"
/>;
}/** @jsxImportSource preact */
import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="datetime-local"
valueFormat="space"
label="Date and time"
name="appointment"
value="2026-10-30 14:30:45.125"
locale="en-US"
/>;
}<script>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<UiDatePicker
type="datetime-local"
valueFormat="space"
label="Date and time"
name="appointment"
value="2026-10-30 14:30:45.125"
locale="en-US"
/>import { Component } from "@angular/core";
import { UiDatePicker } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiDatePicker],
template: `
<span
ui-date-picker
[type]="'datetime-local'"
[valueFormat]="'space'"
[label]="'Date and time'"
[name]="'appointment'"
[value]="'2026-10-30 14:30:45.125'"
[locale]="'en-US'"
></span>
`,
})
export default class Example {}Edit an exact time
An instant is displayed and edited in an explicit zone, while the form submits UTC. Skipped or repeated wall-clock times are rejected unless disambiguation is chosen explicitly.
Su
M
T
W
Th
F
S
No available dates this month.
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-date-picker/ui-date-picker.html"
>
<ui-date-picker
type="instant"
time-zone="America/New_York"
label="Date and time"
name="appointment"
value="2026-10-31T02:30:00Z"
locale="en-US"
></ui-date-picker><script setup>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<template>
<UiDatePicker
type="instant"
time-zone="America/New_York"
label="Date and time"
name="appointment"
value="2026-10-31T02:30:00Z"
locale="en-US"
/>
</template>import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="instant"
timeZone="America/New_York"
label="Date and time"
name="appointment"
value="2026-10-31T02:30:00Z"
locale="en-US"
/>;
}/** @jsxImportSource preact */
import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="instant"
timeZone="America/New_York"
label="Date and time"
name="appointment"
value="2026-10-31T02:30:00Z"
locale="en-US"
/>;
}<script>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<UiDatePicker
type="instant"
timeZone="America/New_York"
label="Date and time"
name="appointment"
value="2026-10-31T02:30:00Z"
locale="en-US"
/>import { Component } from "@angular/core";
import { UiDatePicker } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiDatePicker],
template: `
<span
ui-date-picker
[type]="'instant'"
[timeZone]="'America/New_York'"
[label]="'Date and time'"
[name]="'appointment'"
[value]="'2026-10-31T02:30:00Z'"
[locale]="'en-US'"
></span>
`,
})
export default class Example {}Keep the appointment's zone
A zoned binding saves the date, clock, offset and region together. Its bracketed zone supplies the editing zone, so no separate time-zone prop is needed. Date-only fields omit type and save just YYYY-MM-DD.
Su
M
T
W
Th
F
S
No available dates this month.
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-date-picker/ui-date-picker.html"
>
<ui-date-picker
type="zoned"
label="Appointment"
name="appointment"
value="2026-10-30T09:00-07:00[America/Vancouver]"
locale="en-US"
></ui-date-picker><script setup>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<template>
<UiDatePicker
type="zoned"
label="Appointment"
name="appointment"
value="2026-10-30T09:00-07:00[America/Vancouver]"
locale="en-US"
/>
</template>import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="zoned"
label="Appointment"
name="appointment"
value="2026-10-30T09:00-07:00[America/Vancouver]"
locale="en-US"
/>;
}/** @jsxImportSource preact */
import { UiDatePicker } from "@threadlabs/looma";
export default function Example() {
return <UiDatePicker
type="zoned"
label="Appointment"
name="appointment"
value="2026-10-30T09:00-07:00[America/Vancouver]"
locale="en-US"
/>;
}<script>
import { UiDatePicker } from "@threadlabs/looma";
</script>
<UiDatePicker
type="zoned"
label="Appointment"
name="appointment"
value="2026-10-30T09:00-07:00[America/Vancouver]"
locale="en-US"
/>import { Component } from "@angular/core";
import { UiDatePicker } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiDatePicker],
template: `
<span
ui-date-picker
[type]="'zoned'"
[label]="'Appointment'"
[name]="'appointment'"
[value]="'2026-10-30T09:00-07:00[America/Vancouver]'"
[locale]="'en-US'"
></span>
`,
})
export default class Example {}API
Package: @threadlabs/looma · Native root: span
Attributes
| Name | Description | Property | Type | Default | Allowed values |
|---|---|---|---|---|---|
allowed-dates | Allowed ISO dates, unioned with allowedRanges. Omission imposes no allow restriction; an explicitly empty allow set permits nothing. | allowedDates | list(string) | — | — |
allowed-ranges | Allowed inclusive ISO-date intervals, unioned with allowedDates. | allowedRanges | list(object)
| — | — |
disabled | Prevents editing and omits the value from submission. | disabled | boolean | false | — |
disabled-dates | Unavailable ISO dates, applied in the editing zone for exact values. | disabledDates | list(string) | [] | — |
disabled-ranges | Unavailable inclusive ISO-date intervals. | disabledRanges | list(object)
| [] | — |
disabled-weekdays | Unavailable ISO weekdays, from 1 (Monday) to 7 (Sunday). | disabledWeekdays | list(integer) | [] | — |
disambiguation | How zoned edits resolve a skipped or repeated wall-clock time. Reject leaves the draft visible with a validation error. | disambiguation | keyword | reject | reject, earlier, later, compatible |
display-options | Intl display options while unfocused. Focusing uses the numeric editing grammar; formatting does not change the binding. Calendar identity and editing timezone stay with the field. | displayOptions | object
| — | — |
form | Optional ID of a form outside this component’s ancestor tree. | form | string | | — |
granularity | Smallest displayed time unit. Existing nonzero seconds and fractions remain editable without precision loss. | granularity | keyword | minute | minute, second |
hour-cycle | Intl hour cycle. Omit to follow locale conventions. | hourCycle | keyword | — | h11, h12, h23, h24 |
input-id | ID of the active native input for an authored label's for attribute, preserved across upgrade. | inputId | string | | — |
invalid | External invalid state, independent of parsing and availability. | invalid | boolean | false | — |
label | Optional accessible name. Prefer an authored visible label associated with input-id; a supplied label overrides that name. | label | string | | — |
locale | Explicit Intl locale for numeric editing order, digits and display. ISO input is always accepted. | locale | string | en-US | — |
max | Inclusive maximum in the bound value's format. | max | string | | — |
min | Inclusive minimum in the bound value's format. | min | string | | — |
model | Server-prepared civil date/time projection owned by the component module. | model | object
| — | — |
month-label | Accessible name of the month navigation toggle. | monthLabel | string | Choose month | — |
name | Native form field name. The enhanced field submits its canonical value. | name | string | | — |
next-label | Accessible name of the next-page action. | nextLabel | string | Next | — |
picker-label | Accessible name of the calendar action and its dialog. | pickerLabel | string | Choose date | — |
placeholder | Optional editing hint. A placeholder never replaces the label. | placeholder | string | | — |
previous-label | Accessible name of the previous-page action. | previousLabel | string | Previous | — |
readonly | Retains selection and submission while preventing edits. | readonly | boolean | false | — |
required | Requires a complete value. | required | boolean | false | — |
size | Input's shared size scale. | size | keyword | md | sm, md, lg |
time-label | Label of the time field. | timeLabel | string | Time | — |
time-zone | Display/editing zone for instant values, required for localized instant editing. Zoned values otherwise use their saved zone; an override preserves that saved zone. Required when creating a new zoned value. Date and local date-time bindings remain without a zone. | timeZone | string | | — |
today | Optional YYYY-MM-DD date to mark as today in the calendar. | today | string | | — |
type | The value's meaning and export format. Date is the default and exports only YYYY-MM-DD, without a time or timezone. Local date-time is a wall-clock value; instant uses a UTC timestamp; zoned retains a named zone. Time-zone and display options alone never change this type. | type | keyword | date | date, datetime-local, instant, zoned |
value | Initial canonical value, and a replacement when changed externally. Valid edits update live state and emit input/change; a form reset returns to the last external value. | value | string | | — |
value-format | Local date-time bindings use T by default; space emits YYYY-MM-DD HH:ss. Other types retain their ISO form. | valueFormat | keyword | iso | iso, space |
week-starts-on | Week order override using ISO weekdays: Sunday 7, Saturday 6, or Monday 1. Omission follows the locale's week information, with Sunday as the fallback when unavailable. | weekStartsOn | integer | — | — |
year-label | Accessible name of the year navigation toggle and direct year input. | yearLabel | string | Choose year | — |
Framework props
| Name | Type | Default | Allowed values |
|---|---|---|---|
allowedDates | readonly (string)[] | — | — |
allowedRanges | readonly ({ readonly start: string; readonly end: string })[]
| — | — |
disabled | boolean | false | — |
disabledDates | readonly (string)[] | [] | — |
disabledRanges | readonly ({ readonly start: string; readonly end: string })[]
| [] | — |
disabledWeekdays | readonly (number)[] | [] | — |
disambiguation | "reject" | "earlier" | "later" | "compatible" | reject | reject, earlier, later, compatible |
displayOptions | { readonly dateStyle?: "full" | "long" | "medium" | "short" | null; readonly timeStyle?: "full" | "long" | "medium" | "short" | null; readonly weekday?: "long" | "short" | "narrow" | null; readonly era?: "long" | "short" | "narrow" | null; readonly year?: "numeric" | "2-digit" | null; readonly month?: "numeric" | "2-digit" | "long" | "short" | "narrow" | null; readonly day?: "numeric" | "2-digit" | null; readonly hour?: "numeric" | "2-digit" | null; readonly minute?: "numeric" | "2-digit" | null; readonly second?: "numeric" | "2-digit" | null; readonly timeZoneName?: "long" | "short" | "shortOffset" | "longOffset" | "shortGeneric" | "longGeneric" | null; readonly dayPeriod?: "long" | "short" | "narrow" | null; readonly hourCycle?: "h11" | "h12" | "h23" | "h24" | null; readonly localeMatcher?: "lookup" | "best fit" | null; readonly formatMatcher?: "basic" | "best fit" | null; readonly fractionalSecondDigits?: number | null; readonly hour12?: boolean | null; readonly numberingSystem?: string | null }
| — | — |
form | string | | — |
granularity | "minute" | "second" | minute | minute, second |
hourCycle | "h11" | "h12" | "h23" | "h24" | — | h11, h12, h23, h24 |
inputId | string | | — |
invalid | boolean | false | — |
label | string | | — |
locale | string | en-US | — |
max | string | | — |
min | string | | — |
model | { readonly date: string; readonly time: string; readonly minDate: string; readonly maxDate: string; readonly weekStartsOn: number; readonly allowedDates: readonly (string)[]; readonly allowedRanges: readonly ({ readonly start: string; readonly end: string })[] }
| — | — |
monthLabel | string | Choose month | — |
name | string | | — |
nextLabel | string | Next | — |
pickerLabel | string | Choose date | — |
placeholder | string | | — |
previousLabel | string | Previous | — |
readonly | boolean | false | — |
required | boolean | false | — |
size | "sm" | "md" | "lg" | md | sm, md, lg |
timeLabel | string | Time | — |
timeZone | string | | — |
today | string | | — |
type | "date" | "datetime-local" | "instant" | "zoned" | date | date, datetime-local, instant, zoned |
value | string | | — |
valueFormat | "iso" | "space" | iso | iso, space |
weekStartsOn | number | — | — |
yearLabel | string | Choose year | — |
Events
| Name | Detail | Description |
|---|---|---|
change | object
| Emitted when a toggleable control changes checked state. |
close | object
| Emitted when the component transitions to a closed state. |
input | object
| Emitted with the declared detail payload. |
open | object
| Emitted when the component transitions to an open state. |
query-change | object
| Emitted with the declared detail payload. |
validation-change | object
| Emitted with the declared detail payload. |
Slots
No slots.
Design tokens
Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.
Component tokens
No component tokens.
Shared tokens
No shared tokens.