@rt-tools/ui-kit-v2 0.38.0 → 0.39.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.
Files changed (89) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +45 -7
  2. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +2 -2
  4. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +3 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +10 -7
  8. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +45 -44
  10. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +2 -2
  12. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -2
  14. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +2 -2
  16. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +4 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +10 -0
  20. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +2 -2
  22. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  23. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +2 -2
  24. package/fesm2022/rt-tools-ui-kit-v2-message.mjs +3 -3
  25. package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +4 -4
  27. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -2
  29. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +22 -6
  31. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -1
  32. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +9 -5
  33. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +2 -1
  35. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  36. package/fesm2022/rt-tools-ui-kit-v2-table-core.mjs +101 -0
  37. package/fesm2022/rt-tools-ui-kit-v2-table-core.mjs.map +1 -0
  38. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +39 -38
  39. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  40. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +41 -4
  41. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  42. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +342 -17
  43. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  44. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +2 -0
  45. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  46. package/package.json +5 -1
  47. package/src/assets/icons-material/bookmark.fill.svg +5 -0
  48. package/src/assets/icons-material/bookmark.svg +5 -0
  49. package/src/assets/icons-material/flag.fill.svg +3 -0
  50. package/src/assets/icons-material/flag.svg +5 -0
  51. package/src/lib/components/aside/CONTEXT.md +4 -1
  52. package/src/lib/components/aside/footer/CONTEXT.md +27 -0
  53. package/src/lib/components/aside/footer/rt-aside-footer.component.scss +8 -3
  54. package/src/lib/components/aside/header/rt-aside-header.component.scss +15 -4
  55. package/src/lib/components/button/rt-button.directive.scss +5 -1
  56. package/src/lib/components/data-table/CONTEXT.md +8 -2
  57. package/src/lib/components/field/CONTEXT.md +4 -2
  58. package/src/lib/components/field/rt-field.component.scss +14 -0
  59. package/src/lib/components/form-control/CONTEXT.md +13 -8
  60. package/src/lib/components/input/rt-input.component.scss +4 -0
  61. package/src/lib/components/message/CONTEXT.md +1 -1
  62. package/src/lib/components/message/rt-message.component.scss +2 -1
  63. package/src/lib/components/multiselect/rt-multiselect.component.scss +21 -0
  64. package/src/lib/components/popover/CONTEXT.md +3 -0
  65. package/src/lib/components/profile-menu/CONTEXT.md +4 -0
  66. package/src/lib/components/profile-menu/rt-profile-menu.component.scss +11 -0
  67. package/src/lib/components/service-block/stories/component/test-service-block-panel.component.scss +29 -0
  68. package/src/lib/components/table/CONTEXT.md +3 -0
  69. package/src/lib/components/table/copy-cell/CONTEXT.md +32 -0
  70. package/src/lib/components/table/copy-cell/rt-copy-cell.component.scss +26 -0
  71. package/src/lib/components/tabs/CONTEXT.md +19 -16
  72. package/src/lib/components/tabs/rt-tabs.component.scss +25 -1
  73. package/src/lib/components/toolbar/CONTEXT.md +21 -4
  74. package/src/lib/components/toolbar/filters-aside/rt-toolbar-filters-aside.component.scss +22 -0
  75. package/src/lib/components/toolbar/rt-toolbar.component.scss +12 -0
  76. package/src/styles/_form.scss +10 -0
  77. package/src/styles/_semantic.scss +2 -1
  78. package/styles/tokens.css +29 -9
  79. package/types/rt-tools-ui-kit-v2-aside.d.ts +21 -2
  80. package/types/rt-tools-ui-kit-v2-core.d.ts +21 -5
  81. package/types/rt-tools-ui-kit-v2-data-table.d.ts +23 -9
  82. package/types/rt-tools-ui-kit-v2-form-control.d.ts +2 -2
  83. package/types/rt-tools-ui-kit-v2-message.d.ts +1 -1
  84. package/types/rt-tools-ui-kit-v2-popover.d.ts +3 -1
  85. package/types/rt-tools-ui-kit-v2-profile-menu.d.ts +6 -1
  86. package/types/rt-tools-ui-kit-v2-table-core.d.ts +76 -0
  87. package/types/rt-tools-ui-kit-v2-table.d.ts +21 -18
  88. package/types/rt-tools-ui-kit-v2-tabs.d.ts +26 -0
  89. package/types/rt-tools-ui-kit-v2-toolbar.d.ts +79 -2
