# Date Picker

Popup date input built natively on the library Calendar and CDK overlay, styled through the shared shadcn token bridge.

The upstream shadcn Date Picker is composed from Popover and Calendar. This Angular library exposes `DatePicker` as the app-level wrapper while preserving the same product behavior: an input trigger, a calendar popup, selected state, and date constraints.

## Date adapter

```ts
export const appConfig = { providers: [] };
```

## Import

```ts
import { DatePickerComponent } from '@edsis/component/date-picker';
import { LabelComponent } from '@edsis/component/label';
```

## Usage

Pair the picker with a visible label through the `id` input, then bind the selected date through the signal model.

```html
<label Label for="date-picker-demo">Date</label>
<DatePicker id="date-picker-demo" class="w-72" [(value)]="date" placeholder="Pick a date" />
```

The component also implements `ControlValueAccessor`, so it can be used with reactive forms or `ngModel`.

## Common patterns

### Basic

```html
<label Label for="date-picker-simple">Date</label>
<DatePicker id="date-picker-simple" class="w-44" [(value)]="basicDate" placeholder="Pick a date" />
```

### Coordinated range

Use two date pickers when the product needs a start and end date but does not need a dedicated range-calendar primitive.

```html
<div class="grid gap-4 sm:grid-cols-2">
  <div class="grid gap-2">
    <label Label for="date-range-start">Start date</label>
    <DatePicker id="date-range-start" [(value)]="rangeStart" [max]="rangeEnd()" />
  </div>
  <div class="grid gap-2">
    <label Label for="date-range-end">End date</label>
    <DatePicker id="date-range-end" [(value)]="rangeEnd" [min]="rangeStart()" />
  </div>
</div>
```

### Date of birth

Use `startView="multi-year"` and `startAt` for dates that are usually far away from the current month.

```html
<label Label for="date-picker-birth">Date of birth</label>
<DatePicker
  id="date-picker-birth"
  class="w-48"
  [(value)]="birthDate"
  placeholder="Select date"
  [startAt]="birthStartAt"
  startView="multi-year"
/>
```

### Date plus time

Pair the date picker with a native `input[type="time"]` for date-time forms.

```html
<div class="grid gap-4 sm:grid-cols-[minmax(0,12rem)_8rem]">
  <div class="grid gap-2">
    <label Label for="date-picker-time-date">Date</label>
    <DatePicker id="date-picker-time-date" [(value)]="timeDate" />
  </div>
  <div class="grid gap-2">
    <label Label for="date-picker-time-input">Time</label>
    <input id="date-picker-time-input" Input type="time" step="1" [value]="timeValue()" />
  </div>
</div>
```

### Disabled dates

Use `min`, `max`, and `dateFilter` to prevent invalid choices in the calendar before submit.

```ts
readonly minBookingDate = new Date(2026, 0, 1);
readonly maxBookingDate = new Date(2026, 11, 31);
readonly weekdayFilter = (date: Date | null): boolean => {
  const day = date?.getDay();
  return day !== 0 && day !== 6;
};
```

```html
<DatePicker
  id="date-picker-subscription"
  [(value)]="subscriptionDate"
  [min]="minBookingDate"
  [max]="maxBookingDate"
  [dateFilter]="weekdayFilter"
/>
```

### RTL

Set `dir="rtl"` on a wrapping container or at the application shell. The picker follows the surrounding direction.

```html
<div dir="rtl" lang="ar" class="grid max-w-xs gap-2 text-right">
  <label Label for="date-picker-rtl">Date</label>
  <DatePicker id="date-picker-rtl" [(value)]="rtlDate" placeholder="Pick a date" />
</div>
```

## API reference

| Input / Model     | Type                                | Default              |
| ----------------- | ----------------------------------- | -------------------- |
| `value`           | `Date \| null`                      | `null`               |
| `id`              | `string \| null`                    | `null`               |
| `placeholder`     | `string`                            | `'Pick a date'`      |
| `required`        | `boolean`                           | `false`              |
| `min`             | `Date \| null`                      | `null`               |
| `max`             | `Date \| null`                      | `null`               |
| `startAt`         | `Date \| null`                      | `null`               |
| `startView`       | `'month' \| 'year' \| 'multi-year'` | `'month'`            |
| `touchUi`         | `boolean`                           | `false`              |
| `dateFilter`      | `(date: Date \| null) => boolean`   | `null`               |
| `panelClass`      | `string \| string[]`                | `'datepicker-panel'` |
| `aria-label`      | `string \| null`                    | `null`               |
| `aria-labelledby` | `string \| null`                    | `null`               |
| `disabled`        | `boolean`                           | `false`              |
| `class`           | `string`                            | `''`                 |

## Styling and theming

The host accepts `class` for width and layout utilities. The inner field is full width, so classes such as `w-44`, `w-72`, and `w-full` should be placed on `DatePicker`.

The popup panel accepts `panelClass`, and calendar colors come from the shared theme tokens for popover, foreground, primary, and ring colors.

## Accessibility

- Pair the date picker with a visible label using the `id` input, or provide `aria-label` / `aria-labelledby`.

- Use constraints such as `min`, `max`, and `dateFilter` when dates are not selectable.
- Keep the visible label specific, such as `Start date`, `End date`, or `Subscription date`.

## Keyboard interactions

- Tab moves focus to the date input and toggle button.
- Enter or Space on the toggle opens the calendar popup.
- Arrow keys navigate dates while the calendar is open.
- Enter selects the focused date.
- Escape closes the popup and returns focus to the trigger.

## Angular notes

- A native date adapter is built in; provide one at the application root only for a custom adapter/locale.
- Use `[(value)]` when binding to a signal-backed `Date | null` value.
- Use the component as a CVA inside Angular forms when validation and form submission belong to a `FormControl`.
- `startView="multi-year"` is useful for birthdays and other far-past dates.
- For range selection today, coordinate two `DatePicker` instances with reciprocal `min` and `max` bindings.

## Source parity

This Angular implementation follows the current shadcn Date Picker information architecture, composing the native library Calendar inside a CDK overlay.

The upstream Range Picker example is represented as two coordinated `DatePicker` controls rather than a single range-calendar API. The upstream Natural Language example can be built by parsing text into a `Date | null` value and binding that value to `DatePicker`.
