@rt-tools/ui-kit-v2 0.29.1 → 0.30.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 (57) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +23 -29
  2. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +2 -2
  4. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +223 -3
  6. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2 -2
  8. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +1 -2
  10. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +2 -2
  12. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +277 -904
  14. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +2 -2
  16. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +1 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +35 -48
  20. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -2
  22. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs +2 -2
  23. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs.map +1 -1
  24. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +4 -4
  25. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +37 -181
  27. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +5 -36
  29. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +2 -3
  31. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  32. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +2 -2
  33. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +8 -13
  35. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
  36. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +12 -7
  37. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
  38. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +2 -2
  39. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/src/lib/components/dynamic-selector/stories/component/test-dynamic-selector-popup-frame.component.scss +6 -0
  42. package/src/lib/components/page-header/rt-page-header.component.scss +4 -2
  43. package/src/lib/components/tree/CONTEXT.md +1 -1
  44. package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +1 -1
  45. package/src/styles/_breakpoints.scss +37 -4
  46. package/src/styles/_index.scss +0 -4
  47. package/styles/tokens.css +0 -8
  48. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +4 -3
  49. package/types/rt-tools-ui-kit-v2-core.d.ts +155 -1
  50. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +51 -269
  51. package/types/rt-tools-ui-kit-v2-multiselect.d.ts +4 -3
  52. package/types/rt-tools-ui-kit-v2-select.d.ts +12 -74
  53. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +5 -20
  54. package/types/rt-tools-ui-kit-v2-tag.d.ts +2 -3
  55. package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +0 -2
  56. package/types/rt-tools-ui-kit-v2-tree.d.ts +7 -9
  57. package/src/styles/_place.scss +0 -7