@@ -0,0 +1,101 @@
1
+ import { EListSortOrder } from "@rt-tools/utils";
2
+ function rtIsEmptyFilterValue(value, mode) {
3
+ return mode === "falsy" ? !value : value === "";
4
+ }
5
+ function rtFilterOf(filters, propertyName) {
6
+ return filters.find((filter) => filter.propertyName === propertyName) ?? null;
7
+ }
8
+ function rtFiltersWithValue(filters, propertyName, operatorType, value, mode) {
9
+ const current = rtFilterOf(filters, propertyName);
10
+ if (rtIsEmptyFilterValue(value, mode)) return current === null ? filters : filters.filter((filter) => filter !== current);
11
+ if (current === null) return [...filters, {
12
+ propertyName,
13
+ operatorType,
14
+ value
15
+ }];
16
+ if (current.value === value) return filters;
17
+ return filters.map((filter) => filter === current ? {
18
+ ...filter,
19
+ value
20
+ } : filter);
21
+ }
22
+ function rtFiltersWithOperator(filters, propertyName, operatorType, value, mode) {
23
+ const current = rtFilterOf(filters, propertyName);
24
+ if (current === null) return rtIsEmptyFilterValue(value, mode) ? filters : [...filters, {
25
+ propertyName,
26
+ operatorType,
27
+ value
28
+ }];
29
+ if (current.operatorType === operatorType) return filters;
30
+ return filters.map((filter) => filter === current ? {
31
+ ...filter,
32
+ operatorType
33
+ } : filter);
34
+ }
35
+ function rtKeysOf(entities, keyExp) {
36
+ return entities.map((entity) => entity[keyExp]);
37
+ }
38
+ function rtWithPageEntities(selected, page, keyExp) {
39
+ const keys = rtKeysOf(selected, keyExp);
40
+ return [...selected, ...page.filter((entity) => !keys.includes(entity[keyExp]))];
41
+ }
42
+ function rtWithoutPageEntities(selected, page, keyExp) {
43
+ const keys = rtKeysOf(page, keyExp);
44
+ return selected.filter((entity) => !keys.includes(entity[keyExp]));
45
+ }
46
+ function rtWithEntity(selected, entity, checked, keyExp) {
47
+ const without = selected.filter((el) => el[keyExp] !== entity[keyExp]);
48
+ return checked ? [...without, entity] : without;
49
+ }
50
+ function rtAnyOnPage(page, selectedKeys, keyExp) {
51
+ return page.some((entity) => selectedKeys.includes(entity[keyExp]));
52
+ }
53
+ function rtAllOnPage(page, selectedKeys, keyExp) {
54
+ return page.every((entity) => selectedKeys.includes(entity[keyExp]));
55
+ }
56
+ function rtPresetEntities(entities, keys, keyExp) {
57
+ return entities.filter((entity) => keys.includes(entity[keyExp]));
58
+ }
59
+ function rtSelectedAfterPage(selected, page, excluded, keyExp) {
60
+ const excludedKeys = rtKeysOf(excluded, keyExp);
61
+ return rtWithPageEntities(selected, page, keyExp).filter((entity) => !excludedKeys.includes(entity[keyExp]));
62
+ }
63
+ function rtExcludedAfterEntity(excluded, entity, checked, keyExp) {
64
+ return rtWithEntity(excluded, entity, !checked, keyExp);
65
+ }
66
+ function rtExcludedAfterPageMarked(excluded, page, keyExp) {
67
+ return rtWithoutPageEntities(excluded, page, keyExp);
68
+ }
69
+ function rtExcludedAfterPageUnmarked(excluded, page, keyExp) {
70
+ return rtWithPageEntities(excluded, page, keyExp);
71
+ }
72
+ function rtIsSortedBy(current, propertyName) {
73
+ return !!propertyName && current?.propertyName === propertyName;
74
+ }
75
+ function rtSortDirectionOf(current, propertyName) {
76
+ return current && rtIsSortedBy(current, propertyName) ? current.sortDirection : null;
77
+ }
78
+ function rtNextSort(current, propertyName, cycle) {
79
+ const direction = current?.sortDirection?.toLowerCase();
80
+ if (!rtIsSortedBy(current, propertyName)) return {
81
+ propertyName,
82
+ sortDirection: EListSortOrder.ASC
83
+ };
84
+ if (direction === EListSortOrder.ASC) return {
85
+ propertyName,
86
+ sortDirection: EListSortOrder.DESC
87
+ };
88
+ return cycle === "repeats" ? {
89
+ propertyName,
90
+ sortDirection: EListSortOrder.ASC
91
+ } : null;
92
+ }
93
+ function rtAriaSortOf(current, propertyName) {
94
+ if (!rtIsSortedBy(current, propertyName)) return "none";
95
+ const direction = current?.sortDirection?.toLowerCase();
96
+ if (direction === EListSortOrder.ASC) return "ascending";
97
+ return direction === EListSortOrder.DESC ? "descending" : "none";
98
+ }
99
+ export { rtAllOnPage, rtAnyOnPage, rtAriaSortOf, rtExcludedAfterEntity, rtExcludedAfterPageMarked, rtExcludedAfterPageUnmarked, rtFilterOf, rtFiltersWithOperator, rtFiltersWithValue, rtIsEmptyFilterValue, rtIsSortedBy, rtKeysOf, rtNextSort, rtPresetEntities, rtSelectedAfterPage, rtSortDirectionOf, rtWithEntity, rtWithPageEntities, rtWithoutPageEntities };
100
+
101
+ //# sourceMappingURL=rt-tools-ui-kit-v2-table-core.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-table-core.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/table-core/rt-table-filter.core.ts","../../../projects/ui-kit-v2/src/lib/components/table-core/rt-table-selection.core.ts","../../../projects/ui-kit-v2/src/lib/components/table-core/rt-table-sort.core.ts"],"sourcesContent":["import { IFilterModel, TFilterOperatorType } from '@rt-tools/utils';\n\n/** Значение условия в том виде, в каком оно хранится и сверяется. Одно для обеих таблиц. */\nexport type TRtFilterValue = string | number | boolean;\n\n/**\n * Какие значения поля снимают условие колонки.\n *\n * `empty-string` — только пустая строка; `0` и `false` остаются значениями, так ведёт себя `rt-table`.\n * `falsy` — любое ложное значение, как в первом ките; так ведёт себя `rt-data-table`.\n */\nexport type TRtFilterEmptyMode = 'empty-string' | 'falsy';\n\n/** Снимает ли это значение условие колонки при режиме таблицы. */\nexport function rtIsEmptyFilterValue(value: unknown, mode: TRtFilterEmptyMode): boolean {\n return mode === 'falsy' ? !value : value === '';\n}\n\n/** Условие по этой колонке из набора либо `null`, когда колонка ничего не отбирает. */\nexport function rtFilterOf<KEY extends string>(filters: ReadonlyArray<IFilterModel<KEY>>, propertyName: KEY): IFilterModel<KEY> | null {\n return filters.find((filter: IFilterModel<KEY>): boolean => filter.propertyName === propertyName) ?? null;\n}\n\n/**\n * Набор условий после перемены значения по одной колонке.\n *\n * Пустое по режиму значение снимает колонку с отбора, а не уходит пустым условием: условие без\n * значения просит потребителя ответить «подходит всё», и потребитель, прочитавший его буквально, не\n * вернёт ни одной строки.\n *\n * Возвращает прежний набор тем же объектом, когда менять нечего: по этому признаку таблица и решает,\n * сообщать ли наружу.\n */\nexport function rtFiltersWithValue<KEY extends string>(\n filters: ReadonlyArray<IFilterModel<KEY>>,\n propertyName: KEY,\n operatorType: TFilterOperatorType,\n value: TRtFilterValue,\n mode: TRtFilterEmptyMode\n): ReadonlyArray<IFilterModel<KEY>> {\n const current: IFilterModel<KEY> | null = rtFilterOf(filters, propertyName);\n\n if (rtIsEmptyFilterValue(value, mode)) {\n return current === null ? filters : filters.filter((filter: IFilterModel<KEY>): boolean => filter !== current);\n }\n\n if (current === null) {\n return [...filters, { propertyName, operatorType, value }];\n }\n\n if (current.value === value) {\n return filters;\n }\n\n return filters.map((filter: IFilterModel<KEY>): IFilterModel<KEY> => (filter === current ? { ...filter, value } : filter));\n}\n\n/**\n * Набор условий после перемены вида сравнения по одной колонке.\n *\n * Колонка с условием меняет в нём вид сравнения. Колонка без условия, но с набранным значением,\n * получает условие; без значения отбирать нечего, и набор не меняется — наружу ничего не уходит.\n */\nexport function rtFiltersWithOperator<KEY extends string>(\n filters: ReadonlyArray<IFilterModel<KEY>>,\n propertyName: KEY,\n operatorType: TFilterOperatorType,\n value: IFilterModel<KEY>['value'],\n mode: TRtFilterEmptyMode\n): ReadonlyArray<IFilterModel<KEY>> {\n const current: IFilterModel<KEY> | null = rtFilterOf(filters, propertyName);\n\n if (current === null) {\n return rtIsEmptyFilterValue(value, mode) ? filters : [...filters, { propertyName, operatorType, value }];\n }\n\n if (current.operatorType === operatorType) {\n return filters;\n }\n\n return filters.map((filter: IFilterModel<KEY>): IFilterModel<KEY> => (filter === current ? { ...filter, operatorType } : filter));\n}\n","/** Ключи записей списка. */\nexport function rtKeysOf<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n entities: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): Array<ENTITY_TYPE[KEY]> {\n return entities.map((entity: ENTITY_TYPE) => entity[keyExp]);\n}\n\n/** Записи страницы, добавленные к отмеченным; повторов не будет. */\nexport function rtWithPageEntities<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n selected: ReadonlyArray<ENTITY_TYPE>,\n page: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n const keys: Array<ENTITY_TYPE[KEY]> = rtKeysOf(selected, keyExp);\n\n return [...selected, ...page.filter((entity: ENTITY_TYPE) => !keys.includes(entity[keyExp]))];\n}\n\n/** Отмеченные без записей страницы. */\nexport function rtWithoutPageEntities<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n selected: ReadonlyArray<ENTITY_TYPE>,\n page: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n const keys: Array<ENTITY_TYPE[KEY]> = rtKeysOf(page, keyExp);\n\n return selected.filter((entity: ENTITY_TYPE) => !keys.includes(entity[keyExp]));\n}\n\n/** Отмеченные после отметки или снятия одной записи. */\nexport function rtWithEntity<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n selected: ReadonlyArray<ENTITY_TYPE>,\n entity: ENTITY_TYPE,\n checked: boolean,\n keyExp: KEY\n): ENTITY_TYPE[] {\n const without: ENTITY_TYPE[] = selected.filter((el: ENTITY_TYPE) => el[keyExp] !== entity[keyExp]);\n\n return checked ? [...without, entity] : without;\n}\n\n/** Хоть одна запись страницы отмечена. */\nexport function rtAnyOnPage<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n page: ReadonlyArray<ENTITY_TYPE>,\n selectedKeys: ReadonlyArray<ENTITY_TYPE[KEY]>,\n keyExp: KEY\n): boolean {\n return page.some((entity: ENTITY_TYPE) => selectedKeys.includes(entity[keyExp]));\n}\n\n/** Отмечены все записи страницы; пустая страница у первого кита считается отмеченной целиком. */\nexport function rtAllOnPage<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n page: ReadonlyArray<ENTITY_TYPE>,\n selectedKeys: ReadonlyArray<ENTITY_TYPE[KEY]>,\n keyExp: KEY\n): boolean {\n return page.every((entity: ENTITY_TYPE) => selectedKeys.includes(entity[keyExp]));\n}\n\n/** Записи первой страницы, чьи ключи названы приложением как отмеченные заранее. */\nexport function rtPresetEntities<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n entities: ReadonlyArray<ENTITY_TYPE>,\n keys: ReadonlyArray<ENTITY_TYPE[KEY]>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n return entities.filter((entity: ENTITY_TYPE) => keys.includes(entity[keyExp]));\n}\n\n/** Отметки после смены страницы под «отметить все»: пришедшие строки отмечаются, кроме исключённых. */\nexport function rtSelectedAfterPage<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n selected: ReadonlyArray<ENTITY_TYPE>,\n page: ReadonlyArray<ENTITY_TYPE>,\n excluded: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n const excludedKeys: Array<ENTITY_TYPE[KEY]> = rtKeysOf(excluded, keyExp);\n\n return rtWithPageEntities(selected, page, keyExp).filter((entity: ENTITY_TYPE) => !excludedKeys.includes(entity[keyExp]));\n}\n\n/** Исключения после отметки или снятия одной записи под «отметить все». */\nexport function rtExcludedAfterEntity<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n excluded: ReadonlyArray<ENTITY_TYPE>,\n entity: ENTITY_TYPE,\n checked: boolean,\n keyExp: KEY\n): ENTITY_TYPE[] {\n return rtWithEntity(excluded, entity, !checked, keyExp);\n}\n\n/** Исключения после отметки всей страницы под «отметить все»: её записи уходят из исключений. */\nexport function rtExcludedAfterPageMarked<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n excluded: ReadonlyArray<ENTITY_TYPE>,\n page: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n return rtWithoutPageEntities(excluded, page, keyExp);\n}\n\n/** Исключения после снятия всей страницы под «отметить все»: её записи становятся исключениями. */\nexport function rtExcludedAfterPageUnmarked<ENTITY_TYPE, KEY extends keyof ENTITY_TYPE>(\n excluded: ReadonlyArray<ENTITY_TYPE>,\n page: ReadonlyArray<ENTITY_TYPE>,\n keyExp: KEY\n): ENTITY_TYPE[] {\n return rtWithPageEntities(excluded, page, keyExp);\n}\n","import { EListSortOrder, ISortModel, TListSortOrderType, TNullable } from '@rt-tools/utils';\n\n/** Значение атрибута `aria-sort` шапки: направление либо его отсутствие. Одно для обеих таблиц. */\nexport type TRtAriaSort = 'ascending' | 'descending' | 'none';\n\n/**\n * Что просит нажатие на шапку после убывания.\n *\n * `clears` — порядок снимается: по возрастанию → по убыванию → без порядка, так ведёт себя `rt-table`.\n * `repeats` — снова по возрастанию, как в первом ките; так ведёт себя `rt-data-table`.\n */\nexport type TRtSortCycle = 'clears' | 'repeats';\n\n/** Порядок стоит по этой колонке. */\nexport function rtIsSortedBy(current: TNullable<ISortModel<string>>, propertyName: TNullable<string>): boolean {\n return !!propertyName && current?.propertyName === propertyName;\n}\n\n/** Направление порядка по этой колонке либо `null`, когда порядок стоит по другой или не стоит вовсе. */\nexport function rtSortDirectionOf(current: TNullable<ISortModel<string>>, propertyName: string): TListSortOrderType | null {\n return current && rtIsSortedBy(current, propertyName) ? current.sortDirection : null;\n}\n\n/**\n * Следующий порядок после нажатия на шапку колонки.\n *\n * Оба круга смотрят на нажатую колонку: другая колонка встаёт по возрастанию, та, что идёт по\n * возрастанию, — по убыванию. Круги расходятся только после убывания.\n */\nexport function rtNextSort(current: TNullable<ISortModel<string>>, propertyName: string, cycle: TRtSortCycle): ISortModel<string> | null {\n const direction: string | undefined = current?.sortDirection?.toLowerCase();\n\n if (!rtIsSortedBy(current, propertyName)) {\n return { propertyName, sortDirection: EListSortOrder.ASC };\n }\n\n if (direction === EListSortOrder.ASC) {\n return { propertyName, sortDirection: EListSortOrder.DESC };\n }\n\n return cycle === 'repeats' ? { propertyName, sortDirection: EListSortOrder.ASC } : null;\n}\n\n/** Значение `aria-sort` шапки: скринридер называет порядок колонки, а не только её имя. */\nexport function rtAriaSortOf(current: TNullable<ISortModel<string>>, propertyName: string): TRtAriaSort {\n if (!rtIsSortedBy(current, propertyName)) {\n return 'none';\n }\n\n const direction: string | undefined = current?.sortDirection?.toLowerCase();\n\n if (direction === EListSortOrder.ASC) {\n return 'ascending';\n }\n\n return direction === EListSortOrder.DESC ? 'descending' : 'none';\n}\n"],"mappings":"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"}
@@ -8,6 +8,7 @@ import { RtTooltipDirective } from "@rt-tools/ui-kit-v2/tooltip";
8
8
  import { NgTemplateOutlet } from "@angular/common";
