@rt-tools/ui-kit-v2 0.19.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -347,9 +347,21 @@ class RtSelectComponent extends RtFormControlBase {
347
347
  super.clear(event);
348
348
  this.selectionChange.emit(null);
349
349
  }
350
+ /**
351
+ * Открытый список встаёт подсветкой на выбранный пункт.
352
+ *
353
+ * Иначе стрелка вниз начинала с первого пункта, и человек с выбранным «20» из «10, 20, 40»
354
+ * получал «10» вместо «40».
355
+ */
350
356
  onOpened() {
351
357
  const v = this.value();
352
358
  this.openBranches.set(rtTreeOpenFor(this.options(), v === null ? [] : [v]));
359
+ if (v !== null) {
360
+ const chosen = this.rows().findIndex((row) => row.option.value === v);
361
+ if (chosen >= 0) {
362
+ this.activeIndex.set(chosen);
363
+ }
364
+ }
353
365
  }
354
366
  toggleBranch(event, value) {
355
367
  event.stopPropagation();
@@ -382,7 +394,9 @@ class RtSelectComponent extends RtFormControlBase {
382
394
  if (OPEN_KEYS.has(event.key)) {
383
395
  event.preventDefault();
384
396
  this.popover().open();
385
- this.#moveActive(1);
397
+ if (this.activeIndex() < 0) {
398
+ this.#moveActive(1);
399
+ }
386
400
  }
387
401
  return;
388
402
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-select.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/select/rt-select-active-option.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select-tree.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select-trigger.directive.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select.component.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select.component.html","../../../projects/ui-kit-v2/src/lib/components/select/rt-tools-ui-kit-v2-select.ts"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport { afterRenderEffect, inject } from '@angular/core';\n\n/**\n * Держит подсвеченную клавишами опцию в видимой части панели.\n *\n * Панель списка ограничена по высоте, и длинный список прокручивается внутри неё. Клавиши двигают\n * подсветку, но фокус остаётся на поле: браузер сам панель не прокручивает, и подсветка уходила\n * за нижний край — человек выбирал Enter'ом то, чего не видел. После каждой отрисовки, в которой\n * сменилась подсвеченная опция, она прокручивается ровно настолько, чтобы встать в панель.\n *\n * Панель рисуется в наложении, вне поддерева семьи, поэтому опция ищется в документе по своему\n * идентификатору — тому же, что стоит в `aria-activedescendant`. На сервере отрисовки нет, и\n * эффект не выполняется; среда без `scrollIntoView` пропускается.\n *\n * Зовётся в контексте внедрения — полем или конструктором семьи.\n *\n * @param activeOptionId идентификатор подсвеченной опции; `null` — подсветки нет или панель закрыта\n */\nexport function rtScrollActiveOptionIntoView(activeOptionId: () => string | null): void {\n const document: Document = inject(DOCUMENT);\n\n afterRenderEffect((): void => {\n const id: string | null = activeOptionId();\n const option: HTMLElement | null = id ? document.getElementById(id) : null;\n\n if (typeof option?.scrollIntoView === 'function') {\n option.scrollIntoView({ block: 'nearest' });\n }\n });\n}\n","import { IRtSelect } from './rt-select.model';\n\n/**\n * Дерево опций выбора из списка — общее для `rt-select` и `rt-multiselect`.\n *\n * Обе семьи раскладывают, ищут и считают дерево одинаково, поэтому это чистые функции в одном\n * месте: две копии разошлись бы на первой правке. Состояние — какие ветки раскрыты — живёт в семье,\n * здесь только расчёт по нему.\n */\n\ntype TOption<TValue> = IRtSelect.Option<TValue>;\ntype TRow<TValue> = IRtSelect.Row<TValue>;\n\nfunction childrenOf<TValue>(option: TOption<TValue>): ReadonlyArray<TOption<TValue>> {\n return option.children ?? [];\n}\n\nfunction isBranch<TValue>(option: TOption<TValue>): boolean {\n return childrenOf(option).length > 0;\n}\n\n/** Список — дерево, если хоть у одной опции есть дети. Плоский список рисуется как прежде. */\nexport function rtTreeIsTree<TValue>(options: ReadonlyArray<TOption<TValue>>): boolean {\n return options.some((option: TOption<TValue>): boolean => isBranch(option));\n}\n\n/** Опция по значению на любой глубине. */\nexport function rtTreeFind<TValue>(options: ReadonlyArray<TOption<TValue>>, value: TValue): TOption<TValue> | undefined {\n for (const option of options) {\n if (option.value === value) {\n return option;\n }\n const found: TOption<TValue> | undefined = rtTreeFind(childrenOf(option), value);\n if (found) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * Включённые листья под опцией; у самого листа — он сам. Отключённая ветка не отдаёт никого: её\n * листья выбрать нельзя, как и её саму.\n */\nexport function rtTreeLeaves<TValue>(option: TOption<TValue>): ReadonlyArray<TValue> {\n if (option.disabled) {\n return [];\n }\n if (!isBranch(option)) {\n return [option.value];\n }\n return childrenOf(option).flatMap((child: TOption<TValue>): ReadonlyArray<TValue> => rtTreeLeaves(child));\n}\n\n/** Сколько включённых листьев ветки выбрано. Флажок ветки выводится из этого, а не хранится. */\nexport function rtTreeBranchState<TValue>(option: TOption<TValue>, chosen: ReadonlyArray<TValue>): IRtSelect.TBranchState {\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(option);\n const count: number = leaves.filter((leaf: TValue): boolean => chosen.includes(leaf)).length;\n if (count === 0) {\n return 'none';\n }\n return count === leaves.length ? 'all' : 'some';\n}\n\nfunction holdsChosen<TValue>(option: TOption<TValue>, chosen: ReadonlyArray<TValue>): boolean {\n return childrenOf(option).some((child: TOption<TValue>): boolean => chosen.includes(child.value) || holdsChosen(child, chosen));\n}\n\nfunction collectOpen<TValue>(list: ReadonlyArray<TOption<TValue>>, chosen: ReadonlyArray<TValue>, open: Set<TValue>): void {\n for (const option of list) {\n if (holdsChosen(option, chosen)) {\n open.add(option.value);\n collectOpen(childrenOf(option), chosen, open);\n }\n }\n}\n\n/** Ветки, под которыми лежит выбранное значение: они раскрыты, когда список открывается. */\nexport function rtTreeOpenFor<TValue>(options: ReadonlyArray<TOption<TValue>>, chosen: ReadonlyArray<TValue>): ReadonlySet<TValue> {\n const open: Set<TValue> = new Set<TValue>();\n collectOpen(options, chosen, open);\n return open;\n}\n\nfunction matches<TValue>(option: TOption<TValue>, term: string): boolean {\n return option.label.toLowerCase().includes(term);\n}\n\nfunction descendantMatches<TValue>(option: TOption<TValue>, term: string): boolean {\n return childrenOf(option).some((child: TOption<TValue>): boolean => matches(child, term) || descendantMatches(child, term));\n}\n\ninterface ITreeWalk<TValue> {\n readonly open: ReadonlySet<TValue>;\n readonly term: string;\n readonly rows: TRow<TValue>[];\n}\n\ninterface IRowPlace<TValue> {\n readonly level: number;\n readonly parent: TValue | null;\n readonly filtered: boolean;\n}\n\n/**\n * Раскладка одной опции: кладёт её строку и отвечает, где раскладывать её детей, или `null`, если\n * их не видно. `filtered` — действует ли поисковое слово на уровень: под веткой, совпавшей самой и\n * раскрытой, дети идут все, как без поиска.\n */\nfunction placeOption<TValue>(walk: ITreeWalk<TValue>, option: TOption<TValue>, place: IRowPlace<TValue>): IRowPlace<TValue> | null {\n const self: boolean = !place.filtered || matches(option, walk.term);\n const below: boolean = place.filtered && descendantMatches(option, walk.term);\n if (!self && !below) {\n return null;\n }\n const branch: boolean = isBranch(option);\n const openBySet: boolean = self && walk.open.has(option.value);\n const open: boolean = branch && (openBySet || below);\n walk.rows.push({ option, branch, open, level: place.level, parent: place.parent });\n return open ? { level: place.level + 1, parent: option.value, filtered: place.filtered && !openBySet } : null;\n}\n\nfunction walkRows<TValue>(walk: ITreeWalk<TValue>, list: ReadonlyArray<TOption<TValue>>, place: IRowPlace<TValue>): void {\n for (const option of list) {\n const childPlace: IRowPlace<TValue> | null = placeOption(walk, option, place);\n if (childPlace) {\n walkRows(walk, childrenOf(option), childPlace);\n }\n }\n}\n\n/**\n * Видимые строки по уровням. Без поискового слова раскрыты ветки из `open`. Со словом строка\n * остаётся, если совпала она сама или кто-то под ней, и путь к совпадению показан раскрытым.\n * Ветка, совпавшая сама, держит детей такими, какими они были.\n */\nexport function rtTreeRows<TValue>(\n options: ReadonlyArray<TOption<TValue>>,\n open: ReadonlySet<TValue>,\n rawTerm: string = ''\n): ReadonlyArray<TRow<TValue>> {\n const term: string = rawTerm.toLowerCase().trim();\n const walk: ITreeWalk<TValue> = { open, term, rows: [] };\n walkRows(walk, options, { level: 0, parent: null, filtered: term.length > 0 });\n return walk.rows;\n}\n\nfunction sideRight<TValue>(rows: ReadonlyArray<TRow<TValue>>, row: TRow<TValue>, index: number): IRtSelect.SideKeyAnswer<TValue> {\n if (row.branch && !row.open) {\n return { toggle: row.option.value, index };\n }\n const firstChild: boolean = row.branch && rows[index + 1]?.parent === row.option.value;\n return { toggle: null, index: firstChild ? index + 1 : index };\n}\n\nfunction sideLeft<TValue>(rows: ReadonlyArray<TRow<TValue>>, row: TRow<TValue>, index: number): IRtSelect.SideKeyAnswer<TValue> {\n if (row.branch && row.open) {\n return { toggle: row.option.value, index };\n }\n const parentIndex: number = rows.findIndex((candidate: TRow<TValue>): boolean => candidate.option.value === row.parent);\n return { toggle: null, index: parentIndex >= 0 ? parentIndex : index };\n}\n\n/**\n * Ответ на боковую стрелку. Вправо: свёрнутая ветка раскрывается, раскрытая уводит подсветку на\n * первого ребёнка. Влево: раскрытая ветка сворачивается, иначе подсветка уходит на родителя.\n */\nexport function rtTreeSideKey<TValue>(rows: ReadonlyArray<TRow<TValue>>, index: number, key: string): IRtSelect.SideKeyAnswer<TValue> {\n const row: TRow<TValue> | undefined = rows[index];\n if (row && key === 'ArrowRight') {\n return sideRight(rows, row, index);\n }\n if (row && key === 'ArrowLeft') {\n return sideLeft(rows, row, index);\n }\n return { toggle: null, index };\n}\n\n/** Набор раскрытых веток с переключённой одной. */\nexport function rtTreeToggle<TValue>(open: ReadonlySet<TValue>, value: TValue): ReadonlySet<TValue> {\n const next: Set<TValue> = new Set<TValue>(open);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n return next;\n}\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtSelect } from './rt-select.model';\n\n/**\n * Маркер своей разметки указателя — того, что человек нажимает, чтобы открыть список.\n *\n * Поведение указателя остаётся киту: открытие панели, её ширина, приметы доступности,\n * отключённость, клавиши и закрытие висят на кнопке. Потребитель даёт только то, что рисуется\n * внутри неё, и получает три значения обстановки: открыт ли список, что выбрано, отключён ли выбор.\n *\n * Один маркер на обе семьи выбора: они отличаются только разметкой внутри кнопки, и два маркера\n * разошлись бы на первой же правке.\n *\n * @example\n * ```html\n * <rt-select [options]=\"options\">\n * <ng-template rtSelectTrigger let-state>\n * <rt-tag [value]=\"state.label\" [icon]=\"state.isOpen ? 'chevron-up' : 'chevron-down'\" />\n * </ng-template>\n * </rt-select>\n * ```\n */\n@Directive({\n selector: '[rtSelectTrigger]',\n})\nexport class RtSelectTriggerDirective<TValue = unknown> {\n public readonly templateRef: TemplateRef<IRtSelect.TriggerContext<TValue>> =\n inject<TemplateRef<IRtSelect.TriggerContext<TValue>>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n forwardRef,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { IRtInput } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { IRtPopover } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { rtScrollActiveOptionIntoView } from './rt-select-active-option';\nimport { rtTreeFind, rtTreeIsTree, rtTreeOpenFor, rtTreeRows, rtTreeSideKey, rtTreeToggle } from './rt-select-tree';\nimport { RtSelectTriggerDirective } from './rt-select-trigger.directive';\nimport { IRtSelect } from './rt-select.model';\n\nconst BEM_BLOCK: string = 'rt-select';\n\n/** Клавиши, открывающие закрытый dropdown с фокуса на trigger'е. */\nconst OPEN_KEYS: ReadonlySet<string> = new Set<string>(['ArrowDown', 'ArrowUp', 'Enter', ' ']);\n\ntype TBooleanInput = boolean | string;\n\nlet panelIdSeed: number = 0;\n\nfunction nextPanelId(): number {\n panelIdSeed += 1;\n return panelIdSeed;\n}\n\n/**\n * Single-select dropdown с опциональным filter input.\n *\n * Panel рендерится через CDK Overlay (директива `[rtPopover]` на trigger'е) —\n * не обрезается `overflow: hidden` предками (таблицы, aside, карточки) и\n * авто-flip'ается у края viewport. CVA через общий `RtFormControlBase`. Крестик\n * (`clearable`) слева от шеврона — виден при наличии значения, очищает выбор.\n *\n * Keyboard-nav (activedescendant): фокус на trigger'е, ArrowUp/Down двигают\n * виртуальный highlight (`aria-activedescendant`), Enter выбирает, Escape\n * закрывает. Home/End/typeahead — deferred.\n */\n@Component({\n selector: 'rt-select',\n templateUrl: './rt-select.component.html',\n styleUrl: './rt-select.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n FormsModule,\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtIconComponent,\n RtInputComponent,\n RtPopoverDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtSelectComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-select--open]': 'isOpen()',\n '[class.rt-select--disabled]': 'isDisabled()',\n '[class.rt-select--readonly]': 'isReadonly()',\n '[class.rt-select--invalid]': 'isInvalid()',\n '[class.rt-select--borderless]': '!bordered()',\n '[class.rt-select--appearance--fill]': \"appearance() === 'fill'\",\n '[class.rt-select--size--sm]': \"size() === 'sm'\",\n '[class.rt-select--size--lg]': \"size() === 'lg'\",\n '[class.rt-select--with-icon-left]': '!!iconLeft()',\n },\n})\nexport class RtSelectComponent<TValue> extends RtFormControlBase<TValue | null> {\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly panelId: string = `rt-select-panel-${nextPanelId()}`;\n\n protected readonly filterPlaceholderText: Signal<string> = computed((): string => this.filterPlaceholder() || this.#t_uiSearch());\n\n protected readonly popover: Signal<RtPopoverDirective> = viewChild.required(RtPopoverDirective);\n\n protected readonly triggerEl: Signal<ElementRef<HTMLButtonElement> | undefined> = viewChild<ElementRef<HTMLButtonElement>>('triggerEl');\n\n protected readonly filterTerm: WritableSignal<string> = signal<string>('');\n protected readonly activeIndex: WritableSignal<number> = signal<number>(-1);\n /** Раскрытые ветки дерева. Живут, пока открыта панель: при открытии раскрыты ветки над выбранным. */\n protected readonly openBranches: WritableSignal<ReadonlySet<TValue>> = signal<ReadonlySet<TValue>>(new Set<TValue>());\n\n protected readonly isOpen: Signal<boolean> = computed((): boolean => this.popover().isOpen());\n\n /** Идентификатор подсвеченной опции — тот же, что уходит в `aria-activedescendant`. */\n protected readonly activeOptionId: Signal<string | null> = computed((): string | null =>\n this.isOpen() && this.activeIndex() >= 0 ? `${this.panelId}-opt-${this.activeIndex()}` : null\n );\n\n /**\n * Своя разметка указателя, если потребитель её объявил. Не объявил — кит рисует свою, и ни один\n * нынешний потребитель не двигается.\n */\n protected readonly triggerTpl: Signal<RtSelectTriggerDirective<TValue> | undefined> = contentChild(RtSelectTriggerDirective);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value() !== null);\n\n protected readonly selectedLabel: Signal<string> = computed((): string => {\n const v: TValue | null = this.value();\n if (v === null) {\n return '';\n }\n return rtTreeFind(this.options(), v)?.label ?? '';\n });\n\n /** Дерево ли список: тогда у строк есть место под стрелку и отступ по уровню. */\n protected readonly isTree: Signal<boolean> = computed((): boolean => rtTreeIsTree(this.options()));\n\n /** Видимые строки: плоский список — как прежде, дерево — по раскрытым веткам и поисковому слову. */\n protected readonly rows: Signal<ReadonlyArray<IRtSelect.Row<TValue>>> = computed((): ReadonlyArray<IRtSelect.Row<TValue>> =>\n rtTreeRows(this.options(), this.openBranches(), this.filterTerm())\n );\n\n /** Три значения, которые кит отдаёт своей разметке указателя, и не больше. */\n protected readonly triggerState: Signal<IRtSelect.TriggerState<TValue>> = computed((): IRtSelect.TriggerState<TValue> => ({\n isOpen: this.isOpen(),\n value: this.value(),\n label: this.selectedLabel(),\n isDisabled: this.isDisabled(),\n }));\n\n /** Вид рамки: `outline` — рамка со всех сторон, `fill` — залитое поле с чертой снизу. */\n public readonly appearance: InputSignal<IRtInput.Appearance> = input<IRtInput.Appearance>('outline');\n\n public readonly displayText: Signal<string> = computed((): string => this.selectedLabel());\n\n public readonly options: InputSignal<ReadonlyArray<IRtSelect.Option<TValue>>> = input<ReadonlyArray<IRtSelect.Option<TValue>>>([]);\n\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n public readonly iconLeft: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly filter: InputSignalWithTransform<boolean, TBooleanInput> = input<boolean, TBooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly filterPlaceholder: InputSignal<string> = input<string>('');\n\n /**\n * Чем мерится панель. По умолчанию она не уже кнопки и дальше растёт по содержимому:\n * со своим указателем кнопка бывает узкой, и панель по её ширине давила бы содержимое.\n * `trigger` возвращает прежнее — ровно по кнопке, `auto` пускает панель по содержимому\n * целиком. Предел высоты назначается входом `panelMaxHeight`.\n */\n public readonly panelWidth: InputSignal<IRtPopover.Width> = input<IRtPopover.Width>('trigger-min');\n\n /**\n * Предел высоты панели — длина как в стилях, например `20rem`. Пусто — предел кита\n * `--rt-input-panel-max-height`, и длинный список прокручивается внутри панели: без предела\n * он уходил за нижний край экрана, и пункты за краем были недостижимы. `none` снимает предел —\n * для короткого списка, который должен открываться целиком, без прокрутки. Значение ставится\n * на саму панель: она рисуется в наложении, вне поддерева блока.\n */\n public readonly panelMaxHeight: InputSignal<string | null> = input<string | null>(null);\n\n public readonly selectionChange: OutputEmitterRef<TValue | null> = output<TValue | null>();\n\n constructor() {\n super();\n // Подсветка, сдвинутая клавишами, не уходит за край панели с пределом высоты.\n rtScrollActiveOptionIntoView(this.activeOptionId);\n }\n\n public override setDisabledState(disabled: boolean): void {\n super.setDisabledState(disabled);\n if (disabled) {\n this.popover().close();\n }\n }\n\n protected getEmptyValue(): TValue | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.triggerEl()?.nativeElement.focus();\n }\n\n protected override clear(event?: Event): void {\n if (this.isDisabled()) {\n return;\n }\n super.clear(event);\n this.selectionChange.emit(null);\n }\n\n protected onOpened(): void {\n const v: TValue | null = this.value();\n this.openBranches.set(rtTreeOpenFor(this.options(), v === null ? [] : [v]));\n }\n\n protected toggleBranch(event: Event, value: TValue): void {\n event.stopPropagation();\n this.openBranches.update((open: ReadonlySet<TValue>): ReadonlySet<TValue> => rtTreeToggle(open, value));\n }\n\n protected onClosed(): void {\n // Закрытие (outside-click / Escape / выбор) = пользователь увёл фокус.\n this.filterTerm.set('');\n this.activeIndex.set(-1);\n this.markTouched();\n }\n\n protected select(opt: IRtSelect.Option<TValue>): void {\n if (opt.disabled) {\n return;\n }\n this.value.set(opt.value);\n this.emitChange(opt.value);\n this.selectionChange.emit(opt.value);\n this.popover().close();\n }\n\n protected setFilter(term: string): void {\n this.filterTerm.set(term);\n this.activeIndex.set(-1);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n if (!this.isOpen()) {\n if (OPEN_KEYS.has(event.key)) {\n event.preventDefault();\n this.popover().open();\n this.#moveActive(1);\n }\n return;\n }\n this.#handleOpenKeydown(event);\n }\n\n #handleOpenKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.#moveActive(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.#moveActive(-1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.#selectActive();\n break;\n case 'Escape':\n event.preventDefault();\n this.popover().close();\n break;\n case 'ArrowRight':\n case 'ArrowLeft':\n event.preventDefault();\n this.#sideKey(event.key);\n break;\n default:\n break;\n }\n }\n\n #sideKey(key: string): void {\n const answer: IRtSelect.SideKeyAnswer<TValue> = rtTreeSideKey(this.rows(), this.activeIndex(), key);\n const toggle: TValue | null = answer.toggle;\n if (toggle !== null) {\n this.openBranches.update((open: ReadonlySet<TValue>): ReadonlySet<TValue> => rtTreeToggle(open, toggle));\n }\n this.activeIndex.set(answer.index);\n }\n\n #moveActive(delta: number): void {\n const opts: ReadonlyArray<IRtSelect.Option<TValue>> = this.rows().map(\n (row: IRtSelect.Row<TValue>): IRtSelect.Option<TValue> => row.option\n );\n if (opts.length === 0) {\n this.activeIndex.set(-1);\n return;\n }\n let index: number = this.activeIndex();\n for (let step: number = 0; step < opts.length; step += 1) {\n index = (index + delta + opts.length) % opts.length;\n if (!opts[index].disabled) {\n this.activeIndex.set(index);\n return;\n }\n }\n }\n\n #selectActive(): void {\n const opts: ReadonlyArray<IRtSelect.Option<TValue>> = this.rows().map(\n (row: IRtSelect.Row<TValue>): IRtSelect.Option<TValue> => row.option\n );\n const index: number = this.activeIndex();\n if (index >= 0 && index < opts.length) {\n this.select(opts[index]);\n }\n }\n}\n","<ng-container rtBlock=\"rt-select\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n }\n <button\n #triggerEl\n rtElem=\"trigger\"\n qa-dataid=\"select-trigger\"\n type=\"button\"\n [rtPopoverWidth]=\"panelWidth()\"\n [rtMod]=\"{ own: !!triggerTpl() }\"\n [rtPopover]=\"panelTpl\"\n [rtPopoverDisabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [disabled]=\"isDisabled()\"\n (keydown)=\"onTriggerKeydown($event)\"\n (rtPopoverOpened)=\"onOpened()\"\n (rtPopoverClosed)=\"onClosed()\">\n <!--\n Разметка указателя: своя, если потребитель её объявил, иначе зашитая китом. Она встаёт\n внутрь кнопки, а не вместо неё: поведение — открытие панели, приметы доступности,\n отключённость, клавиши и закрытие — остаётся на кнопке кита.\n -->\n @if (triggerTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: triggerState() }\" />\n } @else {\n @if (iconLeft(); as left) {\n <rt-icon rtElem=\"icon-left\" size=\"sm\" color=\"muted\" [name]=\"left\" />\n }\n <span rtElem=\"label\" [rtMod]=\"{ placeholder: !selectedLabel() }\">\n {{ selectedLabel() || placeholder() }}\n </span>\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n icon=\"ico-close\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n [ariaLabel]=\"t().uiClear\"\n [tabIndex]=\"-1\"\n (clicked)=\"clear($event)\" />\n }\n <rt-icon rtElem=\"chevron\" name=\"chevron-down\" size=\"sm\" color=\"muted\" />\n }\n </button>\n\n <ng-template #panelTpl>\n <div rtElem=\"panel\" role=\"listbox\" [style.--rt-select-panel-max-height]=\"panelMaxHeight()\" [attr.aria-label]=\"ariaLabel()\">\n @if (filter()) {\n <div rtElem=\"filter\">\n <rt-input\n iconLeft=\"ico-search\"\n [placeholder]=\"filterPlaceholderText()\"\n [ngModel]=\"filterTerm()\"\n (ngModelChange)=\"setFilter($event)\" />\n </div>\n }\n <!--\n Опции listbox'а выбираются мышью через (click); keyboard-nav —\n на trigger'е (activedescendant: ArrowUp/Down/Enter), опции не\n focusable индивидуально, поэтому a11y-правила здесь не применимы.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <ul rtElem=\"list\">\n @for (row of rows(); track row.option.value; let i = $index) {\n <li\n rtElem=\"option\"\n qa-dataid=\"select-option\"\n role=\"option\"\n [id]=\"panelId + '-opt-' + i\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"isTree() ? row.level + 1 : null\"\n [style.--rt-select-tree-level]=\"row.level\"\n [rtMod]=\"{\n selected: row.option.value === value(),\n active: i === activeIndex(),\n disabled: !!row.option.disabled,\n }\"\n [attr.aria-selected]=\"row.option.value === value()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n (click)=\"select(row.option)\">\n @if (isTree()) {\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"select-option-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n [attr.aria-expanded]=\"row.open\"\n (click)=\"toggleBranch($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n }\n <span rtElem=\"option-label\">{{ row.option.label }}</span>\n @if (row.option.value === value()) {\n <rt-icon rtElem=\"check\" name=\"check\" size=\"sm\" aria-hidden=\"true\" />\n }\n </li>\n } @empty {\n <li rtElem=\"empty\">{{ t().uiNoOptions }}</li>\n }\n </ul>\n </div>\n </ng-template>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-select.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/select/rt-select-active-option.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select-tree.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select-trigger.directive.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select.component.ts","../../../projects/ui-kit-v2/src/lib/components/select/rt-select.component.html","../../../projects/ui-kit-v2/src/lib/components/select/rt-tools-ui-kit-v2-select.ts"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport { afterRenderEffect, inject } from '@angular/core';\n\n/**\n * Держит подсвеченную клавишами опцию в видимой части панели.\n *\n * Панель списка ограничена по высоте, и длинный список прокручивается внутри неё. Клавиши двигают\n * подсветку, но фокус остаётся на поле: браузер сам панель не прокручивает, и подсветка уходила\n * за нижний край — человек выбирал Enter'ом то, чего не видел. После каждой отрисовки, в которой\n * сменилась подсвеченная опция, она прокручивается ровно настолько, чтобы встать в панель.\n *\n * Панель рисуется в наложении, вне поддерева семьи, поэтому опция ищется в документе по своему\n * идентификатору — тому же, что стоит в `aria-activedescendant`. На сервере отрисовки нет, и\n * эффект не выполняется; среда без `scrollIntoView` пропускается.\n *\n * Зовётся в контексте внедрения — полем или конструктором семьи.\n *\n * @param activeOptionId идентификатор подсвеченной опции; `null` — подсветки нет или панель закрыта\n */\nexport function rtScrollActiveOptionIntoView(activeOptionId: () => string | null): void {\n const document: Document = inject(DOCUMENT);\n\n afterRenderEffect((): void => {\n const id: string | null = activeOptionId();\n const option: HTMLElement | null = id ? document.getElementById(id) : null;\n\n if (typeof option?.scrollIntoView === 'function') {\n option.scrollIntoView({ block: 'nearest' });\n }\n });\n}\n","import { IRtSelect } from './rt-select.model';\n\n/**\n * Дерево опций выбора из списка — общее для `rt-select` и `rt-multiselect`.\n *\n * Обе семьи раскладывают, ищут и считают дерево одинаково, поэтому это чистые функции в одном\n * месте: две копии разошлись бы на первой правке. Состояние — какие ветки раскрыты — живёт в семье,\n * здесь только расчёт по нему.\n */\n\ntype TOption<TValue> = IRtSelect.Option<TValue>;\ntype TRow<TValue> = IRtSelect.Row<TValue>;\n\nfunction childrenOf<TValue>(option: TOption<TValue>): ReadonlyArray<TOption<TValue>> {\n return option.children ?? [];\n}\n\nfunction isBranch<TValue>(option: TOption<TValue>): boolean {\n return childrenOf(option).length > 0;\n}\n\n/** Список — дерево, если хоть у одной опции есть дети. Плоский список рисуется как прежде. */\nexport function rtTreeIsTree<TValue>(options: ReadonlyArray<TOption<TValue>>): boolean {\n return options.some((option: TOption<TValue>): boolean => isBranch(option));\n}\n\n/** Опция по значению на любой глубине. */\nexport function rtTreeFind<TValue>(options: ReadonlyArray<TOption<TValue>>, value: TValue): TOption<TValue> | undefined {\n for (const option of options) {\n if (option.value === value) {\n return option;\n }\n const found: TOption<TValue> | undefined = rtTreeFind(childrenOf(option), value);\n if (found) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * Включённые листья под опцией; у самого листа — он сам. Отключённая ветка не отдаёт никого: её\n * листья выбрать нельзя, как и её саму.\n */\nexport function rtTreeLeaves<TValue>(option: TOption<TValue>): ReadonlyArray<TValue> {\n if (option.disabled) {\n return [];\n }\n if (!isBranch(option)) {\n return [option.value];\n }\n return childrenOf(option).flatMap((child: TOption<TValue>): ReadonlyArray<TValue> => rtTreeLeaves(child));\n}\n\n/** Сколько включённых листьев ветки выбрано. Флажок ветки выводится из этого, а не хранится. */\nexport function rtTreeBranchState<TValue>(option: TOption<TValue>, chosen: ReadonlyArray<TValue>): IRtSelect.TBranchState {\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(option);\n const count: number = leaves.filter((leaf: TValue): boolean => chosen.includes(leaf)).length;\n if (count === 0) {\n return 'none';\n }\n return count === leaves.length ? 'all' : 'some';\n}\n\nfunction holdsChosen<TValue>(option: TOption<TValue>, chosen: ReadonlyArray<TValue>): boolean {\n return childrenOf(option).some((child: TOption<TValue>): boolean => chosen.includes(child.value) || holdsChosen(child, chosen));\n}\n\nfunction collectOpen<TValue>(list: ReadonlyArray<TOption<TValue>>, chosen: ReadonlyArray<TValue>, open: Set<TValue>): void {\n for (const option of list) {\n if (holdsChosen(option, chosen)) {\n open.add(option.value);\n collectOpen(childrenOf(option), chosen, open);\n }\n }\n}\n\n/** Ветки, под которыми лежит выбранное значение: они раскрыты, когда список открывается. */\nexport function rtTreeOpenFor<TValue>(options: ReadonlyArray<TOption<TValue>>, chosen: ReadonlyArray<TValue>): ReadonlySet<TValue> {\n const open: Set<TValue> = new Set<TValue>();\n collectOpen(options, chosen, open);\n return open;\n}\n\nfunction matches<TValue>(option: TOption<TValue>, term: string): boolean {\n return option.label.toLowerCase().includes(term);\n}\n\nfunction descendantMatches<TValue>(option: TOption<TValue>, term: string): boolean {\n return childrenOf(option).some((child: TOption<TValue>): boolean => matches(child, term) || descendantMatches(child, term));\n}\n\ninterface ITreeWalk<TValue> {\n readonly open: ReadonlySet<TValue>;\n readonly term: string;\n readonly rows: TRow<TValue>[];\n}\n\ninterface IRowPlace<TValue> {\n readonly level: number;\n readonly parent: TValue | null;\n readonly filtered: boolean;\n}\n\n/**\n * Раскладка одной опции: кладёт её строку и отвечает, где раскладывать её детей, или `null`, если\n * их не видно. `filtered` — действует ли поисковое слово на уровень: под веткой, совпавшей самой и\n * раскрытой, дети идут все, как без поиска.\n */\nfunction placeOption<TValue>(walk: ITreeWalk<TValue>, option: TOption<TValue>, place: IRowPlace<TValue>): IRowPlace<TValue> | null {\n const self: boolean = !place.filtered || matches(option, walk.term);\n const below: boolean = place.filtered && descendantMatches(option, walk.term);\n if (!self && !below) {\n return null;\n }\n const branch: boolean = isBranch(option);\n const openBySet: boolean = self && walk.open.has(option.value);\n const open: boolean = branch && (openBySet || below);\n walk.rows.push({ option, branch, open, level: place.level, parent: place.parent });\n return open ? { level: place.level + 1, parent: option.value, filtered: place.filtered && !openBySet } : null;\n}\n\nfunction walkRows<TValue>(walk: ITreeWalk<TValue>, list: ReadonlyArray<TOption<TValue>>, place: IRowPlace<TValue>): void {\n for (const option of list) {\n const childPlace: IRowPlace<TValue> | null = placeOption(walk, option, place);\n if (childPlace) {\n walkRows(walk, childrenOf(option), childPlace);\n }\n }\n}\n\n/**\n * Видимые строки по уровням. Без поискового слова раскрыты ветки из `open`. Со словом строка\n * остаётся, если совпала она сама или кто-то под ней, и путь к совпадению показан раскрытым.\n * Ветка, совпавшая сама, держит детей такими, какими они были.\n */\nexport function rtTreeRows<TValue>(\n options: ReadonlyArray<TOption<TValue>>,\n open: ReadonlySet<TValue>,\n rawTerm: string = ''\n): ReadonlyArray<TRow<TValue>> {\n const term: string = rawTerm.toLowerCase().trim();\n const walk: ITreeWalk<TValue> = { open, term, rows: [] };\n walkRows(walk, options, { level: 0, parent: null, filtered: term.length > 0 });\n return walk.rows;\n}\n\nfunction sideRight<TValue>(rows: ReadonlyArray<TRow<TValue>>, row: TRow<TValue>, index: number): IRtSelect.SideKeyAnswer<TValue> {\n if (row.branch && !row.open) {\n return { toggle: row.option.value, index };\n }\n const firstChild: boolean = row.branch && rows[index + 1]?.parent === row.option.value;\n return { toggle: null, index: firstChild ? index + 1 : index };\n}\n\nfunction sideLeft<TValue>(rows: ReadonlyArray<TRow<TValue>>, row: TRow<TValue>, index: number): IRtSelect.SideKeyAnswer<TValue> {\n if (row.branch && row.open) {\n return { toggle: row.option.value, index };\n }\n const parentIndex: number = rows.findIndex((candidate: TRow<TValue>): boolean => candidate.option.value === row.parent);\n return { toggle: null, index: parentIndex >= 0 ? parentIndex : index };\n}\n\n/**\n * Ответ на боковую стрелку. Вправо: свёрнутая ветка раскрывается, раскрытая уводит подсветку на\n * первого ребёнка. Влево: раскрытая ветка сворачивается, иначе подсветка уходит на родителя.\n */\nexport function rtTreeSideKey<TValue>(rows: ReadonlyArray<TRow<TValue>>, index: number, key: string): IRtSelect.SideKeyAnswer<TValue> {\n const row: TRow<TValue> | undefined = rows[index];\n if (row && key === 'ArrowRight') {\n return sideRight(rows, row, index);\n }\n if (row && key === 'ArrowLeft') {\n return sideLeft(rows, row, index);\n }\n return { toggle: null, index };\n}\n\n/** Набор раскрытых веток с переключённой одной. */\nexport function rtTreeToggle<TValue>(open: ReadonlySet<TValue>, value: TValue): ReadonlySet<TValue> {\n const next: Set<TValue> = new Set<TValue>(open);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n return next;\n}\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtSelect } from './rt-select.model';\n\n/**\n * Маркер своей разметки указателя — того, что человек нажимает, чтобы открыть список.\n *\n * Поведение указателя остаётся киту: открытие панели, её ширина, приметы доступности,\n * отключённость, клавиши и закрытие висят на кнопке. Потребитель даёт только то, что рисуется\n * внутри неё, и получает три значения обстановки: открыт ли список, что выбрано, отключён ли выбор.\n *\n * Один маркер на обе семьи выбора: они отличаются только разметкой внутри кнопки, и два маркера\n * разошлись бы на первой же правке.\n *\n * @example\n * ```html\n * <rt-select [options]=\"options\">\n * <ng-template rtSelectTrigger let-state>\n * <rt-tag [value]=\"state.label\" [icon]=\"state.isOpen ? 'chevron-up' : 'chevron-down'\" />\n * </ng-template>\n * </rt-select>\n * ```\n */\n@Directive({\n selector: '[rtSelectTrigger]',\n})\nexport class RtSelectTriggerDirective<TValue = unknown> {\n public readonly templateRef: TemplateRef<IRtSelect.TriggerContext<TValue>> =\n inject<TemplateRef<IRtSelect.TriggerContext<TValue>>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n forwardRef,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { IRtInput } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { IRtPopover } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { rtScrollActiveOptionIntoView } from './rt-select-active-option';\nimport { rtTreeFind, rtTreeIsTree, rtTreeOpenFor, rtTreeRows, rtTreeSideKey, rtTreeToggle } from './rt-select-tree';\nimport { RtSelectTriggerDirective } from './rt-select-trigger.directive';\nimport { IRtSelect } from './rt-select.model';\n\nconst BEM_BLOCK: string = 'rt-select';\n\n/** Клавиши, открывающие закрытый dropdown с фокуса на trigger'е. */\nconst OPEN_KEYS: ReadonlySet<string> = new Set<string>(['ArrowDown', 'ArrowUp', 'Enter', ' ']);\n\ntype TBooleanInput = boolean | string;\n\nlet panelIdSeed: number = 0;\n\nfunction nextPanelId(): number {\n panelIdSeed += 1;\n return panelIdSeed;\n}\n\n/**\n * Single-select dropdown с опциональным filter input.\n *\n * Panel рендерится через CDK Overlay (директива `[rtPopover]` на trigger'е) —\n * не обрезается `overflow: hidden` предками (таблицы, aside, карточки) и\n * авто-flip'ается у края viewport. CVA через общий `RtFormControlBase`. Крестик\n * (`clearable`) слева от шеврона — виден при наличии значения, очищает выбор.\n *\n * Keyboard-nav (activedescendant): фокус на trigger'е, ArrowUp/Down двигают\n * виртуальный highlight (`aria-activedescendant`), Enter выбирает, Escape\n * закрывает. Home/End/typeahead — deferred.\n */\n@Component({\n selector: 'rt-select',\n templateUrl: './rt-select.component.html',\n styleUrl: './rt-select.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n FormsModule,\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtIconComponent,\n RtInputComponent,\n RtPopoverDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtSelectComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-select--open]': 'isOpen()',\n '[class.rt-select--disabled]': 'isDisabled()',\n '[class.rt-select--readonly]': 'isReadonly()',\n '[class.rt-select--invalid]': 'isInvalid()',\n '[class.rt-select--borderless]': '!bordered()',\n '[class.rt-select--appearance--fill]': \"appearance() === 'fill'\",\n '[class.rt-select--size--sm]': \"size() === 'sm'\",\n '[class.rt-select--size--lg]': \"size() === 'lg'\",\n '[class.rt-select--with-icon-left]': '!!iconLeft()',\n },\n})\nexport class RtSelectComponent<TValue> extends RtFormControlBase<TValue | null> {\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly panelId: string = `rt-select-panel-${nextPanelId()}`;\n\n protected readonly filterPlaceholderText: Signal<string> = computed((): string => this.filterPlaceholder() || this.#t_uiSearch());\n\n protected readonly popover: Signal<RtPopoverDirective> = viewChild.required(RtPopoverDirective);\n\n protected readonly triggerEl: Signal<ElementRef<HTMLButtonElement> | undefined> = viewChild<ElementRef<HTMLButtonElement>>('triggerEl');\n\n protected readonly filterTerm: WritableSignal<string> = signal<string>('');\n protected readonly activeIndex: WritableSignal<number> = signal<number>(-1);\n /** Раскрытые ветки дерева. Живут, пока открыта панель: при открытии раскрыты ветки над выбранным. */\n protected readonly openBranches: WritableSignal<ReadonlySet<TValue>> = signal<ReadonlySet<TValue>>(new Set<TValue>());\n\n protected readonly isOpen: Signal<boolean> = computed((): boolean => this.popover().isOpen());\n\n /** Идентификатор подсвеченной опции — тот же, что уходит в `aria-activedescendant`. */\n protected readonly activeOptionId: Signal<string | null> = computed((): string | null =>\n this.isOpen() && this.activeIndex() >= 0 ? `${this.panelId}-opt-${this.activeIndex()}` : null\n );\n\n /**\n * Своя разметка указателя, если потребитель её объявил. Не объявил — кит рисует свою, и ни один\n * нынешний потребитель не двигается.\n */\n protected readonly triggerTpl: Signal<RtSelectTriggerDirective<TValue> | undefined> = contentChild(RtSelectTriggerDirective);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value() !== null);\n\n protected readonly selectedLabel: Signal<string> = computed((): string => {\n const v: TValue | null = this.value();\n if (v === null) {\n return '';\n }\n return rtTreeFind(this.options(), v)?.label ?? '';\n });\n\n /** Дерево ли список: тогда у строк есть место под стрелку и отступ по уровню. */\n protected readonly isTree: Signal<boolean> = computed((): boolean => rtTreeIsTree(this.options()));\n\n /** Видимые строки: плоский список — как прежде, дерево — по раскрытым веткам и поисковому слову. */\n protected readonly rows: Signal<ReadonlyArray<IRtSelect.Row<TValue>>> = computed((): ReadonlyArray<IRtSelect.Row<TValue>> =>\n rtTreeRows(this.options(), this.openBranches(), this.filterTerm())\n );\n\n /** Три значения, которые кит отдаёт своей разметке указателя, и не больше. */\n protected readonly triggerState: Signal<IRtSelect.TriggerState<TValue>> = computed((): IRtSelect.TriggerState<TValue> => ({\n isOpen: this.isOpen(),\n value: this.value(),\n label: this.selectedLabel(),\n isDisabled: this.isDisabled(),\n }));\n\n /** Вид рамки: `outline` — рамка со всех сторон, `fill` — залитое поле с чертой снизу. */\n public readonly appearance: InputSignal<IRtInput.Appearance> = input<IRtInput.Appearance>('outline');\n\n public readonly displayText: Signal<string> = computed((): string => this.selectedLabel());\n\n public readonly options: InputSignal<ReadonlyArray<IRtSelect.Option<TValue>>> = input<ReadonlyArray<IRtSelect.Option<TValue>>>([]);\n\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n public readonly iconLeft: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly filter: InputSignalWithTransform<boolean, TBooleanInput> = input<boolean, TBooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly filterPlaceholder: InputSignal<string> = input<string>('');\n\n /**\n * Чем мерится панель. По умолчанию она не уже кнопки и дальше растёт по содержимому:\n * со своим указателем кнопка бывает узкой, и панель по её ширине давила бы содержимое.\n * `trigger` возвращает прежнее — ровно по кнопке, `auto` пускает панель по содержимому\n * целиком. Предел высоты назначается входом `panelMaxHeight`.\n */\n public readonly panelWidth: InputSignal<IRtPopover.Width> = input<IRtPopover.Width>('trigger-min');\n\n /**\n * Предел высоты панели — длина как в стилях, например `20rem`. Пусто — предел кита\n * `--rt-input-panel-max-height`, и длинный список прокручивается внутри панели: без предела\n * он уходил за нижний край экрана, и пункты за краем были недостижимы. `none` снимает предел —\n * для короткого списка, который должен открываться целиком, без прокрутки. Значение ставится\n * на саму панель: она рисуется в наложении, вне поддерева блока.\n */\n public readonly panelMaxHeight: InputSignal<string | null> = input<string | null>(null);\n\n public readonly selectionChange: OutputEmitterRef<TValue | null> = output<TValue | null>();\n\n constructor() {\n super();\n // Подсветка, сдвинутая клавишами, не уходит за край панели с пределом высоты.\n rtScrollActiveOptionIntoView(this.activeOptionId);\n }\n\n public override setDisabledState(disabled: boolean): void {\n super.setDisabledState(disabled);\n if (disabled) {\n this.popover().close();\n }\n }\n\n protected getEmptyValue(): TValue | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.triggerEl()?.nativeElement.focus();\n }\n\n protected override clear(event?: Event): void {\n if (this.isDisabled()) {\n return;\n }\n super.clear(event);\n this.selectionChange.emit(null);\n }\n\n /**\n * Открытый список встаёт подсветкой на выбранный пункт.\n *\n * Иначе стрелка вниз начинала с первого пункта, и человек с выбранным «20» из «10, 20, 40»\n * получал «10» вместо «40».\n */\n protected onOpened(): void {\n const v: TValue | null = this.value();\n this.openBranches.set(rtTreeOpenFor(this.options(), v === null ? [] : [v]));\n if (v !== null) {\n const chosen: number = this.rows().findIndex((row: IRtSelect.Row<TValue>): boolean => row.option.value === v);\n if (chosen >= 0) {\n this.activeIndex.set(chosen);\n }\n }\n }\n\n protected toggleBranch(event: Event, value: TValue): void {\n event.stopPropagation();\n this.openBranches.update((open: ReadonlySet<TValue>): ReadonlySet<TValue> => rtTreeToggle(open, value));\n }\n\n protected onClosed(): void {\n // Закрытие (outside-click / Escape / выбор) = пользователь увёл фокус.\n this.filterTerm.set('');\n this.activeIndex.set(-1);\n this.markTouched();\n }\n\n protected select(opt: IRtSelect.Option<TValue>): void {\n if (opt.disabled) {\n return;\n }\n this.value.set(opt.value);\n this.emitChange(opt.value);\n this.selectionChange.emit(opt.value);\n this.popover().close();\n }\n\n protected setFilter(term: string): void {\n this.filterTerm.set(term);\n this.activeIndex.set(-1);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n if (!this.isOpen()) {\n if (OPEN_KEYS.has(event.key)) {\n event.preventDefault();\n this.popover().open();\n if (this.activeIndex() < 0) {\n this.#moveActive(1);\n }\n }\n return;\n }\n this.#handleOpenKeydown(event);\n }\n\n #handleOpenKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.#moveActive(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.#moveActive(-1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.#selectActive();\n break;\n case 'Escape':\n event.preventDefault();\n this.popover().close();\n break;\n case 'ArrowRight':\n case 'ArrowLeft':\n event.preventDefault();\n this.#sideKey(event.key);\n break;\n default:\n break;\n }\n }\n\n #sideKey(key: string): void {\n const answer: IRtSelect.SideKeyAnswer<TValue> = rtTreeSideKey(this.rows(), this.activeIndex(), key);\n const toggle: TValue | null = answer.toggle;\n if (toggle !== null) {\n this.openBranches.update((open: ReadonlySet<TValue>): ReadonlySet<TValue> => rtTreeToggle(open, toggle));\n }\n this.activeIndex.set(answer.index);\n }\n\n #moveActive(delta: number): void {\n const opts: ReadonlyArray<IRtSelect.Option<TValue>> = this.rows().map(\n (row: IRtSelect.Row<TValue>): IRtSelect.Option<TValue> => row.option\n );\n if (opts.length === 0) {\n this.activeIndex.set(-1);\n return;\n }\n let index: number = this.activeIndex();\n for (let step: number = 0; step < opts.length; step += 1) {\n index = (index + delta + opts.length) % opts.length;\n if (!opts[index].disabled) {\n this.activeIndex.set(index);\n return;\n }\n }\n }\n\n #selectActive(): void {\n const opts: ReadonlyArray<IRtSelect.Option<TValue>> = this.rows().map(\n (row: IRtSelect.Row<TValue>): IRtSelect.Option<TValue> => row.option\n );\n const index: number = this.activeIndex();\n if (index >= 0 && index < opts.length) {\n this.select(opts[index]);\n }\n }\n}\n","<ng-container rtBlock=\"rt-select\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n }\n <button\n #triggerEl\n rtElem=\"trigger\"\n qa-dataid=\"select-trigger\"\n type=\"button\"\n [rtPopoverWidth]=\"panelWidth()\"\n [rtMod]=\"{ own: !!triggerTpl() }\"\n [rtPopover]=\"panelTpl\"\n [rtPopoverDisabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-invalid]=\"isInvalid() || null\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [disabled]=\"isDisabled()\"\n (keydown)=\"onTriggerKeydown($event)\"\n (rtPopoverOpened)=\"onOpened()\"\n (rtPopoverClosed)=\"onClosed()\">\n <!--\n Разметка указателя: своя, если потребитель её объявил, иначе зашитая китом. Она встаёт\n внутрь кнопки, а не вместо неё: поведение — открытие панели, приметы доступности,\n отключённость, клавиши и закрытие — остаётся на кнопке кита.\n -->\n @if (triggerTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: triggerState() }\" />\n } @else {\n @if (iconLeft(); as left) {\n <rt-icon rtElem=\"icon-left\" size=\"sm\" color=\"muted\" [name]=\"left\" />\n }\n <span rtElem=\"label\" [rtMod]=\"{ placeholder: !selectedLabel() }\">\n {{ selectedLabel() || placeholder() }}\n </span>\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n icon=\"ico-close\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n [ariaLabel]=\"t().uiClear\"\n [tabIndex]=\"-1\"\n (clicked)=\"clear($event)\" />\n }\n <rt-icon rtElem=\"chevron\" name=\"chevron-down\" size=\"sm\" color=\"muted\" />\n }\n </button>\n\n <ng-template #panelTpl>\n <div rtElem=\"panel\" role=\"listbox\" [style.--rt-select-panel-max-height]=\"panelMaxHeight()\" [attr.aria-label]=\"ariaLabel()\">\n @if (filter()) {\n <div rtElem=\"filter\">\n <rt-input\n iconLeft=\"ico-search\"\n [placeholder]=\"filterPlaceholderText()\"\n [ngModel]=\"filterTerm()\"\n (ngModelChange)=\"setFilter($event)\" />\n </div>\n }\n <!--\n Опции listbox'а выбираются мышью через (click); keyboard-nav —\n на trigger'е (activedescendant: ArrowUp/Down/Enter), опции не\n focusable индивидуально, поэтому a11y-правила здесь не применимы.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <ul rtElem=\"list\">\n @for (row of rows(); track row.option.value; let i = $index) {\n <li\n rtElem=\"option\"\n qa-dataid=\"select-option\"\n role=\"option\"\n [id]=\"panelId + '-opt-' + i\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"isTree() ? row.level + 1 : null\"\n [style.--rt-select-tree-level]=\"row.level\"\n [rtMod]=\"{\n selected: row.option.value === value(),\n active: i === activeIndex(),\n disabled: !!row.option.disabled,\n }\"\n [attr.aria-selected]=\"row.option.value === value()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n (click)=\"select(row.option)\">\n @if (isTree()) {\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"select-option-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n [attr.aria-expanded]=\"row.open\"\n (click)=\"toggleBranch($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n }\n <span rtElem=\"option-label\">{{ row.option.label }}</span>\n @if (row.option.value === value()) {\n <rt-icon rtElem=\"check\" name=\"check\" size=\"sm\" aria-hidden=\"true\" />\n }\n </li>\n } @empty {\n <li rtElem=\"empty\">{{ t().uiNoOptions }}</li>\n }\n </ul>\n </div>\n </ng-template>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rt-tools/ui-kit-v2",
3
- "version": "0.19.0",
3
+ "version": "0.19.1",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Yauheni Krumin",
6
6
  "type": "module",
Binary file
@@ -26,8 +26,13 @@
26
26
 
27
27
  ## Края
28
28
 
29
- - Блик подписи — градиент, обрезанный по тексту, и он бежит анимацией. При
29
+ - Блик подписи — градиент, обрезанный по тексту, и он бежит анимацией. Перелив из четырёх цветов
30
+ (`-shimmer-to`, `-shimmer-2…4`) между приглушённым текстом; проход 2,4 с: при 500 мс блик
31
+ мелькал, владелец попросил медленнее и разноцветный. При
30
32
  `prefers-reduced-motion` анимации нет, подпись стоит цветом `--rt-ai-run-status-shimmer-from`.
33
+ - Крутилка переливается теми же цветами: метка анимирует `color` (`rt-ai-run-status-hue`), а
34
+ спиннеру внутри задан `--rt-spinner-progress-color: currentcolor`. Это публичный токен
35
+ спиннера, его ключевые кадры не трогаются. Без анимации крутилка стоит `-shimmer-to`.
31
36
  - `expanded` при пустом `steps` ничего не раскрывает: список рисуется только при шагах.
32
37
 
33
38
  ## Рядом
@@ -8,9 +8,12 @@
8
8
  .rt-ai-run-status {
9
9
  --rt-ai-run-status-radius: var(--rt-radius-sm);
10
10
  --rt-ai-run-status-focus-shadow: var(--rt-shadow-focus-ring);
11
- --rt-ai-run-status-shimmer-duration: var(--rt-duration-slower);
11
+ --rt-ai-run-status-shimmer-duration: 2.4s;
12
12
  --rt-ai-run-status-shimmer-from: var(--rt-color-text-muted);
13
13
  --rt-ai-run-status-shimmer-to: var(--rt-color-action-primary-on-surface);
14
+ --rt-ai-run-status-shimmer-2: var(--rt-info-500);
15
+ --rt-ai-run-status-shimmer-3: var(--rt-success-400);
16
+ --rt-ai-run-status-shimmer-4: var(--rt-amber-400);
14
17
 
15
18
  display: flex;
16
19
  flex-direction: column;
@@ -52,6 +55,15 @@
52
55
  justify-content: center;
53
56
  block-size: 16px;
54
57
  inline-size: 16px;
58
+
59
+ .rt-spinner {
60
+ --rt-spinner-progress-color: currentcolor;
61
+ }
62
+ }
63
+
64
+ &--state--running .rt-ai-run-status__mark {
65
+ animation: rt-ai-run-status-hue var(--rt-ai-run-status-shimmer-duration) linear infinite;
66
+ color: var(--rt-ai-run-status-shimmer-to);
55
67
  }
56
68
 
57
69
  &__label {
@@ -64,7 +76,11 @@
64
76
  background: linear-gradient(
65
77
  90deg,
66
78
  var(--rt-ai-run-status-shimmer-from) 0%,
67
- var(--rt-ai-run-status-shimmer-to) 50%,
79
+ var(--rt-ai-run-status-shimmer-to) 20%,
80
+ var(--rt-ai-run-status-shimmer-2) 35%,
81
+ var(--rt-ai-run-status-shimmer-3) 50%,
82
+ var(--rt-ai-run-status-shimmer-4) 65%,
83
+ var(--rt-ai-run-status-shimmer-from) 80%,
68
84
  var(--rt-ai-run-status-shimmer-from) 100%
69
85
  );
70
86
  background-clip: text;
@@ -109,7 +125,30 @@
109
125
  }
110
126
  }
111
127
 
128
+ @keyframes rt-ai-run-status-hue {
129
+ 0%,
130
+ 100% {
131
+ color: var(--rt-ai-run-status-shimmer-to);
132
+ }
133
+
134
+ 25% {
135
+ color: var(--rt-ai-run-status-shimmer-2);
136
+ }
137
+
138
+ 50% {
139
+ color: var(--rt-ai-run-status-shimmer-3);
140
+ }
141
+
142
+ 75% {
143
+ color: var(--rt-ai-run-status-shimmer-4);
144
+ }
145
+ }
146
+
112
147
  @media (prefers-reduced-motion: reduce) {
148
+ .rt-ai-run-status--state--running .rt-ai-run-status__mark {
149
+ animation: none;
150
+ }
151
+
113
152
  .rt-ai-run-status__label--state--running {
114
153
  animation: none;
115
154
  background: none;
@@ -100,3 +100,8 @@
100
100
  - Выбор по одной рисует радиокнопку, и флажка страницы в шапке нет.
101
101
  - Отметки, названные заранее (`selectedEntitiesKeys`), ставятся один раз — к первым непустым
102
102
  строкам; позже присланный набор уже ничего не переписывает.
103
+
104
+ ## Ячейка отбора: фокус после сброса
105
+
106
+ `rt-data-table-filter-cell.onClear` после сброса даты или списка переводит фокус в поле рядом.
107
+ Крестик без значения выключается, и выключенная кнопка роняла фокус на `body`.
@@ -33,8 +33,8 @@
33
33
 
34
34
  ## Клавиатура
35
35
 
36
- - Закрытый список раскрывают `ArrowDown`, `ArrowUp`, `Enter`, `Space` — и сразу подсвечивают
37
- первую доступную опцию.
36
+ - Закрытый список раскрывают `ArrowDown`, `ArrowUp`, `Enter`, `Space`. Подсветка встаёт на
37
+ выбранную опцию (`onOpened`, и при открытии мышью тоже), без выбора — на первую доступную.
38
38
  - Стрелки **перешагивают отключённые опции** и заворачиваются по кругу.
39
39
  - `Enter`/`Space` выбирают подсвеченную, `Escape` закрывает без выбора.
40
40
  - В дереве `ArrowRight` раскрывает ветку или спускается к первому ребёнку, `ArrowLeft` сворачивает
@@ -479,7 +479,7 @@ declare const RT_KIT_LABELS_EN: {
479
479
  readonly dataTableFilterOperatorGreaterThan: "More than";
480
480
  readonly dataTableFilterOperatorLessThan: "Less than";
481
481
  readonly dataTableFilterOperatorNotEquals: "Not equal";
482
- readonly dataTableFilterSelectPlaceholder: "Chose filter";
482
+ readonly dataTableFilterSelectPlaceholder: "Choose filter";
483
483
  readonly dataTableFilterValuePlaceholder: "Type in filter value";
484
484
  readonly dataTableSelectPage: "Select the rows of this page";
485
485
  readonly dataTableSelectRow: "Select row";
@@ -319,6 +319,13 @@ declare class RtDataTableFilterCellComponent<KEY extends string = string> {
319
319
  protected onNumberDraft(value: number | null): void;
320
320
  protected onDayChange(day: string | null): void;
321
321
  protected onValueChange(value: TRtDataTableFilterValue | null): void;
322
+ /**
323
+ * Сброс крестиком переводит фокус в поле рядом.
324
+ *
325
+ * Без значения крестик выключается, и выключенная кнопка роняет фокус на `body`: человек с
326
+ * клавиатуры оказывается в начале страницы.
327
+ */
328
+ protected onClear(): void;
322
329
  protected onOperatorChange(operatorType: TFilterOperatorType): void;
323
330
  static ɵfac: i0.ɵɵFactoryDeclaration<RtDataTableFilterCellComponent<any>, never>;
324
331
  static ɵcmp: i0.ɵɵComponentDeclaration<RtDataTableFilterCellComponent<any>, "rt-data-table-filter-cell", never, { "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "filterProperty": { "alias": "filterProperty"; "required": true; "isSignal": true; }; "filterType": { "alias": "filterType"; "required": true; "isSignal": true; }; "filterModel": { "alias": "filterModel"; "required": false; "isSignal": true; }; "defaultFilterOperator": { "alias": "defaultFilterOperator"; "required": false; "isSignal": true; }; "filterOperators": { "alias": "filterOperators"; "required": false; "isSignal": true; }; "filterSelectOptions": { "alias": "filterSelectOptions"; "required": false; "isSignal": true; }; }, { "filterChange": "filterChange"; }, never, never, true, never>;
@@ -148,6 +148,12 @@ declare class RtSelectComponent<TValue> extends RtFormControlBase<TValue | null>
148
148
  protected getEmptyValue(): TValue | null;
149
149
  protected focusAfterClear(): void;
150
150
  protected clear(event?: Event): void;
151
+ /**
152
+ * Открытый список встаёт подсветкой на выбранный пункт.
153
+ *
154
+ * Иначе стрелка вниз начинала с первого пункта, и человек с выбранным «20» из «10, 20, 40»
155
+ * получал «10» вместо «40».
156
+ */
151
157
  protected onOpened(): void;
152
158
  protected toggleBranch(event: Event, value: TValue): void;
153
159
  protected onClosed(): void;
Binary file