Level: molecule.
Purpose and use
Choose one or several filter values, optionally finding them by text. Use the single mode for immediate application and multiple mode for a draft with Apply.
Anatomy, behavior, and accessibility
- Filter Chip anchors a Dropdown in ordinary single mode, or a custom search/ multiselect overlay. Single mode prepends «Все», which emits null.
- Single selection emits the ID and closes. Multiple mode edits selected IDs in a draft; Apply emits the array, including an empty array when clearing an existing selection. Closing and reopening restores the applied selection.
- Search filters the supplied options by case-insensitive label substring after minSearchLength (default 3). It emits query changes but makes no request. Matching text is emphasized; hint/empty messages appear as status text.
- Selected options are grouped first; live multiselect also shows removable tags. maxSelected disables unselected options at the limit without disabling removal of enabled selected options. Disabled options cannot be toggled.
- Custom option rows support Enter/Space and checkbox/option selection semantics; decorative child checkboxes are hidden. Use unique IDs, meaningful labels and a search prompt matching the configured minimum.
- Searchable panels keep their outer overflow hidden and delegate vertical
scrolling to
.wbl-filter-dropdown-select__listand its__optionsregion. The list maximum height is16.75rem; live multiple selection keeps a 268px list height. Scroll containers useoverflow-y: autoandoverscroll-behavior: contain. - Lifecycle, open state, and validation state are controlled by the owning
screen through the nested Filter Chip.
openRequestasks the owner to setopened; the semantic Chip action is forwarded asactionand asks the owner to clear, reset, or remove its filter. The wrapper closes its overlay after that action but never mutates the owner's applied selection itself.
Open Questions
Custom overlays have no explicit Escape handler, arrow-key option navigation or focus restoration. The component does not provide remote-loading/error states; searchable means local filtering of options currently supplied by the parent.
Local component contract
This is the active owned contract for component.filter-dropdown-select. 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
WblFilterDropdownSelectComponent—wbl-filter-dropdown-select(src/app/design-system/patterns/filter-row/filter-dropdown-select.component.ts).
Inputs
WblFilterDropdownSelectComponent.label = input('Фильтр')WblFilterDropdownSelectComponent.allLabel = input('Все')WblFilterDropdownSelectComponent.options = input<WblFilterDropdownSelectOption[]>([])WblFilterDropdownSelectComponent.selectedId = input<string | null>(null)WblFilterDropdownSelectComponent.selectedIds = input<string[]>([])WblFilterDropdownSelectComponent.lifecycle = input<WblFilterLifecycle>('pinned')WblFilterDropdownSelectComponent.opened = input(false)WblFilterDropdownSelectComponent.invalid = input(false)WblFilterDropdownSelectComponent.errorText = input('')WblFilterDropdownSelectComponent.disabled = input(false)WblFilterDropdownSelectComponent.multiple = input(false)WblFilterDropdownSelectComponent.maxSelected = input<number | null>(null)WblFilterDropdownSelectComponent.searchable = input(false)WblFilterDropdownSelectComponent.searchValue = input('')WblFilterDropdownSelectComponent.searchPlaceholder = input('Введите первые 3 символа УИН')WblFilterDropdownSelectComponent.searchAriaLabel = input('Поиск')WblFilterDropdownSelectComponent.minSearchLength = input(MIN_SEARCH_LENGTH)WblFilterDropdownSelectComponent.emptyResultsText = input('Ничего не найдено')WblFilterDropdownSelectComponent.clearLabel = input('Очистить')WblFilterDropdownSelectComponent.applyLabel = input('Применить')WblFilterDropdownSelectComponent.showSelectAll = input(false)WblFilterDropdownSelectComponent.selectAllLabel = input('Выбрать все')
Public types and allowed values
type WblFilterDropdownSelectOption = {
id: string;
label: string;
disabled?: boolean;
};
WblFilterLifecycle and WblFilterAction are the shared Filter Chip types:
'required' | 'pinned' | 'optional' and 'clear' | 'reset' | 'remove'.
Models
- None.
Outputs
WblFilterDropdownSelectComponent.selectedIdChange = output<string | null>()WblFilterDropdownSelectComponent.selectedIdsChange = output<string[]>()WblFilterDropdownSelectComponent.openRequest = output<boolean>()WblFilterDropdownSelectComponent.searchValueChange = output<string>()WblFilterDropdownSelectComponent.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-select.component.ts. - Focused test:
src/app/design-system/patterns/filter-row/filter-dropdown-select.component.spec.ts. - Public export:
export * from './patterns/filter-row/filter-dropdown-select.component';insrc/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.
M-002 extension
M-002 added two optional inputs for the multiple-selection panel:
WblFilterDropdownSelectComponent.showSelectAll = input(false)WblFilterDropdownSelectComponent.selectAllLabel = input('Выбрать все')
When multiple=true and showSelectAll=true, the panel displays a native
button with selectAllLabel. It copies every enabled option into the draft
selection, respects maxSelected when a limit exists, and does not emit the
applied value until the user chooses Apply. The action is disabled when there
are no enabled options or all enabled options are already selected. The default
false preserves the existing helper text and behavior.
The current Transport Requests Тип заявки filter enables showSelectAll for
its three available preliminary request types. The Angular implementation,
focused test, and shared Filter Row Storybook evidence are current.
M-002 per-tab option catalogs
Transport Requests uses screen-owned request-type option sets: three values for Preliminary, eleven for New, In progress and Archived, and Commercial only for Awaiting payment. The Type control remains hidden on Awaiting payment. Selection state is separate per tab and the screen provides option IDs and labels. Filter Dropdown Select does not own a global request-type enum.
The Route control uses multiple=true and searchable=true; Status uses
multiple=true; vehicle, assignment, shipment and participant controls use
searchable single selection. Options come from the active tab's static fixtures,
and applied values stay in that tab's screen-owned state. Existing component
inputs express every mode, so the public API is unchanged.
M-002 scrollbar treatment
The list/options scroll containers extend the scrollbar outside their content
with margin-inline-end: calc(-1 * var(--space-100)) and matching
padding-inline-end: var(--space-100). They use the same native 4px treatment
as Dropdown: tertiary thumb, transparent track/corner, pill radius,
scrollbar-width: thin fallback and scrollbar-color tertiary/transparent.
The thumb is visible whenever content overflows and is not hover-only. Searchable
panel overflow remains hidden so the list, rather than the whole panel, scrolls.
No public Filter Dropdown Select API is added.