9
9
  import { EFilterOperatorType, EListSortOrder } from "@rt-tools/utils";
10
10
  import { RtIconComponent } from "@rt-tools/ui-kit-v2/icon";
11
+ import { rtAriaSortOf, rtFilterOf, rtFiltersWithOperator, rtFiltersWithValue, rtNextSort, rtSortDirectionOf } from "@rt-tools/ui-kit-v2/table-core";
11
12
  import { CDK_TABLE, CdkCell, CdkCellDef, CdkColumnDef, CdkHeaderCell, CdkHeaderCellDef, CdkTable, DataRowOutlet, FooterRowOutlet, HeaderRowOutlet, NoDataRowOutlet } from "@angular/cdk/table";
12
13
  import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
13
14
  import { RtEmptyStateComponent } from "@rt-tools/ui-kit-v2/empty-state";
@@ -50,7 +51,7 @@ var RtCopyCellComponent = class RtCopyCellComponent {
50
51
  this.#copiedLabel = rtKitLabel(COPIED_KEY);
51
52
  this.copied = signal(false, ...ngDevMode ? [{ debugName: "copied" }] : /* istanbul ignore next */ []);
52
53
  this.hint = signal("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
53
- this.iconName = computed(() => this.copied() ? "check" : "copy", ...ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []);
54
+ this.iconName = computed(() => this.copied() ? "check" : "ico-copy", ...ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []);
54
55
  this.actionLabel = computed(() => this.copied() ? this.#copiedLabel() : this.#copyLabel(), ...ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []);
55
56
  this.value = input(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
56
57
  this.variant = input("ghost", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
@@ -58,6 +59,10 @@ var RtCopyCellComponent = class RtCopyCellComponent {
58
59
  ...ngDevMode ? { debugName: "revealOnHover" } : /* istanbul ignore next */ {},
59
60
  transform: booleanAttribute
60
61
  });
62
+ this.framed = input(false, {
63
+ ...ngDevMode ? { debugName: "framed" } : /* istanbul ignore next */ {},
64
+ transform: booleanAttribute
65
+ });
61
66
  this.#destroyRef.onDestroy(() => this.#clearTimer());
62
67
  }
63
68
  measureTruncation() {
@@ -125,6 +130,13 @@ var RtCopyCellComponent = class RtCopyCellComponent {
125
130
  isSignal: true,
126
131
  isRequired: false,
127
132
  transformFunction: null
133
+ },
134
+ framed: {
135
+ classPropertyName: "framed",
136
+ publicName: "framed",
137
+ isSignal: true,
138
+ isRequired: false,
139
+ transformFunction: null
128
140
  }
129
141
  },
130
142
  host: {
@@ -132,12 +144,15 @@ var RtCopyCellComponent = class RtCopyCellComponent {
132
144
  "mouseenter": "measureTruncation()",
133
145
  "focusin": "measureTruncation()"
134
146
  },
135
- properties: { "class.rt-copy-cell--static": "!revealOnHover()" },
147
+ properties: {
148
+ "class.rt-copy-cell--static": "!revealOnHover() || framed()",
149
+ "class.rt-copy-cell--framed": "framed()"
150
+ },
136
151
  classAttribute: "rt-copy-cell"
137
152
  },
138
153
  ngImport: i0,
139
154
  template: "<ng-container rtBlock=\"rt-copy-cell\">\n <span rtElem=\"content\" qa-dataid=\"copy-cell-content\" [rtTooltip]=\"hint()\"><ng-content /></span>\n <rt-icon-button\n rtElem=\"button\"\n qa-dataid=\"copy-cell-button\"\n size=\"sm\"\n [icon]=\"iconName()\"\n [variant]=\"variant()\"\n [ariaLabel]=\"actionLabel()\"\n [tooltip]=\"actionLabel()\"\n (clicked)=\"onCopy($event)\" />\n</ng-container>\n",
140
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-copy-cell{--rt-copy-cell-transition-duration: var(--rt-duration-fast);display:inline-flex;min-width:0;align-items:center;gap:var(--rt-space-xs)}.rt-copy-cell__content{overflow:hidden;min-width:0;text-overflow:ellipsis;white-space:nowrap}.rt-copy-cell__button{flex:0 0 auto;opacity:0;transition:opacity var(--rt-copy-cell-transition-duration) ease}.rt-copy-cell:hover .rt-copy-cell__button,.rt-copy-cell:focus-within .rt-copy-cell__button{opacity:1}.rt-copy-cell--static .rt-copy-cell__button{opacity:1}.rt-table tbody tr:hover .rt-copy-cell__button,.rt-table tbody tr:focus-within .rt-copy-cell__button{opacity:1}}\n"],
155
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-copy-cell{--rt-copy-cell-transition-duration: var(--rt-duration-fast);display:inline-flex;min-width:0;align-items:center;gap:var(--rt-space-xs)}.rt-copy-cell__content{overflow:hidden;min-width:0;text-overflow:ellipsis;white-space:nowrap}.rt-copy-cell__button{flex:0 0 auto;opacity:0;transition:opacity var(--rt-copy-cell-transition-duration) ease}.rt-copy-cell:hover .rt-copy-cell__button,.rt-copy-cell:focus-within .rt-copy-cell__button{opacity:1}.rt-copy-cell--static .rt-copy-cell__button{opacity:1}.rt-copy-cell--framed{display:flex;width:100%;box-sizing:border-box;padding:var(--rt-space-1) var(--rt-space-1) var(--rt-space-1) var(--rt-input-padding-x);border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);gap:var(--rt-space-sm);line-height:var(--rt-leading-normal)}.rt-copy-cell--framed .rt-copy-cell__content{flex:1 1 auto;overflow-wrap:anywhere;text-overflow:clip;white-space:normal}.rt-table tbody tr:hover .rt-copy-cell__button,.rt-table tbody tr:focus-within .rt-copy-cell__button{opacity:1}}\n"],
141
156
  dependencies: [
142
157
  {
143
158
  kind: "component",
@@ -217,12 +232,13 @@ i0.ɵɵngDeclareClassMetadata({
217
232
  ],
218
233
  host: {
219
234
  class: BEM_BLOCK$5,
220
- "[class.rt-copy-cell--static]": "!revealOnHover()",
235
+ "[class.rt-copy-cell--static]": "!revealOnHover() || framed()",
236
+ "[class.rt-copy-cell--framed]": "framed()",
221
237
  "(mouseenter)": "measureTruncation()",
222
238
  "(focusin)": "measureTruncation()"
223
239
  },
224
240
  template: "<ng-container rtBlock=\"rt-copy-cell\">\n <span rtElem=\"content\" qa-dataid=\"copy-cell-content\" [rtTooltip]=\"hint()\"><ng-content /></span>\n <rt-icon-button\n rtElem=\"button\"\n qa-dataid=\"copy-cell-button\"\n size=\"sm\"\n [icon]=\"iconName()\"\n [variant]=\"variant()\"\n [ariaLabel]=\"actionLabel()\"\n [tooltip]=\"actionLabel()\"\n (clicked)=\"onCopy($event)\" />\n</ng-container>\n",
225
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-copy-cell{--rt-copy-cell-transition-duration: var(--rt-duration-fast);display:inline-flex;min-width:0;align-items:center;gap:var(--rt-space-xs)}.rt-copy-cell__content{overflow:hidden;min-width:0;text-overflow:ellipsis;white-space:nowrap}.rt-copy-cell__button{flex:0 0 auto;opacity:0;transition:opacity var(--rt-copy-cell-transition-duration) ease}.rt-copy-cell:hover .rt-copy-cell__button,.rt-copy-cell:focus-within .rt-copy-cell__button{opacity:1}.rt-copy-cell--static .rt-copy-cell__button{opacity:1}.rt-table tbody tr:hover .rt-copy-cell__button,.rt-table tbody tr:focus-within .rt-copy-cell__button{opacity:1}}\n"]
241
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-copy-cell{--rt-copy-cell-transition-duration: var(--rt-duration-fast);display:inline-flex;min-width:0;align-items:center;gap:var(--rt-space-xs)}.rt-copy-cell__content{overflow:hidden;min-width:0;text-overflow:ellipsis;white-space:nowrap}.rt-copy-cell__button{flex:0 0 auto;opacity:0;transition:opacity var(--rt-copy-cell-transition-duration) ease}.rt-copy-cell:hover .rt-copy-cell__button,.rt-copy-cell:focus-within .rt-copy-cell__button{opacity:1}.rt-copy-cell--static .rt-copy-cell__button{opacity:1}.rt-copy-cell--framed{display:flex;width:100%;box-sizing:border-box;padding:var(--rt-space-1) var(--rt-space-1) var(--rt-space-1) var(--rt-input-padding-x);border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);gap:var(--rt-space-sm);line-height:var(--rt-leading-normal)}.rt-copy-cell--framed .rt-copy-cell__content{flex:1 1 auto;overflow-wrap:anywhere;text-overflow:clip;white-space:normal}.rt-table tbody tr:hover .rt-copy-cell__button,.rt-table tbody tr:focus-within .rt-copy-cell__button{opacity:1}}\n"]
226
242
  }]
