# Filter Dropdown Range

Level: molecule.

## Purpose and use

Edit a bounded integer interval with explicit Apply/Clear. Use a date-range
filter for dates and a different input contract for fractional/signed entry.

## Anatomy, behavior, and accessibility

- Filter Chip opens a named dialog with From/To Inputs, helper text and footer.
  The chip can display both bounds or a single externally supplied bound.
- Opening copies applied values to a draft. Typed/pasted nondigits are removed;
  blur clamps each bound to truncated min/max. Apply requires both draft fields,
  except clearing an existing range to `{from:null,to:null}`.
- An inverted range is changed to `max-1,max`, with both bounds clamped; it is
  not swapped and does not show an error. Apply emits rangeChange and closes.
- The first field receives focus on attach. Enter in either input applies;
  Escape in either input, backdrop and detach close. Field names can be explicit
  or derived from label; helper text describes the bounds. Unit appears in chip copy.
- Disabled blocks trigger and footer actions. Lifecycle, open state, and error
  state 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 then closes the overlay.
  Clear edits the draft until Apply.

## Open Questions

Input handling strips minus signs and decimal separators despite numeric inputs.
Escape is bound to the two field wrappers, not the whole dialog. There is no
explicit focus trap or return-to-trigger behavior.

## Local component contract

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

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

### Inputs

- `WblFilterDropdownRangeComponent.label = input('Фильтр')`
- `WblFilterDropdownRangeComponent.fromValue = input<number | null>(null)`
- `WblFilterDropdownRangeComponent.toValue = input<number | null>(null)`
- `WblFilterDropdownRangeComponent.min = input(0)`
- `WblFilterDropdownRangeComponent.max = input(999)`
- `WblFilterDropdownRangeComponent.unit = input('')`
- `WblFilterDropdownRangeComponent.lifecycle = input<WblFilterLifecycle>('pinned')`
- `WblFilterDropdownRangeComponent.opened = input(false)`
- `WblFilterDropdownRangeComponent.invalid = input(false)`
- `WblFilterDropdownRangeComponent.errorText = input('')`
- `WblFilterDropdownRangeComponent.disabled = input(false)`
- `WblFilterDropdownRangeComponent.description = input<string | null>(null)`
- `WblFilterDropdownRangeComponent.fromPlaceholder = input('От')`
- `WblFilterDropdownRangeComponent.toPlaceholder = input('До')`
- `WblFilterDropdownRangeComponent.fromAriaLabel = input<string | null>(null)`
- `WblFilterDropdownRangeComponent.toAriaLabel = input<string | null>(null)`
- `WblFilterDropdownRangeComponent.clearLabel = input('Очистить')`
- `WblFilterDropdownRangeComponent.applyLabel = input('Применить')`

### Public types and allowed values

```ts
type WblFilterDropdownRangeValue = {
  from: number | null;
  to: number | null;
};
```

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

### Models

- None.

### Outputs

- `WblFilterDropdownRangeComponent.rangeChange = output<WblFilterDropdownRangeValue>()`
- `WblFilterDropdownRangeComponent.openRequest = output<boolean>()`
- `WblFilterDropdownRangeComponent.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-range.component.ts`.
- Focused test: `src/app/design-system/patterns/filter-row/filter-dropdown-range.component.spec.ts`.
- Public export: `export * from './patterns/filter-row/filter-dropdown-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.