@@ -1,37 +1,25 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ElementRef, InputSignal, InputSignalWithTransform, OutputEmitterRef, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
- import { IRtIcon, IRtInput, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
3
+ import { IRtIcon, IRtInput, IRtOptionTree, RtOptionList, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
4
4
  import { RtFormControlBase } from "@rt-tools/ui-kit-v2/form-control";
5
5
  import { IRtPopover, RtPopoverDirective } from "@rt-tools/ui-kit-v2/popover";
6
6
  import * as i1 from "@rt-tools/ui-kit-v2/radius";
7
7
  /**
8
8
  * Модель `<rt-select>`: один корневой неймспейс с префиксом `I`.
9
9
  * Generic-параметр `TValue` повторяет тип значения, который сидит в опциях.
10
+ *
11
+ * Опция и строка дерева объявлены в ядре: их раскладывают и деревья кита, а те не берут выбор из
12
+ * списка. Здесь — те же типы под прежними именами.
10
13
  */
11
14
  export declare namespace IRtSelect {
12
15
  /** Одна опция dropdown'а. */
13
- interface Option<TValue> {
14
- label: string;
15
- value: TValue;
16
- disabled?: boolean;
17
- /** Дети опции того же вида. Хотя бы одна опция с детьми делает список деревом. */
18
- children?: ReadonlyArray<Option<TValue>>;
19
- }
16
+ type Option<TValue> = IRtOptionTree.Option<TValue>;
20
17
  /** Видимая строка дерева: опция, её уровень и то, ветка ли она и раскрыта ли. */
21
- interface Row<TValue> {
22
- readonly option: Option<TValue>;
23
- readonly level: number;
24
- readonly branch: boolean;
25
- readonly open: boolean;
26
- readonly parent: TValue | null;
27
- }
18
+ type Row<TValue> = IRtOptionTree.Row<TValue>;
28
19
  /** Сколько включённых листьев ветки выбрано: все, часть или ни одного. */
29
- type TBranchState = 'all' | 'some' | 'none';
20
+ type TBranchState = IRtOptionTree.TBranchState;
30
21
  /** Что делать по боковой стрелке: какую ветку переключить и куда увести подсветку. */
31
- interface SideKeyAnswer<TValue> {
32
- readonly toggle: TValue | null;
33
- readonly index: number;
34
- }
22
+ type SideKeyAnswer<TValue> = IRtOptionTree.SideKeyAnswer<TValue>;
35
23
  /**
36
24
  * Что кит отдаёт своей разметке указателя. Три значения и не больше: большее привязало бы
37
25
  * разметку потребителя к устройству семьи, и семью стало бы не поправить, не сломав её.
@@ -75,6 +63,7 @@ export declare class RtSelectTriggerDirective<TValue = unknown> {
75
63
  static ɵfac: i0.ɵɵFactoryDeclaration<RtSelectTriggerDirective<any>, never>;
76
64
  static ɵdir: i0.ɵɵDirectiveDeclaration<RtSelectTriggerDirective<any>, "[rtSelectTrigger]", never, {}, {}, never, never, true, never>;
77
65
  }
66
+ /** Клавиши, открывающие закрытый dropdown с фокуса на trigger'е. */
78
67
  type TBooleanInput = boolean | string;
79
68
  /**
80
69
  * Single-select dropdown с опциональным filter input.
@@ -96,10 +85,12 @@ export declare class RtSelectComponent<TValue> extends RtFormControlBase<TValue
96
85
  protected readonly popover: Signal<RtPopoverDirective>;
97
86
  protected readonly triggerEl: Signal<ElementRef<HTMLButtonElement> | undefined>;
98
87
  protected readonly filterTerm: WritableSignal<string>;
99
- protected readonly activeIndex: WritableSignal<number>;
100
88
  /** Раскрытые ветки дерева. Живут, пока открыта панель: при открытии раскрыты ветки над выбранным. */
101
89
  protected readonly openBranches: WritableSignal<ReadonlySet<TValue>>;
102
90
  protected readonly isOpen: Signal<boolean>;
91
+ /** Клавиатура списка: подсветка, клавиши открытия, id для `aria-activedescendant`, прокрутка к опции. */
92
+ protected readonly optionList: RtOptionList;
93
+ protected readonly activeIndex: WritableSignal<number>;
103
94
  /** Идентификатор подсвеченной опции — тот же, что уходит в `aria-activedescendant`. */
104
95
  protected readonly activeOptionId: Signal<string | null>;
105
96
  /**
@@ -140,7 +131,6 @@ export declare class RtSelectComponent<TValue> extends RtFormControlBase<TValue
140
131
  */
141
132
  readonly panelMaxHeight: InputSignal<string | null>;
142
133
  readonly selectionChange: OutputEmitterRef<TValue | null>;
143
- constructor();
144
134
  setDisabledState(disabled: boolean): void;
145
135
  protected getEmptyValue(): TValue | null;
146
136
  protected focusAfterClear(): void;
@@ -209,56 +199,4 @@ export declare class RtSelectComponent<TValue> extends RtFormControlBase<TValue
209
199
  outputs: {};
210
200
  }]>;
211
201
  }
