@rt-tools/ui-kit-v2 0.35.0 → 0.36.0

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.
Files changed (80) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +1 -0
  2. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +2 -1
  4. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +1 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +2 -1
  8. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +1 -0
  10. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +4 -2
  12. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +1 -0
  14. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +1 -0
  16. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +2 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +5 -2
  20. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +1 -0
  22. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  23. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +2 -1
  24. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  25. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +2 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -1
  27. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +2 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
  29. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +2 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  31. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +2 -1
  32. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
  33. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +2 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
  35. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +1 -0
  36. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  37. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +10 -6
  38. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  39. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +22 -2
  40. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -1
  41. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +36 -5
  42. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  43. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +2 -1
  44. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  45. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +1 -0
  46. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  47. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +4 -2
  48. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  49. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +3 -1
  50. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
  51. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +1 -0
  52. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -1
  53. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +3 -1
  54. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  55. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +2 -1
  56. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  57. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +2 -1
  58. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  59. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +53 -5
  60. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  61. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +2 -1
  62. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  63. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +37 -0
  64. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  65. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +2 -1
  66. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
  67. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +2 -1
  68. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
  69. package/fesm2022/rt-tools-ui-kit-v2-usage-ring.mjs +4 -3
  70. package/fesm2022/rt-tools-ui-kit-v2-usage-ring.mjs.map +1 -1
  71. package/package.json +1 -1
  72. package/src/lib/components/page-header/rt-page-header-mobile.scss +6 -0
  73. package/src/lib/components/popover/CONTEXT.md +4 -0
  74. package/src/lib/components/thread-list/rt-thread-list.component.scss +7 -0
  75. package/src/lib/components/tooltip/CONTEXT.md +4 -0
  76. package/src/rich-editor/lib/components/chat/rt-chat.component.scss +31 -1
  77. package/types/rt-tools-ui-kit-v2-popover.d.ts +11 -0
  78. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +7 -0
  79. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +7 -1
  80. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +12 -0
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-multiselect.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect-label.pipe.ts","../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect.component.ts","../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect.component.html"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\nimport { rtTreeFind } from '@rt-tools/ui-kit-v2/core';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\n\n/** Лейбл опции по её value для отображения чипа выбранного значения — на любой глубине дерева. */\n@Pipe({ name: 'rtMultiselectLabel' })\nexport class RtMultiselectLabelPipe implements PipeTransform {\n public transform<TValue>(value: TValue, options: ReadonlyArray<IRtSelect.Option<TValue>>): string {\n return rtTreeFind(options, value)?.label ?? String(value);\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\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 { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\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 { RtOptionList, TRtOptionListAction } from '@rt-tools/ui-kit-v2/core';\nimport {\n rtTreeBranchState,\n rtTreeFind,\n rtTreeIsTree,\n rtTreeLeaves,\n rtTreeOpenFor,\n rtTreeRows,\n rtTreeSideKey,\n rtTreeToggle,\n} from '@rt-tools/ui-kit-v2/core';\nimport { RtSelectTriggerDirective } from '@rt-tools/ui-kit-v2/select';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\nimport { RtTagComponent } from '@rt-tools/ui-kit-v2/tag';\nimport { RtMultiselectLabelPipe } from './rt-multiselect-label.pipe';\n\nconst BEM_BLOCK: string = 'rt-multiselect';\n\n/** Клавиши, открывающие закрытый dropdown с фокуса на trigger'е. */\n\nlet panelIdSeed: number = 0;\n\nfunction nextPanelId(): number {\n panelIdSeed += 1;\n return panelIdSeed;\n}\n\n/**\n * Multi-select с chip-rendering выбранных значений в trigger.\n *\n * Panel рендерится через CDK Overlay (`[rtPopover]`) — не обрезается overflow,\n * авто-flip. Панель НЕ закрывается после выбора (multi vs single). CVA через\n * общий `RtFormControlBase`. Reuses `IRtSelect.Option<TValue>` (type-import).\n * Чипы закрываются поштучно; крестик (`clearable`) слева от шеврона очищает весь\n * выбор.\n *\n * Keyboard-nav (activedescendant): фокус на trigger'е, ArrowUp/Down — highlight,\n * Enter — toggle опции (panel остаётся открытой), Escape — закрыть. Home/End —\n * deferred.\n */\n@Component({\n selector: 'rt-multiselect',\n templateUrl: './rt-multiselect.component.html',\n styleUrl: './rt-multiselect.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtIconComponent,\n RtPopoverDirective,\n RtTagComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n\n // pipes\n RtMultiselectLabelPipe,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtMultiselectComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-multiselect--open]': 'isOpen()',\n '[class.rt-multiselect--disabled]': 'isDisabled()',\n '[class.rt-multiselect--readonly]': 'isReadonly()',\n '[class.rt-multiselect--invalid]': 'isInvalid()',\n '[class.rt-multiselect--borderless]': '!bordered()',\n '[class.rt-multiselect--size--sm]': \"size() === 'sm'\",\n '[class.rt-multiselect--size--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtMultiselectComponent<TValue> extends RtFormControlBase<ReadonlyArray<TValue>> {\n readonly #t_uiSelectValues: Signal<string> = rtKitLabel('uiSelectValues');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly panelId: string = `rt-multiselect-panel-${nextPanelId()}`;\n\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#t_uiSelectValues());\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 /** Раскрытые ветки дерева. Живут, пока открыта панель: при открытии раскрыты ветки над выбранным. */\n protected readonly openBranches: WritableSignal<ReadonlySet<TValue>> = signal<ReadonlySet<TValue>>(new Set<TValue>());\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())\n );\n\n /** Флажок каждой строки: у листа — выбран ли он, у ветки — выведен из её включённых листьев. */\n protected readonly rowChecks: Signal<ReadonlyArray<IRtSelect.TBranchState>> = computed((): ReadonlyArray<IRtSelect.TBranchState> =>\n this.rows().map((row: IRtSelect.Row<TValue>): IRtSelect.TBranchState => this.#checkOf(row))\n );\n\n protected readonly isOpen: Signal<boolean> = computed((): boolean => this.popover().isOpen());\n\n /** Клавиатура списка: подсветка, клавиши открытия, id для `aria-activedescendant`, прокрутка к опции. */\n protected readonly optionList: RtOptionList = new RtOptionList({\n panelId: (): string => this.panelId,\n isOpen: (): boolean => this.isOpen(),\n count: (): number => this.rows().length,\n isDisabled: (index: number): boolean => Boolean(this.rows()[index]?.option.disabled),\n chooseKeys: new Set<string>(['Enter', ' ']),\n sideKeys: true,\n edgeKeys: true,\n });\n\n protected readonly activeIndex: WritableSignal<number> = this.optionList.activeIndex;\n\n /** Идентификатор подсвеченной опции — тот же, что уходит в `aria-activedescendant`. */\n protected readonly activeOptionId: Signal<string | null> = this.optionList.activeOptionId;\n\n /**\n * Своя разметка указателя, если потребитель её объявил. Маркер тот же, что у выбора одного\n * значения: семьи отличаются только разметкой внутри кнопки.\n */\n protected readonly triggerTpl: Signal<RtSelectTriggerDirective<ReadonlyArray<TValue>> | undefined> =\n contentChild(RtSelectTriggerDirective);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value().length > 0);\n\n protected readonly visibleChips: Signal<ReadonlyArray<TValue>> = computed((): ReadonlyArray<TValue> =>\n this.value().slice(0, this.maxChips())\n );\n\n protected readonly extraChipsCount: Signal<number> = computed((): number => Math.max(0, this.value().length - this.maxChips()));\n\n /** Три значения, которые кит отдаёт своей разметке указателя, и не больше. */\n protected readonly triggerState: Signal<IRtSelect.TriggerState<ReadonlyArray<TValue>>> = computed(\n (): IRtSelect.TriggerState<ReadonlyArray<TValue>> => ({\n isOpen: this.isOpen(),\n value: this.value(),\n label: this.displayText(),\n isDisabled: this.isDisabled(),\n })\n );\n\n public readonly displayText: Signal<string> = computed((): string =>\n this.value()\n .map((v: TValue): string => this.labelOf(v))\n .join(', ')\n );\n\n public readonly options: InputSignal<ReadonlyArray<IRtSelect.Option<TValue>>> = input<ReadonlyArray<IRtSelect.Option<TValue>>>([]);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly placeholder: InputSignal<string> = input<string>('');\n public readonly maxChips: InputSignal<number> = input<number>(3);\n\n /** Иконка слева в указателе — та же, что у `rt-select`: перед подсказкой или чипами. */\n public readonly iconLeft: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\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 override setDisabledState(disabled: boolean): void {\n super.setDisabledState(disabled);\n if (disabled) {\n this.popover().close();\n }\n }\n\n protected getEmptyValue(): ReadonlyArray<TValue> {\n return [];\n }\n\n protected focusAfterClear(): void {\n this.triggerEl()?.nativeElement.focus();\n }\n\n protected labelOf(value: TValue): string {\n return rtTreeFind(this.options(), value)?.label ?? String(value);\n }\n\n protected isSelected(value: TValue): boolean {\n return this.value().includes(value);\n }\n\n protected onOpened(): void {\n this.openBranches.set(rtTreeOpenFor(this.options(), this.value()));\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 this.activeIndex.set(-1);\n this.markTouched();\n }\n\n /**\n * Лист переключается сам. Ветка выбирает все свои включённые листья или снимает их, когда\n * выбраны все; своё значение ветки в выбор не пишется.\n */\n protected toggleOption(opt: IRtSelect.Option<TValue>): void {\n if (opt.disabled || this.isDisabled()) {\n return;\n }\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(opt);\n const current: ReadonlyArray<TValue> = this.value();\n const clearing: boolean = rtTreeBranchState(opt, current) === 'all';\n const next: ReadonlyArray<TValue> = clearing\n ? current.filter((v: TValue): boolean => !leaves.includes(v))\n : [...current, ...leaves.filter((leaf: TValue): boolean => !current.includes(leaf))];\n this.value.set(next);\n this.emitChange([...next]);\n }\n\n protected removeChip(value: TValue, event: MouseEvent): void {\n event.stopPropagation();\n if (this.isDisabled()) {\n return;\n }\n const next: ReadonlyArray<TValue> = this.value().filter((v: TValue): boolean => v !== value);\n this.value.set(next);\n this.emitChange([...next]);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n if (!this.isOpen()) {\n if (this.optionList.opensBy(event.key)) {\n event.preventDefault();\n this.popover().open();\n this.optionList.move(1);\n }\n return;\n }\n this.#handleOpenKeydown(event);\n }\n\n #handleOpenKeydown(event: KeyboardEvent): void {\n const action: TRtOptionListAction = this.optionList.actionOf(event.key);\n if (action === 'none') {\n return;\n }\n event.preventDefault();\n switch (action) {\n case 'next':\n this.optionList.move(1);\n break;\n case 'previous':\n this.optionList.move(-1);\n break;\n case 'first':\n this.optionList.first();\n break;\n case 'last':\n this.optionList.last();\n break;\n case 'choose':\n this.#toggleActive();\n break;\n case 'close':\n // Escape закрывает один слой: панель. Без остановки событие всплывает до document,\n // и оверлей под панелью — боковая панель, окно — закрывается вместе с ней.\n event.stopPropagation();\n this.popover().close();\n break;\n case 'side':\n this.#sideKey(event.key);\n break;\n }\n }\n\n #checkOf(row: IRtSelect.Row<TValue>): IRtSelect.TBranchState {\n if (row.branch) {\n return rtTreeBranchState(row.option, this.value());\n }\n return this.value().includes(row.option.value) ? 'all' : 'none';\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 #toggleActive(): 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.toggleOption(opts[index]);\n }\n }\n}\n","<ng-container rtBlock=\"rt-multiselect\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"multiselect-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n }\n <button\n #triggerEl\n rtElem=\"trigger\"\n qa-dataid=\"multiselect-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\" qa-dataid=\"multiselect-icon-left\" size=\"sm\" color=\"muted\" [name]=\"left\" />\n }\n @if (value().length === 0) {\n <span rtElem=\"placeholder\" qa-dataid=\"multiselect-placeholder\">{{ placeholderText() }}</span>\n } @else {\n <span rtElem=\"chips\">\n @for (val of visibleChips(); track val) {\n <span rtElem=\"chip\" qa-dataid=\"multiselect-chip\" [attr.data-value]=\"val\">\n <rt-tag\n severity=\"info\"\n [value]=\"val | rtMultiselectLabel: options()\"\n [closable]=\"true\"\n (closed)=\"removeChip(val, $event)\" />\n </span>\n }\n @if (extraChipsCount() > 0) {\n <span rtElem=\"chip-more\" qa-dataid=\"multiselect-chip-more\">+{{ extraChipsCount() }}</span>\n }\n </span>\n }\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n qa-dataid=\"multiselect-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\n rtElem=\"panel\"\n qa-dataid=\"multiselect-panel\"\n role=\"listbox\"\n [style.--rt-multiselect-panel-max-height]=\"panelMaxHeight()\"\n [attr.aria-label]=\"ariaLabel()\">\n <!--\n Опции выбираются мышью через (click); keyboard-nav — на trigger'е\n (activedescendant), опции не focusable индивидуально.\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=\"multiselect-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-multiselect-tree-level]=\"row.level\"\n [rtMod]=\"{\n selected: rowChecks()[i] === 'all',\n active: i === activeIndex(),\n disabled: !!row.option.disabled,\n }\"\n [attr.aria-selected]=\"rowChecks()[i] === 'all'\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n (click)=\"toggleOption(row.option)\">\n @if (isTree()) {\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"multiselect-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 <input\n rtElem=\"checkbox\"\n qa-dataid=\"multiselect-option-checkbox\"\n type=\"checkbox\"\n tabindex=\"-1\"\n [checked]=\"rowChecks()[i] === 'all'\"\n [indeterminate]=\"rowChecks()[i] === 'some'\" />\n <span rtElem=\"option-label\" qa-dataid=\"multiselect-option-label\">{{ row.option.label }}</span>\n </li>\n } @empty {\n <li rtElem=\"empty\" qa-dataid=\"multiselect-empty\">{{ t().uiNoOptions }}</li>\n }\n </ul>\n </div>\n </ng-template>\n</ng-container>\n"],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-multiselect.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect-label.pipe.ts","../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect.component.ts","../../../projects/ui-kit-v2/src/lib/components/multiselect/rt-multiselect.component.html"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\nimport { rtTreeFind } from '@rt-tools/ui-kit-v2/core';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\n\n/** Лейбл опции по её value для отображения чипа выбранного значения — на любой глубине дерева. */\n@Pipe({ name: 'rtMultiselectLabel' })\nexport class RtMultiselectLabelPipe implements PipeTransform {\n public transform<TValue>(value: TValue, options: ReadonlyArray<IRtSelect.Option<TValue>>): string {\n return rtTreeFind(options, value)?.label ?? String(value);\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\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 { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\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 { RtOptionList, TRtOptionListAction } from '@rt-tools/ui-kit-v2/core';\nimport {\n rtTreeBranchState,\n rtTreeFind,\n rtTreeIsTree,\n rtTreeLeaves,\n rtTreeOpenFor,\n rtTreeRows,\n rtTreeSideKey,\n rtTreeToggle,\n} from '@rt-tools/ui-kit-v2/core';\nimport { RtSelectTriggerDirective } from '@rt-tools/ui-kit-v2/select';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\nimport { RtTagComponent } from '@rt-tools/ui-kit-v2/tag';\nimport { RtMultiselectLabelPipe } from './rt-multiselect-label.pipe';\n\nconst BEM_BLOCK: string = 'rt-multiselect';\n\n/** Клавиши, открывающие закрытый dropdown с фокуса на trigger'е. */\n\nlet panelIdSeed: number = 0;\n\nfunction nextPanelId(): number {\n panelIdSeed += 1;\n return panelIdSeed;\n}\n\n/**\n * Multi-select с chip-rendering выбранных значений в trigger.\n *\n * Panel рендерится через CDK Overlay (`[rtPopover]`) — не обрезается overflow,\n * авто-flip. Панель НЕ закрывается после выбора (multi vs single). CVA через\n * общий `RtFormControlBase`. Reuses `IRtSelect.Option<TValue>` (type-import).\n * Чипы закрываются поштучно; крестик (`clearable`) слева от шеврона очищает весь\n * выбор.\n *\n * Keyboard-nav (activedescendant): фокус на trigger'е, ArrowUp/Down — highlight,\n * Enter — toggle опции (panel остаётся открытой), Escape — закрыть. Home/End —\n * deferred.\n */\n@Component({\n selector: 'rt-multiselect',\n templateUrl: './rt-multiselect.component.html',\n styleUrl: './rt-multiselect.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtIconComponent,\n RtPopoverDirective,\n RtTagComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n\n // pipes\n RtMultiselectLabelPipe,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtMultiselectComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-multiselect--open]': 'isOpen()',\n '[class.rt-multiselect--disabled]': 'isDisabled()',\n '[class.rt-multiselect--readonly]': 'isReadonly()',\n '[class.rt-multiselect--invalid]': 'isInvalid()',\n '[class.rt-multiselect--borderless]': '!bordered()',\n '[class.rt-multiselect--size--sm]': \"size() === 'sm'\",\n '[class.rt-multiselect--size--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtMultiselectComponent<TValue> extends RtFormControlBase<ReadonlyArray<TValue>> {\n readonly #t_uiSelectValues: Signal<string> = rtKitLabel('uiSelectValues');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly panelId: string = `rt-multiselect-panel-${nextPanelId()}`;\n\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#t_uiSelectValues());\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 /** Раскрытые ветки дерева. Живут, пока открыта панель: при открытии раскрыты ветки над выбранным. */\n protected readonly openBranches: WritableSignal<ReadonlySet<TValue>> = signal<ReadonlySet<TValue>>(new Set<TValue>());\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())\n );\n\n /** Флажок каждой строки: у листа — выбран ли он, у ветки — выведен из её включённых листьев. */\n protected readonly rowChecks: Signal<ReadonlyArray<IRtSelect.TBranchState>> = computed((): ReadonlyArray<IRtSelect.TBranchState> =>\n this.rows().map((row: IRtSelect.Row<TValue>): IRtSelect.TBranchState => this.#checkOf(row))\n );\n\n protected readonly isOpen: Signal<boolean> = computed((): boolean => this.popover().isOpen());\n\n /** Клавиатура списка: подсветка, клавиши открытия, id для `aria-activedescendant`, прокрутка к опции. */\n protected readonly optionList: RtOptionList = new RtOptionList({\n panelId: (): string => this.panelId,\n isOpen: (): boolean => this.isOpen(),\n count: (): number => this.rows().length,\n isDisabled: (index: number): boolean => Boolean(this.rows()[index]?.option.disabled),\n chooseKeys: new Set<string>(['Enter', ' ']),\n sideKeys: true,\n edgeKeys: true,\n });\n\n protected readonly activeIndex: WritableSignal<number> = this.optionList.activeIndex;\n\n /** Идентификатор подсвеченной опции — тот же, что уходит в `aria-activedescendant`. */\n protected readonly activeOptionId: Signal<string | null> = this.optionList.activeOptionId;\n\n /**\n * Своя разметка указателя, если потребитель её объявил. Маркер тот же, что у выбора одного\n * значения: семьи отличаются только разметкой внутри кнопки.\n */\n protected readonly triggerTpl: Signal<RtSelectTriggerDirective<ReadonlyArray<TValue>> | undefined> =\n contentChild(RtSelectTriggerDirective);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value().length > 0);\n\n protected readonly visibleChips: Signal<ReadonlyArray<TValue>> = computed((): ReadonlyArray<TValue> =>\n this.value().slice(0, this.maxChips())\n );\n\n protected readonly extraChipsCount: Signal<number> = computed((): number => Math.max(0, this.value().length - this.maxChips()));\n\n /** Три значения, которые кит отдаёт своей разметке указателя, и не больше. */\n protected readonly triggerState: Signal<IRtSelect.TriggerState<ReadonlyArray<TValue>>> = computed(\n (): IRtSelect.TriggerState<ReadonlyArray<TValue>> => ({\n isOpen: this.isOpen(),\n value: this.value(),\n label: this.displayText(),\n isDisabled: this.isDisabled(),\n })\n );\n\n public readonly displayText: Signal<string> = computed((): string =>\n this.value()\n .map((v: TValue): string => this.labelOf(v))\n .join(', ')\n );\n\n public readonly options: InputSignal<ReadonlyArray<IRtSelect.Option<TValue>>> = input<ReadonlyArray<IRtSelect.Option<TValue>>>([]);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly placeholder: InputSignal<string> = input<string>('');\n public readonly maxChips: InputSignal<number> = input<number>(3);\n\n /** Иконка слева в указателе — та же, что у `rt-select`: перед подсказкой или чипами. */\n public readonly iconLeft: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\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 override setDisabledState(disabled: boolean): void {\n super.setDisabledState(disabled);\n if (disabled) {\n this.popover().close();\n }\n }\n\n protected getEmptyValue(): ReadonlyArray<TValue> {\n return [];\n }\n\n protected focusAfterClear(): void {\n this.triggerEl()?.nativeElement.focus();\n }\n\n protected labelOf(value: TValue): string {\n return rtTreeFind(this.options(), value)?.label ?? String(value);\n }\n\n protected isSelected(value: TValue): boolean {\n return this.value().includes(value);\n }\n\n protected onOpened(): void {\n this.openBranches.set(rtTreeOpenFor(this.options(), this.value()));\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 this.activeIndex.set(-1);\n this.markTouched();\n }\n\n /**\n * Лист переключается сам. Ветка выбирает все свои включённые листья или снимает их, когда\n * выбраны все; своё значение ветки в выбор не пишется.\n */\n protected toggleOption(opt: IRtSelect.Option<TValue>): void {\n if (opt.disabled || this.isDisabled()) {\n return;\n }\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(opt);\n const current: ReadonlyArray<TValue> = this.value();\n const clearing: boolean = rtTreeBranchState(opt, current) === 'all';\n const next: ReadonlyArray<TValue> = clearing\n ? current.filter((v: TValue): boolean => !leaves.includes(v))\n : [...current, ...leaves.filter((leaf: TValue): boolean => !current.includes(leaf))];\n this.value.set(next);\n this.emitChange([...next]);\n }\n\n protected removeChip(value: TValue, event: MouseEvent): void {\n event.stopPropagation();\n if (this.isDisabled()) {\n return;\n }\n const next: ReadonlyArray<TValue> = this.value().filter((v: TValue): boolean => v !== value);\n this.value.set(next);\n this.emitChange([...next]);\n }\n\n protected onTriggerKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) {\n return;\n }\n if (!this.isOpen()) {\n if (this.optionList.opensBy(event.key)) {\n event.preventDefault();\n this.popover().open();\n this.optionList.move(1);\n }\n return;\n }\n this.#handleOpenKeydown(event);\n }\n\n #handleOpenKeydown(event: KeyboardEvent): void {\n const action: TRtOptionListAction = this.optionList.actionOf(event.key);\n if (action === 'none') {\n return;\n }\n event.preventDefault();\n switch (action) {\n case 'next':\n this.optionList.move(1);\n break;\n case 'previous':\n this.optionList.move(-1);\n break;\n case 'first':\n this.optionList.first();\n break;\n case 'last':\n this.optionList.last();\n break;\n case 'choose':\n this.#toggleActive();\n break;\n case 'close':\n // Escape закрывает один слой: панель. Без остановки событие всплывает до document,\n // и оверлей под панелью — боковая панель, окно — закрывается вместе с ней.\n event.stopPropagation();\n this.popover().close();\n break;\n case 'side':\n this.#sideKey(event.key);\n break;\n }\n }\n\n #checkOf(row: IRtSelect.Row<TValue>): IRtSelect.TBranchState {\n if (row.branch) {\n return rtTreeBranchState(row.option, this.value());\n }\n return this.value().includes(row.option.value) ? 'all' : 'none';\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 #toggleActive(): 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.toggleOption(opts[index]);\n }\n }\n}\n","<ng-container rtBlock=\"rt-multiselect\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"multiselect-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n }\n <button\n #triggerEl\n rtElem=\"trigger\"\n qa-dataid=\"multiselect-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\" qa-dataid=\"multiselect-icon-left\" size=\"sm\" color=\"muted\" [name]=\"left\" />\n }\n @if (value().length === 0) {\n <span rtElem=\"placeholder\" qa-dataid=\"multiselect-placeholder\">{{ placeholderText() }}</span>\n } @else {\n <span rtElem=\"chips\">\n @for (val of visibleChips(); track val) {\n <span rtElem=\"chip\" qa-dataid=\"multiselect-chip\" [attr.data-value]=\"val\">\n <rt-tag\n severity=\"info\"\n [value]=\"val | rtMultiselectLabel: options()\"\n [closable]=\"true\"\n (closed)=\"removeChip(val, $event)\" />\n </span>\n }\n @if (extraChipsCount() > 0) {\n <span rtElem=\"chip-more\" qa-dataid=\"multiselect-chip-more\">+{{ extraChipsCount() }}</span>\n }\n </span>\n }\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n qa-dataid=\"multiselect-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\n rtElem=\"panel\"\n qa-dataid=\"multiselect-panel\"\n role=\"listbox\"\n [style.--rt-multiselect-panel-max-height]=\"panelMaxHeight()\"\n [attr.aria-label]=\"ariaLabel()\">\n <!--\n Опции выбираются мышью через (click); keyboard-nav — на trigger'е\n (activedescendant), опции не focusable индивидуально.\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=\"multiselect-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-multiselect-tree-level]=\"row.level\"\n [rtMod]=\"{\n selected: rowChecks()[i] === 'all',\n active: i === activeIndex(),\n disabled: !!row.option.disabled,\n }\"\n [attr.aria-selected]=\"rowChecks()[i] === 'all'\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n (click)=\"toggleOption(row.option)\">\n @if (isTree()) {\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"multiselect-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 <input\n rtElem=\"checkbox\"\n qa-dataid=\"multiselect-option-checkbox\"\n type=\"checkbox\"\n tabindex=\"-1\"\n [checked]=\"rowChecks()[i] === 'all'\"\n [indeterminate]=\"rowChecks()[i] === 'some'\" />\n <span rtElem=\"option-label\" qa-dataid=\"multiselect-option-label\">{{ row.option.label }}</span>\n </li>\n } @empty {\n <li rtElem=\"empty\" qa-dataid=\"multiselect-empty\">{{ t().uiNoOptions }}</li>\n }\n </ul>\n </div>\n </ng-template>\n</ng-container>\n"],"mappings":"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"}