# Filter Dropdown Calendar Range

Level: molecule.

## Purpose and use

Edit a period filter while preserving the applied range until confirmation.
Use the single-date wrapper when the user should choose exactly one date.

## Anatomy, behavior, and accessibility

- Filter Chip opens a named dialog with a two-month Calendar, optional description,
  Clear and Apply. Applied endpoints format as DD.MM.YYYY - DD.MM.YYYY.
- Opening copies the applied endpoints into a draft. A changed complete draft
  enables Apply; a half-range does not. Clear sets both draft endpoints to null
  and can be applied only to clear an existing complete range.
- Apply emits `{start,end}` and closes. Backdrop/detach or Escape in the dialog
  closes without committing. Lifecycle, open state, and validation are
  controlled by the owning screen through the nested Filter Chip. `openRequest`
  asks the owner to set `opened`; its semantic `action` asks the owner to clear,
  reset, or remove the filter and closes the overlay. The parent owns applied
  state and removal.
- Focus moves to the first Calendar input/control on attach. Disabled blocks
  trigger opening and footer actions. Supply a descriptive period label; both
  endpoint values use YYYY-MM-DD and Calendar enforces its current date policy.

## Open Questions

There is no explicit focus trap or focus restoration. An externally supplied
partial applied range is not a filled chip and cannot be cleared through the
same complete-range Apply path; consumers should supply complete/null pairs.

## Local component contract

This is the active owned contract for `component.filter-dropdown-calendar-range`. 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

- `WblFilterDropdownCalendarRangeComponent` — `wbl-filter-dropdown-calendar-range` (src/app/design-system/patterns/filter-row/filter-dropdown-calendar-range.component.ts).

### Inputs

- `WblFilterDropdownCalendarRangeComponent.label = input('Период')`
- `WblFilterDropdownCalendarRangeComponent.rangeStart = input<string | null>(null)`
- `WblFilterDropdownCalendarRangeComponent.rangeEnd = input<string | null>(null)`
- `WblFilterDropdownCalendarRangeComponent.referenceDate = input(DEFAULT_TODAY)`
- `WblFilterDropdownCalendarRangeComponent.today = input(DEFAULT_TODAY)`
- `WblFilterDropdownCalendarRangeComponent.lifecycle = input<WblFilterLifecycle>('pinned')`
- `WblFilterDropdownCalendarRangeComponent.opened = input(false)`
- `WblFilterDropdownCalendarRangeComponent.invalid = input(false)`
- `WblFilterDropdownCalendarRangeComponent.errorText = input('')`
- `WblFilterDropdownCalendarRangeComponent.disabled = input(false)`
- `WblFilterDropdownCalendarRangeComponent.description = input<string | null>(null)`
- `WblFilterDropdownCalendarRangeComponent.clearLabel = input('Очистить')`
- `WblFilterDropdownCalendarRangeComponent.applyLabel = input('Применить')`

### Public types and allowed values

```ts
interface WblCalendarRange {
  start: string | null;
  end: string | null;
}
```

`WblFilterLifecycle` and `WblFilterAction` are shared with Filter Chip:
`'required' | 'pinned' | 'optional'` and `'clear' | 'reset' | 'remove'`.

### Models

- None.

### Outputs

- `WblFilterDropdownCalendarRangeComponent.rangeChange = output<WblCalendarRange>()`
- `WblFilterDropdownCalendarRangeComponent.openRequest = output<boolean>()`
- `WblFilterDropdownCalendarRangeComponent.action = output<WblFilterAction>()`

### Slots and projection markers

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

### Local evidence

- Code: `src/app/design-system/patterns/filter-row/filter-dropdown-calendar-range.component.ts`.
- Focused test: `src/app/design-system/patterns/filter-row/filter-dropdown-calendar-range.component.spec.ts`.
- Public export: `export * from './patterns/filter-row/filter-dropdown-calendar-range.component';` in `src/app/design-system/index.ts`.
- Storybook: `storybook/stories/filter-row.stories.ts` (`Design System/Patterns/wbl-filter-row`). This is the shared active Storybook story for this family.

## 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.