212
- /**
213
- * Держит подсвеченную клавишами опцию в видимой части панели.
214
- *
215
- * Панель списка ограничена по высоте, и длинный список прокручивается внутри неё. Клавиши двигают
216
- * подсветку, но фокус остаётся на поле: браузер сам панель не прокручивает, и подсветка уходила
217
- * за нижний край — человек выбирал Enter'ом то, чего не видел. После каждой отрисовки, в которой
218
- * сменилась подсвеченная опция, она прокручивается ровно настолько, чтобы встать в панель.
219
- *
220
- * Панель рисуется в наложении, вне поддерева семьи, поэтому опция ищется в документе по своему
221
- * идентификатору — тому же, что стоит в `aria-activedescendant`. На сервере отрисовки нет, и
222
- * эффект не выполняется; среда без `scrollIntoView` пропускается.
223
- *
224
- * Зовётся в контексте внедрения — полем или конструктором семьи.
225
- *
226
- * @param activeOptionId идентификатор подсвеченной опции; `null` — подсветки нет или панель закрыта
227
- */
228
- export declare function rtScrollActiveOptionIntoView(activeOptionId: () => string | null): void;
229
- /**
230
- * Дерево опций выбора из списка — общее для `rt-select` и `rt-multiselect`.
231
- *
232
- * Обе семьи раскладывают, ищут и считают дерево одинаково, поэтому это чистые функции в одном
233
- * месте: две копии разошлись бы на первой правке. Состояние — какие ветки раскрыты — живёт в семье,
234
- * здесь только расчёт по нему.
235
- */
236
- type TOption<TValue> = IRtSelect.Option<TValue>;
237
- type TRow<TValue> = IRtSelect.Row<TValue>;
238
- /** Список — дерево, если хоть у одной опции есть дети. Плоский список рисуется как прежде. */
239
- export declare function rtTreeIsTree<TValue>(options: ReadonlyArray<TOption<TValue>>): boolean;
240
- /** Опция по значению на любой глубине. */
241
- export declare function rtTreeFind<TValue>(options: ReadonlyArray<TOption<TValue>>, value: TValue): TOption<TValue> | undefined;
242
- /**
243
- * Включённые листья под опцией; у самого листа — он сам. Отключённая ветка не отдаёт никого: её
244
- * листья выбрать нельзя, как и её саму.
245
- */
246
- export declare function rtTreeLeaves<TValue>(option: TOption<TValue>): ReadonlyArray<TValue>;
247
- /** Сколько включённых листьев ветки выбрано. Флажок ветки выводится из этого, а не хранится. */
248
- export declare function rtTreeBranchState<TValue>(option: TOption<TValue>, chosen: ReadonlyArray<TValue>): IRtSelect.TBranchState;
249
- /** Ветки, под которыми лежит выбранное значение: они раскрыты, когда список открывается. */
250
- export declare function rtTreeOpenFor<TValue>(options: ReadonlyArray<TOption<TValue>>, chosen: ReadonlyArray<TValue>): ReadonlySet<TValue>;
251
- /**
252
- * Видимые строки по уровням. Без поискового слова раскрыты ветки из `open`. Со словом строка
253
- * остаётся, если совпала она сама или кто-то под ней, и путь к совпадению показан раскрытым.
254
- * Ветка, совпавшая сама, держит детей такими, какими они были.
255
- */
256
- export declare function rtTreeRows<TValue>(options: ReadonlyArray<TOption<TValue>>, open: ReadonlySet<TValue>, rawTerm?: string): ReadonlyArray<TRow<TValue>>;
257
- /**
258
- * Ответ на боковую стрелку. Вправо: свёрнутая ветка раскрывается, раскрытая уводит подсветку на
259
- * первого ребёнка. Влево: раскрытая ветка сворачивается, иначе подсветка уходит на родителя.
260
- */
261
- export declare function rtTreeSideKey<TValue>(rows: ReadonlyArray<TRow<TValue>>, index: number, key: string): IRtSelect.SideKeyAnswer<TValue>;
262
- /** Набор раскрытых веток с переключённой одной. */
263
- export declare function rtTreeToggle<TValue>(open: ReadonlySet<TValue>, value: TValue): ReadonlySet<TValue>;
264
202
  export {};
@@ -1,7 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ElementRef, EnvironmentProviders, InjectionToken, InputSignal, InputSignalWithTransform, OutputEmitterRef, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
3
  import { FormControl } from "@angular/forms";
4
- import { IRtIcon, IRtInput } from "@rt-tools/ui-kit-v2/core";
4
+ import { IRtIcon, IRtInput, IRtMatchPart } from "@rt-tools/ui-kit-v2/core";
5
5
  /**
6
6
  * Входы вида бокового меню: подписи и заливка значков, поле поиска, подсказка прокрутки панели. Ни
7
7
  * один не меняет поведения — по ним приложение даёт меню вид первого кита, а без них меню рисуется
@@ -113,11 +113,8 @@ export declare namespace IRtSideMenu {
113
113
  data?: ItemData;
114
114
  };
115
115
  }
116
- /** Кусок подписи: отмеченный — тот, которым она совпала с запросом. */
117
- interface TitlePart {
118
- text: string;
119
- matched: boolean;
120
- }
116
+ /** Кусок подписи: отмеченный — тот, которым она совпала с запросом. Объявлен в ядре. */
117
+ type TitlePart = IRtMatchPart;
121
118
  }
