# Calendar

Inline single-date calendar built on the native library Calendar and wrapped with shadcn-style theme tokens.

Use Calendar when the date grid should stay visible in the page. Use `DatePickerComponent` when the same selection should live behind an input and popover trigger.

## Import

```ts
import { CalendarComponent } from '@edsis/component/calendar';
```

## Date adapter

consumer — including when federated into a host app that never wired one. You only need
to add a date adapter at the application root if you want a non-native one or a custom
locale (`MAT_DATE_LOCALE` flows in from the parent injector):

```ts
// app.config.ts — optional, only for a custom adapter/locale

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

## Usage

Bind `[(value)]` to a `Date | null` signal or component field. Use `startAt` when the first visible month should differ from the selected value.

```html
<Calendar [(value)]="selectedDate" [startAt]="selectedDate()" />
```

```ts
protected readonly selectedDate = signal<Date | null>(new Date(2026, 4, 22));
```

## Common patterns

### Constrained range

Use `min` and `max` to disable dates outside an allowed window.

```html
<Calendar [(value)]="billingDate" [min]="minDate" [max]="maxDate" [startAt]="billingDate()" />
```

```ts
protected readonly billingDate = signal<Date | null>(new Date(2026, 4, 15));
protected readonly minDate = new Date(2026, 4, 5);
protected readonly maxDate = new Date(2026, 4, 25);
```

### Disabled or booked dates

Pass a `dateFilter` function. It must return `true` for selectable dates and `false` for disabled dates.

```html
<Calendar [(value)]="visitDate" [dateFilter]="availableDateFilter" [startAt]="visitDate()" />
```

```ts
protected readonly bookedDates = [new Date(2026, 1, 12), new Date(2026, 1, 13)];

protected readonly availableDateFilter = (candidate: Date | null): boolean =>
  !!candidate && !this.bookedDates.some((bookedDate) => this.isSameDay(bookedDate, candidate));
```

### Presets

Compose preset buttons around the calendar and update the same `value` model.

```html
<Calendar [(value)]="presetDate" [startAt]="presetDate()" class="border-0" />

<button Button type="button" variant="outline" size="sm" (click)="selectPreset(7)">
  In a week
</button>
```

### Date and time

Calendar owns the date. Native time inputs or `InputGroupComponent` can own the time value next to it.

```html
<Calendar [(value)]="meetingDate" [startAt]="meetingDate()" />

<InputGroup>
  <input InputGroupInput type="time" [value]="startTime()" (input)="updateStartTime($event)" />
</InputGroup>
```

## API reference

| Input / Model | Type                                | Default   |
| ------------- | ----------------------------------- | --------- |
| `value`       | `Date \| null`                      | `null`    |
| `min`         | `Date \| null`                      | `null`    |
| `max`         | `Date \| null`                      | `null`    |
| `startAt`     | `Date \| null`                      | `null`    |
| `startView`   | `'month' \| 'year' \| 'multi-year'` | `'month'` |
| `dateFilter`  | `(date: Date \| null) => boolean`   | `null`    |
| `disabled`    | `boolean`                           | `false`   |
| `class`       | `string`                            | `''`      |

Implements `ControlValueAccessor` — usable with `[(ngModel)]` and reactive forms.

## Styling and theming

The host uses `--border`, `--background`, `--foreground`, and `--radius`. Pass `class` for layout utilities such as `shadow-sm`, `border-0`, or `[--calendar-width:20rem]`.

The calendar implements grid ARIA semantics and full keyboard navigation natively inside the shadcn token wrapper. Use `DatePickerComponent` for popover input flows; this primitive intentionally stays inline.

## Accessibility

## Keyboard interactions

- Arrow keys move between dates.
- Page Up and Page Down move by month.
- Home and End move to the start or end of the row.
- Enter selects the focused date.

## Angular notes

- A native date adapter is built in; provide one at app bootstrap only for a custom adapter/locale.
- `dateFilter` returns `true` for enabled dates, unlike some predicate APIs that return `true` for blocked dates.
- `disabled` marks the host as inert and updates the CVA disabled state.
- This component is a single-date primitive. Range selection is best modeled as a separate range primitive or by composing two calendars with application state.

## Source parity