227
243
  }],
228
244
  ctorParameters: () => [],
@@ -250,27 +266,25 @@ i0.ɵɵngDeclareClassMetadata({
250
266
  alias: "revealOnHover",
251
267
  required: false
252
268
  }]
269
+ }],
270
+ framed: [{
271
+ type: i0.Input,
272
+ args: [{
273
+ isSignal: true,
274
+ alias: "framed",
275
+ required: false
276
+ }]
253
277
  }]
254
278
  }
255
279
  });
256
280
  function nextSort(current, propertyName) {
257
- if (current === null || current.propertyName !== propertyName) return {
258
- propertyName,
259
- sortDirection: EListSortOrder.ASC
260
- };
261
- if (current.sortDirection === EListSortOrder.ASC) return {
262
- propertyName,
263
- sortDirection: EListSortOrder.DESC
264
- };
265
- return null;
281
+ return rtNextSort(current, propertyName, "clears");
266
282
  }
267
283
  function sortDirectionOf(current, propertyName) {
268
- return current !== null && current.propertyName === propertyName ? current.sortDirection : null;
284
+ return rtSortDirectionOf(current, propertyName);
269
285
  }
270
286
  function ariaSortOf(current, propertyName) {
271
- const direction = sortDirectionOf(current, propertyName);
272
- if (direction === null) return "none";
273
- return direction === EListSortOrder.ASC ? "ascending" : "descending";
287
+ return rtAriaSortOf(current, propertyName);
274
288
  }