122
119
  /** Шапка бокового меню: над полосой пунктов. */
123
120
  export declare class RtSideMenuHeaderDirective {
@@ -368,12 +365,12 @@ export declare class RtSideMenuComponent extends RtSideMenuLookBase implements I
368
365
  }, ["headerTpl", "footerTpl", "ownIconTpl"], never, true, never>;
369
366
  }
370
367
  /**
371
- * Отбор пунктов подменю по подстроке подписи.
368
+ * Отбор пунктов подменю по подписи — правилом поиска кита: каждое слово запроса в любом порядке.
372
369
  *
373
370
  * Отбор спускается внутрь папок на любую глубину: потребитель кладёт в папки то, что человек и ищет
374
371
  * по имени, и по одному верхнему уровню такой пункт не нашёлся бы.
375
372
  *
376
- * В выдаче стоят только строки, содержащие запрос. Папка остаётся путём к совпавшим детям, а её
373
+ * В выдаче стоят только строки, совпавшие с запросом. Папка остаётся путём к совпавшим детям, а её
377
374
  * состав отбирается тем же правилом: иначе одно совпадение по имени папки вытаскивало бы весь её
378
375
  * состав. Папка, совпавшая только по имени, остаётся одной строкой без детей.
379
376
  *
@@ -396,18 +393,6 @@ export declare const RT_SIDE_MENU_WIDTH_MAX: number;
396
393
  export declare const RT_SIDE_MENU_WIDTH_STEP: number;
397
394
  /** Приведение ширины к пределам. */
398
395
  export declare function clampSideMenuWidth(width: number): number;
399
- /**
400
- * Резка подписи на совпавшие и несовпавшие куски.
401
- *
402
- * Отмечаются все вхождения: отмеченное одно первое читается как «второго нет». Сравнение без учёта
403
- * регистра, а куски режутся из оригинала — приведение к нижнему регистру переписало бы названия.
404
- */
405
- export declare function splitSideMenuTitle(name: string, query: string): IRtSideMenu.TitlePart[];
406
- /**
407
- * Резка подписи по каждому слову запроса. Приложение делит поиск по пробелам и ищет каждое слово
408
- * отдельно, поэтому и отмечено каждое. Слово внутри уже отмеченного куска не режет его второй раз.
409
- */
410
- export declare function splitTitleByWords(name: string, query: string): IRtSideMenu.TitlePart[];
411
396
  /**
412
397
  * Пункты подменю в том порядке, в каком они стоят на экране. Внутрь папки список спускается, только
413
398
  * если та раскрыта: ходьба стрелками идёт по видимому, а не по всему набору.
@@ -1,8 +1,7 @@
1
1
  import { BooleanInput } from "@angular/cdk/coercion";
2
2
  import * as i0 from "@angular/core";
3
3
  import { ElementRef, InputSignal, InputSignalWithTransform, OnDestroy, OutputEmitterRef, Signal, WritableSignal } from "@angular/core";
4
- import { IRtIcon, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
5
- import { IRtSideMenu } from "@rt-tools/ui-kit-v2/side-menu";
4
+ import { IRtIcon, IRtMatchPart, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
6
5
  import * as i1 from "@rt-tools/ui-kit-v2/radius";
7
6
  /**
8
7
  * Контракты `rt-tag` — status pill компонент.
@@ -41,7 +40,7 @@ export declare class RtTagComponent implements OnDestroy {
41
40
  /** Размер значка ведёт ступень пилюли: свой вход у него был бы вторым числом об одном. */
42
41
  protected readonly iconSize: Signal<IRtIcon.Size>;
43
42
  /** Подпись, разрезанная по словам `highlight`: без них — один кусок целиком. */
44
- protected readonly parts: Signal<ReadonlyArray<IRtSideMenu.TitlePart>>;
43
+ protected readonly parts: Signal<ReadonlyArray<IRtMatchPart>>;
45
44
  readonly value: InputSignal<string>;
