@rt-tools/ui-kit-v2 0.35.0 → 0.35.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.
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +4 -2
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +4 -2
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +4 -2
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +20 -4
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +4 -2
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +52 -5
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-usage-ring.mjs +4 -3
- package/fesm2022/rt-tools-ui-kit-v2-usage-ring.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/components/thread-list/rt-thread-list.component.scss +7 -0
- package/src/lib/components/tooltip/CONTEXT.md +4 -0
- package/src/rich-editor/lib/components/chat/rt-chat.component.scss +25 -0
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +7 -0
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +7 -1
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +12 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rt-tools-ui-kit-v2-tooltip.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.component.ts","../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.directive.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, signal, ViewEncapsulation, WritableSignal } from '@angular/core';\n\nconst BEM_BLOCK: string = 'rt-tooltip';\n\n/**\n * Презентационная панель tooltip'а. Рендерится директивой `[rtTooltip]` через\n * CDK `ComponentPortal` в overlay; текст выставляется императивно\n * (`ref.instance.text.set(...)`) — отдельного `input()` нет, т.к. компонент\n * создаётся вручную, а не в шаблоне.\n *\n * `ViewEncapsulation.None` — стили префиксованы `.rt-tooltip` (единообразно с\n * остальным common/ui). `role=\"tooltip\"` — вспомогательный ярлык для AT.\n */\n@Component({\n selector: 'rt-tooltip',\n template: '{{ text() }}',\n styleUrl: './rt-tooltip.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: BEM_BLOCK,\n role: 'tooltip',\n },\n})\nexport class RtTooltipComponent {\n public readonly text: WritableSignal<string> = signal<string>('');\n}\n","import { ConnectedPosition } from '@angular/cdk/overlay';\n\nimport { IRtTooltip } from './rt-tooltip.model';\n\n/** Зазор между подсказкой и host'ом. */\nconst TOOLTIP_GAP_PX: number = 6;\n\nconst POSITION_BY_PLACEMENT: Readonly<Record<IRtTooltip.Placement, ConnectedPosition>> = {\n top: { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -TOOLTIP_GAP_PX },\n bottom: { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: TOOLTIP_GAP_PX },\n left: { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -TOOLTIP_GAP_PX },\n right: { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: TOOLTIP_GAP_PX },\n};\n\nconst FALLBACKS: Readonly<Record<IRtTooltip.Placement, readonly IRtTooltip.Placement[]>> = {\n top: ['top', 'bottom'],\n bottom: ['bottom', 'top'],\n left: ['left', 'right', 'top', 'bottom'],\n right: ['right', 'left', 'top', 'bottom'],\n};\n\n/**\n * Позиции подсказки по порядку попыток: заданная сторона, противоположная, а у боковой ещё\n * верх и низ — на узком экране сбоку не помещается ни одна сторона, и подсказка, придвинутая\n * к краю, легла бы на сам host. Бока заданы логическими `start`/`end`: в письме справа налево\n * `left` встаёт справа — как и вся раскладка кита.\n */\n/**\n * Сторона подсказки: своя на элементе, иначе из настроек кита, иначе сверху, а под материальным\n * набором снизу, как у первого кита.\n */\nexport function tooltipPlacement(\n own: IRtTooltip.Placement | null,\n configured: IRtTooltip.Placement | null,\n materialPreset: boolean\n): IRtTooltip.Placement {\n return own ?? configured ?? (materialPreset ? 'bottom' : 'top');\n}\n\nexport function tooltipPositions(placement: IRtTooltip.Placement): ConnectedPosition[] {\n return FALLBACKS[placement].map((side: IRtTooltip.Placement): ConnectedPosition => ({ ...POSITION_BY_PLACEMENT[side] }));\n}\n\n/** Размеры узла, по которым судят об обрезке: видимая ширина и ширина содержимого. */\nexport interface IRtTooltipBox {\n readonly clientWidth: number;\n readonly scrollWidth: number;\n}\n\n/**\n * Текст узла обрезан: содержимое шире видимой коробки. Высота не судится — узел с видимым\n * переполнением по высоте показывает всё, и его подсказка только повторяла бы текст.\n */\nexport function isTooltipTextCut(box: IRtTooltipBox): boolean {\n return box.scrollWidth > box.clientWidth;\n}\n","import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\nimport { NumberInput } from '@angular/cdk/coercion';\nimport { hasModifierKey } from '@angular/cdk/keycodes';\nimport {\n ConnectedPosition,\n FlexibleConnectedPositionStrategy,\n Overlay,\n OverlayConfig,\n OverlayRef,\n ScrollStrategyOptions,\n} from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n booleanAttribute,\n ComponentRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n OnDestroy,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { carryThemeScope, IRtKitConfig, materialPresetClassesOf, rtKitDefault } from '@rt-tools/ui-kit-v2/core';\nimport { RtTooltipComponent } from './rt-tooltip.component';\nimport { isTooltipTextCut, tooltipPlacement, tooltipPositions } from './rt-tooltip.logic';\nimport { IRtTooltip } from './rt-tooltip.model';\n\nconst SHOW_DELAY_MS: number = 300;\nconst VIEWPORT_MARGIN: number = 8;\n\n/**\n * Tooltip-директива поверх CDK Overlay. Показывает короткую подсказку\n * (`rtTooltip` = строка) на hover/focus host'а. Движок — CDK `flexibleConnectedTo`\n * (авто-flip у края viewport, reposition при скролле), так что подсказка не\n * режется `overflow: hidden` предками (таблицы, aside, карточки).\n *\n * Триггеры: `mouseenter` и фокус с клавиатуры показывают (с задержкой `SHOW_DELAY_MS`),\n * `mouseleave`/`focusout`/`click`/Escape прячут. Фокус, поставленный мышью или кодом, подсказку не\n * показывает, как у Material: меню возвращает фокус кнопке после выбора пункта мышью, и\n * подсказка кнопки всплывала поверх того, что пункт открыл. Пустой текст → no-op (директива\n * выключена), поэтому её можно безусловно вешать на icon-кнопки и включать\n * выставлением строки.\n *\n * @example\n * ```html\n * <rt-icon-button icon=\"ico-trash\" ariaLabel=\"Удалить\" tooltip=\"Удалить\" />\n * <button rtButton [rtTooltip]=\"'Подсказка'\">…</button>\n * ```\n */\n@Directive({\n selector: '[rtTooltip]',\n exportAs: 'rtTooltip',\n host: {\n '(mouseenter)': 'show()',\n '(mouseleave)': 'hide()',\n '(focusout)': 'hide()',\n '(click)': 'onClick()',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class RtTooltipDirective implements OnDestroy {\n readonly #overlay: Overlay = inject(Overlay);\n readonly #elementRef: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #scrollStrategies: ScrollStrategyOptions = inject(ScrollStrategyOptions);\n readonly #focusMonitor: FocusMonitor = inject(FocusMonitor);\n\n #overlayRef: OverlayRef | null = null;\n #tooltipRef: ComponentRef<RtTooltipComponent> | null = null;\n #showTimer: ReturnType<typeof setTimeout> | null = null;\n /**\n * Сторона из настроек кита. Не умолчание входа: обёртка кита, передающая свой `null`, перебила\n * бы настройку приложения.\n */\n readonly #placementDefault: IRtTooltip.Placement | null = rtKitDefault(\n 'tooltip',\n (it: IRtKitConfig.Tooltip): IRtTooltip.Placement | undefined => it.placement,\n null\n );\n /**\n * Задержка показа по умолчанию: из настроек кита `components.tooltip.showDelay`, без них —\n * `SHOW_DELAY_MS`. Не умолчание входа — по той же причине, что и сторона.\n */\n readonly #showDelayDefault: number = rtKitDefault(\n 'tooltip',\n (it: IRtKitConfig.Tooltip): number | undefined => it.showDelay,\n SHOW_DELAY_MS\n );\n\n /**\n * Текст подсказки. Принимает `null`/`undefined` (частый результат date-пайпа\n * или nullable-полей модели) и нормализует их в пустую строку — иначе\n * биндинги вида `value | date` ломали бы строгую типизацию шаблона. Пустая\n * строка → no-op (директива выключена).\n */\n public readonly text: InputSignalWithTransform<string, string | null | undefined> = input<string, string | null | undefined>('', {\n alias: 'rtTooltip',\n transform: (value: string | null | undefined): string => value ?? '',\n });\n\n /**\n * Сторона подсказки. `null` — сторона из настроек кита `components.tooltip.placement`, без них\n * сверху, а под материальным набором снизу, как у первого кита.\n */\n public readonly placement: InputSignal<IRtTooltip.Placement | null> = input<IRtTooltip.Placement | null>(null, {\n alias: 'rtTooltipPlacement',\n });\n\n /**\n * Задержка показа этой подсказки в миллисекундах. `null` — общая задержка из настроек кита, без\n * них 300.\n */\n public readonly showDelay: InputSignalWithTransform<number | null, NumberInput> = input<number | null, NumberInput>(null, {\n alias: 'rtTooltipShowDelay',\n transform: (value: NumberInput): number | null => {\n const delay: number = value === null || value === undefined || value === '' ? Number.NaN : numberAttribute(value, Number.NaN);\n return delay >= 0 ? delay : null;\n },\n });\n\n /**\n * Подсказка только у обрезанного текста: хост меряется в момент показа, и подсказка не\n * появляется, пока его содержимое помещается целиком. Мерить заранее не нужно — показ идёт\n * только отсюда, и признак в эту минуту всегда свежий.\n */\n public readonly whenTruncated: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n alias: 'rtTooltipWhenTruncated',\n transform: booleanAttribute,\n });\n\n /**\n * Клик прячет открытую подсказку — по умолчанию, как раньше; умолчание на всё приложение —\n * `components.tooltip.hideOnClick` в настройках кита. `false` оставляет её открытой:\n * кнопка-переключатель показывает в ней новое состояние сразу после нажатия. Отложенный показ\n * клик снимает при любом значении — касание на тач-экране (mouseenter + click) подсказку не\n * показывает.\n */\n public readonly hideOnClick: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(\n rtKitDefault('tooltip', (it: IRtKitConfig.Tooltip): boolean | undefined => it.hideOnClick, true),\n {\n alias: 'rtTooltipHideOnClick',\n transform: booleanAttribute,\n }\n );\n\n constructor() {\n // Новый текст доходит до открытой панели на месте, без повторного наведения.\n effect((): void => this.#syncText(this.text()));\n this.#focusMonitor\n .monitor(this.#elementRef, true)\n .pipe(takeUntilDestroyed())\n .subscribe((origin: FocusOrigin): void => {\n if (origin === 'keyboard') {\n this.show();\n }\n });\n }\n\n public ngOnDestroy(): void {\n this.#focusMonitor.stopMonitoring(this.#elementRef);\n this.#clearTimer();\n this.#disposeOverlay();\n }\n\n protected show(): void {\n if (this.text().trim() === '' || this.#tooltipRef !== null) {\n return;\n }\n this.#clearTimer();\n this.#showTimer = setTimeout((): void => this.#attach(), this.showDelay() ?? this.#showDelayDefault);\n }\n\n protected hide(): void {\n this.#clearTimer();\n this.#overlayRef?.detach();\n this.#tooltipRef = null;\n }\n\n protected onClick(): void {\n if (this.hideOnClick() || this.#tooltipRef === null) {\n this.hide();\n }\n }\n\n /**\n * Escape прячет подсказку и снимает отложенный показ, фокус остаётся на хосте. Событие гасится,\n * только когда панель была открыта: при закрытой Escape доходит до диалога или панели выше.\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Escape' || hasModifierKey(event)) {\n return;\n }\n const wasOpen: boolean = this.#tooltipRef !== null;\n this.hide();\n if (wasOpen) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n #syncText(text: string): void {\n if (this.#tooltipRef === null) {\n return;\n }\n if (text.trim() === '') {\n this.hide();\n return;\n }\n this.#tooltipRef.instance.text.set(text);\n this.#tooltipRef.changeDetectorRef.markForCheck();\n this.#overlayRef?.updatePosition();\n }\n\n #attach(): void {\n if (this.text().trim() === '' || (this.whenTruncated() && !isTooltipTextCut(this.#elementRef.nativeElement))) {\n return;\n }\n const overlayRef: OverlayRef = this.#ensureOverlay();\n // Коробка переживает закрытие, а кусок темы вокруг host'а мог смениться — переносим на каждом показе.\n carryThemeScope(overlayRef.overlayElement, this.#elementRef.nativeElement);\n const portal: ComponentPortal<RtTooltipComponent> = new ComponentPortal(RtTooltipComponent);\n this.#tooltipRef = overlayRef.attach(portal);\n this.#tooltipRef.instance.text.set(this.text());\n this.#tooltipRef.changeDetectorRef.markForCheck();\n }\n\n #ensureOverlay(): OverlayRef {\n if (this.#overlayRef !== null) {\n return this.#overlayRef;\n }\n const presetClasses: string[] = materialPresetClassesOf(this.#elementRef.nativeElement);\n const placement: IRtTooltip.Placement = tooltipPlacement(this.placement(), this.#placementDefault, presetClasses.length > 0);\n const positions: ConnectedPosition[] = tooltipPositions(placement);\n\n const positionStrategy: FlexibleConnectedPositionStrategy = this.#overlay\n .position()\n .flexibleConnectedTo(this.#elementRef)\n .withPush(true)\n .withViewportMargin(VIEWPORT_MARGIN)\n .withFlexibleDimensions(false)\n .withPositions(positions);\n\n const config: OverlayConfig = new OverlayConfig({\n positionStrategy,\n scrollStrategy: this.#scrollStrategies.reposition(),\n hasBackdrop: false,\n panelClass: ['rt-tooltip-panel', ...presetClasses],\n });\n this.#overlayRef = this.#overlay.create(config);\n return this.#overlayRef;\n }\n\n #clearTimer(): void {\n if (this.#showTimer !== null) {\n clearTimeout(this.#showTimer);\n this.#showTimer = null;\n }\n }\n\n #disposeOverlay(): void {\n this.#overlayRef?.dispose();\n this.#overlayRef = null;\n this.#tooltipRef = null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-tooltip.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.component.ts","../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tooltip/rt-tooltip.directive.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, signal, ViewEncapsulation, WritableSignal } from '@angular/core';\n\nconst BEM_BLOCK: string = 'rt-tooltip';\n\n/**\n * Презентационная панель tooltip'а. Рендерится директивой `[rtTooltip]` через\n * CDK `ComponentPortal` в overlay; текст выставляется императивно\n * (`ref.instance.text.set(...)`) — отдельного `input()` нет, т.к. компонент\n * создаётся вручную, а не в шаблоне.\n *\n * `ViewEncapsulation.None` — стили префиксованы `.rt-tooltip` (единообразно с\n * остальным common/ui). `role=\"tooltip\"` — вспомогательный ярлык для AT.\n */\n@Component({\n selector: 'rt-tooltip',\n template: '{{ text() }}',\n styleUrl: './rt-tooltip.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: BEM_BLOCK,\n role: 'tooltip',\n },\n})\nexport class RtTooltipComponent {\n public readonly text: WritableSignal<string> = signal<string>('');\n}\n","import { ConnectedPosition } from '@angular/cdk/overlay';\n\nimport { IRtTooltip } from './rt-tooltip.model';\n\n/** Зазор между подсказкой и host'ом. */\nconst TOOLTIP_GAP_PX: number = 6;\n\nconst POSITION_BY_PLACEMENT: Readonly<Record<IRtTooltip.Placement, ConnectedPosition>> = {\n top: { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -TOOLTIP_GAP_PX },\n bottom: { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: TOOLTIP_GAP_PX },\n left: { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -TOOLTIP_GAP_PX },\n right: { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: TOOLTIP_GAP_PX },\n};\n\nconst FALLBACKS: Readonly<Record<IRtTooltip.Placement, readonly IRtTooltip.Placement[]>> = {\n top: ['top', 'bottom'],\n bottom: ['bottom', 'top'],\n left: ['left', 'right', 'top', 'bottom'],\n right: ['right', 'left', 'top', 'bottom'],\n};\n\n/**\n * Позиции подсказки по порядку попыток: заданная сторона, противоположная, а у боковой ещё\n * верх и низ — на узком экране сбоку не помещается ни одна сторона, и подсказка, придвинутая\n * к краю, легла бы на сам host. Бока заданы логическими `start`/`end`: в письме справа налево\n * `left` встаёт справа — как и вся раскладка кита.\n */\n/**\n * Сторона подсказки: своя на элементе, иначе из настроек кита, иначе сверху, а под материальным\n * набором снизу, как у первого кита.\n */\nexport function tooltipPlacement(\n own: IRtTooltip.Placement | null,\n configured: IRtTooltip.Placement | null,\n materialPreset: boolean\n): IRtTooltip.Placement {\n return own ?? configured ?? (materialPreset ? 'bottom' : 'top');\n}\n\nexport function tooltipPositions(placement: IRtTooltip.Placement): ConnectedPosition[] {\n return FALLBACKS[placement].map((side: IRtTooltip.Placement): ConnectedPosition => ({ ...POSITION_BY_PLACEMENT[side] }));\n}\n\n/** Размеры узла, по которым судят об обрезке: видимая ширина и ширина содержимого. */\nexport interface IRtTooltipBox {\n readonly clientWidth: number;\n readonly scrollWidth: number;\n}\n\n/**\n * Текст узла обрезан: содержимое шире видимой коробки. Высота не судится — узел с видимым\n * переполнением по высоте показывает всё, и его подсказка только повторяла бы текст.\n */\nexport function isTooltipTextCut(box: IRtTooltipBox): boolean {\n return box.scrollWidth > box.clientWidth;\n}\n","import { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\nimport { NumberInput } from '@angular/cdk/coercion';\nimport { hasModifierKey } from '@angular/cdk/keycodes';\nimport {\n ConnectedPosition,\n FlexibleConnectedPositionStrategy,\n Overlay,\n OverlayConfig,\n OverlayRef,\n ScrollStrategyOptions,\n} from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n booleanAttribute,\n ComponentRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n OnDestroy,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { filter, Observable, Subject, switchMap } from 'rxjs';\n\nimport { carryThemeScope, IRtKitConfig, materialPresetClassesOf, rtKitDefault } from '@rt-tools/ui-kit-v2/core';\nimport { RtTooltipComponent } from './rt-tooltip.component';\nimport { isTooltipTextCut, tooltipPlacement, tooltipPositions } from './rt-tooltip.logic';\nimport { IRtTooltip } from './rt-tooltip.model';\n\nconst SHOW_DELAY_MS: number = 300;\nconst VIEWPORT_MARGIN: number = 8;\n\n/**\n * Tooltip-директива поверх CDK Overlay. Показывает короткую подсказку\n * (`rtTooltip` = строка) на hover/focus host'а. Движок — CDK `flexibleConnectedTo`\n * (авто-flip у края viewport, reposition при скролле), так что подсказка не\n * режется `overflow: hidden` предками (таблицы, aside, карточки).\n *\n * Триггеры: `mouseenter` и фокус с клавиатуры показывают (с задержкой `SHOW_DELAY_MS`),\n * `mouseleave`/`focusout`/`click`/Escape прячут. Фокус, поставленный мышью или кодом, подсказку не\n * показывает, как у Material: меню возвращает фокус кнопке после выбора пункта мышью, и\n * подсказка кнопки всплывала поверх того, что пункт открыл. Пустой текст → no-op (директива\n * выключена), поэтому её можно безусловно вешать на icon-кнопки и включать\n * выставлением строки.\n *\n * @example\n * ```html\n * <rt-icon-button icon=\"ico-trash\" ariaLabel=\"Удалить\" tooltip=\"Удалить\" />\n * <button rtButton [rtTooltip]=\"'Подсказка'\">…</button>\n * ```\n */\n@Directive({\n selector: '[rtTooltip]',\n exportAs: 'rtTooltip',\n host: {\n '(mouseenter)': 'show()',\n '(mouseleave)': 'hide()',\n '(focusout)': 'hide()',\n '(click)': 'onClick()',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class RtTooltipDirective implements OnDestroy {\n readonly #overlay: Overlay = inject(Overlay);\n readonly #elementRef: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #scrollStrategies: ScrollStrategyOptions = inject(ScrollStrategyOptions);\n readonly #focusMonitor: FocusMonitor = inject(FocusMonitor);\n\n #overlayRef: OverlayRef | null = null;\n #tooltipRef: ComponentRef<RtTooltipComponent> | null = null;\n #showTimer: ReturnType<typeof setTimeout> | null = null;\n /** Коробка подсказки, созданная при первом показе: на её нажатия вне хоста подписан конструктор */\n readonly #overlaySource: Subject<OverlayRef> = new Subject<OverlayRef>();\n /**\n * Сторона из настроек кита. Не умолчание входа: обёртка кита, передающая свой `null`, перебила\n * бы настройку приложения.\n */\n readonly #placementDefault: IRtTooltip.Placement | null = rtKitDefault(\n 'tooltip',\n (it: IRtKitConfig.Tooltip): IRtTooltip.Placement | undefined => it.placement,\n null\n );\n /**\n * Задержка показа по умолчанию: из настроек кита `components.tooltip.showDelay`, без них —\n * `SHOW_DELAY_MS`. Не умолчание входа — по той же причине, что и сторона.\n */\n readonly #showDelayDefault: number = rtKitDefault(\n 'tooltip',\n (it: IRtKitConfig.Tooltip): number | undefined => it.showDelay,\n SHOW_DELAY_MS\n );\n\n /**\n * Текст подсказки. Принимает `null`/`undefined` (частый результат date-пайпа\n * или nullable-полей модели) и нормализует их в пустую строку — иначе\n * биндинги вида `value | date` ломали бы строгую типизацию шаблона. Пустая\n * строка → no-op (директива выключена).\n */\n public readonly text: InputSignalWithTransform<string, string | null | undefined> = input<string, string | null | undefined>('', {\n alias: 'rtTooltip',\n transform: (value: string | null | undefined): string => value ?? '',\n });\n\n /**\n * Сторона подсказки. `null` — сторона из настроек кита `components.tooltip.placement`, без них\n * сверху, а под материальным набором снизу, как у первого кита.\n */\n public readonly placement: InputSignal<IRtTooltip.Placement | null> = input<IRtTooltip.Placement | null>(null, {\n alias: 'rtTooltipPlacement',\n });\n\n /**\n * Задержка показа этой подсказки в миллисекундах. `null` — общая задержка из настроек кита, без\n * них 300.\n */\n public readonly showDelay: InputSignalWithTransform<number | null, NumberInput> = input<number | null, NumberInput>(null, {\n alias: 'rtTooltipShowDelay',\n transform: (value: NumberInput): number | null => {\n const delay: number = value === null || value === undefined || value === '' ? Number.NaN : numberAttribute(value, Number.NaN);\n return delay >= 0 ? delay : null;\n },\n });\n\n /**\n * Подсказка только у обрезанного текста: хост меряется в момент показа, и подсказка не\n * появляется, пока его содержимое помещается целиком. Мерить заранее не нужно — показ идёт\n * только отсюда, и признак в эту минуту всегда свежий.\n */\n public readonly whenTruncated: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n alias: 'rtTooltipWhenTruncated',\n transform: booleanAttribute,\n });\n\n /**\n * Клик прячет открытую подсказку — по умолчанию, как раньше; умолчание на всё приложение —\n * `components.tooltip.hideOnClick` в настройках кита. `false` оставляет её открытой:\n * кнопка-переключатель показывает в ней новое состояние сразу после нажатия. Отложенный показ\n * клик снимает при любом значении — касание на тач-экране (mouseenter + click) подсказку не\n * показывает.\n */\n public readonly hideOnClick: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(\n rtKitDefault('tooltip', (it: IRtKitConfig.Tooltip): boolean | undefined => it.hideOnClick, true),\n {\n alias: 'rtTooltipHideOnClick',\n transform: booleanAttribute,\n }\n );\n\n /**\n * Нажатие открывает подсказку сразу, повторное нажатие или нажатие вне хоста закрывает. Для\n * хоста без своего действия — значка или кольца, подсказка которого и есть то, ради чего на него\n * нажимают. У кнопки вход не ставят: её нажатие выполняет действие, и касание подсказку не\n * показывает.\n */\n public readonly showOnTap: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n alias: 'rtTooltipShowOnTap',\n transform: booleanAttribute,\n });\n\n constructor() {\n // Новый текст доходит до открытой панели на месте, без повторного наведения.\n effect((): void => this.#syncText(this.text()));\n this.#focusMonitor\n .monitor(this.#elementRef, true)\n .pipe(takeUntilDestroyed())\n .subscribe((origin: FocusOrigin): void => {\n if (origin === 'keyboard') {\n this.show();\n }\n });\n // Подсказку, открытую нажатием, закрывает нажатие вне хоста; нажатие по хосту решает сам хост\n this.#overlaySource\n .pipe(\n switchMap((overlayRef: OverlayRef): Observable<MouseEvent> => overlayRef.outsidePointerEvents()),\n filter((event: MouseEvent): boolean => this.showOnTap() && !this.#isOnHost(event.target)),\n takeUntilDestroyed()\n )\n .subscribe((): void => this.hide());\n }\n\n public ngOnDestroy(): void {\n this.#focusMonitor.stopMonitoring(this.#elementRef);\n this.#clearTimer();\n this.#disposeOverlay();\n }\n\n protected show(): void {\n if (this.text().trim() === '' || this.#tooltipRef !== null) {\n return;\n }\n this.#clearTimer();\n this.#showTimer = setTimeout((): void => this.#attach(), this.showDelay() ?? this.#showDelayDefault);\n }\n\n protected hide(): void {\n this.#clearTimer();\n this.#overlayRef?.detach();\n this.#tooltipRef = null;\n }\n\n protected onClick(): void {\n if (this.showOnTap()) {\n this.#toggleNow();\n return;\n }\n if (this.hideOnClick() || this.#tooltipRef === null) {\n this.hide();\n }\n }\n\n /**\n * Escape прячет подсказку и снимает отложенный показ, фокус остаётся на хосте. Событие гасится,\n * только когда панель была открыта: при закрытой Escape доходит до диалога или панели выше.\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Escape' || hasModifierKey(event)) {\n return;\n }\n const wasOpen: boolean = this.#tooltipRef !== null;\n this.hide();\n if (wasOpen) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n #isOnHost(target: EventTarget | null): boolean {\n return target instanceof Node && this.#elementRef.nativeElement.contains(target);\n }\n\n /** Нажатие по хосту с `showOnTap`: открытая подсказка закрывается, закрытая открывается без задержки */\n #toggleNow(): void {\n const wasOpen: boolean = this.#tooltipRef !== null;\n this.hide();\n if (!wasOpen) {\n this.#attach();\n }\n }\n\n #syncText(text: string): void {\n if (this.#tooltipRef === null) {\n return;\n }\n if (text.trim() === '') {\n this.hide();\n return;\n }\n this.#tooltipRef.instance.text.set(text);\n this.#tooltipRef.changeDetectorRef.markForCheck();\n this.#overlayRef?.updatePosition();\n }\n\n #attach(): void {\n if (this.text().trim() === '' || (this.whenTruncated() && !isTooltipTextCut(this.#elementRef.nativeElement))) {\n return;\n }\n const overlayRef: OverlayRef = this.#ensureOverlay();\n // Коробка переживает закрытие, а кусок темы вокруг host'а мог смениться — переносим на каждом показе.\n carryThemeScope(overlayRef.overlayElement, this.#elementRef.nativeElement);\n const portal: ComponentPortal<RtTooltipComponent> = new ComponentPortal(RtTooltipComponent);\n this.#tooltipRef = overlayRef.attach(portal);\n this.#tooltipRef.instance.text.set(this.text());\n this.#tooltipRef.changeDetectorRef.markForCheck();\n }\n\n #ensureOverlay(): OverlayRef {\n if (this.#overlayRef !== null) {\n return this.#overlayRef;\n }\n const presetClasses: string[] = materialPresetClassesOf(this.#elementRef.nativeElement);\n const placement: IRtTooltip.Placement = tooltipPlacement(this.placement(), this.#placementDefault, presetClasses.length > 0);\n const positions: ConnectedPosition[] = tooltipPositions(placement);\n\n const positionStrategy: FlexibleConnectedPositionStrategy = this.#overlay\n .position()\n .flexibleConnectedTo(this.#elementRef)\n .withPush(true)\n .withViewportMargin(VIEWPORT_MARGIN)\n .withFlexibleDimensions(false)\n .withPositions(positions);\n\n const config: OverlayConfig = new OverlayConfig({\n positionStrategy,\n scrollStrategy: this.#scrollStrategies.reposition(),\n hasBackdrop: false,\n panelClass: ['rt-tooltip-panel', ...presetClasses],\n });\n this.#overlayRef = this.#overlay.create(config);\n this.#overlaySource.next(this.#overlayRef);\n return this.#overlayRef;\n }\n\n #clearTimer(): void {\n if (this.#showTimer !== null) {\n clearTimeout(this.#showTimer);\n this.#showTimer = null;\n }\n }\n\n #disposeOverlay(): void {\n this.#overlayRef?.dispose();\n this.#overlayRef = null;\n this.#tooltipRef = null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -634,7 +634,8 @@ var RtTreeSelectorComponent = class RtTreeSelectorComponent {
|
|
|
634
634
|
"rtTooltipPlacement",
|
|
635
635
|
"rtTooltipShowDelay",
|
|
636
636
|
"rtTooltipWhenTruncated",
|
|
637
|
-
"rtTooltipHideOnClick"
|
|
637
|
+
"rtTooltipHideOnClick",
|
|
638
|
+
"rtTooltipShowOnTap"
|
|
638
639
|
],
|
|
639
640
|
exportAs: ["rtTooltip"]
|
|
640
641
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rt-tools-ui-kit-v2-tree-selector.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.directives.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.component.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\n/**\n * Свои контролы приложения в строке селектора — после «Развернуть всё» и «Свернуть всё». Так в\n * строку встаёт, например, выбор группировки.\n */\n@Directive({ selector: 'ng-template[rtTreeSelectorControls]' })\nexport class RtTreeSelectorControlsDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Разметка приложения сразу под полем поиска — между полем и строкой контролов. Так под поиском\n * встаёт, например, выбор области поиска или подсказка.\n */\n@Directive({ selector: 'ng-template[rtTreeSelectorUnderSearch]' })\nexport class RtTreeSelectorUnderSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { rtSearchMatches, rtSearchWords } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\n\nfunction nodeText<TValue>(node: TNode<TValue>): string {\n const badges: string = (node.badges ?? []).map((badge: IRtTree.Badge): string => badge.text).join(' ');\n return `${node.label} ${node.description ?? ''} ${badges}`;\n}\n\nfunction keepMatching<TValue>(nodes: ReadonlyArray<TNode<TValue>>, term: string): TNode<TValue>[] {\n return nodes.reduce((kept: TNode<TValue>[], node: TNode<TValue>): TNode<TValue>[] => {\n if (rtSearchMatches(nodeText(node), term)) {\n kept.push(node);\n return kept;\n }\n const inside: TNode<TValue>[] = keepMatching(node.children ?? [], term);\n if (inside.length > 0) {\n kept.push({ ...node, children: inside });\n }\n return kept;\n }, []);\n}\n\n/**\n * Узлы, в которых нашлось каждое слово поиска — в подписи, описании или метках. Совпавшая ветка\n * остаётся со всем поддеревом: без детей она выглядела бы листом. Несовпавшая ветка остаётся путём к\n * совпавшим внизу. Узлы не правятся: отобранная ветка — новый объект.\n */\nexport function rtTreeSelectorFilter<TValue>(nodes: ReadonlyArray<TNode<TValue>>, term: string): ReadonlyArray<TNode<TValue>> {\n if (rtSearchWords(term).length === 0) {\n return nodes;\n }\n return keepMatching(nodes, term);\n}\n\n/** Выключенные узлы дерева на любой глубине. */\nfunction disabledValues<TValue>(nodes: ReadonlyArray<TNode<TValue>>, into: Set<TValue>): Set<TValue> {\n nodes.forEach((node: TNode<TValue>): void => {\n if (node.disabled) {\n into.add(node.value);\n }\n disabledValues(node.children ?? [], into);\n });\n return into;\n}\n\n/** Выбор после «Очистить»: остаются только выключенные узлы — снять их человек не может. */\nexport function rtTreeSelectorClear<TValue>(nodes: ReadonlyArray<TNode<TValue>>, choice: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n const disabled: Set<TValue> = disabledValues(nodes, new Set<TValue>());\n return choice.filter((value: TValue): boolean => disabled.has(value));\n}\n\n/** Равны ли два выбора без учёта порядка. */\nexport function rtTreeSelectorSame<TValue>(a: ReadonlyArray<TValue>, b: ReadonlyArray<TValue>): boolean {\n const left: Set<TValue> = new Set<TValue>(a);\n const right: Set<TValue> = new Set<TValue>(b);\n return left.size === right.size && [...left].every((value: TValue): boolean => right.has(value));\n}\n\n/** Включено ли «Применить»: черновик отличается от выбора и не пуст там, где пустой выбор запрещён. */\nexport function rtTreeSelectorCanApply<TValue>(\n draft: ReadonlyArray<TValue>,\n choice: ReadonlyArray<TValue>,\n emptyAllowed: boolean\n): boolean {\n if (!emptyAllowed && draft.length === 0) {\n return false;\n }\n return !rtTreeSelectorSame(draft, choice);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n linkedSignal,\n model,\n output,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n Injector,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel, IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtToggleSwitchComponent } from '@rt-tools/ui-kit-v2/toggle-switch';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtHybridTreeComponent } from '@rt-tools/ui-kit-v2/hybrid-tree';\nimport { RtTreeComponent, RtTreeNodeEndDirective, RtTreeNodeMetaDirective } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtTreeSelectorControlsDirective, RtTreeSelectorUnderSearchDirective } from './rt-tree-selector.directives';\nimport { rtTreeSelectorCanApply, rtTreeSelectorClear, rtTreeSelectorFilter, rtTreeSelectorSame } from './rt-tree-selector.logic';\nimport { IRtTreeSelector } from './rt-tree-selector.model';\n\nconst BEM_BLOCK: string = 'rt-tree-selector';\n\n/**\n * Выбор деревом с поиском: поле поиска, строка контролов и `rt-tree` под ними.\n *\n * Строки, отметки, клавиши и подсветку рисует `rt-tree`; селектор отбирает узлы по каждому слову\n * поиска и держит выбор. В прямой форме каждое изменение сразу пишется в `value`, в подтверждаемой —\n * копится в черновике до «Применить». Поле поиска не отдаёт фокус и передаёт клавиши дереву.\n */\n@Component({\n selector: 'rt-tree-selector',\n templateUrl: './rt-tree-selector.component.html',\n styleUrl: './rt-tree-selector.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n FormsModule,\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtButtonDirective,\n RtIconComponent,\n RtInputComponent,\n RtToggleSwitchComponent,\n RtTooltipDirective,\n RtTreeComponent,\n RtHybridTreeComponent,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtTreeSelectorComponent<TValue> {\n readonly #host: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #injector: Injector = inject(Injector);\n\n protected readonly searchLabel: Signal<string> = rtKitLabel('dynamicSelectorSearch');\n protected readonly expandAllLabel: Signal<string> = rtKitLabel('uiExpandAll');\n protected readonly collapseAllLabel: Signal<string> = rtKitLabel('uiCollapseAll');\n protected readonly clearLabel: Signal<string> = rtKitLabel('uiClearSelection');\n protected readonly revertLabel: Signal<string> = rtKitLabel('uiRevertSelection');\n protected readonly multiLabel: Signal<string> = rtKitLabel('dynamicSelectorMulti');\n protected readonly multiHintLabel: Signal<string> = rtKitLabel('dynamicSelectorMultiHint');\n protected readonly cancelLabel: Signal<string> = rtKitLabel('uiCancel');\n protected readonly applyLabel: Signal<string> = rtKitLabel('uiApply');\n protected readonly nothingFoundLabel: Signal<string> = rtKitLabel('uiNothingFound');\n\n /** Гибридное ли дерево внутри. Ставит его наследник `rt-hybrid-tree-selector`. */\n protected readonly hybrid: boolean = false;\n\n protected readonly plainTree: Signal<RtTreeComponent<TValue> | undefined> = viewChild<RtTreeComponent<TValue>>(RtTreeComponent);\n\n protected readonly hybridTree: Signal<RtHybridTreeComponent<TValue> | undefined> =\n viewChild<RtHybridTreeComponent<TValue>>(RtHybridTreeComponent);\n\n /** Дерево внутри, какое бы ни стояло: у гибридного те же раскрытие и клавиши. */\n protected readonly tree: Signal<RtTreeComponent<TValue> | undefined> = computed(\n (): RtTreeComponent<TValue> | undefined => this.hybridTree() ?? this.plainTree()\n );\n\n protected readonly controlsTpl: Signal<RtTreeSelectorControlsDirective | undefined> = contentChild(RtTreeSelectorControlsDirective);\n\n protected readonly underSearchTpl: Signal<RtTreeSelectorUnderSearchDirective | undefined> =\n contentChild(RtTreeSelectorUnderSearchDirective);\n\n /** Разметка строк, отданная селектору: дерево внутри его содержимым не видит, и она уходит туда входом. */\n protected readonly nodeEnd: Signal<RtTreeNodeEndDirective<TValue> | undefined> = contentChild(RtTreeNodeEndDirective);\n\n protected readonly nodeMeta: Signal<RtTreeNodeMetaDirective<TValue> | undefined> = contentChild(RtTreeNodeMetaDirective);\n\n protected readonly endTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeEnd()?.templateRef ?? null\n );\n\n protected readonly metaTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeMeta()?.templateRef ?? null\n );\n\n /** Строка поиска: начинается с `searchTerm` и дальше живёт от набора в поле. */\n protected readonly term: WritableSignal<string> = linkedSignal((): string => this.searchTerm());\n\n /** Включён ли множественный выбор: без переключателя клик всегда добавляет. */\n protected readonly multiOn: WritableSignal<boolean> = linkedSignal((): boolean => this.multiDefault());\n\n /** Черновик выбора: начинается с выбора и сбрасывается к нему при каждой смене выбора снаружи. */\n protected readonly draft: WritableSignal<ReadonlyArray<TValue>> = linkedSignal((): ReadonlyArray<TValue> => this.value());\n\n protected readonly shownNodes: Signal<ReadonlyArray<IRtTree.Node<TValue>>> = computed((): ReadonlyArray<IRtTree.Node<TValue>> =>\n rtTreeSelectorFilter(this.nodes(), this.term())\n );\n\n /** Слово, которое дерево отмечает в строках: без подсветки — пустое, а отбор узлов идёт по `term`. */\n protected readonly markTerm: Signal<string> = computed((): string => (this.matchHighlight() ? this.term() : ''));\n\n protected readonly hasRows: Signal<boolean> = computed((): boolean => this.shownNodes().length > 0);\n\n /** Поиск ничего не нашёл. Дереву ушёл бы пустой список, и оно написало бы «нет вариантов». */\n protected readonly isNothingFound: Signal<boolean> = computed((): boolean => !this.hasRows() && this.nodes().length > 0);\n\n protected readonly isExpandShown: Signal<boolean> = computed((): boolean => this.expandControls() && this.hasRows());\n\n /** Откат стоит только в подтверждаемой форме: в прямой выбор уже записан, откатывать не к чему. */\n protected readonly isRevertShown: Signal<boolean> = computed(\n (): boolean => this.revertable() && this.confirm() && this.mode() !== 'none'\n );\n\n protected readonly isDraftChanged: Signal<boolean> = computed((): boolean => !rtTreeSelectorSame(this.draft(), this.value()));\n\n protected readonly isMultiToggleShown: Signal<boolean> = computed((): boolean => this.multiToggle() && this.mode() === 'multiple');\n\n protected readonly isExclusive: Signal<boolean> = computed((): boolean => this.isMultiToggleShown() && !this.multiOn());\n\n protected readonly isClearShown: Signal<boolean> = computed(\n (): boolean => this.clearable() && this.mode() !== 'none' && this.draft().length > 0\n );\n\n protected readonly isFooterShown: Signal<boolean> = computed((): boolean => this.confirm() && this.footer());\n\n public readonly nodes: InputSignal<ReadonlyArray<IRtTree.Node<TValue>>> = input.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n public readonly value: ModelSignal<ReadonlyArray<TValue>> = model<ReadonlyArray<TValue>>([]);\n public readonly mode: InputSignal<IRtTree.Mode> = input<IRtTree.Mode>('multiple');\n public readonly cascade: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly branchMarks: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** «Выбрать все» — необязательная, как кнопки строки: по умолчанию её нет. */\n public readonly selectAll: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** Подтверждаемая форма: выбор копится в черновике и уходит по «Применить». */\n public readonly confirm: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, { transform: booleanAttribute });\n /** Свой подвал с «Отмена» и «Применить». Без него приложение зовёт `apply()` и `cancel()` само. */\n public readonly footer: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly emptyAllowed: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** Иконочные кнопки «Развернуть всё» и «Свернуть всё». */\n public readonly expandControls: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly clearable: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** Иконочная кнопка «Откатить выбор»: возвращает черновик к выбору, не закрывая селектор. */\n public readonly revertable: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly multiToggle: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** С чего начинает переключатель множественного выбора. */\n public readonly multiDefault: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly expandOnStart: InputSignal<IRtTreeSelector.ExpandOnStart> = input<IRtTreeSelector.ExpandOnStart>('chosen');\n public readonly label: InputSignal<string> = input<string>('');\n /** Начальная строка поиска. */\n public readonly searchTerm: InputSignal<string> = input<string>('');\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Отмечать ли найденные слова в строках. Выключенная, подсветка не мешает отбору: узлы отбираются так же. */\n public readonly matchHighlight: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** Значок кита над подписью «ничего не найдено» и над пустым деревом внутри. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n /** Выключенный селектор не меняет выбор: поле поиска, кнопки, переключатель, дерево и подвал выключены. */\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n public readonly applied: OutputEmitterRef<ReadonlyArray<TValue>> = output<ReadonlyArray<TValue>>();\n public readonly cancelled: OutputEmitterRef<void> = output<void>();\n\n /** Можно ли применить черновик: он отличается от выбора и не пуст там, где пустой запрещён. */\n public readonly canApply: Signal<boolean> = computed(\n (): boolean => !this.disabled() && rtTreeSelectorCanApply(this.draft(), this.value(), this.emptyAllowed())\n );\n\n constructor() {\n afterNextRender((): void => {\n if (!this.disabled()) {\n this.#host.nativeElement.querySelector<HTMLInputElement>('.rt-tree-selector__search input')?.focus();\n }\n this.#expandOnStart();\n });\n }\n\n public apply(): void {\n if (!this.canApply()) {\n return;\n }\n const next: ReadonlyArray<TValue> = [...this.draft()];\n this.value.set(next);\n this.applied.emit(next);\n }\n\n public cancel(): void {\n this.draft.set(this.value());\n this.cancelled.emit();\n }\n\n protected onTerm(term: string): void {\n this.term.set(term);\n if (term.trim() !== '') {\n afterNextRender((): void => this.tree()?.expandAll(), { injector: this.#injector });\n }\n }\n\n protected onSearchKeydown(event: KeyboardEvent): void {\n this.tree()?.handleKeydown(event);\n }\n\n protected onTreeChange(next: ReadonlyArray<TValue>): void {\n this.#write(next);\n }\n\n /** Enter в выборе одного узла подтверждает: новый узел применяется, тот же — закрывает без изменений. */\n protected onPicked(): void {\n if (!this.confirm() || this.mode() !== 'single') {\n return;\n }\n if (this.canApply()) {\n this.apply();\n return;\n }\n this.cancel();\n }\n\n protected onClear(): void {\n this.#write(rtTreeSelectorClear(this.nodes(), this.draft()));\n }\n\n protected onRevert(): void {\n this.draft.set(this.value());\n }\n\n protected expandAll(): void {\n this.tree()?.expandAll();\n }\n\n protected collapseAll(): void {\n this.tree()?.collapseAll();\n }\n\n protected onMultiToggle(on: boolean): void {\n this.multiOn.set(on);\n }\n\n #write(next: ReadonlyArray<TValue>): void {\n this.draft.set(next);\n if (!this.confirm()) {\n this.value.set(next);\n }\n }\n\n #expandOnStart(): void {\n const start: IRtTreeSelector.ExpandOnStart = this.expandOnStart();\n if (start === 'all' || this.term().trim() !== '') {\n this.tree()?.expandAll();\n return;\n }\n if (start === 'none') {\n this.tree()?.collapseAll();\n }\n }\n}\n","<ng-container rtBlock=\"rt-tree-selector\">\n <div rtElem=\"head\">\n @if (label()) {\n <div rtElem=\"label\" qa-dataid=\"tree-selector-label\">{{ label() }}</div>\n }\n\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"tree-selector-search\"\n iconLeft=\"search\"\n [disabled]=\"disabled()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [ngModel]=\"term()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onTerm($event)\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (underSearchTpl(); as underSearch) {\n <div rtElem=\"under-search\" qa-dataid=\"tree-selector-under-search\">\n <ng-container [ngTemplateOutlet]=\"underSearch.templateRef\" />\n </div>\n }\n\n <div rtElem=\"controls\">\n <div rtElem=\"row\">\n @if (isExpandShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-expand-all\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"expand-all\"\n [rtTooltip]=\"expandAllLabel()\"\n [attr.aria-label]=\"expandAllLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"expandAll()\"></button>\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-collapse-all\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"collapse-all\"\n [rtTooltip]=\"collapseAllLabel()\"\n [attr.aria-label]=\"collapseAllLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"collapseAll()\"></button>\n }\n @if (isRevertShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-revert\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"undo\"\n [rtTooltip]=\"revertLabel()\"\n [attr.aria-label]=\"revertLabel()\"\n [disabled]=\"disabled() || !isDraftChanged()\"\n (click)=\"onRevert()\"></button>\n }\n @if (isClearShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-clear\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"danger\"\n size=\"sm\"\n icon=\"trash\"\n [rtTooltip]=\"clearLabel()\"\n [attr.aria-label]=\"clearLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClear()\"></button>\n }\n @if (controlsTpl(); as controls) {\n <div rtElem=\"own\">\n <ng-container [ngTemplateOutlet]=\"controls.templateRef\" />\n </div>\n }\n </div>\n\n @if (isMultiToggleShown()) {\n <div rtElem=\"multi\">\n <rt-toggle-switch\n qa-dataid=\"tree-selector-multi\"\n [ariaLabel]=\"multiLabel()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"multiOn()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onMultiToggle($event)\" />\n <span rtElem=\"multi-label\">{{ multiLabel() }}</span>\n <rt-icon rtElem=\"multi-hint-icon\" name=\"info-circle\" size=\"sm\" [rtTooltip]=\"multiHintLabel()\" />\n </div>\n }\n </div>\n </div>\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"tree-selector-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"tree-selector-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ nothingFoundLabel() }}\n </div>\n } @else {\n @if (hybrid) {\n <rt-hybrid-tree\n rtElem=\"tree\"\n qa-dataid=\"tree-selector-tree\"\n [nodes]=\"shownNodes()\"\n [value]=\"draft()\"\n [mode]=\"mode()\"\n [cascade]=\"cascade()\"\n [branchMarks]=\"branchMarks()\"\n [exclusive]=\"isExclusive()\"\n [showSelectAll]=\"selectAll()\"\n [searchTerm]=\"markTerm()\"\n [filter]=\"false\"\n [emptyIcon]=\"emptyIcon()\"\n [nodeEndTemplate]=\"endTemplate()\"\n [nodeMetaTemplate]=\"metaTemplate()\"\n [ariaLabel]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (valueChange)=\"onTreeChange($event)\"\n (picked)=\"onPicked()\" />\n } @else {\n <rt-tree\n rtElem=\"tree\"\n qa-dataid=\"tree-selector-tree\"\n [nodes]=\"shownNodes()\"\n [value]=\"draft()\"\n [mode]=\"mode()\"\n [cascade]=\"cascade()\"\n [branchMarks]=\"branchMarks()\"\n [exclusive]=\"isExclusive()\"\n [showSelectAll]=\"selectAll()\"\n [searchTerm]=\"markTerm()\"\n [filter]=\"false\"\n [emptyIcon]=\"emptyIcon()\"\n [nodeEndTemplate]=\"endTemplate()\"\n [nodeMetaTemplate]=\"metaTemplate()\"\n [ariaLabel]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (valueChange)=\"onTreeChange($event)\"\n (picked)=\"onPicked()\" />\n }\n }\n\n @if (isFooterShown()) {\n <div rtElem=\"foot\">\n <button\n rtButton\n qa-dataid=\"tree-selector-cancel\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"cancelLabel()\"\n [attr.aria-label]=\"cancelLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"cancel()\"></button>\n <button\n rtButton\n qa-dataid=\"tree-selector-apply\"\n type=\"button\"\n [label]=\"applyLabel()\"\n [attr.aria-label]=\"applyLabel()\"\n [disabled]=\"!canApply()\"\n (click)=\"apply()\"></button>\n </div>\n }\n</ng-container>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-tree-selector.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.directives.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.component.ts","../../../projects/ui-kit-v2/src/lib/components/tree-selector/rt-tree-selector.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\n/**\n * Свои контролы приложения в строке селектора — после «Развернуть всё» и «Свернуть всё». Так в\n * строку встаёт, например, выбор группировки.\n */\n@Directive({ selector: 'ng-template[rtTreeSelectorControls]' })\nexport class RtTreeSelectorControlsDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Разметка приложения сразу под полем поиска — между полем и строкой контролов. Так под поиском\n * встаёт, например, выбор области поиска или подсказка.\n */\n@Directive({ selector: 'ng-template[rtTreeSelectorUnderSearch]' })\nexport class RtTreeSelectorUnderSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { rtSearchMatches, rtSearchWords } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\n\nfunction nodeText<TValue>(node: TNode<TValue>): string {\n const badges: string = (node.badges ?? []).map((badge: IRtTree.Badge): string => badge.text).join(' ');\n return `${node.label} ${node.description ?? ''} ${badges}`;\n}\n\nfunction keepMatching<TValue>(nodes: ReadonlyArray<TNode<TValue>>, term: string): TNode<TValue>[] {\n return nodes.reduce((kept: TNode<TValue>[], node: TNode<TValue>): TNode<TValue>[] => {\n if (rtSearchMatches(nodeText(node), term)) {\n kept.push(node);\n return kept;\n }\n const inside: TNode<TValue>[] = keepMatching(node.children ?? [], term);\n if (inside.length > 0) {\n kept.push({ ...node, children: inside });\n }\n return kept;\n }, []);\n}\n\n/**\n * Узлы, в которых нашлось каждое слово поиска — в подписи, описании или метках. Совпавшая ветка\n * остаётся со всем поддеревом: без детей она выглядела бы листом. Несовпавшая ветка остаётся путём к\n * совпавшим внизу. Узлы не правятся: отобранная ветка — новый объект.\n */\nexport function rtTreeSelectorFilter<TValue>(nodes: ReadonlyArray<TNode<TValue>>, term: string): ReadonlyArray<TNode<TValue>> {\n if (rtSearchWords(term).length === 0) {\n return nodes;\n }\n return keepMatching(nodes, term);\n}\n\n/** Выключенные узлы дерева на любой глубине. */\nfunction disabledValues<TValue>(nodes: ReadonlyArray<TNode<TValue>>, into: Set<TValue>): Set<TValue> {\n nodes.forEach((node: TNode<TValue>): void => {\n if (node.disabled) {\n into.add(node.value);\n }\n disabledValues(node.children ?? [], into);\n });\n return into;\n}\n\n/** Выбор после «Очистить»: остаются только выключенные узлы — снять их человек не может. */\nexport function rtTreeSelectorClear<TValue>(nodes: ReadonlyArray<TNode<TValue>>, choice: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n const disabled: Set<TValue> = disabledValues(nodes, new Set<TValue>());\n return choice.filter((value: TValue): boolean => disabled.has(value));\n}\n\n/** Равны ли два выбора без учёта порядка. */\nexport function rtTreeSelectorSame<TValue>(a: ReadonlyArray<TValue>, b: ReadonlyArray<TValue>): boolean {\n const left: Set<TValue> = new Set<TValue>(a);\n const right: Set<TValue> = new Set<TValue>(b);\n return left.size === right.size && [...left].every((value: TValue): boolean => right.has(value));\n}\n\n/** Включено ли «Применить»: черновик отличается от выбора и не пуст там, где пустой выбор запрещён. */\nexport function rtTreeSelectorCanApply<TValue>(\n draft: ReadonlyArray<TValue>,\n choice: ReadonlyArray<TValue>,\n emptyAllowed: boolean\n): boolean {\n if (!emptyAllowed && draft.length === 0) {\n return false;\n }\n return !rtTreeSelectorSame(draft, choice);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n linkedSignal,\n model,\n output,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n Injector,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel, IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtToggleSwitchComponent } from '@rt-tools/ui-kit-v2/toggle-switch';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtHybridTreeComponent } from '@rt-tools/ui-kit-v2/hybrid-tree';\nimport { RtTreeComponent, RtTreeNodeEndDirective, RtTreeNodeMetaDirective } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtTreeSelectorControlsDirective, RtTreeSelectorUnderSearchDirective } from './rt-tree-selector.directives';\nimport { rtTreeSelectorCanApply, rtTreeSelectorClear, rtTreeSelectorFilter, rtTreeSelectorSame } from './rt-tree-selector.logic';\nimport { IRtTreeSelector } from './rt-tree-selector.model';\n\nconst BEM_BLOCK: string = 'rt-tree-selector';\n\n/**\n * Выбор деревом с поиском: поле поиска, строка контролов и `rt-tree` под ними.\n *\n * Строки, отметки, клавиши и подсветку рисует `rt-tree`; селектор отбирает узлы по каждому слову\n * поиска и держит выбор. В прямой форме каждое изменение сразу пишется в `value`, в подтверждаемой —\n * копится в черновике до «Применить». Поле поиска не отдаёт фокус и передаёт клавиши дереву.\n */\n@Component({\n selector: 'rt-tree-selector',\n templateUrl: './rt-tree-selector.component.html',\n styleUrl: './rt-tree-selector.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n FormsModule,\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtButtonDirective,\n RtIconComponent,\n RtInputComponent,\n RtToggleSwitchComponent,\n RtTooltipDirective,\n RtTreeComponent,\n RtHybridTreeComponent,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtTreeSelectorComponent<TValue> {\n readonly #host: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #injector: Injector = inject(Injector);\n\n protected readonly searchLabel: Signal<string> = rtKitLabel('dynamicSelectorSearch');\n protected readonly expandAllLabel: Signal<string> = rtKitLabel('uiExpandAll');\n protected readonly collapseAllLabel: Signal<string> = rtKitLabel('uiCollapseAll');\n protected readonly clearLabel: Signal<string> = rtKitLabel('uiClearSelection');\n protected readonly revertLabel: Signal<string> = rtKitLabel('uiRevertSelection');\n protected readonly multiLabel: Signal<string> = rtKitLabel('dynamicSelectorMulti');\n protected readonly multiHintLabel: Signal<string> = rtKitLabel('dynamicSelectorMultiHint');\n protected readonly cancelLabel: Signal<string> = rtKitLabel('uiCancel');\n protected readonly applyLabel: Signal<string> = rtKitLabel('uiApply');\n protected readonly nothingFoundLabel: Signal<string> = rtKitLabel('uiNothingFound');\n\n /** Гибридное ли дерево внутри. Ставит его наследник `rt-hybrid-tree-selector`. */\n protected readonly hybrid: boolean = false;\n\n protected readonly plainTree: Signal<RtTreeComponent<TValue> | undefined> = viewChild<RtTreeComponent<TValue>>(RtTreeComponent);\n\n protected readonly hybridTree: Signal<RtHybridTreeComponent<TValue> | undefined> =\n viewChild<RtHybridTreeComponent<TValue>>(RtHybridTreeComponent);\n\n /** Дерево внутри, какое бы ни стояло: у гибридного те же раскрытие и клавиши. */\n protected readonly tree: Signal<RtTreeComponent<TValue> | undefined> = computed(\n (): RtTreeComponent<TValue> | undefined => this.hybridTree() ?? this.plainTree()\n );\n\n protected readonly controlsTpl: Signal<RtTreeSelectorControlsDirective | undefined> = contentChild(RtTreeSelectorControlsDirective);\n\n protected readonly underSearchTpl: Signal<RtTreeSelectorUnderSearchDirective | undefined> =\n contentChild(RtTreeSelectorUnderSearchDirective);\n\n /** Разметка строк, отданная селектору: дерево внутри его содержимым не видит, и она уходит туда входом. */\n protected readonly nodeEnd: Signal<RtTreeNodeEndDirective<TValue> | undefined> = contentChild(RtTreeNodeEndDirective);\n\n protected readonly nodeMeta: Signal<RtTreeNodeMetaDirective<TValue> | undefined> = contentChild(RtTreeNodeMetaDirective);\n\n protected readonly endTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeEnd()?.templateRef ?? null\n );\n\n protected readonly metaTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeMeta()?.templateRef ?? null\n );\n\n /** Строка поиска: начинается с `searchTerm` и дальше живёт от набора в поле. */\n protected readonly term: WritableSignal<string> = linkedSignal((): string => this.searchTerm());\n\n /** Включён ли множественный выбор: без переключателя клик всегда добавляет. */\n protected readonly multiOn: WritableSignal<boolean> = linkedSignal((): boolean => this.multiDefault());\n\n /** Черновик выбора: начинается с выбора и сбрасывается к нему при каждой смене выбора снаружи. */\n protected readonly draft: WritableSignal<ReadonlyArray<TValue>> = linkedSignal((): ReadonlyArray<TValue> => this.value());\n\n protected readonly shownNodes: Signal<ReadonlyArray<IRtTree.Node<TValue>>> = computed((): ReadonlyArray<IRtTree.Node<TValue>> =>\n rtTreeSelectorFilter(this.nodes(), this.term())\n );\n\n /** Слово, которое дерево отмечает в строках: без подсветки — пустое, а отбор узлов идёт по `term`. */\n protected readonly markTerm: Signal<string> = computed((): string => (this.matchHighlight() ? this.term() : ''));\n\n protected readonly hasRows: Signal<boolean> = computed((): boolean => this.shownNodes().length > 0);\n\n /** Поиск ничего не нашёл. Дереву ушёл бы пустой список, и оно написало бы «нет вариантов». */\n protected readonly isNothingFound: Signal<boolean> = computed((): boolean => !this.hasRows() && this.nodes().length > 0);\n\n protected readonly isExpandShown: Signal<boolean> = computed((): boolean => this.expandControls() && this.hasRows());\n\n /** Откат стоит только в подтверждаемой форме: в прямой выбор уже записан, откатывать не к чему. */\n protected readonly isRevertShown: Signal<boolean> = computed(\n (): boolean => this.revertable() && this.confirm() && this.mode() !== 'none'\n );\n\n protected readonly isDraftChanged: Signal<boolean> = computed((): boolean => !rtTreeSelectorSame(this.draft(), this.value()));\n\n protected readonly isMultiToggleShown: Signal<boolean> = computed((): boolean => this.multiToggle() && this.mode() === 'multiple');\n\n protected readonly isExclusive: Signal<boolean> = computed((): boolean => this.isMultiToggleShown() && !this.multiOn());\n\n protected readonly isClearShown: Signal<boolean> = computed(\n (): boolean => this.clearable() && this.mode() !== 'none' && this.draft().length > 0\n );\n\n protected readonly isFooterShown: Signal<boolean> = computed((): boolean => this.confirm() && this.footer());\n\n public readonly nodes: InputSignal<ReadonlyArray<IRtTree.Node<TValue>>> = input.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n public readonly value: ModelSignal<ReadonlyArray<TValue>> = model<ReadonlyArray<TValue>>([]);\n public readonly mode: InputSignal<IRtTree.Mode> = input<IRtTree.Mode>('multiple');\n public readonly cascade: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly branchMarks: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** «Выбрать все» — необязательная, как кнопки строки: по умолчанию её нет. */\n public readonly selectAll: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** Подтверждаемая форма: выбор копится в черновике и уходит по «Применить». */\n public readonly confirm: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, { transform: booleanAttribute });\n /** Свой подвал с «Отмена» и «Применить». Без него приложение зовёт `apply()` и `cancel()` само. */\n public readonly footer: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly emptyAllowed: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** Иконочные кнопки «Развернуть всё» и «Свернуть всё». */\n public readonly expandControls: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly clearable: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** Иконочная кнопка «Откатить выбор»: возвращает черновик к выбору, не закрывая селектор. */\n public readonly revertable: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly multiToggle: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n /** С чего начинает переключатель множественного выбора. */\n public readonly multiDefault: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly expandOnStart: InputSignal<IRtTreeSelector.ExpandOnStart> = input<IRtTreeSelector.ExpandOnStart>('chosen');\n public readonly label: InputSignal<string> = input<string>('');\n /** Начальная строка поиска. */\n public readonly searchTerm: InputSignal<string> = input<string>('');\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Отмечать ли найденные слова в строках. Выключенная, подсветка не мешает отбору: узлы отбираются так же. */\n public readonly matchHighlight: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n /** Значок кита над подписью «ничего не найдено» и над пустым деревом внутри. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n /** Выключенный селектор не меняет выбор: поле поиска, кнопки, переключатель, дерево и подвал выключены. */\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n public readonly applied: OutputEmitterRef<ReadonlyArray<TValue>> = output<ReadonlyArray<TValue>>();\n public readonly cancelled: OutputEmitterRef<void> = output<void>();\n\n /** Можно ли применить черновик: он отличается от выбора и не пуст там, где пустой запрещён. */\n public readonly canApply: Signal<boolean> = computed(\n (): boolean => !this.disabled() && rtTreeSelectorCanApply(this.draft(), this.value(), this.emptyAllowed())\n );\n\n constructor() {\n afterNextRender((): void => {\n if (!this.disabled()) {\n this.#host.nativeElement.querySelector<HTMLInputElement>('.rt-tree-selector__search input')?.focus();\n }\n this.#expandOnStart();\n });\n }\n\n public apply(): void {\n if (!this.canApply()) {\n return;\n }\n const next: ReadonlyArray<TValue> = [...this.draft()];\n this.value.set(next);\n this.applied.emit(next);\n }\n\n public cancel(): void {\n this.draft.set(this.value());\n this.cancelled.emit();\n }\n\n protected onTerm(term: string): void {\n this.term.set(term);\n if (term.trim() !== '') {\n afterNextRender((): void => this.tree()?.expandAll(), { injector: this.#injector });\n }\n }\n\n protected onSearchKeydown(event: KeyboardEvent): void {\n this.tree()?.handleKeydown(event);\n }\n\n protected onTreeChange(next: ReadonlyArray<TValue>): void {\n this.#write(next);\n }\n\n /** Enter в выборе одного узла подтверждает: новый узел применяется, тот же — закрывает без изменений. */\n protected onPicked(): void {\n if (!this.confirm() || this.mode() !== 'single') {\n return;\n }\n if (this.canApply()) {\n this.apply();\n return;\n }\n this.cancel();\n }\n\n protected onClear(): void {\n this.#write(rtTreeSelectorClear(this.nodes(), this.draft()));\n }\n\n protected onRevert(): void {\n this.draft.set(this.value());\n }\n\n protected expandAll(): void {\n this.tree()?.expandAll();\n }\n\n protected collapseAll(): void {\n this.tree()?.collapseAll();\n }\n\n protected onMultiToggle(on: boolean): void {\n this.multiOn.set(on);\n }\n\n #write(next: ReadonlyArray<TValue>): void {\n this.draft.set(next);\n if (!this.confirm()) {\n this.value.set(next);\n }\n }\n\n #expandOnStart(): void {\n const start: IRtTreeSelector.ExpandOnStart = this.expandOnStart();\n if (start === 'all' || this.term().trim() !== '') {\n this.tree()?.expandAll();\n return;\n }\n if (start === 'none') {\n this.tree()?.collapseAll();\n }\n }\n}\n","<ng-container rtBlock=\"rt-tree-selector\">\n <div rtElem=\"head\">\n @if (label()) {\n <div rtElem=\"label\" qa-dataid=\"tree-selector-label\">{{ label() }}</div>\n }\n\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"tree-selector-search\"\n iconLeft=\"search\"\n [disabled]=\"disabled()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [ngModel]=\"term()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onTerm($event)\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (underSearchTpl(); as underSearch) {\n <div rtElem=\"under-search\" qa-dataid=\"tree-selector-under-search\">\n <ng-container [ngTemplateOutlet]=\"underSearch.templateRef\" />\n </div>\n }\n\n <div rtElem=\"controls\">\n <div rtElem=\"row\">\n @if (isExpandShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-expand-all\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"expand-all\"\n [rtTooltip]=\"expandAllLabel()\"\n [attr.aria-label]=\"expandAllLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"expandAll()\"></button>\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-collapse-all\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"collapse-all\"\n [rtTooltip]=\"collapseAllLabel()\"\n [attr.aria-label]=\"collapseAllLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"collapseAll()\"></button>\n }\n @if (isRevertShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-revert\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"secondary\"\n size=\"sm\"\n icon=\"undo\"\n [rtTooltip]=\"revertLabel()\"\n [attr.aria-label]=\"revertLabel()\"\n [disabled]=\"disabled() || !isDraftChanged()\"\n (click)=\"onRevert()\"></button>\n }\n @if (isClearShown()) {\n <button\n rtButton\n rtElem=\"control\"\n qa-dataid=\"tree-selector-clear\"\n type=\"button\"\n appearance=\"outlined\"\n theme=\"danger\"\n size=\"sm\"\n icon=\"trash\"\n [rtTooltip]=\"clearLabel()\"\n [attr.aria-label]=\"clearLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onClear()\"></button>\n }\n @if (controlsTpl(); as controls) {\n <div rtElem=\"own\">\n <ng-container [ngTemplateOutlet]=\"controls.templateRef\" />\n </div>\n }\n </div>\n\n @if (isMultiToggleShown()) {\n <div rtElem=\"multi\">\n <rt-toggle-switch\n qa-dataid=\"tree-selector-multi\"\n [ariaLabel]=\"multiLabel()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"multiOn()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onMultiToggle($event)\" />\n <span rtElem=\"multi-label\">{{ multiLabel() }}</span>\n <rt-icon rtElem=\"multi-hint-icon\" name=\"info-circle\" size=\"sm\" [rtTooltip]=\"multiHintLabel()\" />\n </div>\n }\n </div>\n </div>\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"tree-selector-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"tree-selector-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ nothingFoundLabel() }}\n </div>\n } @else {\n @if (hybrid) {\n <rt-hybrid-tree\n rtElem=\"tree\"\n qa-dataid=\"tree-selector-tree\"\n [nodes]=\"shownNodes()\"\n [value]=\"draft()\"\n [mode]=\"mode()\"\n [cascade]=\"cascade()\"\n [branchMarks]=\"branchMarks()\"\n [exclusive]=\"isExclusive()\"\n [showSelectAll]=\"selectAll()\"\n [searchTerm]=\"markTerm()\"\n [filter]=\"false\"\n [emptyIcon]=\"emptyIcon()\"\n [nodeEndTemplate]=\"endTemplate()\"\n [nodeMetaTemplate]=\"metaTemplate()\"\n [ariaLabel]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (valueChange)=\"onTreeChange($event)\"\n (picked)=\"onPicked()\" />\n } @else {\n <rt-tree\n rtElem=\"tree\"\n qa-dataid=\"tree-selector-tree\"\n [nodes]=\"shownNodes()\"\n [value]=\"draft()\"\n [mode]=\"mode()\"\n [cascade]=\"cascade()\"\n [branchMarks]=\"branchMarks()\"\n [exclusive]=\"isExclusive()\"\n [showSelectAll]=\"selectAll()\"\n [searchTerm]=\"markTerm()\"\n [filter]=\"false\"\n [emptyIcon]=\"emptyIcon()\"\n [nodeEndTemplate]=\"endTemplate()\"\n [nodeMetaTemplate]=\"metaTemplate()\"\n [ariaLabel]=\"ariaLabel()\"\n [disabled]=\"disabled()\"\n (valueChange)=\"onTreeChange($event)\"\n (picked)=\"onPicked()\" />\n }\n }\n\n @if (isFooterShown()) {\n <div rtElem=\"foot\">\n <button\n rtButton\n qa-dataid=\"tree-selector-cancel\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"cancelLabel()\"\n [attr.aria-label]=\"cancelLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"cancel()\"></button>\n <button\n rtButton\n qa-dataid=\"tree-selector-apply\"\n type=\"button\"\n [label]=\"applyLabel()\"\n [attr.aria-label]=\"applyLabel()\"\n [disabled]=\"!canApply()\"\n (click)=\"apply()\"></button>\n </div>\n }\n</ng-container>\n"],"mappings":"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"}
|