275
289
  function isColumnSortable(config, key) {
276
290
  const column = config.find((candidate) => candidate.key === key);
@@ -307,30 +321,15 @@ function withoutLockedHidden(config, settings) {
307
321
  function filterValueOf(value) {
308
322
  return value instanceof Date ? value.toISOString() : value ?? "";
309
323
  }
324
+ const RT_TABLE_EMPTY_MODE = "empty-string";
310
325
  function filterOf(filters, propertyName) {
311
- return filters.find((filter) => filter.propertyName === propertyName) ?? null;
326
+ return rtFilterOf(filters, propertyName);
312
327
  }
313
328
  function filtersWithValue(filters, propertyName, operatorType, value) {
314
- const current = filterOf(filters, propertyName);
315
- if (value === "") return current === null ? filters : filters.filter((filter) => filter !== current);
316
- if (current === null) return [...filters, {
317
- propertyName,
318
- operatorType,
319
- value
320
- }];
321
- if (current.value === value) return filters;
322
- return filters.map((filter) => filter === current ? {
323
- ...filter,
324
- value
325
- } : filter);
329
+ return rtFiltersWithValue(filters, propertyName, operatorType, value, RT_TABLE_EMPTY_MODE);
326
330
  }
327
331
  function filtersWithOperator(filters, propertyName, operatorType) {
328
- const current = filterOf(filters, propertyName);
329
- if (current === null || current.operatorType === operatorType) return filters;
330
- return filters.map((filter) => filter === current ? {
331
- ...filter,
332
- operatorType
333
- } : filter);
332
+ return rtFiltersWithOperator(filters, propertyName, operatorType, "", RT_TABLE_EMPTY_MODE);
334
333
  }
335
334
  function startOperatorOf(allowed, start) {
336
335
  if (start !== void 0) return start;
@@ -2417,13 +2416,15 @@ var RtTableSettingsAsideComponent = class RtTableSettingsAsideComponent extends
2417
2416
  "ariaLabel",
2418
2417
  "requestError",
2419
2418
  "trapFocus",
2419
+ "modal",
2420
2420
  "pending"
2421
2421
  ]
2422
2422
  },
2423
2423
  {
2424
2424
  kind: "component",
2425
2425
  type: RtAsideFooterComponent,
2426
- selector: "rt-aside-footer"
2426
+ selector: "rt-aside-footer",
2427
+ inputs: ["phoneCloseLabel"]
2427
2428
  },
2428
2429
  {
2429
2430
  kind: "component",