46
45
  /**
47
46
  * Слова поиска, найденные куски которых метка отмечает: приложение, что ищет и по меткам,
@@ -240,8 +240,6 @@ export declare class RtTreeSelectorComponent<TValue> {
240
240
  }, ["controlsTpl", "underSearchTpl", "nodeEnd", "nodeMeta"], never, true, never>;
241
241
  }
242
242
  type TNode<TValue> = IRtTree.Node<TValue>;
243
- /** Слова строки поиска в нижнем регистре, без пустых. */
244
- export declare function rtTreeSelectorWords(term: string): ReadonlyArray<string>;
245
243
  /**
246
244
  * Узлы, в которых нашлось каждое слово поиска — в подписи, описании или метках. Совпавшая ветка
247
245
  * остаётся со всем поддеревом: без детей она выглядела бы листом. Несовпавшая ветка остаётся путём к
@@ -1,8 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { InputSignal, InputSignalWithTransform, ModelSignal, OutputEmitterRef, Signal, TemplateRef } from "@angular/core";
3
- import { IRtIcon, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
4
- import { IRtSelect } from "@rt-tools/ui-kit-v2/select";
5
- import { IRtSideMenu } from "@rt-tools/ui-kit-v2/side-menu";
3
+ import { IRtIcon, IRtMatchPart, IRtOptionTree, TRtKitLabelMap } from "@rt-tools/ui-kit-v2/core";
6
4
  import { IRtTag } from "@rt-tools/ui-kit-v2/tag";
7
5
  /**
8
6
  * Модель `<rt-tree>`: один корневой неймспейс с префиксом `I`. Узел повторяет опцию выбора из
@@ -10,7 +8,7 @@ import { IRtTag } from "@rt-tools/ui-kit-v2/tag";
10
8
  */
11
9
  export declare namespace IRtTree {
12
10
  /** Узел дерева: опция выбора из списка с необязательным описанием и детьми того же вида. */
13
- interface Node<TValue> extends IRtSelect.Option<TValue> {
11
+ interface Node<TValue> extends IRtOptionTree.Option<TValue> {
14
12
  /** Вторая строка под подписью. */
15
13
  description?: string;
16
14
  /** Метки под подписью: поиск отмечает в них найденное так же, как в подписи. */
@@ -28,16 +26,16 @@ export declare namespace IRtTree {
28
26
  */
29
27
  type Mode = 'multiple' | 'single' | 'none';
30
28
  /** Отметка строки: выбрано всё, часть или ничего. У листа части не бывает. */
31
- type Mark = IRtSelect.TBranchState;
29
+ type Mark = IRtOptionTree.TBranchState;
32
30
  /** Видимая строка дерева: та же, что у выбора из списка, с узлом дерева внутри. */
33
- interface Row<TValue> extends IRtSelect.Row<TValue> {
31
+ interface Row<TValue> extends IRtOptionTree.Row<TValue> {
34
32
  readonly option: Node<TValue>;
35
33
  }
36
34
  /** Подпись и описание строки, разрезанные по найденному слову. */
37
35
  interface LabelParts {
38
- readonly label: ReadonlyArray<IRtSideMenu.TitlePart>;
39
- readonly description: ReadonlyArray<IRtSideMenu.TitlePart>;
40
- readonly badges: ReadonlyArray<ReadonlyArray<IRtSideMenu.TitlePart>>;
36
+ readonly label: ReadonlyArray<IRtMatchPart>;
37
+ readonly description: ReadonlyArray<IRtMatchPart>;
38
+ readonly badges: ReadonlyArray<ReadonlyArray<IRtMatchPart>>;
41
39
  }
42
40
  /** Отметка строки, радио ли она и сколько выбрано под группой; `null` — числа нет. */
43
41
  interface RowState {
@@ -1,7 +0,0 @@
1
- /* Корень документа — запасное место страницы. Компонент кита считает пороги от ближайшего
2
- места по имени: внутри `rt-container` от его ширины, вне его от корня, а ширина корня равна
3
- окну. Так потребитель без контейнера видит пороги окна, как раньше. Объявление стоит вне
4
- слоя, как и свойства на корне: потребитель перебивает его порядком. */
5
- :root {
6
- container: rt-place / inline-size;
7
- }