@rt-tools/ui-kit-v2 0.32.0 → 0.34.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 (220) hide show
  1. package/README.md +4 -3
  2. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +1 -0
  3. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
  4. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +92 -5
  5. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  6. package/fesm2022/rt-tools-ui-kit-v2-badge.mjs +191 -0
  7. package/fesm2022/rt-tools-ui-kit-v2-badge.mjs.map +1 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +3 -2
  9. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/rt-tools-ui-kit-v2-button.mjs +6 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
  12. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +35 -4
  13. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
  14. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +13 -4
  15. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -1
  16. package/fesm2022/rt-tools-ui-kit-v2-container.mjs +245 -60
  17. package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +30 -5
  19. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
  20. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +114 -2
  21. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  22. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +14 -3
  23. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  24. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +17 -3
  25. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +6 -3
  27. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -2
  29. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-divider.mjs +112 -0
  31. package/fesm2022/rt-tools-ui-kit-v2-divider.mjs.map +1 -0
  32. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +1 -0
  33. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs +854 -0
  35. package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs.map +1 -0
  36. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +16 -5
  37. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  38. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +580 -65
  39. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  40. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +203 -15
  41. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
  42. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +40 -8
  43. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  44. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +1 -0
  45. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  46. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +7 -3
  47. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
  48. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +53 -2
  49. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
  50. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +14 -4
  51. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -1
  52. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +6 -3
  53. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
  54. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +16 -5
  55. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  56. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +1 -0
  57. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
  58. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +14 -4
  59. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
  60. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +3 -2
  61. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  62. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +207 -7
  63. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
  64. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1 -0
  65. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  66. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +3 -2
  67. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  68. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -0
  69. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  70. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +3 -2
  71. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
  72. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +3 -2
  73. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -1
  74. package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs +171 -0
  75. package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs.map +1 -0
  76. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +176 -6
  77. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
  78. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +9 -6
  79. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  80. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +1 -0
  81. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  82. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +142 -23
  83. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  84. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +22 -9
  85. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  86. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +3 -2
  87. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
  88. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +105 -8
  89. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
  90. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +13 -2
  91. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  92. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +609 -33
  93. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  94. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +1 -0
  95. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  96. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +45 -7
  97. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
  98. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +2 -2
  99. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
  100. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +11 -2
  101. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  102. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +152 -11
  103. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  104. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +199 -17
  105. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  106. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +35 -5
  107. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  108. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +14 -4
  109. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
  110. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +6 -3
  111. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
  112. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +21 -6
  113. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  114. package/fesm2022/rt-tools-ui-kit-v2.mjs +4 -0
  115. package/package.json +17 -1
  116. package/src/assets/icons/volume-off.svg +2 -1
  117. package/src/lib/components/autocomplete/CONTEXT.md +25 -14
  118. package/src/lib/components/autocomplete/rt-autocomplete.component.scss +19 -0
  119. package/src/lib/components/badge/CONTEXT.md +33 -0
  120. package/src/lib/components/badge/rt-badge.directive.scss +104 -0
  121. package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +2 -2
  122. package/src/lib/components/button/CONTEXT.md +5 -0
  123. package/src/lib/components/button/rt-button.directive.scss +3 -1
  124. package/src/lib/components/checkbox/CONTEXT.md +15 -8
  125. package/src/lib/components/color-palette/rt-color-palette.component.scss +2 -2
  126. package/src/lib/components/container/CONTEXT.md +23 -6
  127. package/src/lib/components/container/rt-container.component.scss +90 -1
  128. package/src/lib/components/copy-value/CONTEXT.md +6 -5
  129. package/src/lib/components/copy-value/rt-copy-value.component.scss +16 -0
  130. package/src/lib/components/date-picker/rt-date-picker.component.scss +7 -0
  131. package/src/lib/components/date-range/rt-date-range.component.scss +7 -0
  132. package/src/lib/components/divider/CONTEXT.md +21 -0
  133. package/src/lib/components/divider/rt-divider.component.scss +34 -0
  134. package/src/lib/components/drawer/CONTEXT.md +73 -0
  135. package/src/lib/components/drawer/rt-drawer-container.component.scss +19 -0
  136. package/src/lib/components/drawer/rt-drawer.component.scss +168 -0
  137. package/src/lib/components/drawer/rt-resize-handle.component.scss +42 -0
  138. package/src/lib/components/dynamic-selector/CONTEXT.md +5 -0
  139. package/src/lib/components/expansion-panel/CONTEXT.md +32 -8
  140. package/src/lib/components/expansion-panel/rt-expansion-panel.component.scss +67 -2
  141. package/src/lib/components/field/CONTEXT.md +43 -0
  142. package/src/lib/components/field/rt-field-label-inside.scss +179 -0
  143. package/src/lib/components/field/rt-field.component.scss +51 -2
  144. package/src/lib/components/icon-button/CONTEXT.md +17 -15
  145. package/src/lib/components/icon-button/rt-icon-button.component.scss +3 -1
  146. package/src/lib/components/inline-edit/rt-inline-edit.component.scss +4 -4
  147. package/src/lib/components/input/CONTEXT.md +45 -11
  148. package/src/lib/components/input/rt-input-floating-label.scss +192 -0
  149. package/src/lib/components/input/rt-input-icons.scss +105 -0
  150. package/src/lib/components/input/rt-input.component.scss +91 -13
  151. package/src/lib/components/input-number/CONTEXT.md +7 -0
  152. package/src/lib/components/input-number/rt-input-number.component.scss +58 -1
  153. package/src/lib/components/menu/CONTEXT.md +1 -0
  154. package/src/lib/components/multiselect/CONTEXT.md +2 -1
  155. package/src/lib/components/multiselect/rt-multiselect.component.scss +7 -0
  156. package/src/lib/components/pagination/CONTEXT.md +3 -0
  157. package/src/lib/components/pagination/rt-pagination.component.scss +7 -0
  158. package/src/lib/components/progress-bar/CONTEXT.md +22 -0
  159. package/src/lib/components/progress-bar/rt-progress-bar.component.scss +77 -0
  160. package/src/lib/components/radio-button/CONTEXT.md +9 -0
  161. package/src/lib/components/radio-button/rt-radio-group.component.scss +13 -0
  162. package/src/lib/components/select/CONTEXT.md +28 -0
  163. package/src/lib/components/select/rt-select-clear.scss +88 -0
  164. package/src/lib/components/select/rt-select-floating-label.scss +155 -0
  165. package/src/lib/components/select/rt-select-material.scss +54 -0
  166. package/src/lib/components/select/rt-select.component.scss +54 -16
  167. package/src/lib/components/side-menu/CONTEXT.md +5 -0
  168. package/src/lib/components/speed-menu/rt-speed-menu.component.scss +5 -5
  169. package/src/lib/components/stepper/CONTEXT.md +13 -5
  170. package/src/lib/components/stepper/rt-stepper.component.scss +93 -0
  171. package/src/lib/components/tabs/CONTEXT.md +57 -9
  172. package/src/lib/components/tabs/rt-tabs.component.scss +201 -5
  173. package/src/lib/components/textarea/CONTEXT.md +12 -1
  174. package/src/lib/components/textarea/rt-textarea.component.scss +116 -1
  175. package/src/lib/components/toast/CONTEXT.md +23 -0
  176. package/src/lib/components/toast/rt-toast.component.scss +37 -0
  177. package/src/lib/components/toggle-button-group/CONTEXT.md +24 -4
  178. package/src/lib/components/toggle-button-group/rt-toggle-button-group-chips.scss +151 -0
  179. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -0
  180. package/src/lib/components/tooltip/CONTEXT.md +7 -1
  181. package/src/lib/components/tree/rt-tree.component.scss +2 -2
  182. package/src/rich-editor/lib/components/chat/CONTEXT.md +3 -0
  183. package/src/rich-editor/lib/components/chat/rt-chat.component.scss +9 -0
  184. package/src/styles/_color-scheme.scss +1 -1
  185. package/src/styles/_density.scss +48 -0
  186. package/src/styles/_index.scss +8 -0
  187. package/src/styles/_preset-material.scss +160 -70
  188. package/src/styles/_primitives.scss +1 -0
  189. package/src/styles/_semantic-navigation.scss +117 -0
  190. package/src/styles/_semantic.scss +29 -98
  191. package/src/styles/_theme-dark.scss +8 -0
  192. package/styles/tokens.css +2066 -1134
  193. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +34 -0
  194. package/types/rt-tools-ui-kit-v2-badge.d.ts +71 -0
  195. package/types/rt-tools-ui-kit-v2-checkbox.d.ts +17 -3
  196. package/types/rt-tools-ui-kit-v2-container.d.ts +65 -9
  197. package/types/rt-tools-ui-kit-v2-copy-value.d.ts +11 -1
  198. package/types/rt-tools-ui-kit-v2-core.d.ts +110 -4
  199. package/types/rt-tools-ui-kit-v2-divider.d.ts +29 -0
  200. package/types/rt-tools-ui-kit-v2-drawer.d.ts +257 -0
  201. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +240 -25
  202. package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +87 -3
  203. package/types/rt-tools-ui-kit-v2-field.d.ts +18 -1
  204. package/types/rt-tools-ui-kit-v2-form-control.d.ts +42 -4
  205. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +2 -1
  206. package/types/rt-tools-ui-kit-v2-input-number.d.ts +1 -0
  207. package/types/rt-tools-ui-kit-v2-input.d.ts +98 -4
  208. package/types/rt-tools-ui-kit-v2-progress-bar.d.ts +53 -0
  209. package/types/rt-tools-ui-kit-v2-radio-button.d.ts +80 -1
  210. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +5 -2
  211. package/types/rt-tools-ui-kit-v2-select.d.ts +65 -1
  212. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +3 -0
  213. package/types/rt-tools-ui-kit-v2-stepper.d.ts +57 -4
  214. package/types/rt-tools-ui-kit-v2-tabs.d.ts +291 -6
  215. package/types/rt-tools-ui-kit-v2-textarea.d.ts +16 -0
  216. package/types/rt-tools-ui-kit-v2-toast.d.ts +38 -2
  217. package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +83 -3
  218. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +17 -2
  219. package/types/rt-tools-ui-kit-v2.d.ts +4 -0
  220. package/src/lib/components/dynamic-selector/stories/component/test-dynamic-selector-popup-frame.component.scss +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-date-range.mjs","names":["MONTH_LEN","BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.model.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.logic.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/panel/rt-date-range-panel.component.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/panel/rt-date-range-panel.component.html","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.component.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.component.html"],"sourcesContent":["/** Быстрый вариант диапазона в панели поля. */\nexport enum ERtDateRangePreset {\n Today = 'today',\n Yesterday = 'yesterday',\n Last7 = 'last-7',\n Last30 = 'last-30',\n ThisMonth = 'this-month',\n LastMonth = 'last-month',\n}\n\n/** Контракт rt-date-range. */\nexport namespace IRtDateRange {\n /** Значение поля: первый и последний день периода `YYYY-MM-DD`, оба включены, `start <= end`. */\n export interface Value {\n start: string;\n end: string;\n }\n\n /** Быстрый вариант в панели: его диапазон и выключен ли он границами. */\n export interface PresetCell {\n preset: ERtDateRangePreset;\n range: Value;\n disabled: boolean;\n }\n\n /** Что месяц панели знает о черновике, наведении и границах. */\n export interface MonthContext {\n locale: string;\n today: string;\n start: string | null;\n end: string | null;\n /** День под указателем, пока выбрано только начало: до него рисуется будущий диапазон. */\n hover: string | null;\n min: string | null;\n max: string | null;\n }\n\n /** Форма числа дней по правилам множественного числа локали. */\n export type Plural = 'one' | 'few' | 'many' | 'other';\n}\n","import { ERtCalendarDayState, IRtCalendar } from '@rt-tools/ui-kit-v2/calendar';\nimport { rtDateAddMonths, rtDateInBounds, rtDateMonth, rtDateRead } from '@rt-tools/ui-kit-v2/date-picker';\nimport { IRtDatePicker } from '@rt-tools/ui-kit-v2/date-picker';\nimport { rtDateParse, rtDateShape, rtDateText } from '@rt-tools/ui-kit-v2/date-picker';\nimport { ERtDateRangePreset, IRtDateRange } from './rt-date-range.model';\n\n/**\n * Чистая логика поля диапазона дат: порядок двух дней, состояния дней месяца, быстрые варианты,\n * итог и текст поля. Сегодняшний день приходит параметром — компонент читает часы сам.\n *\n * Дни — строки `YYYY-MM-DD`: строки одной формы сравниваются как текст в порядке дат.\n */\n\nconst DAY_LENGTH_MS: number = 86_400_000;\nconst DAY_LEN: number = 10;\nconst MONTH_LEN: number = 7;\nconst YEAR_LEN: number = 4;\nconst LAST_WEEK_DAYS: number = 7;\nconst LAST_MONTH_DAYS: number = 30;\n/** Знак между датами в тексте поля. */\nconst DASH: string = ' — ';\n/** Тире между датами набранного текста: длинное или короткое, дефис — только между пробелами. */\nconst DASH_RE: RegExp = /[—–]|\\s-\\s/;\n\nfunction dayToMs(day: string): number {\n const [y, m, d]: number[] = day.split('-').map(Number);\n return Date.UTC(y, m - 1, d);\n}\n\nfunction msToDay(ms: number): string {\n return new Date(ms).toISOString().slice(0, DAY_LEN);\n}\n\nfunction addDays(day: string, delta: number): string {\n return msToDay(dayToMs(day) + delta * DAY_LENGTH_MS);\n}\n\nfunction lastDayOf(month: string): string {\n return addDays(`${rtDateAddMonths(month, 1)}-01`, -1);\n}\n\nfunction dayState(day: string, low: string | null, high: string | null): ERtCalendarDayState {\n if (high === null || low === high) {\n return day === low ? ERtCalendarDayState.Chosen : ERtCalendarDayState.Free;\n }\n if (day === low) {\n return ERtCalendarDayState.Start;\n }\n if (day === high) {\n return ERtCalendarDayState.End;\n }\n const ms: number = dayToMs(day);\n return low !== null && ms > dayToMs(low) && ms < dayToMs(high) ? ERtCalendarDayState.InRange : ERtCalendarDayState.Free;\n}\n\n/** Два дня по порядку: второй раньше первого — они меняются местами. */\nexport function rtRangeOrder(a: string, b: string): IRtDateRange.Value {\n return dayToMs(a) <= dayToMs(b) ? { start: a, end: b } : { start: b, end: a };\n}\n\n/** Значение поля из того, что пришло из формы; не пара дней по порядку — `null`. */\nexport function rtRangeRead(value: unknown): IRtDateRange.Value | null {\n if (typeof value !== 'object' || value === null) {\n return null;\n }\n const start: unknown = Reflect.get(value, 'start');\n const end: unknown = Reflect.get(value, 'end');\n if (typeof start !== 'string' || typeof end !== 'string') {\n return null;\n }\n const ok: boolean = rtDateRead(start, 'date') !== null && rtDateRead(end, 'date') !== null && dayToMs(start) <= dayToMs(end);\n return ok ? { start, end } : null;\n}\n\n/** Диапазон лежит в границах целиком. */\nexport function rtRangeInBounds(range: IRtDateRange.Value, min: string | null, max: string | null): boolean {\n return rtDateInBounds(range.start, min, max) && rtDateInBounds(range.end, min, max);\n}\n\n/**\n * Месяц `YYYY-MM` для календаря: дни черновика — начало, конец и дни между ними. Пока выбрано только\n * начало, будущий диапазон тянется до дня под указателем, и этот день светлый, как дни между краями:\n * залит только выбранный край.\n */\nexport function rtRangeMonth(month: string, ctx: IRtDateRange.MonthContext): IRtCalendar.Month {\n const base: IRtCalendar.Month = rtDateMonth(month, { locale: ctx.locale, today: ctx.today, chosen: null, min: ctx.min, max: ctx.max });\n const other: string | null = ctx.end ?? ctx.hover;\n const range: IRtDateRange.Value | null = ctx.start === null || other === null ? null : rtRangeOrder(ctx.start, other);\n const low: string | null = range?.start ?? ctx.start;\n const high: string | null = range?.end ?? null;\n const preview: string | null = ctx.end === null && ctx.hover !== ctx.start ? ctx.hover : null;\n return {\n ...base,\n days: base.days.map((day: IRtCalendar.Day): IRtCalendar.Day => {\n const state: ERtCalendarDayState = dayState(day.key, low, high);\n return { ...day, state: day.key === preview ? ERtCalendarDayState.InRange : state };\n }),\n };\n}\n\n/** Диапазоны быстрых вариантов от сегодняшнего дня. */\nexport function rtRangePresets(today: string): Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> {\n const month: string = today.slice(0, MONTH_LEN);\n const lastMonth: string = rtDateAddMonths(month, -1);\n const yesterday: string = addDays(today, -1);\n return {\n [ERtDateRangePreset.Today]: { start: today, end: today },\n [ERtDateRangePreset.Yesterday]: { start: yesterday, end: yesterday },\n [ERtDateRangePreset.Last7]: { start: addDays(today, 1 - LAST_WEEK_DAYS), end: today },\n [ERtDateRangePreset.Last30]: { start: addDays(today, 1 - LAST_MONTH_DAYS), end: today },\n [ERtDateRangePreset.ThisMonth]: { start: `${month}-01`, end: today },\n [ERtDateRangePreset.LastMonth]: { start: `${lastMonth}-01`, end: lastDayOf(lastMonth) },\n };\n}\n\n/** Быстрые варианты в порядке панели; вариант, не лежащий в границах целиком, выключен. */\nexport function rtRangePresetCells(today: string, min: string | null, max: string | null): IRtDateRange.PresetCell[] {\n const ranges: Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> = rtRangePresets(today);\n return Object.values(ERtDateRangePreset).map((preset: ERtDateRangePreset): IRtDateRange.PresetCell => ({\n preset,\n range: ranges[preset],\n disabled: !rtRangeInBounds(ranges[preset], min, max),\n }));\n}\n\n/** Вариант, чей диапазон совпадает с черновиком; иначе `null`. */\nexport function rtRangePresetOf(range: IRtDateRange.Value | null, today: string): ERtDateRangePreset | null {\n if (range === null) {\n return null;\n }\n const ranges: Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> = rtRangePresets(today);\n const found: ERtDateRangePreset | undefined = Object.values(ERtDateRangePreset).find(\n (preset: ERtDateRangePreset): boolean => ranges[preset].start === range.start && ranges[preset].end === range.end\n );\n return found ?? null;\n}\n\n/** Число дней диапазона, оба края включены. */\nexport function rtRangeDays(range: IRtDateRange.Value): number {\n return Math.round((dayToMs(range.end) - dayToMs(range.start)) / DAY_LENGTH_MS) + 1;\n}\n\n/** Форма числа по правилам локали; `zero` и `two` идут подписью `other`. */\nexport function rtRangePlural(count: number, locale: string): IRtDateRange.Plural {\n const form: Intl.LDMLPluralRule = new Intl.PluralRules(locale).select(count);\n return form === 'one' || form === 'few' || form === 'many' ? form : 'other';\n}\n\n/** Даты итога по локали: `12–15 октября`; год пишется, когда края в разных годах. */\nexport function rtRangeDates(range: IRtDateRange.Value, locale: string): string {\n const sameYear: boolean = range.start.slice(0, YEAR_LEN) === range.end.slice(0, YEAR_LEN);\n const options: Intl.DateTimeFormatOptions = sameYear\n ? { day: 'numeric', month: 'long', timeZone: 'UTC' }\n : { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' };\n return new Intl.DateTimeFormat(locale, options).formatRange(dayToMs(range.start), dayToMs(range.end));\n}\n\n/** Текст поля: две даты в порядке локали через тире; пусто — пустой текст. */\nexport function rtRangeText(value: IRtDateRange.Value | null, layout: IRtDatePicker.TextLayout): string {\n return value === null ? '' : `${rtDateText(value.start, 'date', layout)}${DASH}${rtDateText(value.end, 'date', layout)}`;\n}\n\n/** Подсказка формы текста буквами кита: `дд.мм.гггг — дд.мм.гггг`. */\nexport function rtRangeShape(layout: IRtDatePicker.TextLayout, letters: IRtDatePicker.ShapeLetters): string {\n const day: string = rtDateShape('date', layout, letters);\n return `${day}${DASH}${day}`;\n}\n\n/**\n * Читает набранный текст в диапазон; `null` — текст не две даты. Даты читаются в порядке локали,\n * форма значения тоже; даты в обратном порядке ставятся по порядку.\n */\nexport function rtRangeParse(text: string, layout: IRtDatePicker.TextLayout): IRtDateRange.Value | null {\n const parts: string[] = text.trim().split(DASH_RE);\n if (parts.length !== 2) {\n return null;\n }\n const start: string | null = rtDateParse(parts[0].trim(), 'date', layout);\n const end: string | null = rtDateParse(parts[1].trim(), 'date', layout);\n return start === null || end === null ? null : rtRangeOrder(start, end);\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { rtKitLabel, RT_KIT_LABELS, RT_KIT_LOCALE, TRtKitLabelKey, TRtKitLabelMap, TRtKitLabelParams } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCalendarComponent } from '@rt-tools/ui-kit-v2/calendar';\nimport { IRtCalendar } from '@rt-tools/ui-kit-v2/calendar';\nimport { rtDateAddMonths, rtDateCanPage, rtDateFirstDay, rtDateGridKey, rtDateNow, rtDateWeekdays } from '@rt-tools/ui-kit-v2/date-picker';\nimport {\n rtRangeDates,\n rtRangeDays,\n rtRangeMonth,\n rtRangeOrder,\n rtRangePlural,\n rtRangePresetCells,\n rtRangePresetOf,\n} from '../rt-date-range.logic';\nimport { ERtDateRangePreset, IRtDateRange } from '../rt-date-range.model';\n\nconst BEM_BLOCK: string = 'rt-date-range-panel';\nconst MONTH_LEN: number = 7;\n\n/** Подпись каждого быстрого варианта в наборе кита. */\nconst PRESET_LABELS: Readonly<Record<ERtDateRangePreset, TRtKitLabelKey>> = {\n [ERtDateRangePreset.Today]: 'uiToday',\n [ERtDateRangePreset.Yesterday]: 'uiYesterday',\n [ERtDateRangePreset.Last7]: 'uiLast7Days',\n [ERtDateRangePreset.Last30]: 'uiLast30Days',\n [ERtDateRangePreset.ThisMonth]: 'uiThisMonth',\n [ERtDateRangePreset.LastMonth]: 'uiLastMonth',\n};\n\n/** Подпись числа дней для каждой формы множественного числа. */\nconst DAY_LABELS: Readonly<Record<IRtDateRange.Plural, TRtKitLabelKey>> = {\n one: 'uiDaysOne',\n few: 'uiDaysFew',\n many: 'uiDaysMany',\n other: 'uiDaysOther',\n};\n\n/** Быстрый вариант, готовый к показу: подпись и выбран ли он. */\ninterface IPresetView {\n cell: IRtDateRange.PresetCell;\n label: string;\n chosen: boolean;\n}\n\n/**\n * Панель rt-date-range: быстрые варианты, два месяца рядом (в шторке — один) и подвал с итогом,\n * «Сбросить» и «Применить».\n *\n * Панель не пишет в форму: готовый диапазон уходит событием `picked`, просьба закрыться — `closed`.\n * Черновик живёт, пока панель открыта; поле создаёт её заново на каждое открытие. Вся арифметика\n * диапазона — в `rt-date-range.logic`.\n */\n@Component({\n selector: 'rt-date-range-panel',\n templateUrl: './rt-date-range-panel.component.html',\n styleUrl: './rt-date-range-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // rt-tools\n BlockDirective,\n ElemDirective,\n\n // components\n RtButtonDirective,\n RtCalendarComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-date-range-panel--sheet]': 'sheet()',\n '(keydown.escape)': 'closed.emit()',\n },\n})\nexport class RtDateRangePanelComponent {\n /** Локаль кита: названия месяцев, дней недели, даты итога и форма числа дней идут по ней. */\n readonly #locale: Signal<string> = inject(RT_KIT_LOCALE);\n /** Минута открытия панели: от неё считается «сегодня», когда вход `now` не задан. */\n readonly #openedAt: Date = new Date();\n readonly #firstDay: Signal<number> = computed((): number => rtDateFirstDay(this.#locale()));\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n protected readonly weekdays: Signal<readonly string[]> = computed((): readonly string[] => rtDateWeekdays(this.#locale()));\n protected readonly today: Signal<string> = computed((): string => rtDateNow(this.now() ?? this.#openedAt, 1).day);\n\n protected readonly start: WritableSignal<string | null> = linkedSignal((): string | null => this.value()?.start ?? null);\n protected readonly end: WritableSignal<string | null> = linkedSignal((): string | null => this.value()?.end ?? null);\n /** День под указателем: пока выбрано только начало, до него рисуется будущий диапазон. */\n protected readonly hover: WritableSignal<string | null> = signal<string | null>(null);\n protected readonly activeKey: WritableSignal<string | null> = signal<string | null>(null);\n\n protected readonly shownMonth: WritableSignal<string> = linkedSignal((): string =>\n (this.value()?.start ?? this.today()).slice(0, MONTH_LEN)\n );\n\n /** Готовый черновик: оба края выбраны. */\n protected readonly draft: Signal<IRtDateRange.Value | null> = computed((): IRtDateRange.Value | null => {\n const start: string | null = this.start();\n const end: string | null = this.end();\n return start === null || end === null ? null : { start, end };\n });\n\n protected readonly months: Signal<IRtCalendar.Month[]> = computed((): IRtCalendar.Month[] => {\n const ctx: IRtDateRange.MonthContext = {\n locale: this.#locale(),\n today: this.today(),\n start: this.start(),\n end: this.end(),\n hover: this.hover(),\n min: this.min(),\n max: this.max(),\n };\n return this.#shown().map((month: string): IRtCalendar.Month => rtRangeMonth(month, ctx));\n });\n protected readonly canPrev: Signal<boolean> = computed((): boolean => rtDateCanPage(this.shownMonth(), -1, this.min(), this.max()));\n /** Вперёд листается, пока последний показанный месяц не упёрся в границу. */\n protected readonly canNext: Signal<boolean> = computed((): boolean => rtDateCanPage(this.#lastShown(), 1, this.min(), this.max()));\n\n protected readonly presets: Signal<IPresetView[]> = computed((): IPresetView[] => {\n const labels: TRtKitLabelMap = this.t();\n const chosen: ERtDateRangePreset | null = rtRangePresetOf(this.draft(), this.today());\n return rtRangePresetCells(this.today(), this.min(), this.max()).map((cell: IRtDateRange.PresetCell): IPresetView => ({\n cell,\n label: labels[PRESET_LABELS[cell.preset]],\n chosen: cell.preset === chosen,\n }));\n });\n\n /** Число дней черновика подписью кита по форме множественного числа локали. */\n protected readonly daysText: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey | '' => {\n const draft: IRtDateRange.Value | null = this.draft();\n return draft === null ? '' : DAY_LABELS[rtRangePlural(rtRangeDays(draft), this.#locale())];\n }),\n computed((): TRtKitLabelParams => {\n const draft: IRtDateRange.Value | null = this.draft();\n return { count: draft === null ? 0 : rtRangeDays(draft) };\n })\n );\n\n /** Итог подвала: даты и число дней, в шторке — только число; с одним началом — просьба о конце. */\n protected readonly summary: Signal<string> = computed((): string => {\n const draft: IRtDateRange.Value | null = this.draft();\n if (draft === null) {\n return this.start() === null ? this.t().uiPickStartDate : this.t().uiPickEndDate;\n }\n return this.sheet() ? this.daysText() : `${rtRangeDates(draft, this.#locale())} · ${this.daysText()}`;\n });\n\n /** Значение поля: с него начинается черновик. */\n public readonly value: InputSignal<IRtDateRange.Value | null> = input<IRtDateRange.Value | null>(null);\n public readonly min: InputSignal<string | null> = input<string | null>(null);\n public readonly max: InputSignal<string | null> = input<string | null>(null);\n /** Раскладка нижней шторки: один месяц, варианты строкой сверху, дни под палец. */\n public readonly sheet: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /**\n * Момент, от которого считаются «сегодня» и быстрые варианты. Поле его не задаёт — панель\n * читает часы сама; задаёт витрина, чтобы кадр не менялся день ото дня.\n */\n public readonly now: InputSignal<Date | null> = input<Date | null>(null);\n\n /** Готовый диапазон: панель просит поле его записать. */\n public readonly picked: OutputEmitterRef<IRtDateRange.Value> = output<IRtDateRange.Value>();\n /** Панель просит закрыть себя. */\n public readonly closed: OutputEmitterRef<void> = output<void>();\n\n /** Первый выбор — начало, второй — конец; выбор после готового диапазона начинает новый. */\n protected pickDay(day: IRtCalendar.Day): void {\n this.activeKey.set(day.key);\n const start: string | null = this.start();\n if (start === null || this.end() !== null) {\n this.start.set(day.key);\n this.end.set(null);\n return;\n }\n const range: IRtDateRange.Value = rtRangeOrder(start, day.key);\n this.start.set(range.start);\n this.end.set(range.end);\n this.hover.set(null);\n }\n\n protected onHover(day: IRtCalendar.Day | null): void {\n this.hover.set(day?.key ?? null);\n }\n\n protected pickPreset(cell: IRtDateRange.PresetCell): void {\n if (cell.disabled) {\n return;\n }\n this.start.set(cell.range.start);\n this.end.set(cell.range.end);\n this.hover.set(null);\n this.shownMonth.set(cell.range.start.slice(0, MONTH_LEN));\n }\n\n /** Клавиша сетки: фокус переходит на день, и месяцы листаются, если он ушёл за показанные. */\n protected onGridKey(event: IRtCalendar.GridKey): void {\n const next: string | null = rtDateGridKey(event.key, event.day.key, this.#firstDay(), this.min(), this.max());\n if (next === null) {\n return;\n }\n const month: string = next.slice(0, MONTH_LEN);\n if (!this.#shown().includes(month)) {\n const before: boolean = Number(month.replace('-', '')) < Number(this.shownMonth().replace('-', ''));\n this.shownMonth.set(before ? month : rtDateAddMonths(month, 1 - this.#shown().length));\n }\n this.activeKey.set(next);\n this.hover.set(next);\n }\n\n protected page(delta: number): void {\n this.shownMonth.set(rtDateAddMonths(this.shownMonth(), delta));\n }\n\n protected reset(): void {\n this.start.set(null);\n this.end.set(null);\n this.hover.set(null);\n }\n\n /** «Применить»: готовый черновик уходит значением, панель закрывается. */\n protected apply(): void {\n const draft: IRtDateRange.Value | null = this.draft();\n if (draft !== null) {\n this.picked.emit(draft);\n this.closed.emit();\n }\n }\n\n /** Показанные месяцы `YYYY-MM`: два рядом, в шторке — один. */\n #shown(): string[] {\n const first: string = this.shownMonth();\n return this.sheet() ? [first] : [first, rtDateAddMonths(first, 1)];\n }\n\n #lastShown(): string {\n const shown: string[] = this.#shown();\n return shown[shown.length - 1];\n }\n}\n","<ng-container rtBlock=\"rt-date-range-panel\">\n @if (sheet()) {\n <p rtElem=\"title\" qa-dataid=\"date-range-title\">{{ t().uiPeriod }}</p>\n }\n\n <div rtElem=\"body\">\n <div rtElem=\"presets\" qa-dataid=\"date-range-presets\" role=\"group\" [attr.aria-label]=\"t().uiQuickRanges\">\n @for (item of presets(); track item.cell.preset) {\n <button\n rtButton\n rtElem=\"preset\"\n qa-dataid=\"date-range-preset\"\n type=\"button\"\n size=\"sm\"\n [theme]=\"item.chosen ? 'primary' : 'secondary'\"\n [appearance]=\"sheet() ? 'outlined' : 'text'\"\n [attr.data-preset]=\"item.cell.preset\"\n [label]=\"item.label\"\n [attr.aria-label]=\"item.label\"\n [pressed]=\"item.chosen\"\n [disabled]=\"item.cell.disabled\"\n (click)=\"pickPreset(item.cell)\"></button>\n }\n </div>\n\n <rt-calendar\n rtElem=\"calendar\"\n qa-dataid=\"date-range-calendar\"\n grid\n [months]=\"months()\"\n [weekdayLabels]=\"weekdays()\"\n [canPrev]=\"canPrev()\"\n [canNext]=\"canNext()\"\n [activeKey]=\"activeKey()\"\n [prevAriaLabel]=\"t().uiPrevMonth\"\n [nextAriaLabel]=\"t().uiNextMonth\"\n (prevMonth)=\"page(-1)\"\n (nextMonth)=\"page(1)\"\n (dayClick)=\"pickDay($event)\"\n (dayHover)=\"onHover($event)\"\n (gridKey)=\"onGridKey($event)\" />\n </div>\n\n <div rtElem=\"footer\">\n <span rtElem=\"summary\" qa-dataid=\"date-range-summary\" aria-live=\"polite\">{{ summary() }}</span>\n <button\n rtButton\n qa-dataid=\"date-range-reset\"\n theme=\"primary\"\n appearance=\"text\"\n size=\"sm\"\n type=\"button\"\n [label]=\"t().uiReset\"\n [attr.aria-label]=\"t().uiReset\"\n (click)=\"reset()\"></button>\n <button\n rtButton\n qa-dataid=\"date-range-apply\"\n size=\"sm\"\n type=\"button\"\n [label]=\"t().uiApply\"\n [attr.aria-label]=\"t().uiApply\"\n [disabled]=\"draft() === null\"\n (click)=\"apply()\"></button>\n </div>\n</ng-container>\n","import {\n computed,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_LOCALE, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { BreakpointsService } from '@rt-tools/ui-kit-v2/core';\nimport { RtBottomSheetComponent } from '@rt-tools/ui-kit-v2/bottom-sheet';\nimport { IRtDatePicker } from '@rt-tools/ui-kit-v2/date-picker';\nimport { rtDateLayout } from '@rt-tools/ui-kit-v2/date-picker';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { IRtInput } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtDateRangePanelComponent } from './panel/rt-date-range-panel.component';\nimport { rtRangeInBounds, rtRangeParse, rtRangeRead, rtRangeShape, rtRangeText } from './rt-date-range.logic';\nimport { IRtDateRange } from './rt-date-range.model';\n\nconst BEM_BLOCK: string = 'rt-date-range';\n\n/**\n * Поле диапазона дат со своей панелью кита, визуально и по токенам идентичное rt-input (host — box\n * `--rt-input-*`, input — прозрачный `__field`). Кнопка в конце поля открывает\n * `rt-date-range-panel`: на широком экране в поповере, на узком — в нижней шторке. CVA через общий\n * `RtFormControlBase`: clearable, авто-подсветка invalid, read-only представление.\n *\n * `value` — пара дней `{ start, end }` в форме `YYYY-MM-DD` или `null`. Текст в поле — две даты в\n * порядке языка интерфейса через тире (`12.10.2026 — 15.10.2026` под `ru`); набирается так же.\n * Нечитаемый или лежащий за границами текст оставляет значение прежним и помечает поле ошибкой.\n */\n@Component({\n selector: 'rt-date-range',\n templateUrl: './rt-date-range.component.html',\n styleUrls: ['./rt-date-range.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtBottomSheetComponent,\n RtDateRangePanelComponent,\n RtIconButtonComponent,\n RtPopoverDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtDateRangeComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-date-range--disabled]': 'isDisabled()',\n '[class.rt-date-range--invalid]': 'isInvalid() || textInvalid()',\n '[class.rt-date-range--readonly]': 'isReadonly()',\n '[class.rt-date-range--borderless]': '!bordered()',\n '[class.rt-date-range--appearance--fill]': \"appearance() === 'fill'\",\n '[class.rt-date-range--size--sm]': \"size() === 'sm'\",\n '[class.rt-date-range--size--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtDateRangeComponent extends RtFormControlBase<IRtDateRange.Value | null> {\n /** Локаль кита: приложение, меняющее язык на ходу, меняет её, и текст поля пересчитывается. */\n readonly #locale: Signal<string> = inject(RT_KIT_LOCALE);\n /** Порядок дня, месяца и года в тексте поля — по локали кита. */\n readonly #layout: Signal<IRtDatePicker.TextLayout> = computed((): IRtDatePicker.TextLayout => rtDateLayout(this.#locale()));\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n /** Узкий экран: панель открывается в нижней шторке, а не в поповере. */\n protected readonly narrow: Signal<boolean> = inject(BreakpointsService).viewportNarrow;\n\n protected readonly fieldEl: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fieldEl');\n protected readonly popover: Signal<RtPopoverDirective | undefined> = viewChild(RtPopoverDirective);\n\n /** Набранный текст не читается как диапазон в границах: поле помечено ошибкой. */\n protected readonly textInvalid: WritableSignal<boolean> = signal(false);\n protected readonly sheetOpen: WritableSignal<boolean> = signal(false);\n /** Подсказка формы текста буквами кита: `дд.мм.гггг — дд.мм.гггг` под русскими метками. */\n protected readonly shape: Signal<string> = computed((): string => {\n const labels: TRtKitLabelMap = this.t();\n return rtRangeShape(this.#layout(), {\n day: labels.uiShapeDay,\n month: labels.uiShapeMonth,\n year: labels.uiShapeYear,\n hour: labels.uiShapeHour,\n minute: labels.uiShapeMinute,\n });\n });\n /** Значение, прочитанное из формы: не пара дней по порядку поле показывает пустой. */\n protected readonly range: Signal<IRtDateRange.Value | null> = computed((): IRtDateRange.Value | null => rtRangeRead(this.value()));\n protected readonly text: Signal<string> = computed((): string => rtRangeText(this.range(), this.#layout()));\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.range() !== null);\n /** Ширина поля в знаках — по длине формы значения, как у поля даты. */\n protected readonly fieldSize: Signal<number> = computed((): number => this.shape().length);\n /** Подсказка обрезается многоточием в узком поле, поэтому шаблон целиком виден при наведении. */\n protected readonly shapeTitle: Signal<string | null> = computed((): string | null => (this.hasValue() ? null : this.shape()));\n\n /** Вид рамки: `outline` — рамка со всех сторон, `fill` — залитое поле с чертой снизу. */\n public readonly appearance: InputSignal<IRtInput.Appearance> = input<IRtInput.Appearance>('outline');\n\n public readonly displayText: Signal<string> = computed((): string => this.#format(this.range()));\n\n /** Первый допустимый день `YYYY-MM-DD`. */\n public readonly min: InputSignal<string | null> = input<string | null>(null);\n /** Последний допустимый день `YYYY-MM-DD`. */\n public readonly max: InputSignal<string | null> = input<string | null>(null);\n\n /** Значение из формы снимает ошибку набора: в поле теперь стоит оно. */\n public override writeValue(value: IRtDateRange.Value | null): void {\n super.writeValue(value);\n this.textInvalid.set(false);\n }\n\n protected getEmptyValue(): IRtDateRange.Value | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.fieldEl()?.nativeElement.focus();\n }\n\n protected override clearValue(): void {\n super.clearValue();\n this.#accept(null);\n }\n\n /** Набор текста: значение меняется, только когда текст читается как диапазон в границах. */\n protected onTyped(event: Event): void {\n const text: string = (event.target as HTMLInputElement).value;\n if (text.trim() === '') {\n this.#commit(null);\n return;\n }\n const read: IRtDateRange.Value | null = rtRangeParse(text, this.#layout());\n if (read === null || !rtRangeInBounds(read, this.min(), this.max())) {\n this.textInvalid.set(true);\n return;\n }\n this.#commit(read);\n }\n\n /** Кнопка в конце поля: на узком экране открывает шторку, на широком поповер открывает сам. */\n protected openPanel(): void {\n if (this.narrow() && !this.isDisabled()) {\n this.sheetOpen.set(true);\n }\n }\n\n protected closePanel(): void {\n this.sheetOpen.set(false);\n this.popover()?.close();\n }\n\n protected onPicked(value: IRtDateRange.Value): void {\n this.#commit(value);\n this.markTouched();\n }\n\n protected onBlur(): void {\n this.markTouched();\n }\n\n #commit(value: IRtDateRange.Value | null): void {\n this.value.set(value);\n this.emitChange(value);\n this.#accept(value);\n }\n\n /** Текст в поле — принятое значение, ошибки набора нет. */\n #accept(value: IRtDateRange.Value | null): void {\n this.textInvalid.set(false);\n const node: HTMLInputElement | undefined = this.fieldEl()?.nativeElement;\n if (node !== undefined) {\n node.value = rtRangeText(value, this.#layout());\n }\n }\n\n /** Плоский текст для режима чтения: диапазон по локали, `15 – 20 мар. 2026 г.` под `ru`. */\n #format(range: IRtDateRange.Value | null): string {\n if (range === null) {\n return '';\n }\n return new Intl.DateTimeFormat(this.#locale(), { dateStyle: 'medium', timeZone: 'UTC' }).formatRange(\n Date.parse(range.start),\n Date.parse(range.end)\n );\n }\n}\n","<ng-container rtBlock=\"rt-date-range\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"date-range-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fieldEl\n rtElem=\"field\"\n qa-dataid=\"date-range-control\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [value]=\"text()\"\n [disabled]=\"isDisabled()\"\n [attr.placeholder]=\"shape()\"\n [attr.title]=\"shapeTitle()\"\n [attr.size]=\"fieldSize()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-invalid]=\"isInvalid() || textInvalid() || null\"\n (input)=\"onTyped($event)\"\n (blur)=\"onBlur()\" />\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n qa-dataid=\"date-range-clear\"\n icon=\"ico-close\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n [ariaLabel]=\"t().uiClear\"\n [tabIndex]=\"-1\"\n (clicked)=\"clear($event)\" />\n }\n <rt-icon-button\n rtElem=\"open\"\n qa-dataid=\"date-range-open\"\n icon=\"ico-calendar\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiOpenCalendar\"\n [disabled]=\"isDisabled()\"\n [rtPopover]=\"panelTpl\"\n [rtPopoverDisabled]=\"narrow() || isDisabled()\"\n (clicked)=\"openPanel()\" />\n\n <ng-template #panelTpl>\n <div rtElem=\"popup\" qa-dataid=\"date-range-popup\">\n <rt-date-range-panel [value]=\"range()\" [min]=\"min()\" [max]=\"max()\" (picked)=\"onPicked($event)\" (closed)=\"closePanel()\" />\n </div>\n </ng-template>\n\n @if (narrow()) {\n <rt-bottom-sheet qa-dataid=\"date-range-sheet\" [open]=\"sheetOpen()\" (openChange)=\"sheetOpen.set($event)\">\n @if (sheetOpen()) {\n <rt-date-range-panel\n sheet\n [value]=\"range()\"\n [min]=\"min()\"\n [max]=\"max()\"\n (picked)=\"onPicked($event)\"\n (closed)=\"closePanel()\" />\n }\n </rt-bottom-sheet>\n }\n }\n</ng-container>\n"],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-date-range.mjs","names":["MONTH_LEN","BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.model.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.logic.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/panel/rt-date-range-panel.component.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/panel/rt-date-range-panel.component.html","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.component.ts","../../../projects/ui-kit-v2/src/lib/components/date-range/rt-date-range.component.html"],"sourcesContent":["/** Быстрый вариант диапазона в панели поля. */\nexport enum ERtDateRangePreset {\n Today = 'today',\n Yesterday = 'yesterday',\n Last7 = 'last-7',\n Last30 = 'last-30',\n ThisMonth = 'this-month',\n LastMonth = 'last-month',\n}\n\n/** Контракт rt-date-range. */\nexport namespace IRtDateRange {\n /** Значение поля: первый и последний день периода `YYYY-MM-DD`, оба включены, `start <= end`. */\n export interface Value {\n start: string;\n end: string;\n }\n\n /** Быстрый вариант в панели: его диапазон и выключен ли он границами. */\n export interface PresetCell {\n preset: ERtDateRangePreset;\n range: Value;\n disabled: boolean;\n }\n\n /** Что месяц панели знает о черновике, наведении и границах. */\n export interface MonthContext {\n locale: string;\n today: string;\n start: string | null;\n end: string | null;\n /** День под указателем, пока выбрано только начало: до него рисуется будущий диапазон. */\n hover: string | null;\n min: string | null;\n max: string | null;\n }\n\n /** Форма числа дней по правилам множественного числа локали. */\n export type Plural = 'one' | 'few' | 'many' | 'other';\n}\n","import { ERtCalendarDayState, IRtCalendar } from '@rt-tools/ui-kit-v2/calendar';\nimport { rtDateAddMonths, rtDateInBounds, rtDateMonth, rtDateRead } from '@rt-tools/ui-kit-v2/date-picker';\nimport { IRtDatePicker } from '@rt-tools/ui-kit-v2/date-picker';\nimport { rtDateParse, rtDateShape, rtDateText } from '@rt-tools/ui-kit-v2/date-picker';\nimport { ERtDateRangePreset, IRtDateRange } from './rt-date-range.model';\n\n/**\n * Чистая логика поля диапазона дат: порядок двух дней, состояния дней месяца, быстрые варианты,\n * итог и текст поля. Сегодняшний день приходит параметром — компонент читает часы сам.\n *\n * Дни — строки `YYYY-MM-DD`: строки одной формы сравниваются как текст в порядке дат.\n */\n\nconst DAY_LENGTH_MS: number = 86_400_000;\nconst DAY_LEN: number = 10;\nconst MONTH_LEN: number = 7;\nconst YEAR_LEN: number = 4;\nconst LAST_WEEK_DAYS: number = 7;\nconst LAST_MONTH_DAYS: number = 30;\n/** Знак между датами в тексте поля. */\nconst DASH: string = ' — ';\n/** Тире между датами набранного текста: длинное или короткое, дефис — только между пробелами. */\nconst DASH_RE: RegExp = /[—–]|\\s-\\s/;\n\nfunction dayToMs(day: string): number {\n const [y, m, d]: number[] = day.split('-').map(Number);\n return Date.UTC(y, m - 1, d);\n}\n\nfunction msToDay(ms: number): string {\n return new Date(ms).toISOString().slice(0, DAY_LEN);\n}\n\nfunction addDays(day: string, delta: number): string {\n return msToDay(dayToMs(day) + delta * DAY_LENGTH_MS);\n}\n\nfunction lastDayOf(month: string): string {\n return addDays(`${rtDateAddMonths(month, 1)}-01`, -1);\n}\n\nfunction dayState(day: string, low: string | null, high: string | null): ERtCalendarDayState {\n if (high === null || low === high) {\n return day === low ? ERtCalendarDayState.Chosen : ERtCalendarDayState.Free;\n }\n if (day === low) {\n return ERtCalendarDayState.Start;\n }\n if (day === high) {\n return ERtCalendarDayState.End;\n }\n const ms: number = dayToMs(day);\n return low !== null && ms > dayToMs(low) && ms < dayToMs(high) ? ERtCalendarDayState.InRange : ERtCalendarDayState.Free;\n}\n\n/** Два дня по порядку: второй раньше первого — они меняются местами. */\nexport function rtRangeOrder(a: string, b: string): IRtDateRange.Value {\n return dayToMs(a) <= dayToMs(b) ? { start: a, end: b } : { start: b, end: a };\n}\n\n/** Значение поля из того, что пришло из формы; не пара дней по порядку — `null`. */\nexport function rtRangeRead(value: unknown): IRtDateRange.Value | null {\n if (typeof value !== 'object' || value === null) {\n return null;\n }\n const start: unknown = Reflect.get(value, 'start');\n const end: unknown = Reflect.get(value, 'end');\n if (typeof start !== 'string' || typeof end !== 'string') {\n return null;\n }\n const ok: boolean = rtDateRead(start, 'date') !== null && rtDateRead(end, 'date') !== null && dayToMs(start) <= dayToMs(end);\n return ok ? { start, end } : null;\n}\n\n/** Диапазон лежит в границах целиком. */\nexport function rtRangeInBounds(range: IRtDateRange.Value, min: string | null, max: string | null): boolean {\n return rtDateInBounds(range.start, min, max) && rtDateInBounds(range.end, min, max);\n}\n\n/**\n * Месяц `YYYY-MM` для календаря: дни черновика — начало, конец и дни между ними. Пока выбрано только\n * начало, будущий диапазон тянется до дня под указателем, и этот день светлый, как дни между краями:\n * залит только выбранный край.\n */\nexport function rtRangeMonth(month: string, ctx: IRtDateRange.MonthContext): IRtCalendar.Month {\n const base: IRtCalendar.Month = rtDateMonth(month, { locale: ctx.locale, today: ctx.today, chosen: null, min: ctx.min, max: ctx.max });\n const other: string | null = ctx.end ?? ctx.hover;\n const range: IRtDateRange.Value | null = ctx.start === null || other === null ? null : rtRangeOrder(ctx.start, other);\n const low: string | null = range?.start ?? ctx.start;\n const high: string | null = range?.end ?? null;\n const preview: string | null = ctx.end === null && ctx.hover !== ctx.start ? ctx.hover : null;\n return {\n ...base,\n days: base.days.map((day: IRtCalendar.Day): IRtCalendar.Day => {\n const state: ERtCalendarDayState = dayState(day.key, low, high);\n return { ...day, state: day.key === preview ? ERtCalendarDayState.InRange : state };\n }),\n };\n}\n\n/** Диапазоны быстрых вариантов от сегодняшнего дня. */\nexport function rtRangePresets(today: string): Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> {\n const month: string = today.slice(0, MONTH_LEN);\n const lastMonth: string = rtDateAddMonths(month, -1);\n const yesterday: string = addDays(today, -1);\n return {\n [ERtDateRangePreset.Today]: { start: today, end: today },\n [ERtDateRangePreset.Yesterday]: { start: yesterday, end: yesterday },\n [ERtDateRangePreset.Last7]: { start: addDays(today, 1 - LAST_WEEK_DAYS), end: today },\n [ERtDateRangePreset.Last30]: { start: addDays(today, 1 - LAST_MONTH_DAYS), end: today },\n [ERtDateRangePreset.ThisMonth]: { start: `${month}-01`, end: today },\n [ERtDateRangePreset.LastMonth]: { start: `${lastMonth}-01`, end: lastDayOf(lastMonth) },\n };\n}\n\n/** Быстрые варианты в порядке панели; вариант, не лежащий в границах целиком, выключен. */\nexport function rtRangePresetCells(today: string, min: string | null, max: string | null): IRtDateRange.PresetCell[] {\n const ranges: Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> = rtRangePresets(today);\n return Object.values(ERtDateRangePreset).map((preset: ERtDateRangePreset): IRtDateRange.PresetCell => ({\n preset,\n range: ranges[preset],\n disabled: !rtRangeInBounds(ranges[preset], min, max),\n }));\n}\n\n/** Вариант, чей диапазон совпадает с черновиком; иначе `null`. */\nexport function rtRangePresetOf(range: IRtDateRange.Value | null, today: string): ERtDateRangePreset | null {\n if (range === null) {\n return null;\n }\n const ranges: Readonly<Record<ERtDateRangePreset, IRtDateRange.Value>> = rtRangePresets(today);\n const found: ERtDateRangePreset | undefined = Object.values(ERtDateRangePreset).find(\n (preset: ERtDateRangePreset): boolean => ranges[preset].start === range.start && ranges[preset].end === range.end\n );\n return found ?? null;\n}\n\n/** Число дней диапазона, оба края включены. */\nexport function rtRangeDays(range: IRtDateRange.Value): number {\n return Math.round((dayToMs(range.end) - dayToMs(range.start)) / DAY_LENGTH_MS) + 1;\n}\n\n/** Форма числа по правилам локали; `zero` и `two` идут подписью `other`. */\nexport function rtRangePlural(count: number, locale: string): IRtDateRange.Plural {\n const form: Intl.LDMLPluralRule = new Intl.PluralRules(locale).select(count);\n return form === 'one' || form === 'few' || form === 'many' ? form : 'other';\n}\n\n/** Даты итога по локали: `12–15 октября`; год пишется, когда края в разных годах. */\nexport function rtRangeDates(range: IRtDateRange.Value, locale: string): string {\n const sameYear: boolean = range.start.slice(0, YEAR_LEN) === range.end.slice(0, YEAR_LEN);\n const options: Intl.DateTimeFormatOptions = sameYear\n ? { day: 'numeric', month: 'long', timeZone: 'UTC' }\n : { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' };\n return new Intl.DateTimeFormat(locale, options).formatRange(dayToMs(range.start), dayToMs(range.end));\n}\n\n/** Текст поля: две даты в порядке локали через тире; пусто — пустой текст. */\nexport function rtRangeText(value: IRtDateRange.Value | null, layout: IRtDatePicker.TextLayout): string {\n return value === null ? '' : `${rtDateText(value.start, 'date', layout)}${DASH}${rtDateText(value.end, 'date', layout)}`;\n}\n\n/** Подсказка формы текста буквами кита: `дд.мм.гггг — дд.мм.гггг`. */\nexport function rtRangeShape(layout: IRtDatePicker.TextLayout, letters: IRtDatePicker.ShapeLetters): string {\n const day: string = rtDateShape('date', layout, letters);\n return `${day}${DASH}${day}`;\n}\n\n/**\n * Читает набранный текст в диапазон; `null` — текст не две даты. Даты читаются в порядке локали,\n * форма значения тоже; даты в обратном порядке ставятся по порядку.\n */\nexport function rtRangeParse(text: string, layout: IRtDatePicker.TextLayout): IRtDateRange.Value | null {\n const parts: string[] = text.trim().split(DASH_RE);\n if (parts.length !== 2) {\n return null;\n }\n const start: string | null = rtDateParse(parts[0].trim(), 'date', layout);\n const end: string | null = rtDateParse(parts[1].trim(), 'date', layout);\n return start === null || end === null ? null : rtRangeOrder(start, end);\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { rtKitLabel, RT_KIT_LABELS, RT_KIT_LOCALE, TRtKitLabelKey, TRtKitLabelMap, TRtKitLabelParams } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCalendarComponent } from '@rt-tools/ui-kit-v2/calendar';\nimport { IRtCalendar } from '@rt-tools/ui-kit-v2/calendar';\nimport { rtDateAddMonths, rtDateCanPage, rtDateFirstDay, rtDateGridKey, rtDateNow, rtDateWeekdays } from '@rt-tools/ui-kit-v2/date-picker';\nimport {\n rtRangeDates,\n rtRangeDays,\n rtRangeMonth,\n rtRangeOrder,\n rtRangePlural,\n rtRangePresetCells,\n rtRangePresetOf,\n} from '../rt-date-range.logic';\nimport { ERtDateRangePreset, IRtDateRange } from '../rt-date-range.model';\n\nconst BEM_BLOCK: string = 'rt-date-range-panel';\nconst MONTH_LEN: number = 7;\n\n/** Подпись каждого быстрого варианта в наборе кита. */\nconst PRESET_LABELS: Readonly<Record<ERtDateRangePreset, TRtKitLabelKey>> = {\n [ERtDateRangePreset.Today]: 'uiToday',\n [ERtDateRangePreset.Yesterday]: 'uiYesterday',\n [ERtDateRangePreset.Last7]: 'uiLast7Days',\n [ERtDateRangePreset.Last30]: 'uiLast30Days',\n [ERtDateRangePreset.ThisMonth]: 'uiThisMonth',\n [ERtDateRangePreset.LastMonth]: 'uiLastMonth',\n};\n\n/** Подпись числа дней для каждой формы множественного числа. */\nconst DAY_LABELS: Readonly<Record<IRtDateRange.Plural, TRtKitLabelKey>> = {\n one: 'uiDaysOne',\n few: 'uiDaysFew',\n many: 'uiDaysMany',\n other: 'uiDaysOther',\n};\n\n/** Быстрый вариант, готовый к показу: подпись и выбран ли он. */\ninterface IPresetView {\n cell: IRtDateRange.PresetCell;\n label: string;\n chosen: boolean;\n}\n\n/**\n * Панель rt-date-range: быстрые варианты, два месяца рядом (в шторке — один) и подвал с итогом,\n * «Сбросить» и «Применить».\n *\n * Панель не пишет в форму: готовый диапазон уходит событием `picked`, просьба закрыться — `closed`.\n * Черновик живёт, пока панель открыта; поле создаёт её заново на каждое открытие. Вся арифметика\n * диапазона — в `rt-date-range.logic`.\n */\n@Component({\n selector: 'rt-date-range-panel',\n templateUrl: './rt-date-range-panel.component.html',\n styleUrl: './rt-date-range-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // rt-tools\n BlockDirective,\n ElemDirective,\n\n // components\n RtButtonDirective,\n RtCalendarComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-date-range-panel--sheet]': 'sheet()',\n '(keydown.escape)': 'closed.emit()',\n },\n})\nexport class RtDateRangePanelComponent {\n /** Локаль кита: названия месяцев, дней недели, даты итога и форма числа дней идут по ней. */\n readonly #locale: Signal<string> = inject(RT_KIT_LOCALE);\n /** Минута открытия панели: от неё считается «сегодня», когда вход `now` не задан. */\n readonly #openedAt: Date = new Date();\n readonly #firstDay: Signal<number> = computed((): number => rtDateFirstDay(this.#locale()));\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n protected readonly weekdays: Signal<readonly string[]> = computed((): readonly string[] => rtDateWeekdays(this.#locale()));\n protected readonly today: Signal<string> = computed((): string => rtDateNow(this.now() ?? this.#openedAt, 1).day);\n\n protected readonly start: WritableSignal<string | null> = linkedSignal((): string | null => this.value()?.start ?? null);\n protected readonly end: WritableSignal<string | null> = linkedSignal((): string | null => this.value()?.end ?? null);\n /** День под указателем: пока выбрано только начало, до него рисуется будущий диапазон. */\n protected readonly hover: WritableSignal<string | null> = signal<string | null>(null);\n protected readonly activeKey: WritableSignal<string | null> = signal<string | null>(null);\n\n protected readonly shownMonth: WritableSignal<string> = linkedSignal((): string =>\n (this.value()?.start ?? this.today()).slice(0, MONTH_LEN)\n );\n\n /** Готовый черновик: оба края выбраны. */\n protected readonly draft: Signal<IRtDateRange.Value | null> = computed((): IRtDateRange.Value | null => {\n const start: string | null = this.start();\n const end: string | null = this.end();\n return start === null || end === null ? null : { start, end };\n });\n\n protected readonly months: Signal<IRtCalendar.Month[]> = computed((): IRtCalendar.Month[] => {\n const ctx: IRtDateRange.MonthContext = {\n locale: this.#locale(),\n today: this.today(),\n start: this.start(),\n end: this.end(),\n hover: this.hover(),\n min: this.min(),\n max: this.max(),\n };\n return this.#shown().map((month: string): IRtCalendar.Month => rtRangeMonth(month, ctx));\n });\n protected readonly canPrev: Signal<boolean> = computed((): boolean => rtDateCanPage(this.shownMonth(), -1, this.min(), this.max()));\n /** Вперёд листается, пока последний показанный месяц не упёрся в границу. */\n protected readonly canNext: Signal<boolean> = computed((): boolean => rtDateCanPage(this.#lastShown(), 1, this.min(), this.max()));\n\n protected readonly presets: Signal<IPresetView[]> = computed((): IPresetView[] => {\n const labels: TRtKitLabelMap = this.t();\n const chosen: ERtDateRangePreset | null = rtRangePresetOf(this.draft(), this.today());\n return rtRangePresetCells(this.today(), this.min(), this.max()).map((cell: IRtDateRange.PresetCell): IPresetView => ({\n cell,\n label: labels[PRESET_LABELS[cell.preset]],\n chosen: cell.preset === chosen,\n }));\n });\n\n /** Число дней черновика подписью кита по форме множественного числа локали. */\n protected readonly daysText: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey | '' => {\n const draft: IRtDateRange.Value | null = this.draft();\n return draft === null ? '' : DAY_LABELS[rtRangePlural(rtRangeDays(draft), this.#locale())];\n }),\n computed((): TRtKitLabelParams => {\n const draft: IRtDateRange.Value | null = this.draft();\n return { count: draft === null ? 0 : rtRangeDays(draft) };\n })\n );\n\n /** Итог подвала: даты и число дней, в шторке — только число; с одним началом — просьба о конце. */\n protected readonly summary: Signal<string> = computed((): string => {\n const draft: IRtDateRange.Value | null = this.draft();\n if (draft === null) {\n return this.start() === null ? this.t().uiPickStartDate : this.t().uiPickEndDate;\n }\n return this.sheet() ? this.daysText() : `${rtRangeDates(draft, this.#locale())} · ${this.daysText()}`;\n });\n\n /** Значение поля: с него начинается черновик. */\n public readonly value: InputSignal<IRtDateRange.Value | null> = input<IRtDateRange.Value | null>(null);\n public readonly min: InputSignal<string | null> = input<string | null>(null);\n public readonly max: InputSignal<string | null> = input<string | null>(null);\n /** Раскладка нижней шторки: один месяц, варианты строкой сверху, дни под палец. */\n public readonly sheet: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /**\n * Момент, от которого считаются «сегодня» и быстрые варианты. Поле его не задаёт — панель\n * читает часы сама; задаёт витрина, чтобы кадр не менялся день ото дня.\n */\n public readonly now: InputSignal<Date | null> = input<Date | null>(null);\n\n /** Готовый диапазон: панель просит поле его записать. */\n public readonly picked: OutputEmitterRef<IRtDateRange.Value> = output<IRtDateRange.Value>();\n /** Панель просит закрыть себя. */\n public readonly closed: OutputEmitterRef<void> = output<void>();\n\n /** Первый выбор — начало, второй — конец; выбор после готового диапазона начинает новый. */\n protected pickDay(day: IRtCalendar.Day): void {\n this.activeKey.set(day.key);\n const start: string | null = this.start();\n if (start === null || this.end() !== null) {\n this.start.set(day.key);\n this.end.set(null);\n return;\n }\n const range: IRtDateRange.Value = rtRangeOrder(start, day.key);\n this.start.set(range.start);\n this.end.set(range.end);\n this.hover.set(null);\n }\n\n protected onHover(day: IRtCalendar.Day | null): void {\n this.hover.set(day?.key ?? null);\n }\n\n protected pickPreset(cell: IRtDateRange.PresetCell): void {\n if (cell.disabled) {\n return;\n }\n this.start.set(cell.range.start);\n this.end.set(cell.range.end);\n this.hover.set(null);\n this.shownMonth.set(cell.range.start.slice(0, MONTH_LEN));\n }\n\n /** Клавиша сетки: фокус переходит на день, и месяцы листаются, если он ушёл за показанные. */\n protected onGridKey(event: IRtCalendar.GridKey): void {\n const next: string | null = rtDateGridKey(event.key, event.day.key, this.#firstDay(), this.min(), this.max());\n if (next === null) {\n return;\n }\n const month: string = next.slice(0, MONTH_LEN);\n if (!this.#shown().includes(month)) {\n const before: boolean = Number(month.replace('-', '')) < Number(this.shownMonth().replace('-', ''));\n this.shownMonth.set(before ? month : rtDateAddMonths(month, 1 - this.#shown().length));\n }\n this.activeKey.set(next);\n this.hover.set(next);\n }\n\n protected page(delta: number): void {\n this.shownMonth.set(rtDateAddMonths(this.shownMonth(), delta));\n }\n\n protected reset(): void {\n this.start.set(null);\n this.end.set(null);\n this.hover.set(null);\n }\n\n /** «Применить»: готовый черновик уходит значением, панель закрывается. */\n protected apply(): void {\n const draft: IRtDateRange.Value | null = this.draft();\n if (draft !== null) {\n this.picked.emit(draft);\n this.closed.emit();\n }\n }\n\n /** Показанные месяцы `YYYY-MM`: два рядом, в шторке — один. */\n #shown(): string[] {\n const first: string = this.shownMonth();\n return this.sheet() ? [first] : [first, rtDateAddMonths(first, 1)];\n }\n\n #lastShown(): string {\n const shown: string[] = this.#shown();\n return shown[shown.length - 1];\n }\n}\n","<ng-container rtBlock=\"rt-date-range-panel\">\n @if (sheet()) {\n <p rtElem=\"title\" qa-dataid=\"date-range-title\">{{ t().uiPeriod }}</p>\n }\n\n <div rtElem=\"body\">\n <div rtElem=\"presets\" qa-dataid=\"date-range-presets\" role=\"group\" [attr.aria-label]=\"t().uiQuickRanges\">\n @for (item of presets(); track item.cell.preset) {\n <button\n rtButton\n rtElem=\"preset\"\n qa-dataid=\"date-range-preset\"\n type=\"button\"\n size=\"sm\"\n [theme]=\"item.chosen ? 'primary' : 'secondary'\"\n [appearance]=\"sheet() ? 'outlined' : 'text'\"\n [attr.data-preset]=\"item.cell.preset\"\n [label]=\"item.label\"\n [attr.aria-label]=\"item.label\"\n [pressed]=\"item.chosen\"\n [disabled]=\"item.cell.disabled\"\n (click)=\"pickPreset(item.cell)\"></button>\n }\n </div>\n\n <rt-calendar\n rtElem=\"calendar\"\n qa-dataid=\"date-range-calendar\"\n grid\n [months]=\"months()\"\n [weekdayLabels]=\"weekdays()\"\n [canPrev]=\"canPrev()\"\n [canNext]=\"canNext()\"\n [activeKey]=\"activeKey()\"\n [prevAriaLabel]=\"t().uiPrevMonth\"\n [nextAriaLabel]=\"t().uiNextMonth\"\n (prevMonth)=\"page(-1)\"\n (nextMonth)=\"page(1)\"\n (dayClick)=\"pickDay($event)\"\n (dayHover)=\"onHover($event)\"\n (gridKey)=\"onGridKey($event)\" />\n </div>\n\n <div rtElem=\"footer\">\n <span rtElem=\"summary\" qa-dataid=\"date-range-summary\" aria-live=\"polite\">{{ summary() }}</span>\n <button\n rtButton\n qa-dataid=\"date-range-reset\"\n theme=\"primary\"\n appearance=\"text\"\n size=\"sm\"\n type=\"button\"\n [label]=\"t().uiReset\"\n [attr.aria-label]=\"t().uiReset\"\n (click)=\"reset()\"></button>\n <button\n rtButton\n qa-dataid=\"date-range-apply\"\n size=\"sm\"\n type=\"button\"\n [label]=\"t().uiApply\"\n [attr.aria-label]=\"t().uiApply\"\n [disabled]=\"draft() === null\"\n (click)=\"apply()\"></button>\n </div>\n</ng-container>\n","import {\n computed,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_LOCALE, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { BreakpointsService } from '@rt-tools/ui-kit-v2/core';\nimport { RtBottomSheetComponent } from '@rt-tools/ui-kit-v2/bottom-sheet';\nimport { IRtDatePicker } from '@rt-tools/ui-kit-v2/date-picker';\nimport { rtDateLayout } from '@rt-tools/ui-kit-v2/date-picker';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { IRtInput } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtDateRangePanelComponent } from './panel/rt-date-range-panel.component';\nimport { rtRangeInBounds, rtRangeParse, rtRangeRead, rtRangeShape, rtRangeText } from './rt-date-range.logic';\nimport { IRtDateRange } from './rt-date-range.model';\n\nconst BEM_BLOCK: string = 'rt-date-range';\n\n/**\n * Поле диапазона дат со своей панелью кита, визуально и по токенам идентичное rt-input (host — box\n * `--rt-input-*`, input — прозрачный `__field`). Кнопка в конце поля открывает\n * `rt-date-range-panel`: на широком экране в поповере, на узком — в нижней шторке. CVA через общий\n * `RtFormControlBase`: clearable, авто-подсветка invalid, read-only представление.\n *\n * `value` — пара дней `{ start, end }` в форме `YYYY-MM-DD` или `null`. Текст в поле — две даты в\n * порядке языка интерфейса через тире (`12.10.2026 — 15.10.2026` под `ru`); набирается так же.\n * Нечитаемый или лежащий за границами текст оставляет значение прежним и помечает поле ошибкой.\n */\n@Component({\n selector: 'rt-date-range',\n templateUrl: './rt-date-range.component.html',\n styleUrls: ['./rt-date-range.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtBottomSheetComponent,\n RtDateRangePanelComponent,\n RtIconButtonComponent,\n RtPopoverDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtDateRangeComponent) },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-date-range--disabled]': 'isDisabled()',\n '[class.rt-date-range--invalid]': 'isInvalid() || textInvalid()',\n '[class.rt-date-range--readonly]': 'isReadonly()',\n '[class.rt-date-range--borderless]': '!bordered()',\n '[class.rt-date-range--appearance--fill]': \"appearance() === 'fill'\",\n '[class.rt-date-range--size--sm]': \"size() === 'sm'\",\n '[class.rt-date-range--size--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtDateRangeComponent extends RtFormControlBase<IRtDateRange.Value | null> {\n /** Локаль кита: приложение, меняющее язык на ходу, меняет её, и текст поля пересчитывается. */\n readonly #locale: Signal<string> = inject(RT_KIT_LOCALE);\n /** Порядок дня, месяца и года в тексте поля — по локали кита. */\n readonly #layout: Signal<IRtDatePicker.TextLayout> = computed((): IRtDatePicker.TextLayout => rtDateLayout(this.#locale()));\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n /** Узкий экран: панель открывается в нижней шторке, а не в поповере. */\n protected readonly narrow: Signal<boolean> = inject(BreakpointsService).viewportNarrow;\n\n protected readonly fieldEl: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fieldEl');\n protected readonly popover: Signal<RtPopoverDirective | undefined> = viewChild(RtPopoverDirective);\n\n /** Набранный текст не читается как диапазон в границах: поле помечено ошибкой. */\n protected readonly textInvalid: WritableSignal<boolean> = signal(false);\n protected readonly sheetOpen: WritableSignal<boolean> = signal(false);\n /** Подсказка формы текста буквами кита: `дд.мм.гггг — дд.мм.гггг` под русскими метками. */\n protected readonly shape: Signal<string> = computed((): string => {\n const labels: TRtKitLabelMap = this.t();\n return rtRangeShape(this.#layout(), {\n day: labels.uiShapeDay,\n month: labels.uiShapeMonth,\n year: labels.uiShapeYear,\n hour: labels.uiShapeHour,\n minute: labels.uiShapeMinute,\n });\n });\n /** Значение, прочитанное из формы: не пара дней по порядку поле показывает пустой. */\n protected readonly range: Signal<IRtDateRange.Value | null> = computed((): IRtDateRange.Value | null => rtRangeRead(this.value()));\n protected readonly text: Signal<string> = computed((): string => rtRangeText(this.range(), this.#layout()));\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.range() !== null);\n /** Ширина поля в знаках — по длине формы значения, как у поля даты. */\n protected readonly fieldSize: Signal<number> = computed((): number => this.shape().length);\n /** Подсказка обрезается многоточием в узком поле, поэтому шаблон целиком виден при наведении. */\n protected readonly shapeTitle: Signal<string | null> = computed((): string | null => (this.hasValue() ? null : this.shape()));\n\n /** Вид рамки: `outline` — рамка со всех сторон, `fill` — залитое поле с чертой снизу. */\n public readonly appearance: InputSignal<IRtInput.Appearance> = input<IRtInput.Appearance>('outline');\n\n public readonly displayText: Signal<string> = computed((): string => this.#format(this.range()));\n\n /** Первый допустимый день `YYYY-MM-DD`. */\n public readonly min: InputSignal<string | null> = input<string | null>(null);\n /** Последний допустимый день `YYYY-MM-DD`. */\n public readonly max: InputSignal<string | null> = input<string | null>(null);\n\n /** Значение из формы снимает ошибку набора: в поле теперь стоит оно. */\n public override writeValue(value: IRtDateRange.Value | null): void {\n super.writeValue(value);\n this.textInvalid.set(false);\n }\n\n protected getEmptyValue(): IRtDateRange.Value | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.fieldEl()?.nativeElement.focus();\n }\n\n protected override clearValue(): void {\n super.clearValue();\n this.#accept(null);\n }\n\n /** Набор текста: значение меняется, только когда текст читается как диапазон в границах. */\n protected onTyped(event: Event): void {\n const text: string = (event.target as HTMLInputElement).value;\n if (text.trim() === '') {\n this.#commit(null);\n return;\n }\n const read: IRtDateRange.Value | null = rtRangeParse(text, this.#layout());\n if (read === null || !rtRangeInBounds(read, this.min(), this.max())) {\n this.textInvalid.set(true);\n return;\n }\n this.#commit(read);\n }\n\n /** Кнопка в конце поля: на узком экране открывает шторку, на широком поповер открывает сам. */\n protected openPanel(): void {\n if (this.narrow() && !this.isDisabled()) {\n this.sheetOpen.set(true);\n }\n }\n\n protected closePanel(): void {\n this.sheetOpen.set(false);\n this.popover()?.close();\n }\n\n protected onPicked(value: IRtDateRange.Value): void {\n this.#commit(value);\n this.markTouched();\n }\n\n protected onBlur(): void {\n this.markTouched();\n }\n\n #commit(value: IRtDateRange.Value | null): void {\n this.value.set(value);\n this.emitChange(value);\n this.#accept(value);\n }\n\n /** Текст в поле — принятое значение, ошибки набора нет. */\n #accept(value: IRtDateRange.Value | null): void {\n this.textInvalid.set(false);\n const node: HTMLInputElement | undefined = this.fieldEl()?.nativeElement;\n if (node !== undefined) {\n node.value = rtRangeText(value, this.#layout());\n }\n }\n\n /** Плоский текст для режима чтения: диапазон по локали, `15 – 20 мар. 2026 г.` под `ru`. */\n #format(range: IRtDateRange.Value | null): string {\n if (range === null) {\n return '';\n }\n return new Intl.DateTimeFormat(this.#locale(), { dateStyle: 'medium', timeZone: 'UTC' }).formatRange(\n Date.parse(range.start),\n Date.parse(range.end)\n );\n }\n}\n","<ng-container rtBlock=\"rt-date-range\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"date-range-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fieldEl\n rtElem=\"field\"\n qa-dataid=\"date-range-control\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [value]=\"text()\"\n [disabled]=\"isDisabled()\"\n [attr.placeholder]=\"shape()\"\n [attr.title]=\"shapeTitle()\"\n [attr.size]=\"fieldSize()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-invalid]=\"isInvalid() || textInvalid() || null\"\n (input)=\"onTyped($event)\"\n (blur)=\"onBlur()\" />\n @if (showClearButton()) {\n <rt-icon-button\n rtElem=\"clear\"\n qa-dataid=\"date-range-clear\"\n icon=\"ico-close\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n [ariaLabel]=\"t().uiClear\"\n [tabIndex]=\"-1\"\n (clicked)=\"clear($event)\" />\n }\n <rt-icon-button\n rtElem=\"open\"\n qa-dataid=\"date-range-open\"\n icon=\"ico-calendar\"\n size=\"sm\"\n variant=\"ghost\"\n iconColor=\"muted\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiOpenCalendar\"\n [disabled]=\"isDisabled()\"\n [rtPopover]=\"panelTpl\"\n [rtPopoverDisabled]=\"narrow() || isDisabled()\"\n (clicked)=\"openPanel()\" />\n\n <ng-template #panelTpl>\n <div rtElem=\"popup\" qa-dataid=\"date-range-popup\">\n <rt-date-range-panel [value]=\"range()\" [min]=\"min()\" [max]=\"max()\" (picked)=\"onPicked($event)\" (closed)=\"closePanel()\" />\n </div>\n </ng-template>\n\n @if (narrow()) {\n <rt-bottom-sheet qa-dataid=\"date-range-sheet\" [open]=\"sheetOpen()\" (openChange)=\"sheetOpen.set($event)\">\n @if (sheetOpen()) {\n <rt-date-range-panel\n sheet\n [value]=\"range()\"\n [min]=\"min()\"\n [max]=\"max()\"\n (picked)=\"onPicked($event)\"\n (closed)=\"closePanel()\" />\n }\n </rt-bottom-sheet>\n }\n }\n</ng-container>\n"],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, ViewEncapsulation, booleanAttribute, input } from "@angular/core";
3
+ const BEM_BLOCK = "rt-divider";
4
+ var RtDividerComponent = class RtDividerComponent {
5
+ constructor() {
6
+ this.vertical = input(false, {
7
+ ...ngDevMode ? { debugName: "vertical" } : /* istanbul ignore next */ {},
8
+ transform: booleanAttribute
9
+ });
10
+ this.inset = input(false, {
11
+ ...ngDevMode ? { debugName: "inset" } : /* istanbul ignore next */ {},
12
+ transform: booleanAttribute
13
+ });
14
+ }
15
+ static {
16
+ this.ɵfac = i0.ɵɵngDeclareFactory({
17
+ minVersion: "12.0.0",
18
+ version: "22.2.2",
19
+ ngImport: i0,
20
+ type: RtDividerComponent,
21
+ deps: [],
22
+ target: i0.ɵɵFactoryTarget.Component
23
+ });
24
+ }
25
+ static {
26
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
27
+ minVersion: "17.1.0",
28
+ version: "22.2.2",
29
+ type: RtDividerComponent,
30
+ isStandalone: true,
31
+ selector: "rt-divider",
32
+ inputs: {
33
+ vertical: {
34
+ classPropertyName: "vertical",
35
+ publicName: "vertical",
36
+ isSignal: true,
37
+ isRequired: false,
38
+ transformFunction: null
39
+ },
40
+ inset: {
41
+ classPropertyName: "inset",
42
+ publicName: "inset",
43
+ isSignal: true,
44
+ isRequired: false,
45
+ transformFunction: null
46
+ }
47
+ },
48
+ host: {
49
+ attributes: {
50
+ "role": "separator",
51
+ "qa-dataid": "divider"
52
+ },
53
+ properties: {
54
+ "attr.aria-orientation": "vertical() ? \"vertical\" : \"horizontal\"",
55
+ "class.rt-divider--vertical": "vertical()",
56
+ "class.rt-divider--inset": "inset()"
57
+ },
58
+ classAttribute: "rt-divider"
59
+ },
60
+ ngImport: i0,
61
+ template: "<!-- Своей разметки нет: линию рисует граница хоста. -->\n",
62
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-divider{--rt-divider-width: var(--rt-border-width-thin);--rt-divider-color: var(--rt-color-border-default);--rt-divider-inset: var(--rt-space-16);--rt-divider-inset-block: var(--rt-space-2);display:block;flex-shrink:0;border:0;border-top:var(--rt-divider-width) solid var(--rt-divider-color);margin:0}.rt-divider--inset{margin-inline-start:var(--rt-divider-inset)}.rt-divider--vertical{display:inline-block;min-height:1em;align-self:stretch;border-top:0;border-inline-start:var(--rt-divider-width) solid var(--rt-divider-color)}.rt-divider--vertical.rt-divider--inset{margin-block:var(--rt-divider-inset-block);margin-inline-start:0}}\n"],
63
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
64
+ encapsulation: i0.ViewEncapsulation.None
65
+ });
66
+ }
67
+ };
68
+ i0.ɵɵngDeclareClassMetadata({
69
+ minVersion: "12.0.0",
70
+ version: "22.2.2",
71
+ ngImport: i0,
72
+ type: RtDividerComponent,
73
+ decorators: [{
74
+ type: Component,
75
+ args: [{
76
+ selector: "rt-divider",
77
+ changeDetection: ChangeDetectionStrategy.OnPush,
78
+ encapsulation: ViewEncapsulation.None,
79
+ host: {
80
+ class: BEM_BLOCK,
81
+ role: "separator",
82
+ "qa-dataid": "divider",
83
+ "[attr.aria-orientation]": "vertical() ? \"vertical\" : \"horizontal\"",
84
+ "[class.rt-divider--vertical]": "vertical()",
85
+ "[class.rt-divider--inset]": "inset()"
86
+ },
87
+ template: "<!-- Своей разметки нет: линию рисует граница хоста. -->\n",
88
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-divider{--rt-divider-width: var(--rt-border-width-thin);--rt-divider-color: var(--rt-color-border-default);--rt-divider-inset: var(--rt-space-16);--rt-divider-inset-block: var(--rt-space-2);display:block;flex-shrink:0;border:0;border-top:var(--rt-divider-width) solid var(--rt-divider-color);margin:0}.rt-divider--inset{margin-inline-start:var(--rt-divider-inset)}.rt-divider--vertical{display:inline-block;min-height:1em;align-self:stretch;border-top:0;border-inline-start:var(--rt-divider-width) solid var(--rt-divider-color)}.rt-divider--vertical.rt-divider--inset{margin-block:var(--rt-divider-inset-block);margin-inline-start:0}}\n"]
89
+ }]
90
+ }],
91
+ propDecorators: {
92
+ vertical: [{
93
+ type: i0.Input,
94
+ args: [{
95
+ isSignal: true,
96
+ alias: "vertical",
97
+ required: false
98
+ }]
99
+ }],
100
+ inset: [{
101
+ type: i0.Input,
102
+ args: [{
103
+ isSignal: true,
104
+ alias: "inset",
105
+ required: false
106
+ }]
107
+ }]
108
+ }
109
+ });
110
+ export { RtDividerComponent };
111
+
112
+ //# sourceMappingURL=rt-tools-ui-kit-v2-divider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-divider.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/divider/rt-divider.component.ts","../../../projects/ui-kit-v2/src/lib/components/divider/rt-divider.component.html"],"sourcesContent":["import { booleanAttribute, ChangeDetectionStrategy, Component, input, InputSignalWithTransform, ViewEncapsulation } from '@angular/core';\n\nconst BEM_BLOCK: string = 'rt-divider';\n\n/**\n * Разделитель: тонкая линия между группами пунктов списка, разделами окна, кнопками панели.\n * Горизонтальный идёт во всю ширину родителя, вертикальный — во всю высоту строки, в которой стоит.\n * `inset` отступает от начала строки, чтобы линия начиналась под текстом, а не под значком;\n * вертикальная с `inset` короче строки сверху и снизу.\n *\n * Линия — граница самого хоста: своей разметки у разделителя нет.\n */\n@Component({\n selector: 'rt-divider',\n templateUrl: './rt-divider.component.html',\n styleUrl: './rt-divider.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: BEM_BLOCK,\n role: 'separator',\n 'qa-dataid': 'divider',\n '[attr.aria-orientation]': 'vertical() ? \"vertical\" : \"horizontal\"',\n '[class.rt-divider--vertical]': 'vertical()',\n '[class.rt-divider--inset]': 'inset()',\n },\n})\nexport class RtDividerComponent {\n /** Линия стоит вертикально, во всю высоту строки. */\n public readonly vertical: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n\n /** Отступ: горизонтальная начинается под текстом строки, вертикальная короче сверху и снизу. */\n public readonly inset: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n}\n","<!-- Своей разметки нет: линию рисует граница хоста. -->\n"],"mappings":";;AAEA,MAAM,YAAoB;AAyB1B,IAAa,qBAAb,MAAa,mBAAkB;CAf/B,cAAA;EAiBoB,KAAA,WAAuD,MAAM,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAAI,WAAW;EAAgB,CAAA;EAGjG,KAAA,QAAoD,MAAM,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,QAAA,+BAAA,CAAA;GAAI,WAAW;EAAgB,CAAA;CACjH;CANY;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAkB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAlB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAkB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA;IAAA,YAAA;KAAA,QAAA;KAAA,aAAA;IAAA;IAAA,YAAA;KAAA,yBAAA;KAAA,8BAAA;KAAA,2BAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UC3B/B;GACA,QAAA,CAAA,8qBAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AD0Ba,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAf9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAY,iBAGL,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,MAC/B;IACF,OAAO;IACP,MAAM;IACN,aAAa;IACb,2BAA2B;IAC3B,gCAAgC;IAChC,6BAA6B;GAChC;GAAA,UAAA;GAAA,QAAA,CAAA,8qBAAA;EAAA,CAAA"}
@@ -453,6 +453,7 @@ var RtDraggableTreeComponent = class RtDraggableTreeComponent {
453
453
  inputs: [
454
454
  "rtTooltip",
455
455
  "rtTooltipPlacement",
456
+ "rtTooltipShowDelay",
456
457
  "rtTooltipWhenTruncated",
457
458
  "rtTooltipHideOnClick"
458
459
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-draggable-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\n/**\n * Разметка приложения вместо подписи строки `rt-draggable-tree`. Узел строки приходит в контексте\n * как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtDraggableTreeNode]' })\nexport class RtDraggableTreeNodeDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\ntype TNodes<TValue> = ReadonlyArray<TNode<TValue>>;\n\n/** Где узел лежит: его соседи, место среди них и значение родителя. */\ninterface ILocation<TValue> {\n readonly node: TNode<TValue>;\n readonly siblings: TNodes<TValue>;\n readonly index: number;\n readonly parent: TValue | null;\n}\n\n/** Контейнер — узел с массивом детей, даже пустым: он принимает узлы внутрь. */\nfunction isContainer<TValue>(node: TNode<TValue>): boolean {\n return Array.isArray(node.children);\n}\n\nfunction locate<TValue>(nodes: TNodes<TValue>, value: TValue, parent: TValue | null = null): ILocation<TValue> | null {\n for (let index: number = 0; index < nodes.length; index++) {\n const node: TNode<TValue> = nodes[index];\n if (node.value === value) {\n return { siblings: nodes, node, index, parent };\n }\n const found: ILocation<TValue> | null = locate(node.children ?? [], value, node.value);\n if (found) {\n return found;\n }\n }\n return null;\n}\n\nfunction holds<TValue>(node: TNode<TValue>, value: TValue): boolean {\n return (node.children ?? []).some((child: TNode<TValue>): boolean => child.value === value || holds(child, value));\n}\n\nfunction without<TValue>(nodes: TNodes<TValue>, value: TValue): TNodes<TValue> {\n return nodes\n .filter((node: TNode<TValue>): boolean => node.value !== value)\n .map((node: TNode<TValue>): TNode<TValue> =>\n node.children && holds(node, value) ? { ...node, children: without(node.children, value) } : node\n );\n}\n\nfunction inserted<TValue>(nodes: TNodes<TValue>, moving: TNode<TValue>, drop: IRtDraggableTree.Drop<TValue>): TNodes<TValue> {\n const at: number = nodes.findIndex((node: TNode<TValue>): boolean => node.value === drop.target);\n if (at >= 0 && drop.place !== 'inside') {\n const index: number = drop.place === 'before' ? at : at + 1;\n return [...nodes.slice(0, index), moving, ...nodes.slice(index)];\n }\n return nodes.map((node: TNode<TValue>): TNode<TValue> => {\n if (node.value === drop.target && drop.place === 'inside') {\n return { ...node, children: [...(node.children ?? []), moving] };\n }\n if (node.children && holds(node, drop.target)) {\n return { ...node, children: inserted(node.children, moving, drop) };\n }\n return node;\n });\n}\n\nfunction siblingPlace<TValue>(here: ILocation<TValue>, step: number): IRtDraggableTree.Drop<TValue> | null {\n const next: TNode<TValue> | undefined = here.siblings[here.index + step];\n return next ? { target: next.value, place: step < 0 ? 'before' : 'after' } : null;\n}\n\nfunction levelPlace<TValue>(here: ILocation<TValue>, out: boolean): IRtDraggableTree.Drop<TValue> | null {\n if (out) {\n return here.parent === null ? null : { target: here.parent, place: 'after' };\n }\n const above: TNode<TValue> | undefined = here.siblings[here.index - 1];\n return above && isContainer(above) ? { target: above.value, place: 'inside' } : null;\n}\n\n/**\n * Место сброса по третям высоты строки: верхняя — перед целью, нижняя — после, средняя — внутрь.\n * Средняя треть листа места не даёт: внутрь принимает только контейнер.\n */\nexport function rtDragPlace<TValue>(target: TNode<TValue>, top: number, height: number, pointer: number): IRtDraggableTree.Place | null {\n const third: number = height / 3;\n const offset: number = pointer - top;\n if (offset < third) {\n return 'before';\n }\n if (offset > 2 * third) {\n return 'after';\n }\n return isContainer(target) ? 'inside' : null;\n}\n\n/**\n * Можно ли поставить узел на место: не на себя, не в своё поддерево, внутрь — только в контейнер, и\n * если приложение не запретило.\n */\nexport function rtDragAllowed<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>,\n canDrop: IRtDraggableTree.CanDrop<TValue> | null = null\n): boolean {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n const target: ILocation<TValue> | null = locate(nodes, drop.target);\n if (!moving || !target || drop.target === value || holds(moving.node, drop.target)) {\n return false;\n }\n if (drop.place === 'inside' && !isContainer(target.node)) {\n return false;\n }\n return canDrop ? canDrop(moving.node, target.node, drop.place) : true;\n}\n\n/** Переносит узел вместе с поддеревом. Узлы на входе не меняются: ветки на пути строятся заново. */\nexport function rtDragMove<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>\n): IRtDraggableTree.MoveResult<TValue> | null {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n if (!moving || !rtDragAllowed(nodes, value, drop)) {\n return null;\n }\n const next: TNodes<TValue> = inserted(without(nodes, value), moving.node, drop);\n const landed: ILocation<TValue> | null = locate(next, value);\n if (!landed) {\n return null;\n }\n return { nodes: next, moved: { node: moving.node, parent: landed.parent, index: landed.index } };\n}\n\n/**\n * Место для переноса клавишей с Alt. Вверх и вниз — среди соседей, влево — сразу после своей ветки,\n * вправо — последним в контейнер, стоящий прямо над узлом. Двигаться некуда — `null`.\n */\nexport function rtDragKeyPlace<TValue>(nodes: TNodes<TValue>, value: TValue, key: string): IRtDraggableTree.Drop<TValue> | null {\n const here: ILocation<TValue> | null = locate(nodes, value);\n if (!here) {\n return null;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n return siblingPlace(here, key === 'ArrowUp' ? -1 : 1);\n }\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n return levelPlace(here, key === 'ArrowLeft');\n }\n return null;\n}\n","import { CdkDrag, CdkDragHandle, CdkDragMove, CdkDropList } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtOptionTree, rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/core';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtDraggableTreeNodeDirective } from './rt-draggable-tree.directives';\nimport { rtDragAllowed, rtDragKeyPlace, rtDragMove, rtDragPlace } from './rt-draggable-tree.logic';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\nconst BEM_BLOCK: string = 'rt-draggable-tree';\nconst MOVE_KEYS: ReadonlyArray<string> = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n/**\n * Дерево, узлы которого человек переставляет: перетаскиванием строки до, после или внутрь другой,\n * или клавишами с Alt.\n *\n * Строки, уровни и раскрытие считает тот же модуль, что у `rt-tree`. Узлы на входе не меняются:\n * перенос пишет в `nodes` новый массив и сообщает `moved`. Место сброса — чистая функция от рамки\n * строки под указателем; документ дерево не читает.\n */\n@Component({\n selector: 'rt-draggable-tree',\n templateUrl: './rt-draggable-tree.component.html',\n styleUrl: './rt-draggable-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n CdkDrag,\n CdkDragHandle,\n CdkDropList,\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n tabindex: '0',\n '[attr.aria-label]': 'ariaLabel()',\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtDraggableTreeComponent<TValue> {\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n readonly #dragged: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeTemplate: Signal<RtDraggableTreeNodeDirective<TValue> | undefined> = contentChild(RtDraggableTreeNodeDirective);\n\n protected readonly rowElements: Signal<ReadonlyArray<ElementRef<HTMLElement>>> = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Место, куда встанет перетаскиваемый узел; `null` — сейчас места нет. */\n protected readonly drop: WritableSignal<IRtDraggableTree.Drop<TValue> | null> = signal<IRtDraggableTree.Drop<TValue> | null>(null);\n\n /**\n * Раскрытые ветки. Пока приложение их не задало и человек ничего не сворачивал, раскрыты все:\n * порядок виден целиком с первого взгляда.\n */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed((): ReadonlySet<TValue> => {\n const open: ReadonlyArray<TValue> | null = this.open();\n if (open !== null) {\n return new Set<TValue>(open);\n }\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n return all;\n });\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), '')\n );\n\n protected readonly highlighted: Signal<TValue | null> = this.#highlighted.asReadonly();\n\n public readonly nodes: ModelSignal<ReadonlyArray<IRtTree.Node<TValue>>> = model.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n /** Значения раскрытых веток; `null` — раскрыты все. Пара `openChange` приходит на каждое раскрытие. */\n public readonly open: ModelSignal<ReadonlyArray<TValue> | null> = model<ReadonlyArray<TValue> | null>(null);\n public readonly canDrop: InputSignal<IRtDraggableTree.CanDrop<TValue> | null> = input<IRtDraggableTree.CanDrop<TValue> | null>(null);\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly moved: OutputEmitterRef<IRtDraggableTree.Moved<TValue>> = output<IRtDraggableTree.Moved<TValue>>();\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /** Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой. */\n public handleKeydown(event: KeyboardEvent): boolean {\n const taken: boolean = event.altKey ? this.#moveByKey(event.key) : this.#walkByKey(event.key);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>): void {\n this.#highlighted.set(row.option.value);\n this.picked.emit(row.option);\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onDragStarted(value: TValue): void {\n this.#dragged.set(value);\n }\n\n protected onDragMoved(event: CdkDragMove<TValue>): void {\n this.drop.set(this.#dropAt(event.pointerPosition.y));\n }\n\n protected onDropped(): void {\n const dragged: TValue | null = this.#dragged();\n const drop: IRtDraggableTree.Drop<TValue> | null = this.drop();\n this.#dragged.set(null);\n this.drop.set(null);\n if (dragged !== null && drop) {\n this.#apply(dragged, drop);\n }\n }\n\n #dropAt(pointer: number): IRtDraggableTree.Drop<TValue> | null {\n const dragged: TValue | null = this.#dragged();\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const elements: ReadonlyArray<ElementRef<HTMLElement>> = this.rowElements();\n if (dragged === null) {\n return null;\n }\n const index: number = elements.findIndex((element: ElementRef<HTMLElement>, at: number): boolean => {\n const box: DOMRect = element.nativeElement.getBoundingClientRect();\n return rows[at]?.option.value !== dragged && pointer >= box.top && pointer < box.bottom;\n });\n if (index < 0) {\n return null;\n }\n const box: DOMRect = elements[index].nativeElement.getBoundingClientRect();\n const target: IRtTree.Node<TValue> = rows[index].option;\n const place: IRtDraggableTree.Place | null = rtDragPlace(target, box.top, box.height, pointer);\n const drop: IRtDraggableTree.Drop<TValue> | null = place ? { target: target.value, place } : null;\n return drop && rtDragAllowed(this.nodes(), dragged, drop, this.canDrop()) ? drop : null;\n }\n\n #moveByKey(key: string): boolean {\n const value: TValue | null = this.#highlighted();\n if (!MOVE_KEYS.includes(key)) {\n return false;\n }\n const node: IRtTree.Node<TValue> | undefined = this.rows().find(\n (row: IRtTree.Row<TValue>): boolean => row.option.value === value\n )?.option;\n const drop: IRtDraggableTree.Drop<TValue> | null = node && !node.disabled ? rtDragKeyPlace(this.nodes(), node.value, key) : null;\n if (node && drop && rtDragAllowed(this.nodes(), node.value, drop, this.canDrop())) {\n this.#apply(node.value, drop);\n }\n return true;\n }\n\n #walkByKey(key: string): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = rows.findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === this.#highlighted());\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#step(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n if (index < 0) {\n return false;\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\n const answer: IRtOptionTree.SideKeyAnswer<TValue> = rtTreeSideKey(rows, index, key);\n if (answer.toggle !== null) {\n this.#toggle(answer.toggle);\n }\n this.#highlighted.set(rows[answer.index].option.value);\n return true;\n }\n if (key === 'Enter') {\n this.picked.emit(rows[index].option);\n return true;\n }\n return false;\n }\n\n #step(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, step: number): boolean {\n if (rows.length === 0) {\n return false;\n }\n const next: number = index < 0 ? 0 : Math.min(rows.length - 1, Math.max(0, index + step));\n this.#highlighted.set(rows[next].option.value);\n return true;\n }\n\n #apply(value: TValue, drop: IRtDraggableTree.Drop<TValue>): void {\n const result: IRtDraggableTree.MoveResult<TValue> | null = rtDragMove(this.nodes(), value, drop);\n if (!result) {\n return;\n }\n this.nodes.set(result.nodes);\n if (drop.place === 'inside' && !this.openBranches().has(drop.target)) {\n this.open.set([...this.openBranches(), drop.target]);\n }\n this.moved.emit(result.moved);\n }\n\n #toggle(value: TValue): void {\n this.open.set([...rtTreeToggle(this.openBranches(), value)]);\n }\n\n #collectBranches(list: ReadonlyArray<IRtTree.Node<TValue>>, into: Set<TValue>): void {\n list.forEach((node: IRtTree.Node<TValue>): void => {\n if ((node.children ?? []).length > 0) {\n into.add(node.value);\n this.#collectBranches(node.children ?? [], into);\n }\n });\n }\n}\n","<ng-container rtBlock=\"rt-draggable-tree\">\n <!--\n Строки берут мышь через (click), клавиатура — на самом дереве (handleKeydown): строки фокус не\n берут, подсвеченная строка — состояние рядом с фокусом. Строку тянут за ручку; список один на\n всё дерево, и место сброса считает компонент по рамке строки под указателем.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div rtElem=\"list\" cdkDropList [cdkDropListSortingDisabled]=\"true\" (cdkDropListDropped)=\"onDropped()\">\n @for (row of rows(); track row.option.value) {\n <div\n #row\n rtElem=\"row\"\n qa-dataid=\"draggable-tree-row\"\n role=\"treeitem\"\n cdkDrag\n [cdkDragData]=\"row.option.value\"\n [cdkDragDisabled]=\"!!row.option.disabled\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"row.level + 1\"\n [attr.aria-expanded]=\"row.branch ? row.open : null\"\n [attr.aria-selected]=\"row.option.value === highlighted()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n [style.--rt-draggable-tree-level]=\"row.level\"\n [rtMod]=\"{\n highlighted: row.option.value === highlighted(),\n disabled: !!row.option.disabled,\n 'drop-before': drop()?.target === row.option.value && drop()?.place === 'before',\n 'drop-after': drop()?.target === row.option.value && drop()?.place === 'after',\n 'drop-inside': drop()?.target === row.option.value && drop()?.place === 'inside',\n }\"\n (cdkDragStarted)=\"onDragStarted(row.option.value)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (click)=\"onRowClick(row)\">\n @if (row.option.disabled) {\n <span rtElem=\"handle-space\"></span>\n } @else {\n <span rtElem=\"handle\" qa-dataid=\"draggable-tree-handle\" cdkDragHandle aria-hidden=\"true\">\n <rt-icon name=\"bars\" size=\"sm\" color=\"muted\" />\n </span>\n }\n\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"draggable-tree-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n <span rtElem=\"content\" qa-dataid=\"draggable-tree-content\">\n @if (nodeTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row.option }\" />\n } @else {\n <span rtElem=\"label\" qa-dataid=\"draggable-tree-label\" rtTooltipWhenTruncated [rtTooltip]=\"row.option.label\">\n {{ row.option.label }}\n </span>\n }\n </span>\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"draggable-tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"draggable-tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ t().uiNoOptions }}\n </div>\n }\n </div>\n</ng-container>\n"],"mappings":";;;;;;;;AASA,IAAa,+BAAb,MAAa,6BAA4B;CADzC,cAAA;EAEoB,KAAA,cAAwD,OAAiD,WAAW;CACvI;CAFY;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAA4B,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAA5B;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAA4B,cAAA;GAAA,UAAA;GAAA,UAAA;EAAA,CAAA;CAAA;;AAA5B,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAA4B,YAAA,CAAA;EADxC,MAAA;EAAU,MAAA,CAAA,EAAE,UAAU,mCAAkC,CAAE;;;ACO3D,SAAS,YAAoB,MAAmB;CAC5C,OAAO,MAAM,QAAQ,KAAK,QAAQ;AACtC;AAEA,SAAS,OAAe,OAAuB,OAAe,SAAwB,MAAI;CACtF,KAAK,IAAI,QAAgB,GAAG,QAAQ,MAAM,QAAQ,SAAS;EACvD,MAAM,OAAsB,MAAM;EAClC,IAAI,KAAK,UAAU,OACf,OAAO;GAAE,UAAU;GAAO;GAAM;GAAO;EAAM;EAEjD,MAAM,QAAkC,OAAO,KAAK,YAAY,CAAA,GAAI,OAAO,KAAK,KAAK;EACrF,IAAI,OACA,OAAO;CAEf;CACA,OAAO;AACX;AAEA,SAAS,MAAc,MAAqB,OAAa;CACrD,QAAQ,KAAK,YAAY,CAAA,EAAA,CAAI,MAAM,UAAkC,MAAM,UAAU,SAAS,MAAM,OAAO,KAAK,CAAC;AACrH;AAEA,SAAS,QAAgB,OAAuB,OAAa;CACzD,OAAO,MACF,QAAQ,SAAiC,KAAK,UAAU,KAAK,CAAC,CAC9D,KAAK,SACF,KAAK,YAAY,MAAM,MAAM,KAAK,IAAI;EAAE,GAAG;EAAM,UAAU,QAAQ,KAAK,UAAU,KAAK;CAAC,IAAK,IAAI;AAE7G;AAEA,SAAS,SAAiB,OAAuB,QAAuB,MAAmC;CACvG,MAAM,KAAa,MAAM,WAAW,SAAiC,KAAK,UAAU,KAAK,MAAM;CAC/F,IAAI,MAAM,KAAK,KAAK,UAAU,UAAU;EACpC,MAAM,QAAgB,KAAK,UAAU,WAAW,KAAK,KAAK;EAC1D,OAAO;GAAC,GAAG,MAAM,MAAM,GAAG,KAAK;GAAG;GAAQ,GAAG,MAAM,MAAM,KAAK;EAAC;CACnE;CACA,OAAO,MAAM,KAAK,SAAsC;EACpD,IAAI,KAAK,UAAU,KAAK,UAAU,KAAK,UAAU,UAC7C,OAAO;GAAE,GAAG;GAAM,UAAU,CAAC,GAAI,KAAK,YAAY,CAAA,GAAK,MAAM;EAAC;EAElE,IAAI,KAAK,YAAY,MAAM,MAAM,KAAK,MAAM,GACxC,OAAO;GAAE,GAAG;GAAM,UAAU,SAAS,KAAK,UAAU,QAAQ,IAAI;EAAC;EAErE,OAAO;CACX,CAAC;AACL;AAEA,SAAS,aAAqB,MAAyB,MAAY;CAC/D,MAAM,OAAkC,KAAK,SAAS,KAAK,QAAQ;CACnE,OAAO,OAAO;EAAE,QAAQ,KAAK;EAAO,OAAO,OAAO,IAAI,WAAW;CAAO,IAAK;AACjF;AAEA,SAAS,WAAmB,MAAyB,KAAY;CAC7D,IAAI,KACA,OAAO,KAAK,WAAW,OAAO,OAAO;EAAE,QAAQ,KAAK;EAAQ,OAAO;CAAO;CAE9E,MAAM,QAAmC,KAAK,SAAS,KAAK,QAAQ;CACpE,OAAO,SAAS,YAAY,KAAK,IAAI;EAAE,QAAQ,MAAM;EAAO,OAAO;CAAQ,IAAK;AACpF;AAMA,SAAgB,YAAoB,QAAuB,KAAa,QAAgB,SAAe;CACnG,MAAM,QAAgB,SAAS;CAC/B,MAAM,SAAiB,UAAU;CACjC,IAAI,SAAS,OACT,OAAO;CAEX,IAAI,SAAS,IAAI,OACb,OAAO;CAEX,OAAO,YAAY,MAAM,IAAI,WAAW;AAC5C;AAMA,SAAgB,cACZ,OACA,OACA,MACA,UAAmD,MAAI;CAEvD,MAAM,SAAmC,OAAO,OAAO,KAAK;CAC5D,MAAM,SAAmC,OAAO,OAAO,KAAK,MAAM;CAClE,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,WAAW,SAAS,MAAM,OAAO,MAAM,KAAK,MAAM,GAC7E,OAAO;CAEX,IAAI,KAAK,UAAU,YAAY,CAAC,YAAY,OAAO,IAAI,GACnD,OAAO;CAEX,OAAO,UAAU,QAAQ,OAAO,MAAM,OAAO,MAAM,KAAK,KAAK,IAAI;AACrE;AAGA,SAAgB,WACZ,OACA,OACA,MAAmC;CAEnC,MAAM,SAAmC,OAAO,OAAO,KAAK;CAC5D,IAAI,CAAC,UAAU,CAAC,cAAc,OAAO,OAAO,IAAI,GAC5C,OAAO;CAEX,MAAM,OAAuB,SAAS,QAAQ,OAAO,KAAK,GAAG,OAAO,MAAM,IAAI;CAC9E,MAAM,SAAmC,OAAO,MAAM,KAAK;CAC3D,IAAI,CAAC,QACD,OAAO;CAEX,OAAO;EAAE,OAAO;EAAM,OAAO;GAAE,MAAM,OAAO;GAAM,QAAQ,OAAO;GAAQ,OAAO,OAAO;EAAK;CAAE;AAClG;AAMA,SAAgB,eAAuB,OAAuB,OAAe,KAAW;CACpF,MAAM,OAAiC,OAAO,OAAO,KAAK;CAC1D,IAAI,CAAC,MACD,OAAO;CAEX,IAAI,QAAQ,aAAa,QAAQ,aAC7B,OAAO,aAAa,MAAM,QAAQ,YAAY,KAAK,CAAC;CAExD,IAAI,QAAQ,eAAe,QAAQ,cAC/B,OAAO,WAAW,MAAM,QAAQ,WAAW;CAE/C,OAAO;AACX;ACjHA,MAAM,YAAoB;AAC1B,MAAM,YAAmC;CAAC;CAAW;CAAa;CAAa;AAAY;AAmC3F,IAAa,2BAAb,MAAa,yBAAwB;CAzBrC,cAAA;EA0Ba,KAAA,eAA8C,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EACzE,KAAA,WAA0C,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE3D,KAAA,IAA4B,OAAO,aAAa;EAEhD,KAAA,eAAyE,aAAa,8BAA6B,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAEnH,KAAA,cAA8D,aAAsC,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAG1G,KAAA,OAA6D,OAA6C,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAM/G,KAAA,eAA4C,eAAmC;GAC9F,MAAM,OAAqC,KAAK,KAAI;GACpD,IAAI,SAAS,MACT,OAAO,IAAI,IAAY,IAAI;GAE/B,MAAM,sBAAmB,IAAI,IAAG;GAChC,KAAK,iBAAiB,KAAK,MAAK,GAAI,GAAG;GACvC,OAAO;EACX,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAEiB,KAAA,OAAmD,eAClE,WAAW,KAAK,MAAK,GAAI,KAAK,aAAY,GAAI,EAAE,GACnD,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,cAAqC,KAAK,aAAa,WAAU;EAEpE,KAAA,QAA0D,MAAM,SAA+C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAE/G,KAAA,OAAkD,MAAoC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAC3F,KAAA,UAAgE,MAA+C,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EACpH,KAAA,YAAwC,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAElE,KAAA,YAA8C,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAE9E,KAAA,QAA0D,OAAM;EAChE,KAAA,SAAiD,OAAM;CAqI1E;CA9KY;CACA;CA2CF,cAAc,OAAoB;EACrC,MAAM,QAAiB,MAAM,SAAS,KAAK,WAAW,MAAM,GAAG,IAAI,KAAK,WAAW,MAAM,GAAG;EAC5F,IAAI,OAAO;GACP,MAAM,eAAc;GACpB,MAAM,gBAAe;EACzB;EACA,OAAO;CACX;CAEU,WAAW,KAAwB;EACzC,KAAK,aAAa,IAAI,IAAI,OAAO,KAAK;EACtC,KAAK,OAAO,KAAK,IAAI,MAAM;CAC/B;CAEU,cAAc,OAAc,OAAa;EAC/C,MAAM,gBAAe;EACrB,KAAK,QAAQ,KAAK;CACtB;CAEU,cAAc,OAAa;EACjC,KAAK,SAAS,IAAI,KAAK;CAC3B;CAEU,YAAY,OAA0B;EAC5C,KAAK,KAAK,IAAI,KAAK,QAAQ,MAAM,gBAAgB,CAAC,CAAC;CACvD;CAEU,YAAS;EACf,MAAM,UAAyB,KAAK,SAAQ;EAC5C,MAAM,OAA6C,KAAK,KAAI;EAC5D,KAAK,SAAS,IAAI,IAAI;EACtB,KAAK,KAAK,IAAI,IAAI;EAClB,IAAI,YAAY,QAAQ,MACpB,KAAK,OAAO,SAAS,IAAI;CAEjC;CAEA,QAAQ,SAAe;EACnB,MAAM,UAAyB,KAAK,SAAQ;EAC5C,MAAM,OAA2C,KAAK,KAAI;EAC1D,MAAM,WAAmD,KAAK,YAAW;EACzE,IAAI,YAAY,MACZ,OAAO;EAEX,MAAM,QAAgB,SAAS,WAAW,SAAkC,OAAuB;GAC/F,MAAM,MAAe,QAAQ,cAAc,sBAAqB;GAChE,OAAO,KAAK,GAAG,EAAE,OAAO,UAAU,WAAW,WAAW,IAAI,OAAO,UAAU,IAAI;EACrF,CAAC;EACD,IAAI,QAAQ,GACR,OAAO;EAEX,MAAM,MAAe,SAAS,MAAM,CAAC,cAAc,sBAAqB;EACxE,MAAM,SAA+B,KAAK,MAAM,CAAC;EACjD,MAAM,QAAuC,YAAY,QAAQ,IAAI,KAAK,IAAI,QAAQ,OAAO;EAC7F,MAAM,OAA6C,QAAQ;GAAE,QAAQ,OAAO;GAAO;EAAK,IAAK;EAC7F,OAAO,QAAQ,cAAc,KAAK,MAAK,GAAI,SAAS,MAAM,KAAK,QAAO,CAAE,IAAI,OAAO;CACvF;CAEA,WAAW,KAAW;EAClB,MAAM,QAAuB,KAAK,aAAY;EAC9C,IAAI,CAAC,UAAU,SAAS,GAAG,GACvB,OAAO;EAEX,MAAM,OAAyC,KAAK,KAAI,CAAE,CAAC,MACtD,QAAsC,IAAI,OAAO,UAAU,KAAK,CACpE,EAAE;EACH,MAAM,OAA6C,QAAQ,CAAC,KAAK,WAAW,eAAe,KAAK,MAAK,GAAI,KAAK,OAAO,GAAG,IAAI;EAC5H,IAAI,QAAQ,QAAQ,cAAc,KAAK,MAAK,GAAI,KAAK,OAAO,MAAM,KAAK,QAAO,CAAE,GAC5E,KAAK,OAAO,KAAK,OAAO,IAAI;EAEhC,OAAO;CACX;CAEA,WAAW,KAAW;EAClB,MAAM,OAA2C,KAAK,KAAI;EAC1D,MAAM,QAAgB,KAAK,WAAW,QAAsC,IAAI,OAAO,UAAU,KAAK,aAAY,CAAE;EACpH,IAAI,QAAQ,eAAe,QAAQ,WAC/B,OAAO,KAAK,MAAM,MAAM,OAAO,QAAQ,cAAc,IAAI,EAAE;EAE/D,IAAI,QAAQ,GACR,OAAO;EAEX,IAAI,QAAQ,gBAAgB,QAAQ,aAAa;GAC7C,MAAM,SAA8C,cAAc,MAAM,OAAO,GAAG;GAClF,IAAI,OAAO,WAAW,MAClB,KAAK,QAAQ,OAAO,MAAM;GAE9B,KAAK,aAAa,IAAI,KAAK,OAAO,MAAM,CAAC,OAAO,KAAK;GACrD,OAAO;EACX;EACA,IAAI,QAAQ,SAAS;GACjB,KAAK,OAAO,KAAK,KAAK,MAAM,CAAC,MAAM;GACnC,OAAO;EACX;EACA,OAAO;CACX;CAEA,MAAM,MAA0C,OAAe,MAAY;EACvE,IAAI,KAAK,WAAW,GAChB,OAAO;EAEX,MAAM,OAAe,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC;EACxF,KAAK,aAAa,IAAI,KAAK,KAAK,CAAC,OAAO,KAAK;EAC7C,OAAO;CACX;CAEA,OAAO,OAAe,MAAmC;EACrD,MAAM,SAAqD,WAAW,KAAK,MAAK,GAAI,OAAO,IAAI;EAC/F,IAAI,CAAC,QACD;EAEJ,KAAK,MAAM,IAAI,OAAO,KAAK;EAC3B,IAAI,KAAK,UAAU,YAAY,CAAC,KAAK,aAAY,CAAE,CAAC,IAAI,KAAK,MAAM,GAC/D,KAAK,KAAK,IAAI,CAAC,GAAG,KAAK,aAAY,GAAI,KAAK,MAAM,CAAC;EAEvD,KAAK,MAAM,KAAK,OAAO,KAAK;CAChC;CAEA,QAAQ,OAAa;EACjB,KAAK,KAAK,IAAI,CAAC,GAAG,aAAa,KAAK,aAAY,GAAI,KAAK,CAAC,CAAC;CAC/D;CAEA,iBAAiB,MAA2C,MAAiB;EACzE,KAAK,SAAS,SAAoC;GAC9C,KAAK,KAAK,YAAY,CAAA,EAAA,CAAI,SAAS,GAAG;IAClC,KAAK,IAAI,KAAK,KAAK;IACnB,KAAK,iBAAiB,KAAK,YAAY,CAAA,GAAI,IAAI;GACnD;EACJ,CAAC;CACL;CA9KS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAwB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAxB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAwB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA;IAAA,OAAA;IAAA,MAAA;IAAA,OAAA;IAAA,QAAA;GAAA;GAAA,MAAA;IAAA,YAAA;KAAA,QAAA;KAAA,YAAA;IAAA;IAAA,WAAA,EAAA,WAAA,wBAAA;IAAA,YAAA,EAAA,mBAAA,cAAA;IAAA,gBAAA;GAAA;GAAA,SAAA,CAAA;IAAA,cAAA;IAAA,OAAA;IAAA,WAMwE;IAA4B,aAAA;IAAA,UAAA;GAAA,CAAA;GAAA,aAAA,CAAA;IAAA,cAAA;IAAA,WAAA,CAAA,KAAA;IAAA,aAAA;IAAA,UAAA;GAAA,CAAA;GAAA,UAAA;GAAA,UC3EzI;GA2EA,QAAA,CAAA,o3KAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDxBQ;KAAgB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAChB;KAAO,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACP;KAAa,UAAA;KAAA,QAAA,CAAA,uBAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAW,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,aAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACX;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAY,UAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAUP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAwB,YAAA,CAAA;EAzBpC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAmB,iBAGZ,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK;IACF,OAAO;IACP,MAAM;IACN,UAAU;IACV,qBAAqB;IACrB,aAAa;GAChB;GAAA,UAAA;GAAA,QAAA,CAAA,o3KAAA;EAAA,CAAA;CAQwG,CAAA;CAAA,gBAAA;EAAA,cAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,GAAA,iBAAA,4BAA4B,GAAA,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAEd,OAAK,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,GAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,aAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,GAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,YAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,OAAA;EAAA,CAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,QAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-draggable-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\n/**\n * Разметка приложения вместо подписи строки `rt-draggable-tree`. Узел строки приходит в контексте\n * как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtDraggableTreeNode]' })\nexport class RtDraggableTreeNodeDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\ntype TNodes<TValue> = ReadonlyArray<TNode<TValue>>;\n\n/** Где узел лежит: его соседи, место среди них и значение родителя. */\ninterface ILocation<TValue> {\n readonly node: TNode<TValue>;\n readonly siblings: TNodes<TValue>;\n readonly index: number;\n readonly parent: TValue | null;\n}\n\n/** Контейнер — узел с массивом детей, даже пустым: он принимает узлы внутрь. */\nfunction isContainer<TValue>(node: TNode<TValue>): boolean {\n return Array.isArray(node.children);\n}\n\nfunction locate<TValue>(nodes: TNodes<TValue>, value: TValue, parent: TValue | null = null): ILocation<TValue> | null {\n for (let index: number = 0; index < nodes.length; index++) {\n const node: TNode<TValue> = nodes[index];\n if (node.value === value) {\n return { siblings: nodes, node, index, parent };\n }\n const found: ILocation<TValue> | null = locate(node.children ?? [], value, node.value);\n if (found) {\n return found;\n }\n }\n return null;\n}\n\nfunction holds<TValue>(node: TNode<TValue>, value: TValue): boolean {\n return (node.children ?? []).some((child: TNode<TValue>): boolean => child.value === value || holds(child, value));\n}\n\nfunction without<TValue>(nodes: TNodes<TValue>, value: TValue): TNodes<TValue> {\n return nodes\n .filter((node: TNode<TValue>): boolean => node.value !== value)\n .map((node: TNode<TValue>): TNode<TValue> =>\n node.children && holds(node, value) ? { ...node, children: without(node.children, value) } : node\n );\n}\n\nfunction inserted<TValue>(nodes: TNodes<TValue>, moving: TNode<TValue>, drop: IRtDraggableTree.Drop<TValue>): TNodes<TValue> {\n const at: number = nodes.findIndex((node: TNode<TValue>): boolean => node.value === drop.target);\n if (at >= 0 && drop.place !== 'inside') {\n const index: number = drop.place === 'before' ? at : at + 1;\n return [...nodes.slice(0, index), moving, ...nodes.slice(index)];\n }\n return nodes.map((node: TNode<TValue>): TNode<TValue> => {\n if (node.value === drop.target && drop.place === 'inside') {\n return { ...node, children: [...(node.children ?? []), moving] };\n }\n if (node.children && holds(node, drop.target)) {\n return { ...node, children: inserted(node.children, moving, drop) };\n }\n return node;\n });\n}\n\nfunction siblingPlace<TValue>(here: ILocation<TValue>, step: number): IRtDraggableTree.Drop<TValue> | null {\n const next: TNode<TValue> | undefined = here.siblings[here.index + step];\n return next ? { target: next.value, place: step < 0 ? 'before' : 'after' } : null;\n}\n\nfunction levelPlace<TValue>(here: ILocation<TValue>, out: boolean): IRtDraggableTree.Drop<TValue> | null {\n if (out) {\n return here.parent === null ? null : { target: here.parent, place: 'after' };\n }\n const above: TNode<TValue> | undefined = here.siblings[here.index - 1];\n return above && isContainer(above) ? { target: above.value, place: 'inside' } : null;\n}\n\n/**\n * Место сброса по третям высоты строки: верхняя — перед целью, нижняя — после, средняя — внутрь.\n * Средняя треть листа места не даёт: внутрь принимает только контейнер.\n */\nexport function rtDragPlace<TValue>(target: TNode<TValue>, top: number, height: number, pointer: number): IRtDraggableTree.Place | null {\n const third: number = height / 3;\n const offset: number = pointer - top;\n if (offset < third) {\n return 'before';\n }\n if (offset > 2 * third) {\n return 'after';\n }\n return isContainer(target) ? 'inside' : null;\n}\n\n/**\n * Можно ли поставить узел на место: не на себя, не в своё поддерево, внутрь — только в контейнер, и\n * если приложение не запретило.\n */\nexport function rtDragAllowed<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>,\n canDrop: IRtDraggableTree.CanDrop<TValue> | null = null\n): boolean {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n const target: ILocation<TValue> | null = locate(nodes, drop.target);\n if (!moving || !target || drop.target === value || holds(moving.node, drop.target)) {\n return false;\n }\n if (drop.place === 'inside' && !isContainer(target.node)) {\n return false;\n }\n return canDrop ? canDrop(moving.node, target.node, drop.place) : true;\n}\n\n/** Переносит узел вместе с поддеревом. Узлы на входе не меняются: ветки на пути строятся заново. */\nexport function rtDragMove<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>\n): IRtDraggableTree.MoveResult<TValue> | null {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n if (!moving || !rtDragAllowed(nodes, value, drop)) {\n return null;\n }\n const next: TNodes<TValue> = inserted(without(nodes, value), moving.node, drop);\n const landed: ILocation<TValue> | null = locate(next, value);\n if (!landed) {\n return null;\n }\n return { nodes: next, moved: { node: moving.node, parent: landed.parent, index: landed.index } };\n}\n\n/**\n * Место для переноса клавишей с Alt. Вверх и вниз — среди соседей, влево — сразу после своей ветки,\n * вправо — последним в контейнер, стоящий прямо над узлом. Двигаться некуда — `null`.\n */\nexport function rtDragKeyPlace<TValue>(nodes: TNodes<TValue>, value: TValue, key: string): IRtDraggableTree.Drop<TValue> | null {\n const here: ILocation<TValue> | null = locate(nodes, value);\n if (!here) {\n return null;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n return siblingPlace(here, key === 'ArrowUp' ? -1 : 1);\n }\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n return levelPlace(here, key === 'ArrowLeft');\n }\n return null;\n}\n","import { CdkDrag, CdkDragHandle, CdkDragMove, CdkDropList } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtOptionTree, rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/core';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtDraggableTreeNodeDirective } from './rt-draggable-tree.directives';\nimport { rtDragAllowed, rtDragKeyPlace, rtDragMove, rtDragPlace } from './rt-draggable-tree.logic';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\nconst BEM_BLOCK: string = 'rt-draggable-tree';\nconst MOVE_KEYS: ReadonlyArray<string> = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n/**\n * Дерево, узлы которого человек переставляет: перетаскиванием строки до, после или внутрь другой,\n * или клавишами с Alt.\n *\n * Строки, уровни и раскрытие считает тот же модуль, что у `rt-tree`. Узлы на входе не меняются:\n * перенос пишет в `nodes` новый массив и сообщает `moved`. Место сброса — чистая функция от рамки\n * строки под указателем; документ дерево не читает.\n */\n@Component({\n selector: 'rt-draggable-tree',\n templateUrl: './rt-draggable-tree.component.html',\n styleUrl: './rt-draggable-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n CdkDrag,\n CdkDragHandle,\n CdkDropList,\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n tabindex: '0',\n '[attr.aria-label]': 'ariaLabel()',\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtDraggableTreeComponent<TValue> {\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n readonly #dragged: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeTemplate: Signal<RtDraggableTreeNodeDirective<TValue> | undefined> = contentChild(RtDraggableTreeNodeDirective);\n\n protected readonly rowElements: Signal<ReadonlyArray<ElementRef<HTMLElement>>> = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Место, куда встанет перетаскиваемый узел; `null` — сейчас места нет. */\n protected readonly drop: WritableSignal<IRtDraggableTree.Drop<TValue> | null> = signal<IRtDraggableTree.Drop<TValue> | null>(null);\n\n /**\n * Раскрытые ветки. Пока приложение их не задало и человек ничего не сворачивал, раскрыты все:\n * порядок виден целиком с первого взгляда.\n */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed((): ReadonlySet<TValue> => {\n const open: ReadonlyArray<TValue> | null = this.open();\n if (open !== null) {\n return new Set<TValue>(open);\n }\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n return all;\n });\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), '')\n );\n\n protected readonly highlighted: Signal<TValue | null> = this.#highlighted.asReadonly();\n\n public readonly nodes: ModelSignal<ReadonlyArray<IRtTree.Node<TValue>>> = model.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n /** Значения раскрытых веток; `null` — раскрыты все. Пара `openChange` приходит на каждое раскрытие. */\n public readonly open: ModelSignal<ReadonlyArray<TValue> | null> = model<ReadonlyArray<TValue> | null>(null);\n public readonly canDrop: InputSignal<IRtDraggableTree.CanDrop<TValue> | null> = input<IRtDraggableTree.CanDrop<TValue> | null>(null);\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly moved: OutputEmitterRef<IRtDraggableTree.Moved<TValue>> = output<IRtDraggableTree.Moved<TValue>>();\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /** Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой. */\n public handleKeydown(event: KeyboardEvent): boolean {\n const taken: boolean = event.altKey ? this.#moveByKey(event.key) : this.#walkByKey(event.key);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>): void {\n this.#highlighted.set(row.option.value);\n this.picked.emit(row.option);\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onDragStarted(value: TValue): void {\n this.#dragged.set(value);\n }\n\n protected onDragMoved(event: CdkDragMove<TValue>): void {\n this.drop.set(this.#dropAt(event.pointerPosition.y));\n }\n\n protected onDropped(): void {\n const dragged: TValue | null = this.#dragged();\n const drop: IRtDraggableTree.Drop<TValue> | null = this.drop();\n this.#dragged.set(null);\n this.drop.set(null);\n if (dragged !== null && drop) {\n this.#apply(dragged, drop);\n }\n }\n\n #dropAt(pointer: number): IRtDraggableTree.Drop<TValue> | null {\n const dragged: TValue | null = this.#dragged();\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const elements: ReadonlyArray<ElementRef<HTMLElement>> = this.rowElements();\n if (dragged === null) {\n return null;\n }\n const index: number = elements.findIndex((element: ElementRef<HTMLElement>, at: number): boolean => {\n const box: DOMRect = element.nativeElement.getBoundingClientRect();\n return rows[at]?.option.value !== dragged && pointer >= box.top && pointer < box.bottom;\n });\n if (index < 0) {\n return null;\n }\n const box: DOMRect = elements[index].nativeElement.getBoundingClientRect();\n const target: IRtTree.Node<TValue> = rows[index].option;\n const place: IRtDraggableTree.Place | null = rtDragPlace(target, box.top, box.height, pointer);\n const drop: IRtDraggableTree.Drop<TValue> | null = place ? { target: target.value, place } : null;\n return drop && rtDragAllowed(this.nodes(), dragged, drop, this.canDrop()) ? drop : null;\n }\n\n #moveByKey(key: string): boolean {\n const value: TValue | null = this.#highlighted();\n if (!MOVE_KEYS.includes(key)) {\n return false;\n }\n const node: IRtTree.Node<TValue> | undefined = this.rows().find(\n (row: IRtTree.Row<TValue>): boolean => row.option.value === value\n )?.option;\n const drop: IRtDraggableTree.Drop<TValue> | null = node && !node.disabled ? rtDragKeyPlace(this.nodes(), node.value, key) : null;\n if (node && drop && rtDragAllowed(this.nodes(), node.value, drop, this.canDrop())) {\n this.#apply(node.value, drop);\n }\n return true;\n }\n\n #walkByKey(key: string): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = rows.findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === this.#highlighted());\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#step(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n if (index < 0) {\n return false;\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\n const answer: IRtOptionTree.SideKeyAnswer<TValue> = rtTreeSideKey(rows, index, key);\n if (answer.toggle !== null) {\n this.#toggle(answer.toggle);\n }\n this.#highlighted.set(rows[answer.index].option.value);\n return true;\n }\n if (key === 'Enter') {\n this.picked.emit(rows[index].option);\n return true;\n }\n return false;\n }\n\n #step(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, step: number): boolean {\n if (rows.length === 0) {\n return false;\n }\n const next: number = index < 0 ? 0 : Math.min(rows.length - 1, Math.max(0, index + step));\n this.#highlighted.set(rows[next].option.value);\n return true;\n }\n\n #apply(value: TValue, drop: IRtDraggableTree.Drop<TValue>): void {\n const result: IRtDraggableTree.MoveResult<TValue> | null = rtDragMove(this.nodes(), value, drop);\n if (!result) {\n return;\n }\n this.nodes.set(result.nodes);\n if (drop.place === 'inside' && !this.openBranches().has(drop.target)) {\n this.open.set([...this.openBranches(), drop.target]);\n }\n this.moved.emit(result.moved);\n }\n\n #toggle(value: TValue): void {\n this.open.set([...rtTreeToggle(this.openBranches(), value)]);\n }\n\n #collectBranches(list: ReadonlyArray<IRtTree.Node<TValue>>, into: Set<TValue>): void {\n list.forEach((node: IRtTree.Node<TValue>): void => {\n if ((node.children ?? []).length > 0) {\n into.add(node.value);\n this.#collectBranches(node.children ?? [], into);\n }\n });\n }\n}\n","<ng-container rtBlock=\"rt-draggable-tree\">\n <!--\n Строки берут мышь через (click), клавиатура — на самом дереве (handleKeydown): строки фокус не\n берут, подсвеченная строка — состояние рядом с фокусом. Строку тянут за ручку; список один на\n всё дерево, и место сброса считает компонент по рамке строки под указателем.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div rtElem=\"list\" cdkDropList [cdkDropListSortingDisabled]=\"true\" (cdkDropListDropped)=\"onDropped()\">\n @for (row of rows(); track row.option.value) {\n <div\n #row\n rtElem=\"row\"\n qa-dataid=\"draggable-tree-row\"\n role=\"treeitem\"\n cdkDrag\n [cdkDragData]=\"row.option.value\"\n [cdkDragDisabled]=\"!!row.option.disabled\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"row.level + 1\"\n [attr.aria-expanded]=\"row.branch ? row.open : null\"\n [attr.aria-selected]=\"row.option.value === highlighted()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n [style.--rt-draggable-tree-level]=\"row.level\"\n [rtMod]=\"{\n highlighted: row.option.value === highlighted(),\n disabled: !!row.option.disabled,\n 'drop-before': drop()?.target === row.option.value && drop()?.place === 'before',\n 'drop-after': drop()?.target === row.option.value && drop()?.place === 'after',\n 'drop-inside': drop()?.target === row.option.value && drop()?.place === 'inside',\n }\"\n (cdkDragStarted)=\"onDragStarted(row.option.value)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (click)=\"onRowClick(row)\">\n @if (row.option.disabled) {\n <span rtElem=\"handle-space\"></span>\n } @else {\n <span rtElem=\"handle\" qa-dataid=\"draggable-tree-handle\" cdkDragHandle aria-hidden=\"true\">\n <rt-icon name=\"bars\" size=\"sm\" color=\"muted\" />\n </span>\n }\n\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"draggable-tree-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n <span rtElem=\"content\" qa-dataid=\"draggable-tree-content\">\n @if (nodeTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row.option }\" />\n } @else {\n <span rtElem=\"label\" qa-dataid=\"draggable-tree-label\" rtTooltipWhenTruncated [rtTooltip]=\"row.option.label\">\n {{ row.option.label }}\n </span>\n }\n </span>\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"draggable-tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"draggable-tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ t().uiNoOptions }}\n </div>\n }\n </div>\n</ng-container>\n"],"mappings":"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"}