# Calendar

Level: molecule.

## Purpose and use

Choose a past/current date or a date range. Use a filter-calendar wrapper when
changes must remain drafts until Apply; Calendar itself emits selections directly.

## Anatomy, behavior, and accessibility

- One month is shown for a date, two adjacent months for `range=true`. Headers
  switch between days, months and a 20-year picker. Optional date inputs,
  description and preset menu surround the grids.
- Values use `YYYY-MM-DD`; visible date inputs use `ДД.ММ.ГГГГ`. Future days are
  disabled relative to `today`. Invalid manual dates show validation feedback.
- A first range click emits `{start, end: null}`; a second completes and orders
  the endpoints. A click after a complete range starts a new selection. Clearing
  a single date input and leaving it restores `today` and emits it.
- Day-grid arrows move by day/week; Home/End reach week boundaries; PageUp/Down
  move months and Shift+PageUp/Down move years. Month/year grids also support
  directional focus. Native buttons activate the focused choice.
- Grid cells expose full Russian date labels, selection, today and disabled
  semantics. Visible input description/error text is connected with
  `aria-describedby`. Keep meaningful description text when date limits matter.
- Built-in preset IDs are today, yesterday, current-week, previous-week,
  previous-month and custom. Other IDs emit `presetSelect` without an automatic
  date calculation; the parent owns their meaning.

## Open Questions

There is no min/max input or arbitrary disabled-date predicate. This is not a
future booking calendar. Hiding the description also hides the current manual
input error explanation; that combination needs a product accessibility decision.

## Local component contract

This is the active owned contract for `component.calendar`. The API below
is verified against the current local implementation, focused test and story.
The Source commit `0112cba0779a2d2a4b6c7a17243201694344d70a` remains
migration provenance, not the runtime owner.

### Classes and selectors

- `WblCalendarComponent` — `wbl-calendar` (src/app/design-system/patterns/calendar/calendar.component.ts).

### Inputs

- `WblCalendarComponent.mode = input<WblCalendarMode>('days')`
- `WblCalendarComponent.dropdown = input(true)`
- `WblCalendarComponent.range = input(false)`
- `WblCalendarComponent.referenceDate = input(DEFAULT_TODAY)`
- `WblCalendarComponent.value = input<string | null>(null)`
- `WblCalendarComponent.rangeStart = input<string | null>(null)`
- `WblCalendarComponent.rangeEnd = input<string | null>(null)`
- `WblCalendarComponent.today = input(DEFAULT_TODAY)`
- `WblCalendarComponent.showDateInputs = input(true)`
- `WblCalendarComponent.showDescription = input(true)`
- `WblCalendarComponent.descriptionText = input('Description')`
- `WblCalendarComponent.showPresets = input(true)`
- `WblCalendarComponent.presets = input<WblCalendarPreset[]>(DEFAULT_PRESETS)`
- `WblCalendarComponent.selectedPresetId = input<string | null>('custom')`
- `WblCalendarComponent.ariaLabel = input('Календарь')`

### Public types and allowed values

```ts
type WblCalendarMode = 'days' | 'months' | 'years';
interface WblCalendarPreset {
  id: string;
  label: string;
}
interface WblCalendarRange {
  start: string | null;
  end: string | null;
}
```

### Models

- None.

### Outputs

- `WblCalendarComponent.valueChange = output<string>()`
- `WblCalendarComponent.rangeChange = output<WblCalendarRange>()`
- `WblCalendarComponent.modeChange = output<WblCalendarMode>()`
- `WblCalendarComponent.visibleDateChange = output<string>()`
- `WblCalendarComponent.presetSelect = output<WblCalendarPreset>()`

### Slots and projection markers

- The exact template has no Angular content-projection slot.

### Local evidence

- Code: `src/app/design-system/patterns/calendar/calendar.component.ts`.
- Focused test: `src/app/design-system/patterns/calendar/calendar.component.spec.ts`.
- Public export: `export * from './patterns/calendar/calendar.component';` in `src/app/design-system/index.ts`.
- Storybook: `storybook/stories/calendar.stories.ts` (`Design System/Patterns/wbl-calendar`).

## Figma status

This runtime contract does not infer a Figma owner. Assembly evidence, when
verified, is maintained separately through the inventory-linked sidecar.

## Provenance

The archived source-document copy is historical evidence only. The active
resolver is local code/test/export and the exact Storybook story above.
