Usage
DatePicker lets people select a date, or a range of dates, from a month grid. mode="range" discriminates value/defaultValue/onChange (React), bind:value/defaultValue/onChange (Svelte), or the inputs bound to value/defaultValue/valueChange (Angular) to a [start, end] DateRange instead of a single Date.
Controlled selection
Use value with onChange in React, bind:value in Svelte, or [(value)] in Angular. A controlled DatePicker emits a request but does not change until its owner supplies the new value.
Selected: 9/20/2026
import { useState } from 'react';
import { DatePicker } from '@udixio/ui-react';
export default function DatePickerBasicReact() {
const [date, setDate] = useState<Date | null>(new Date());
return (
<div className="flex flex-col items-center gap-4">
<DatePicker value={date} onChange={setDate} />
<p className="text-body-medium">
Selected: {date ? date.toLocaleDateString() : '-'}
</p>
</div>
);
}Selected: 9/20/2026
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DatePicker } from '@udixio/ui-angular';
@Component({
selector: 'date-picker-basic-angular-example',
standalone: true,
imports: [DatePicker],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-col items-center gap-4">
<udx-date-picker [(value)]="date" />
<p class="text-body-medium">
Selected: {{ date ? date.toLocaleDateString() : '-' }}
</p>
</div>
`,
})
export class DatePickerBasicAngular {
protected date: Date | null = new Date();
}Selected: 9/20/2026
<script lang="ts">
import type { DatePickerValue } from '@udixio/core';
import { DatePicker } from '@udixio/ui-svelte';
let date = $state<DatePickerValue>(new Date());
const formatDate = (value: DatePickerValue) =>
value instanceof Date ? value.toLocaleDateString() : '-';
</script>
<div class="flex flex-col items-center gap-4">
<DatePicker bind:value={date} />
<p class="text-body-medium">Selected: {formatDate(date)}</p>
</div>Selecting a range
Set mode="range". The first click starts a new range; the second completes it in chronological order regardless of click order, and a third click after completion starts a new range.
Start: 6/10/2024
End: 6/20/2024
import { useState } from 'react';
import { DatePicker, type DateRange } from '@udixio/ui-react';
export default function DatePickerRangeReact() {
const [range, setRange] = useState<DateRange | null>([
new Date(2024, 5, 10),
new Date(2024, 5, 20),
]);
const [start, end] = range ?? [null, null];
return (
<div className="flex flex-col items-center gap-4">
<DatePicker mode="range" value={range} onChange={setRange} />
<p className="text-body-medium text-center">
Start: {start?.toLocaleDateString() ?? '-'}
<br />
End: {end?.toLocaleDateString() ?? '-'}
</p>
</div>
);
}Start: 6/10/2024
End: 6/20/2024
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DatePicker } from '@udixio/ui-angular';
import type { DateRange } from '@udixio/core';
@Component({
selector: 'date-picker-range-angular-example',
standalone: true,
imports: [DatePicker],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-col items-center gap-4">
<udx-date-picker mode="range" [(value)]="range" />
<p class="text-body-medium text-center">
Start: {{ start()?.toLocaleDateString() ?? '-' }}
<br />
End: {{ end()?.toLocaleDateString() ?? '-' }}
</p>
</div>
`,
})
export class DatePickerRangeAngular {
protected range: DateRange | null = [
new Date(2024, 5, 10),
new Date(2024, 5, 20),
];
protected start(): Date | null {
return this.range?.[0] ?? null;
}
protected end(): Date | null {
return this.range?.[1] ?? null;
}
}Start: 6/10/2024
End: 6/20/2024
<script lang="ts">
import type { DateRange } from '@udixio/core';
import { DatePicker } from '@udixio/ui-svelte';
let range = $state<DateRange | null>([
new Date(2024, 5, 10),
new Date(2024, 5, 20),
]);
const formatDate = (value: Date | null) => value?.toLocaleDateString() ?? '-';
</script>
<div class="flex flex-col items-center gap-4">
<DatePicker mode="range" bind:value={range} />
<p class="text-body-medium text-center">
Start: {formatDate(range?.[0] ?? null)}<br />
End: {formatDate(range?.[1] ?? null)}
</p>
</div>Uncontrolled usage
defaultValue captures the initial value once; the component then owns its own selection and only notifies changes.
import { DatePicker } from '@udixio/ui-react';
export default function DatePickerUncontrolledReact() {
return (
<DatePicker
defaultValue={new Date(2024, 5, 15)}
onChange={(date) => console.log('Selected:', date)}
/>
);
}import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DatePicker } from '@udixio/ui-angular';
import type { DatePickerValue } from '@udixio/core';
@Component({
selector: 'date-picker-uncontrolled-angular-example',
standalone: true,
imports: [DatePicker],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<udx-date-picker
[defaultValue]="defaultDate"
(valueChange)="log($event)"
/>
`,
})
export class DatePickerUncontrolledAngular {
protected defaultDate = new Date(2024, 5, 15);
protected log(value: DatePickerValue): void {
console.log('Selected:', value);
}
}<script lang="ts">
import { DatePicker } from '@udixio/ui-svelte';
</script>
<DatePicker defaultValue={new Date(2024, 5, 15)} onChange={(value) => console.log('Selected:', value)} />Constraining selectable dates
minDate/maxDate and shouldDisableDate are compared at day granularity, so a boundary carrying a time-of-day (for example new Date()) never disables its own day. Blocked days stay visible and focusable, but cannot be selected.
import { DatePicker } from '@udixio/ui-react';
export default function DatePickerConstraintsReact() {
return (
<div className="flex flex-col items-center gap-8">
<DatePicker
minDate={new Date(2024, 0, 1)}
maxDate={new Date(2024, 11, 31)}
defaultValue={new Date(2024, 5, 1)}
/>
<DatePicker
shouldDisableDate={(date) => {
const day = date.getDay();
return day === 0 || day === 6;
}}
defaultValue={new Date(2024, 5, 1)}
/>
</div>
);
}import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DatePicker } from '@udixio/ui-angular';
@Component({
selector: 'date-picker-constraints-angular-example',
standalone: true,
imports: [DatePicker],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-col items-center gap-8">
<udx-date-picker
[minDate]="minDate"
[maxDate]="maxDate"
[defaultValue]="defaultDate"
/>
<udx-date-picker
[shouldDisableDate]="isWeekend"
[defaultValue]="defaultDate"
/>
</div>
`,
})
export class DatePickerConstraintsAngular {
protected minDate = new Date(2024, 0, 1);
protected maxDate = new Date(2024, 11, 31);
protected defaultDate = new Date(2024, 5, 1);
protected isWeekend(date: Date): boolean {
const day = date.getDay();
return day === 0 || day === 6;
}
}<script lang="ts">
import { DatePicker } from '@udixio/ui-svelte';
</script>
<div class="flex flex-col items-center gap-8">
<DatePicker minDate={new Date(2024, 0, 1)} maxDate={new Date(2024, 11, 31)} defaultValue={new Date(2024, 5, 1)} />
<DatePicker
shouldDisableDate={(date) => date.getDay() === 0 || date.getDay() === 6}
defaultValue={new Date(2024, 5, 1)}
/>
</div>Localization
locale formats the month label and weekday headers; weekStartDay shifts which day begins each row.
import { DatePicker } from '@udixio/ui-react';
export default function DatePickerLocalizationReact() {
return (
<div className="flex flex-wrap justify-center gap-8">
<DatePicker locale="en-US" defaultValue={new Date(2024, 5, 1)} />
<DatePicker
locale="fr-FR"
weekStartDay={1}
defaultValue={new Date(2024, 5, 1)}
/>
</div>
);
}import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DatePicker } from '@udixio/ui-angular';
@Component({
selector: 'date-picker-localization-angular-example',
standalone: true,
imports: [DatePicker],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-wrap justify-center gap-8">
<udx-date-picker locale="en-US" [defaultValue]="defaultDate" />
<udx-date-picker
locale="fr-FR"
[weekStartDay]="1"
[defaultValue]="defaultDate"
/>
</div>
`,
})
export class DatePickerLocalizationAngular {
protected defaultDate = new Date(2024, 5, 1);
}<script lang="ts">
import { DatePicker } from '@udixio/ui-svelte';
</script>
<div class="flex flex-wrap justify-center gap-8">
<DatePicker locale="en-US" defaultValue={new Date(2024, 5, 1)} />
<DatePicker locale="fr-FR" weekStartDay={1} defaultValue={new Date(2024, 5, 1)} />
</div>Accessibility
The day grid uses the composite grid/row/gridcell pattern with one roving tabIndex per visible month. Arrow keys move focus by day or week, Home/End jump to the visible week’s boundaries, and PageUp/PageDown change month (Shift for year). The selected day’s gridcell carries aria-selected; its focusable day button carries aria-current="date" when it is today. Unavailable days stay focusable with aria-disabled instead of the native disabled attribute, so keyboard users can still traverse past them.
DatePicker does not render its own text input or popup positioning; combine it with TextField/IconButton and your own overlay to build a popup picker.