Skip to main content
Urbicon UI

DatePicker

A text field with a calendar popover for picking a single date.

Playground

Input Variant
Calendar Variant
<script lang="ts">
  import { DatePicker } from '@urbicon-ui/blocks';

  const label = 'Date';
  const placeholder = 'Select a date';
</script>

<DatePicker
  {label}
  {placeholder}
/>

01 Examples

Basic DatePicker

A labelled date field with a calendar popover. The bound value is a Date; the field shows it formatted for the locale.
<script lang="ts">
  import { DatePicker } from '@urbicon-ui/blocks';

  let selectedDate = $state<Date | undefined>(undefined);
</script>

<div class="max-w-xs">
  <DatePicker
    bind:value={selectedDate}
    label="Event date"
    placeholder="Select a date"
    defaultMonth={2}
    defaultYear={2026}
  />

  {#if selectedDate}
    <div class="bg-surface-elevated border-border-subtle mt-3 rounded-lg border p-3">
      <p class="text-text-secondary text-sm">
        <span class="text-text-primary font-medium">Selected:</span>
        {selectedDate.toLocaleDateString('en-US', {
          weekday: 'long',
          day: 'numeric',
          month: 'long',
          year: 'numeric'
        })}
      </p>
    </div>
  {/if}
</div>

DateRangePicker

The separate DateRangePicker picks a start and end date in two clicks, and closes once both are set. Use it for bookings or a report filter.
<script lang="ts">
  import { DateRangePicker } from '@urbicon-ui/blocks';

  let value = $state<{ start: Date; end: Date } | undefined>(undefined);
</script>

<div class="max-w-xs">
  <DateRangePicker
    bind:value
    label="Travel dates"
    placeholder="Select a range"
    defaultMonth={2}
    defaultYear={2026}
  />

  {#if value}
    <div class="bg-surface-elevated border-border-subtle mt-3 rounded-lg border p-3">
      <p class="text-text-secondary text-sm">
        <span class="text-text-primary font-medium">From:</span>
        {value.start.toLocaleDateString('en-US', {
          day: 'numeric',
          month: 'long',
          year: 'numeric'
        })}
      </p>
      <p class="text-text-secondary text-sm">
        <span class="text-text-primary font-medium">To:</span>
        {value.end.toLocaleDateString('en-US', {
          day: 'numeric',
          month: 'long',
          year: 'numeric'
        })}
      </p>
      <p class="text-text-secondary mt-1 text-xs">
        {Math.ceil((value.end.getTime() - value.start.getTime()) / (1000 * 60 * 60 * 24)) + 1} days
      </p>
    </div>
  {/if}
</div>

With Constraints

minDate, maxDate, disabledDates and isDateDisabled together: only weekdays in March 2026 stay selectable, with weekends and holidays locked out.
Weekdays in March 2026 only, no holidays.
<script lang="ts">
  import { DatePicker } from '@urbicon-ui/blocks';

  let selectedDate = $state<Date | undefined>(undefined);

  const minDate = new Date(2026, 2, 1);
  const maxDate = new Date(2026, 2, 31);

  /** Disable weekends */
  function isWeekend(date: Date): boolean {
    const day = date.getDay();
    return day === 0 || day === 6;
  }

  /** Specific holidays / blocked dates */
  const holidays = [new Date(2026, 2, 6), new Date(2026, 2, 20)];
</script>

<div class="max-w-xs">
  <DatePicker
    bind:value={selectedDate}
    label="Appointment"
    placeholder="Pick a weekday"
    helper="Weekdays in March 2026 only, no holidays."
    {minDate}
    {maxDate}
    isDateDisabled={isWeekend}
    disabledDates={holidays}
    defaultMonth={2}
    defaultYear={2026}
  />

  {#if selectedDate}
    <div class="bg-surface-elevated border-border-subtle mt-3 rounded-lg border p-3">
      <p class="text-text-secondary text-sm">
        <span class="text-text-primary font-medium">Appointment:</span>
        {selectedDate.toLocaleDateString('en-US', {
          weekday: 'long',
          day: 'numeric',
          month: 'long',
          year: 'numeric'
        })}
      </p>
    </div>
  {/if}
</div>

02 Accessibility

ARIA Roles

The trigger input carries aria-haspopup="dialog" and aria-expanded, so the popover's state is announced. The embedded calendar is a role="grid" of day cells, with the same keyboard model as Calendar.

Keyboard Navigation

Enter, Space or ArrowDown open the calendar, Escape closes it. Inside, the arrow keys move between days and weeks and PageUp/PageDown between months. Focus rings use focus-visible:, so they appear for the keyboard only.

Screen Reader Labels

The label reaches the screen reader through the input. Every day cell carries an aria-label with the full date ("Thursday, 12 March 2026"), and error and helper text are linked through aria-describedby.

Internationalisation

Formatting goes through the native Intl.DateTimeFormat with the configured locale, so weekday names, month names and the input format follow the language without further configuration.

03 API Reference

38 props
38 props
Prop
Type
Default
Description

04 Types

Local type definitions used by this component.

14 types
Name
Kind
Category
Used by
Description

05 Installation

Import

import { DatePicker, DateRangePicker } from '@urbicon-ui/blocks';
import type { DatePickerProps, DateRangePickerProps } from '@urbicon-ui/blocks';