@rt-tools/ui-kit-v2 0.23.3 → 0.24.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 (354) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +142 -71
  2. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +467 -231
  4. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +260 -91
  6. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +80 -46
  8. package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +984 -697
  10. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +452 -210
  12. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +143 -52
  14. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +158 -83
  16. package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +335 -0
  18. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -0
  19. package/fesm2022/rt-tools-ui-kit-v2-button.mjs +437 -363
  20. package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +430 -149
  22. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
  23. package/fesm2022/rt-tools-ui-kit-v2-card.mjs +155 -71
  24. package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -1
  25. package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs +155 -0
  26. package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs.map +1 -0
  27. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +215 -110
  28. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
  29. package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +158 -75
  30. package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -1
  31. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +769 -0
  32. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -0
  33. package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +462 -253
  34. package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -1
  35. package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1276 -1316
  36. package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
  37. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +185 -80
  38. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
  39. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2321 -2619
  40. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  41. package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +100 -44
  42. package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -1
  43. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +290 -155
  44. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -1
  45. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2097 -858
  46. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  47. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +2247 -1176
  48. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  49. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +1043 -705
  50. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  51. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +810 -525
  52. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  53. package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +158 -138
  54. package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -1
  55. package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +177 -67
  56. package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -1
  57. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +550 -477
  58. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -1
  59. package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +185 -168
  60. package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -1
  61. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +116 -43
  62. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -1
  63. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +585 -0
  64. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -0
  65. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +755 -259
  66. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  67. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +3266 -1115
  68. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  69. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +190 -55
  70. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -1
  71. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +283 -103
  72. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
  73. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +393 -177
  74. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  75. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +399 -207
  76. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  77. package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +288 -212
  78. package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -1
  79. package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +262 -116
  80. package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -1
  81. package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +57 -31
  82. package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -1
  83. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +258 -90
  84. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
  85. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +249 -215
  86. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
  87. package/fesm2022/rt-tools-ui-kit-v2-header.mjs +199 -71
  88. package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -1
  89. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +231 -0
  90. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -0
  91. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +336 -0
  92. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -0
  93. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +451 -162
  94. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  95. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +931 -686
  96. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
  97. package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +664 -491
  98. package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -1
  99. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +574 -222
  100. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
  101. package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +150 -36
  102. package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -1
  103. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +606 -0
  104. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -0
  105. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +461 -355
  106. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  107. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +338 -143
  108. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
  109. package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +135 -48
  110. package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -1
  111. package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +166 -92
  112. package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -1
  113. package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +118 -56
  114. package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -1
  115. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1054 -527
  116. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  117. package/fesm2022/rt-tools-ui-kit-v2-message.mjs +230 -104
  118. package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
  119. package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +210 -70
  120. package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -1
  121. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +532 -311
  122. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  123. package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +125 -50
  124. package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -1
  125. package/fesm2022/rt-tools-ui-kit-v2-note.mjs +73 -43
  126. package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -1
  127. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +161 -53
  128. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -1
  129. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +491 -310
  130. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  131. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +374 -174
  132. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
  133. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +202 -159
  134. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -1
  135. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +438 -309
  136. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -1
  137. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +295 -0
  138. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -0
  139. package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +135 -45
  140. package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -1
  141. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +293 -171
  142. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
  143. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +62 -55
  144. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -1
  145. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +3379 -1466
  146. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  147. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +114 -116
  148. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -1
  149. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +406 -299
  150. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  151. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +137 -36
  152. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -1
  153. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +687 -468
  154. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  155. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +2195 -1569
  156. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  157. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +187 -48
  158. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -1
  159. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +242 -122
  160. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -1
  161. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +439 -0
  162. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -0
  163. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +218 -69
  164. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -1
  165. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +292 -91
  166. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -1
  167. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +225 -138
  168. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -1
  169. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +150 -116
  170. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
  171. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2462 -1583
  172. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  173. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +647 -346
  174. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  175. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +335 -121
  176. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  177. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +217 -84
  178. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
  179. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +151 -72
  180. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
  181. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +697 -226
  182. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  183. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +92 -38
  184. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -1
  185. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +752 -338
  186. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  187. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +310 -129
  188. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  189. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +286 -158
  190. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -1
  191. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +270 -134
  192. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  193. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +322 -202
  194. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  195. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +908 -0
  196. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -0
  197. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +785 -0
  198. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -0
  199. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +118 -63
  200. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -1
  201. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +783 -262
  202. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  203. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +633 -294
  204. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  205. package/fesm2022/rt-tools-ui-kit-v2.mjs +100 -103
  206. package/package.json +45 -1
  207. package/src/assets/icons/collapse-all.svg +9 -0
  208. package/src/assets/icons/expand-all.svg +9 -0
  209. package/src/assets/icons-material/collapse-all.fill.svg +5 -0
  210. package/src/assets/icons-material/collapse-all.svg +5 -0
  211. package/src/assets/icons-material/expand-all.fill.svg +5 -0
  212. package/src/assets/icons-material/expand-all.svg +5 -0
  213. package/src/assets/icons-material/undo.fill.svg +5 -0
  214. package/src/assets/icons-material/undo.svg +5 -0
  215. package/src/lib/components/bottom-sheet/CONTEXT.md +20 -2
  216. package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +36 -1
  217. package/src/lib/components/breadcrumbs/CONTEXT.md +37 -0
  218. package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +205 -0
  219. package/src/lib/components/carousel/CONTEXT.md +42 -0
  220. package/src/lib/components/carousel/rt-carousel.component.scss +117 -0
  221. package/src/lib/components/checkbox/CONTEXT.md +3 -0
  222. package/src/lib/components/checkbox/rt-checkbox.component.scss +9 -3
  223. package/src/lib/components/color-palette/CONTEXT.md +49 -0
  224. package/src/lib/components/color-palette/picker/rt-color-picker.component.scss +161 -0
  225. package/src/lib/components/color-palette/rt-color-palette.component.scss +132 -0
  226. package/src/lib/components/draggable-tree/CONTEXT.md +54 -0
  227. package/src/lib/components/draggable-tree/rt-draggable-tree.component.scss +219 -0
  228. package/src/lib/components/hybrid-tree/CONTEXT.md +31 -0
  229. package/src/lib/components/hybrid-tree-selector/CONTEXT.md +25 -0
  230. package/src/lib/components/icon-button/CONTEXT.md +3 -0
  231. package/src/lib/components/inline-edit/CONTEXT.md +41 -0
  232. package/src/lib/components/inline-edit/rt-inline-edit.component.scss +274 -0
  233. package/src/lib/components/popover/CONTEXT.md +3 -0
  234. package/src/lib/components/profile-menu/CONTEXT.md +32 -0
  235. package/src/lib/components/profile-menu/rt-profile-menu.component.scss +104 -0
  236. package/src/lib/components/speed-menu/CONTEXT.md +34 -0
  237. package/src/lib/components/speed-menu/rt-speed-menu.component.scss +118 -0
  238. package/src/lib/components/tag/rt-tag.component.scss +12 -0
  239. package/src/lib/components/thread-list/CONTEXT.md +1 -0
  240. package/src/lib/components/thread-list/rt-thread-list.component.scss +2 -1
  241. package/src/lib/components/toolbar/CONTEXT.md +9 -4
  242. package/src/lib/components/toolbar/rt-toolbar.component.scss +10 -2
  243. package/src/lib/components/tooltip/CONTEXT.md +8 -1
  244. package/src/lib/components/tree/CONTEXT.md +66 -0
  245. package/src/lib/components/tree/rt-tree.component.scss +313 -0
  246. package/src/lib/components/tree-selector/CONTEXT.md +47 -0
  247. package/src/lib/components/tree-selector/rt-tree-selector.component.scss +121 -0
  248. package/src/styles/_primitives.scss +4 -0
  249. package/src/styles/_semantic.scss +5 -0
  250. package/styles/tokens.css +43 -0
  251. package/types/rt-tools-ui-kit-v2-accordion.d.ts +31 -24
  252. package/types/rt-tools-ui-kit-v2-action-bar.d.ts +112 -91
  253. package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +64 -40
  254. package/types/rt-tools-ui-kit-v2-aside-section.d.ts +13 -10
  255. package/types/rt-tools-ui-kit-v2-aside.d.ts +268 -206
  256. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +102 -61
  257. package/types/rt-tools-ui-kit-v2-bar-list.d.ts +39 -27
  258. package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +31 -20
  259. package/types/rt-tools-ui-kit-v2-breadcrumbs.d.ts +89 -0
  260. package/types/rt-tools-ui-kit-v2-button.d.ts +119 -59
  261. package/types/rt-tools-ui-kit-v2-calendar.d.ts +151 -86
  262. package/types/rt-tools-ui-kit-v2-card.d.ts +42 -21
  263. package/types/rt-tools-ui-kit-v2-carousel.d.ts +76 -0
  264. package/types/rt-tools-ui-kit-v2-checkbox.d.ts +48 -24
  265. package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +28 -20
  266. package/types/rt-tools-ui-kit-v2-color-palette.d.ts +208 -0
  267. package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +104 -47
  268. package/types/rt-tools-ui-kit-v2-container.d.ts +278 -221
  269. package/types/rt-tools-ui-kit-v2-copy-value.d.ts +39 -24
  270. package/types/rt-tools-ui-kit-v2-core.d.ts +862 -865
  271. package/types/rt-tools-ui-kit-v2-counter-row.d.ts +20 -12
  272. package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -38
  273. package/types/rt-tools-ui-kit-v2-data-list.d.ts +429 -264
  274. package/types/rt-tools-ui-kit-v2-data-table.d.ts +500 -351
  275. package/types/rt-tools-ui-kit-v2-date-picker.d.ts +164 -138
  276. package/types/rt-tools-ui-kit-v2-date-range.d.ts +102 -84
  277. package/types/rt-tools-ui-kit-v2-delta-view.d.ts +16 -13
  278. package/types/rt-tools-ui-kit-v2-detail-list.d.ts +23 -16
  279. package/types/rt-tools-ui-kit-v2-dialog.d.ts +130 -101
  280. package/types/rt-tools-ui-kit-v2-dot-field.d.ts +10 -13
  281. package/types/rt-tools-ui-kit-v2-download-link.d.ts +22 -17
  282. package/types/rt-tools-ui-kit-v2-draggable-tree.d.ts +132 -0
  283. package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +185 -96
  284. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +904 -404
  285. package/types/rt-tools-ui-kit-v2-empty-state.d.ts +48 -19
  286. package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +67 -39
  287. package/types/rt-tools-ui-kit-v2-field.d.ts +90 -49
  288. package/types/rt-tools-ui-kit-v2-file-card.d.ts +115 -75
  289. package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -48
  290. package/types/rt-tools-ui-kit-v2-file-input.d.ts +53 -36
  291. package/types/rt-tools-ui-kit-v2-file-list.d.ts +5 -8
  292. package/types/rt-tools-ui-kit-v2-filter-control.d.ts +83 -49
  293. package/types/rt-tools-ui-kit-v2-form-control.d.ts +102 -74
  294. package/types/rt-tools-ui-kit-v2-header.d.ts +40 -22
  295. package/types/rt-tools-ui-kit-v2-hybrid-tree-selector.d.ts +14 -0
  296. package/types/rt-tools-ui-kit-v2-hybrid-tree.d.ts +72 -0
  297. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +190 -90
  298. package/types/rt-tools-ui-kit-v2-icon.d.ts +160 -129
  299. package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +151 -111
  300. package/types/rt-tools-ui-kit-v2-image-upload.d.ts +159 -85
  301. package/types/rt-tools-ui-kit-v2-info-item.d.ts +26 -13
  302. package/types/rt-tools-ui-kit-v2-inline-edit.d.ts +194 -0
  303. package/types/rt-tools-ui-kit-v2-input-number.d.ts +102 -53
  304. package/types/rt-tools-ui-kit-v2-input.d.ts +82 -43
  305. package/types/rt-tools-ui-kit-v2-live-badge.d.ts +30 -17
  306. package/types/rt-tools-ui-kit-v2-logo.d.ts +49 -32
  307. package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +26 -17
  308. package/types/rt-tools-ui-kit-v2-menu.d.ts +272 -155
  309. package/types/rt-tools-ui-kit-v2-message.d.ts +59 -33
  310. package/types/rt-tools-ui-kit-v2-money-list.d.ts +36 -18
  311. package/types/rt-tools-ui-kit-v2-multiselect.d.ts +114 -80
  312. package/types/rt-tools-ui-kit-v2-night-grid.d.ts +34 -25
  313. package/types/rt-tools-ui-kit-v2-note.d.ts +12 -9
  314. package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +37 -16
  315. package/types/rt-tools-ui-kit-v2-page-header.d.ts +218 -150
  316. package/types/rt-tools-ui-kit-v2-pagination.d.ts +99 -63
  317. package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +61 -66
  318. package/types/rt-tools-ui-kit-v2-popover.d.ts +116 -55
  319. package/types/rt-tools-ui-kit-v2-profile-menu.d.ts +103 -0
  320. package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +26 -16
  321. package/types/rt-tools-ui-kit-v2-radio-button.d.ts +85 -43
  322. package/types/rt-tools-ui-kit-v2-radius.d.ts +18 -15
  323. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +931 -590
  324. package/types/rt-tools-ui-kit-v2-ripple.d.ts +28 -25
  325. package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +60 -58
  326. package/types/rt-tools-ui-kit-v2-section-nav.d.ts +32 -22
  327. package/types/rt-tools-ui-kit-v2-select.d.ts +182 -139
  328. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +452 -349
  329. package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +53 -20
  330. package/types/rt-tools-ui-kit-v2-skeleton.d.ts +55 -26
  331. package/types/rt-tools-ui-kit-v2-speed-menu.d.ts +131 -0
  332. package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -28
  333. package/types/rt-tools-ui-kit-v2-split-button.d.ts +96 -55
  334. package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +88 -60
  335. package/types/rt-tools-ui-kit-v2-stepper.d.ts +50 -37
  336. package/types/rt-tools-ui-kit-v2-table.d.ts +631 -480
  337. package/types/rt-tools-ui-kit-v2-tabs.d.ts +198 -113
  338. package/types/rt-tools-ui-kit-v2-tag.d.ts +106 -53
  339. package/types/rt-tools-ui-kit-v2-textarea.d.ts +48 -25
  340. package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +28 -26
  341. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +154 -94
  342. package/types/rt-tools-ui-kit-v2-timeline.d.ts +30 -28
  343. package/types/rt-tools-ui-kit-v2-toast.d.ts +174 -98
  344. package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +132 -86
  345. package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +88 -50
  346. package/types/rt-tools-ui-kit-v2-toolbar.d.ts +30 -27
  347. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +65 -41
  348. package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +257 -0
  349. package/types/rt-tools-ui-kit-v2-tree.d.ts +282 -0
  350. package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +21 -24
  351. package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +195 -124
  352. package/types/rt-tools-ui-kit-v2-workspace.d.ts +122 -79
  353. package/types/rt-tools-ui-kit-v2.d.ts +100 -90
  354. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-file-drop.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.html","../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-tools-ui-kit-v2-file-drop.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n HostListener,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtFileDrop } from './rt-file-drop.model';\n\nconst BEM_BLOCK: string = 'rt-file-drop';\n\n/** Задержка скрытия оверлея: dragleave стреляет при переходе между дочерними\n элементами, без debounce рамка мерцает. */\nconst DRAG_LEAVE_DEBOUNCE_MS: number = 80;\n\n/**\n * Зона перетаскивания файлов: оборачивает произвольный контент через\n * content-projection и превращает его в drop-зону. При перетаскивании файла над\n * областью рисует приглушающий оверлей-приглашение поверх контента, на drop —\n * эмитит выброшенные файлы через `(filesDropped)`.\n *\n * Мультизонный режим: при непустом `zones` оверлей делится на вертикальную стопку\n * равных зон с подписями; зона под курсором подсвечивается, drop эмитится через\n * `(zoneFilesDropped)` с id зоны (а `(filesDropped)` в этом режиме НЕ эмитится).\n * Зона курсора вычисляется по Y-координате против host-rect — оверлей остаётся\n * pointer-events:none, drag-события продолжают идти в host-listener'ы.\n *\n * `accept` (формат как у нативного input[accept]) отфильтровывает неподходящие\n * файлы до эмита — drop в обход файл-пикера не проносит запрещённые расширения;\n * отбрасывание молчаливое, как у самого пикера.\n *\n * Слушает drag-события на собственном host'е (всплывают со всего спроецированного\n * контента), гасит браузерный навигейт по файлу и принимает только перетаскивание\n * файлов (а не внутренний drag элементов формы). Потребитель управляет приёмом\n * через `[disabled]` (например «активна вкладка файлов и форма редактируема») и\n * сам решает, что делать с файлами — компонент состояние файлов не хранит.\n *\n * Оверлей `pointer-events: none` — не перехватывает drag/drop, события доходят до\n * host-listener'ов.\n */\n@Component({\n selector: 'rt-file-drop',\n templateUrl: './rt-file-drop.component.html',\n styleUrl: './rt-file-drop.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtFileDropComponent {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n\n readonly #t_uiFileDropOverlay: Signal<string> = rtKitLabel('uiFileDropOverlay');\n\n #dragLeaveTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Активна ли подсветка drop-зоны (файл тащат над областью). */\n protected readonly isDragging: WritableSignal<boolean> = signal(false);\n\n /** Зона под курсором в мультизонном режиме (id из `zones`). */\n protected readonly activeZoneId: WritableSignal<string | null> = signal(null);\n\n protected readonly hasZones: Signal<boolean> = computed((): boolean => this.zones().length > 0);\n\n protected readonly overlayText: Signal<string> = computed((): string => this.overlayLabel() || this.#t_uiFileDropOverlay());\n\n /** Приём drop'а выключен (потребитель решает по своему контексту). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly overlayLabel: InputSignal<string> = input<string>('');\n\n /** Мультизонный режим: непустой список зон делит оверлей на стопку целей. */\n public readonly zones: InputSignal<readonly IRtFileDrop.Zone[]> = input<readonly IRtFileDrop.Zone[]>([]);\n\n /** Фильтр расширений/MIME (формат нативного input[accept]); пусто — без фильтра. */\n public readonly accept: InputSignal<string> = input<string>('');\n\n public readonly filesDropped: OutputEmitterRef<File[]> = output<File[]>();\n\n /** Drop в мультизонном режиме: файлы + id зоны, куда их бросили. */\n public readonly zoneFilesDropped: OutputEmitterRef<IRtFileDrop.ZoneDrop> = output<IRtFileDrop.ZoneDrop>();\n\n public readonly draggingChange: OutputEmitterRef<boolean> = output<boolean>();\n\n constructor() {\n this.#destroyRef.onDestroy((): void => this.#clearLeaveTimer());\n }\n\n @HostListener('dragenter', ['$event'])\n @HostListener('dragover', ['$event'])\n protected onDragOver(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n this.#clearLeaveTimer();\n this.#setDragging(true);\n if (this.hasZones()) {\n this.activeZoneId.set(this.#zoneIdAt(event.clientY));\n }\n }\n\n @HostListener('dragleave', ['$event'])\n protected onDragLeave(event: DragEvent): void {\n if (!this.isDragging()) {\n return;\n }\n event.preventDefault();\n this.#clearLeaveTimer();\n this.#dragLeaveTimer = setTimeout((): void => {\n this.#dragLeaveTimer = null;\n this.#setDragging(false);\n }, DRAG_LEAVE_DEBOUNCE_MS);\n }\n\n @HostListener('drop', ['$event'])\n protected onDrop(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.#clearLeaveTimer();\n this.#setDragging(false);\n\n const files: File[] = Array.from(event.dataTransfer?.files ?? []).filter((file: File): boolean => this.#matchesAccept(file));\n if (files.length === 0) {\n return;\n }\n if (!this.hasZones()) {\n this.filesDropped.emit(files);\n return;\n }\n const zoneId: string | null = this.#zoneIdAt(event.clientY);\n if (zoneId === null) {\n return;\n }\n this.zoneFilesDropped.emit({ zoneId, files });\n }\n\n /** Меняет dragging-флаг и эмитит изменение только при реальном переходе. */\n #setDragging(value: boolean): void {\n if (this.isDragging() === value) {\n return;\n }\n this.isDragging.set(value);\n this.draggingChange.emit(value);\n if (!value) {\n this.activeZoneId.set(null);\n }\n }\n\n /** Зона по Y-координате курсора: стопка равных по высоте полос host-rect. */\n #zoneIdAt(clientY: number): string | null {\n const zones: readonly IRtFileDrop.Zone[] = this.zones();\n if (zones.length === 0) {\n return null;\n }\n const rect: DOMRect = this.#host.nativeElement.getBoundingClientRect();\n if (rect.height <= 0) {\n return zones[0].id;\n }\n const ratio: number = (clientY - rect.top) / rect.height;\n const index: number = Math.min(zones.length - 1, Math.max(0, Math.floor(ratio * zones.length)));\n return zones[index].id;\n }\n\n /** Файл проходит accept-фильтр (расширение `.pdf` / MIME `image/png` / `image/*`). */\n #matchesAccept(file: File): boolean {\n const accept: string = this.accept().trim();\n if (accept === '') {\n return true;\n }\n const name: string = file.name.toLowerCase();\n const mime: string = file.type.toLowerCase();\n return accept.split(',').some((raw: string): boolean => {\n const token: string = raw.trim().toLowerCase();\n if (token === '') {\n return false;\n }\n if (token.startsWith('.')) {\n return name.endsWith(token);\n }\n if (token.endsWith('/*')) {\n return mime.startsWith(token.slice(0, -1));\n }\n return mime === token;\n });\n }\n\n /** Перетаскивают именно файлы (а не внутренний drag элементов формы). */\n #isFileDrag(event: DragEvent): boolean {\n const types: readonly string[] | undefined = event.dataTransfer?.types;\n return types?.includes('Files') ?? false;\n }\n\n #clearLeaveTimer(): void {\n if (this.#dragLeaveTimer !== null) {\n clearTimeout(this.#dragLeaveTimer);\n this.#dragLeaveTimer = null;\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-drop\">\n <ng-content />\n\n @if (isDragging()) {\n <div rtElem=\"overlay\" qa-dataid=\"file-drop-overlay\" aria-hidden=\"true\" [rtMod]=\"{ zoned: hasZones() }\">\n @if (hasZones()) {\n @for (zone of zones(); track zone.id) {\n <div\n rtElem=\"zone\"\n qa-dataid=\"file-drop-zone\"\n [attr.data-zone]=\"zone.id\"\n [attr.data-active]=\"activeZoneId() === zone.id\"\n [rtMod]=\"{ active: activeZoneId() === zone.id }\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-zone-label\">{{ zone.label }}</span>\n @if (zone.sublabel) {\n <span rtElem=\"sublabel\" qa-dataid=\"file-drop-zone-sublabel\">{{ zone.sublabel }}</span>\n }\n </div>\n }\n } @else {\n <div rtElem=\"frame\" qa-dataid=\"file-drop-frame\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-label\">{{ overlayText() }}</span>\n </div>\n }\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-file-drop.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.html"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n HostListener,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtFileDrop } from './rt-file-drop.model';\n\nconst BEM_BLOCK: string = 'rt-file-drop';\n\n/** Задержка скрытия оверлея: dragleave стреляет при переходе между дочерними\n элементами, без debounce рамка мерцает. */\nconst DRAG_LEAVE_DEBOUNCE_MS: number = 80;\n\n/**\n * Зона перетаскивания файлов: оборачивает произвольный контент через\n * content-projection и превращает его в drop-зону. При перетаскивании файла над\n * областью рисует приглушающий оверлей-приглашение поверх контента, на drop —\n * эмитит выброшенные файлы через `(filesDropped)`.\n *\n * Мультизонный режим: при непустом `zones` оверлей делится на вертикальную стопку\n * равных зон с подписями; зона под курсором подсвечивается, drop эмитится через\n * `(zoneFilesDropped)` с id зоны (а `(filesDropped)` в этом режиме НЕ эмитится).\n * Зона курсора вычисляется по Y-координате против host-rect — оверлей остаётся\n * pointer-events:none, drag-события продолжают идти в host-listener'ы.\n *\n * `accept` (формат как у нативного input[accept]) отфильтровывает неподходящие\n * файлы до эмита — drop в обход файл-пикера не проносит запрещённые расширения;\n * отбрасывание молчаливое, как у самого пикера.\n *\n * Слушает drag-события на собственном host'е (всплывают со всего спроецированного\n * контента), гасит браузерный навигейт по файлу и принимает только перетаскивание\n * файлов (а не внутренний drag элементов формы). Потребитель управляет приёмом\n * через `[disabled]` (например «активна вкладка файлов и форма редактируема») и\n * сам решает, что делать с файлами — компонент состояние файлов не хранит.\n *\n * Оверлей `pointer-events: none` — не перехватывает drag/drop, события доходят до\n * host-listener'ов.\n */\n@Component({\n selector: 'rt-file-drop',\n templateUrl: './rt-file-drop.component.html',\n styleUrl: './rt-file-drop.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtFileDropComponent {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n\n readonly #t_uiFileDropOverlay: Signal<string> = rtKitLabel('uiFileDropOverlay');\n\n #dragLeaveTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Активна ли подсветка drop-зоны (файл тащат над областью). */\n protected readonly isDragging: WritableSignal<boolean> = signal(false);\n\n /** Зона под курсором в мультизонном режиме (id из `zones`). */\n protected readonly activeZoneId: WritableSignal<string | null> = signal(null);\n\n protected readonly hasZones: Signal<boolean> = computed((): boolean => this.zones().length > 0);\n\n protected readonly overlayText: Signal<string> = computed((): string => this.overlayLabel() || this.#t_uiFileDropOverlay());\n\n /** Приём drop'а выключен (потребитель решает по своему контексту). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly overlayLabel: InputSignal<string> = input<string>('');\n\n /** Мультизонный режим: непустой список зон делит оверлей на стопку целей. */\n public readonly zones: InputSignal<readonly IRtFileDrop.Zone[]> = input<readonly IRtFileDrop.Zone[]>([]);\n\n /** Фильтр расширений/MIME (формат нативного input[accept]); пусто — без фильтра. */\n public readonly accept: InputSignal<string> = input<string>('');\n\n public readonly filesDropped: OutputEmitterRef<File[]> = output<File[]>();\n\n /** Drop в мультизонном режиме: файлы + id зоны, куда их бросили. */\n public readonly zoneFilesDropped: OutputEmitterRef<IRtFileDrop.ZoneDrop> = output<IRtFileDrop.ZoneDrop>();\n\n public readonly draggingChange: OutputEmitterRef<boolean> = output<boolean>();\n\n constructor() {\n this.#destroyRef.onDestroy((): void => this.#clearLeaveTimer());\n }\n\n @HostListener('dragenter', ['$event'])\n @HostListener('dragover', ['$event'])\n protected onDragOver(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n this.#clearLeaveTimer();\n this.#setDragging(true);\n if (this.hasZones()) {\n this.activeZoneId.set(this.#zoneIdAt(event.clientY));\n }\n }\n\n @HostListener('dragleave', ['$event'])\n protected onDragLeave(event: DragEvent): void {\n if (!this.isDragging()) {\n return;\n }\n event.preventDefault();\n this.#clearLeaveTimer();\n this.#dragLeaveTimer = setTimeout((): void => {\n this.#dragLeaveTimer = null;\n this.#setDragging(false);\n }, DRAG_LEAVE_DEBOUNCE_MS);\n }\n\n @HostListener('drop', ['$event'])\n protected onDrop(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.#clearLeaveTimer();\n this.#setDragging(false);\n\n const files: File[] = Array.from(event.dataTransfer?.files ?? []).filter((file: File): boolean => this.#matchesAccept(file));\n if (files.length === 0) {\n return;\n }\n if (!this.hasZones()) {\n this.filesDropped.emit(files);\n return;\n }\n const zoneId: string | null = this.#zoneIdAt(event.clientY);\n if (zoneId === null) {\n return;\n }\n this.zoneFilesDropped.emit({ zoneId, files });\n }\n\n /** Меняет dragging-флаг и эмитит изменение только при реальном переходе. */\n #setDragging(value: boolean): void {\n if (this.isDragging() === value) {\n return;\n }\n this.isDragging.set(value);\n this.draggingChange.emit(value);\n if (!value) {\n this.activeZoneId.set(null);\n }\n }\n\n /** Зона по Y-координате курсора: стопка равных по высоте полос host-rect. */\n #zoneIdAt(clientY: number): string | null {\n const zones: readonly IRtFileDrop.Zone[] = this.zones();\n if (zones.length === 0) {\n return null;\n }\n const rect: DOMRect = this.#host.nativeElement.getBoundingClientRect();\n if (rect.height <= 0) {\n return zones[0].id;\n }\n const ratio: number = (clientY - rect.top) / rect.height;\n const index: number = Math.min(zones.length - 1, Math.max(0, Math.floor(ratio * zones.length)));\n return zones[index].id;\n }\n\n /** Файл проходит accept-фильтр (расширение `.pdf` / MIME `image/png` / `image/*`). */\n #matchesAccept(file: File): boolean {\n const accept: string = this.accept().trim();\n if (accept === '') {\n return true;\n }\n const name: string = file.name.toLowerCase();\n const mime: string = file.type.toLowerCase();\n return accept.split(',').some((raw: string): boolean => {\n const token: string = raw.trim().toLowerCase();\n if (token === '') {\n return false;\n }\n if (token.startsWith('.')) {\n return name.endsWith(token);\n }\n if (token.endsWith('/*')) {\n return mime.startsWith(token.slice(0, -1));\n }\n return mime === token;\n });\n }\n\n /** Перетаскивают именно файлы (а не внутренний drag элементов формы). */\n #isFileDrag(event: DragEvent): boolean {\n const types: readonly string[] | undefined = event.dataTransfer?.types;\n return types?.includes('Files') ?? false;\n }\n\n #clearLeaveTimer(): void {\n if (this.#dragLeaveTimer !== null) {\n clearTimeout(this.#dragLeaveTimer);\n this.#dragLeaveTimer = null;\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-drop\">\n <ng-content />\n\n @if (isDragging()) {\n <div rtElem=\"overlay\" qa-dataid=\"file-drop-overlay\" aria-hidden=\"true\" [rtMod]=\"{ zoned: hasZones() }\">\n @if (hasZones()) {\n @for (zone of zones(); track zone.id) {\n <div\n rtElem=\"zone\"\n qa-dataid=\"file-drop-zone\"\n [attr.data-zone]=\"zone.id\"\n [attr.data-active]=\"activeZoneId() === zone.id\"\n [rtMod]=\"{ active: activeZoneId() === zone.id }\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-zone-label\">{{ zone.label }}</span>\n @if (zone.sublabel) {\n <span rtElem=\"sublabel\" qa-dataid=\"file-drop-zone-sublabel\">{{ zone.sublabel }}</span>\n }\n </div>\n }\n } @else {\n <div rtElem=\"frame\" qa-dataid=\"file-drop-frame\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-label\">{{ overlayText() }}</span>\n </div>\n }\n </div>\n }\n</ng-container>\n"],"mappings":"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"}
@@ -1,117 +1,263 @@
1
- import * as i0 from '@angular/core';
2
- import { viewChild, computed, input, booleanAttribute, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
4
- import { rtKitLabel } from '@rt-tools/ui-kit-v2/core';
5
- import { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';
6
- import { RtFileCardComponent } from '@rt-tools/ui-kit-v2/file-card';
7
- import { RtFileListComponent } from '@rt-tools/ui-kit-v2/file-list';
8
- import { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';
9
-
10
- const BEM_BLOCK = 'rt-file-input';
11
- /**
12
- * Поле выбора файлов: кнопка «выбрать» + список выбранных файлов карточками
13
- * `rt-file-card` (иконка типа, имя, размер, удаление). Скрывает нативный
14
- * `<input type="file">`, value хранит как `File[]` (одиночный режим = максимум
15
- * один файл). CVA через общий `RtFormControlBase`. Read-only представление —
16
- * имена файлов через запятую.
17
- *
18
- * Без drag-drop (MVP). `accept` пробрасывается в нативный input, `multiple`
19
- * включает множественный выбор.
20
- */
21
- class RtFileInputComponent extends RtFormControlBase {
22
- constructor() {
23
- super(...arguments);
24
- this.#t_uiChooseFile = rtKitLabel('uiChooseFile');
25
- this.fileEl = viewChild('fileEl', /* @ts-ignore */
26
- ...(ngDevMode ? [{ debugName: "fileEl" }] : /* istanbul ignore next */ []));
27
- this.buttonText = computed(() => this.buttonLabel() || this.#t_uiChooseFile(), /* @ts-ignore */
28
- ...(ngDevMode ? [{ debugName: "buttonText" }] : /* istanbul ignore next */ []));
29
- this.hasValue = computed(() => this.value().length > 0, /* @ts-ignore */
30
- ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
31
- this.displayText = computed(() => this.value()
32
- .map((f) => f.name)
33
- .join(', '), /* @ts-ignore */
34
- ...(ngDevMode ? [{ debugName: "displayText" }] : /* istanbul ignore next */ []));
35
- this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
36
- this.accept = input(null, /* @ts-ignore */
37
- ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
38
- /**
39
- * Выбор каталога целиком вместо отдельных файлов. Браузер отдаёт
40
- * относительные пути (`webkitRelativePath`), по ним вызывающая сторона
41
- * восстанавливает структуру — иначе пользователю пришлось бы выбирать
42
- * десятки файлов по одному.
43
- */
44
- this.directory = input(false, { ...(ngDevMode ? { debugName: "directory" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
45
- /** Пусто — берётся переведённая подпись по умолчанию */
46
- this.buttonLabel = input('', /* @ts-ignore */
47
- ...(ngDevMode ? [{ debugName: "buttonLabel" }] : /* istanbul ignore next */ []));
48
- }
49
- #t_uiChooseFile;
50
- getEmptyValue() {
51
- return [];
52
- }
53
- focusAfterClear() {
54
- // Скрытый native input фокусировать бессмысленно — фокус остаётся на кнопке.
55
- }
56
- openPicker() {
57
- if (this.isDisabled()) {
58
- return;
59
- }
60
- this.fileEl()?.nativeElement.click();
61
- }
62
- onFiles(event) {
63
- const list = event.target.files;
64
- const files = list ? Array.from(list) : [];
65
- const next = this.multiple() ? files : files.slice(0, 1);
66
- this.value.set(next);
67
- this.emitChange(next);
68
- this.markTouched();
69
- }
70
- removeFile(index) {
71
- if (this.isDisabled()) {
72
- return;
73
- }
74
- const next = this.value().filter((_, i) => i !== index);
75
- this.value.set(next);
76
- this.emitChange(next);
77
- // Сбрасываем native input, иначе повторный выбор того же файла не сработает.
78
- const el = this.fileEl()?.nativeElement;
79
- if (el) {
80
- el.value = '';
81
- }
82
- }
83
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
84
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFileInputComponent, isStandalone: true, selector: "rt-file-input", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-file-input--disabled": "isDisabled()", "class.rt-file-input--invalid": "isInvalid()", "class.rt-file-input--readonly": "isReadonly()" }, classAttribute: "rt-file-input" }, providers: [
85
- // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.
86
- { provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },
87
- ], viewQueries: [{ propertyName: "fileEl", first: true, predicate: ["fileEl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '\u2014' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"], dependencies: [{ kind: "directive", type:
88
- // standalone components / directives
89
- RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "loadingLabel", "pressed"] }, { kind: "component", type: RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtFileListComponent, selector: "rt-file-list" }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
90
- }
91
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileInputComponent, decorators: [{
92
- type: Component,
93
- args: [{ selector: 'rt-file-input', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
94
- // standalone components / directives
95
- RtButtonDirective,
96
- RtFileCardComponent,
97
- RtFileListComponent,
98
- BlockDirective,
99
- ElemDirective,
100
- ModDirective,
101
- ], providers: [
102
- // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.
103
- { provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },
104
- ], host: {
105
- class: BEM_BLOCK,
106
- '[class.rt-file-input--disabled]': 'isDisabled()',
107
- '[class.rt-file-input--invalid]': 'isInvalid()',
108
- '[class.rt-file-input--readonly]': 'isReadonly()',
109
- }, template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '\u2014' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"] }]
110
- }], propDecorators: { fileEl: [{ type: i0.ViewChild, args: ['fileEl', { isSignal: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }] } });
111
-
112
- /**
113
- * Generated bundle index. Do not edit.
114
- */
115
-
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, ViewEncapsulation, booleanAttribute, computed, forwardRef, input, viewChild } from "@angular/core";
3
+ import { BlockDirective, ElemDirective, ModDirective } from "@rt-tools/core";
4
+ import { rtKitLabel } from "@rt-tools/ui-kit-v2/core";
5
+ import { RtButtonDirective } from "@rt-tools/ui-kit-v2/button";
6
+ import { RtFileCardComponent } from "@rt-tools/ui-kit-v2/file-card";
7
+ import { RtFileListComponent } from "@rt-tools/ui-kit-v2/file-list";
8
+ import { RtFormControlBase } from "@rt-tools/ui-kit-v2/form-control";
9
+ const BEM_BLOCK = "rt-file-input";
10
+ var RtFileInputComponent = class RtFileInputComponent extends RtFormControlBase {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.#t_uiChooseFile = rtKitLabel("uiChooseFile");
14
+ this.fileEl = viewChild("fileEl", ...ngDevMode ? [{ debugName: "fileEl" }] : /* istanbul ignore next */ []);
15
+ this.buttonText = computed(() => this.buttonLabel() || this.#t_uiChooseFile(), ...ngDevMode ? [{ debugName: "buttonText" }] : /* istanbul ignore next */ []);
16
+ this.hasValue = computed(() => this.value().length > 0, ...ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []);
17
+ this.displayText = computed(() => this.value().map((f) => f.name).join(", "), ...ngDevMode ? [{ debugName: "displayText" }] : /* istanbul ignore next */ []);
18
+ this.multiple = input(false, {
19
+ ...ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {},
20
+ transform: booleanAttribute
21
+ });
22
+ this.accept = input(null, ...ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []);
23
+ this.directory = input(false, {
24
+ ...ngDevMode ? { debugName: "directory" } : /* istanbul ignore next */ {},
25
+ transform: booleanAttribute
26
+ });
27
+ this.buttonLabel = input("", ...ngDevMode ? [{ debugName: "buttonLabel" }] : /* istanbul ignore next */ []);
28
+ }
29
+ #t_uiChooseFile;
30
+ getEmptyValue() {
31
+ return [];
32
+ }
33
+ focusAfterClear() {}
34
+ openPicker() {
35
+ if (this.isDisabled()) return;
36
+ this.fileEl()?.nativeElement.click();
37
+ }
38
+ onFiles(event) {
39
+ const list = event.target.files;
40
+ const files = list ? Array.from(list) : [];
41
+ const next = this.multiple() ? files : files.slice(0, 1);
42
+ this.value.set(next);
43
+ this.emitChange(next);
44
+ this.markTouched();
45
+ }
46
+ removeFile(index) {
47
+ if (this.isDisabled()) return;
48
+ const next = this.value().filter((_, i) => i !== index);
49
+ this.value.set(next);
50
+ this.emitChange(next);
51
+ const el = this.fileEl()?.nativeElement;
52
+ if (el) el.value = "";
53
+ }
54
+ static {
55
+ this.ɵfac = i0.ɵɵngDeclareFactory({
56
+ minVersion: "12.0.0",
57
+ version: "22.2.2",
58
+ ngImport: i0,
59
+ type: RtFileInputComponent,
60
+ deps: null,
61
+ target: i0.ɵɵFactoryTarget.Component
62
+ });
63
+ }
64
+ static {
65
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
66
+ minVersion: "17.0.0",
67
+ version: "22.2.2",
68
+ type: RtFileInputComponent,
69
+ isStandalone: true,
70
+ selector: "rt-file-input",
71
+ inputs: {
72
+ multiple: {
73
+ classPropertyName: "multiple",
74
+ publicName: "multiple",
75
+ isSignal: true,
76
+ isRequired: false,
77
+ transformFunction: null
78
+ },
79
+ accept: {
80
+ classPropertyName: "accept",
81
+ publicName: "accept",
82
+ isSignal: true,
83
+ isRequired: false,
84
+ transformFunction: null
85
+ },
86
+ directory: {
87
+ classPropertyName: "directory",
88
+ publicName: "directory",
89
+ isSignal: true,
90
+ isRequired: false,
91
+ transformFunction: null
92
+ },
93
+ buttonLabel: {
94
+ classPropertyName: "buttonLabel",
95
+ publicName: "buttonLabel",
96
+ isSignal: true,
97
+ isRequired: false,
98
+ transformFunction: null
99
+ }
100
+ },
101
+ host: {
102
+ properties: {
103
+ "class.rt-file-input--disabled": "isDisabled()",
104
+ "class.rt-file-input--invalid": "isInvalid()",
105
+ "class.rt-file-input--readonly": "isReadonly()"
106
+ },
107
+ classAttribute: "rt-file-input"
108
+ },
109
+ providers: [{
110
+ provide: RtFormControlBase,
111
+ useExisting: forwardRef(() => RtFileInputComponent)
112
+ }],
113
+ viewQueries: [{
114
+ propertyName: "fileEl",
115
+ first: true,
116
+ predicate: ["fileEl"],
117
+ descendants: true,
118
+ isSignal: true
119
+ }],
120
+ usesInheritance: true,
121
+ ngImport: i0,
122
+ template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n",
123
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"],
124
+ dependencies: [
125
+ {
126
+ kind: "directive",
127
+ type: RtButtonDirective,
128
+ selector: "button[rtButton], a[rtButton]",
129
+ inputs: [
130
+ "label",
131
+ "icon",
132
+ "iconPos",
133
+ "theme",
134
+ "appearance",
135
+ "size",
136
+ "loading",
137
+ "loadingIcon",
138
+ "loadingLabel",
139
+ "pressed"
140
+ ]
141
+ },
142
+ {
143
+ kind: "component",
144
+ type: RtFileCardComponent,
145
+ selector: "rt-file-card",
146
+ inputs: [
147
+ "name",
148
+ "sizeBytes",
149
+ "size",
150
+ "showDownload",
151
+ "showRemove",
152
+ "showRename",
153
+ "disabled"
154
+ ],
155
+ outputs: [
156
+ "download",
157
+ "removed",
158
+ "rename"
159
+ ]
160
+ },
161
+ {
162
+ kind: "component",
163
+ type: RtFileListComponent,
164
+ selector: "rt-file-list"
165
+ },
166
+ {
167
+ kind: "directive",
168
+ type: BlockDirective,
169
+ selector: "[rtBlock]",
170
+ inputs: ["rtMod"]
171
+ },
172
+ {
173
+ kind: "directive",
174
+ type: ElemDirective,
175
+ selector: "[rtElem]",
176
+ inputs: ["rtMod"]
177
+ },
178
+ {
179
+ kind: "directive",
180
+ type: ModDirective,
181
+ selector: "[rtMod]"
182
+ }
183
+ ],
184
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
185
+ encapsulation: i0.ViewEncapsulation.None
186
+ });
187
+ }
188
+ };
189
+ i0.ɵɵngDeclareClassMetadata({
190
+ minVersion: "12.0.0",
191
+ version: "22.2.2",
192
+ ngImport: i0,
193
+ type: RtFileInputComponent,
194
+ decorators: [{
195
+ type: Component,
196
+ args: [{
197
+ selector: "rt-file-input",
198
+ changeDetection: ChangeDetectionStrategy.OnPush,
199
+ encapsulation: ViewEncapsulation.None,
200
+ imports: [
201
+ RtButtonDirective,
202
+ RtFileCardComponent,
203
+ RtFileListComponent,
204
+ BlockDirective,
205
+ ElemDirective,
206
+ ModDirective
207
+ ],
208
+ providers: [{
209
+ provide: RtFormControlBase,
210
+ useExisting: forwardRef(() => RtFileInputComponent)
211
+ }],
212
+ host: {
213
+ class: BEM_BLOCK,
214
+ "[class.rt-file-input--disabled]": "isDisabled()",
215
+ "[class.rt-file-input--invalid]": "isInvalid()",
216
+ "[class.rt-file-input--readonly]": "isReadonly()"
217
+ },
218
+ template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n",
219
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"]
220
+ }]
221
+ }],
222
+ propDecorators: {
223
+ fileEl: [{
224
+ type: i0.ViewChild,
225
+ args: ["fileEl", { isSignal: true }]
226
+ }],
227
+ multiple: [{
228
+ type: i0.Input,
229
+ args: [{
230
+ isSignal: true,
231
+ alias: "multiple",
232
+ required: false
233
+ }]
234
+ }],
235
+ accept: [{
236
+ type: i0.Input,
237
+ args: [{
238
+ isSignal: true,
239
+ alias: "accept",
240
+ required: false
241
+ }]
242
+ }],
243
+ directory: [{
244
+ type: i0.Input,
245
+ args: [{
246
+ isSignal: true,
247
+ alias: "directory",
248
+ required: false
249
+ }]
250
+ }],
251
+ buttonLabel: [{
252
+ type: i0.Input,
253
+ args: [{
254
+ isSignal: true,
255
+ alias: "buttonLabel",
256
+ required: false
257
+ }]
258
+ }]
259
+ }
260
+ });
116
261
  export { RtFileInputComponent };
117
- //# sourceMappingURL=rt-tools-ui-kit-v2-file-input.mjs.map
262
+
263
+ //# sourceMappingURL=rt-tools-ui-kit-v2-file-input.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-file-input.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.html","../../../projects/ui-kit-v2/src/lib/components/file-input/rt-tools-ui-kit-v2-file-input.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtFileCardComponent } from '@rt-tools/ui-kit-v2/file-card';\nimport { RtFileListComponent } from '@rt-tools/ui-kit-v2/file-list';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\n\nconst BEM_BLOCK: string = 'rt-file-input';\n\n/**\n * Поле выбора файлов: кнопка «выбрать» + список выбранных файлов карточками\n * `rt-file-card` (иконка типа, имя, размер, удаление). Скрывает нативный\n * `<input type=\"file\">`, value хранит как `File[]` (одиночный режим = максимум\n * один файл). CVA через общий `RtFormControlBase`. Read-only представление —\n * имена файлов через запятую.\n *\n * Без drag-drop (MVP). `accept` пробрасывается в нативный input, `multiple`\n * включает множественный выбор.\n */\n@Component({\n selector: 'rt-file-input',\n templateUrl: './rt-file-input.component.html',\n styleUrls: ['./rt-file-input.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtButtonDirective,\n RtFileCardComponent,\n RtFileListComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-input--disabled]': 'isDisabled()',\n '[class.rt-file-input--invalid]': 'isInvalid()',\n '[class.rt-file-input--readonly]': 'isReadonly()',\n },\n})\nexport class RtFileInputComponent extends RtFormControlBase<File[]> {\n readonly #t_uiChooseFile: Signal<string> = rtKitLabel('uiChooseFile');\n\n protected readonly fileEl: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fileEl');\n\n protected readonly buttonText: Signal<string> = computed((): string => this.buttonLabel() || this.#t_uiChooseFile());\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value().length > 0);\n\n public readonly displayText: Signal<string> = computed((): string =>\n this.value()\n .map((f: File): string => f.name)\n .join(', ')\n );\n\n public readonly multiple: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly accept: InputSignal<string | null> = input<string | null>(null);\n\n /**\n * Выбор каталога целиком вместо отдельных файлов. Браузер отдаёт\n * относительные пути (`webkitRelativePath`), по ним вызывающая сторона\n * восстанавливает структуру — иначе пользователю пришлось бы выбирать\n * десятки файлов по одному.\n */\n public readonly directory: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly buttonLabel: InputSignal<string> = input<string>('');\n\n protected getEmptyValue(): File[] {\n return [];\n }\n\n protected focusAfterClear(): void {\n // Скрытый native input фокусировать бессмысленно — фокус остаётся на кнопке.\n }\n\n protected openPicker(): void {\n if (this.isDisabled()) {\n return;\n }\n this.fileEl()?.nativeElement.click();\n }\n\n protected onFiles(event: Event): void {\n const list: FileList | null = (event.target as HTMLInputElement).files;\n const files: File[] = list ? Array.from(list) : [];\n const next: File[] = this.multiple() ? files : files.slice(0, 1);\n this.value.set(next);\n this.emitChange(next);\n this.markTouched();\n }\n\n protected removeFile(index: number): void {\n if (this.isDisabled()) {\n return;\n }\n const next: File[] = this.value().filter((_: File, i: number): boolean => i !== index);\n this.value.set(next);\n this.emitChange(next);\n // Сбрасываем native input, иначе повторный выбор того же файла не сработает.\n const el: HTMLInputElement | undefined = this.fileEl()?.nativeElement;\n if (el) {\n el.value = '';\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-file-input.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.html"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtFileCardComponent } from '@rt-tools/ui-kit-v2/file-card';\nimport { RtFileListComponent } from '@rt-tools/ui-kit-v2/file-list';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\n\nconst BEM_BLOCK: string = 'rt-file-input';\n\n/**\n * Поле выбора файлов: кнопка «выбрать» + список выбранных файлов карточками\n * `rt-file-card` (иконка типа, имя, размер, удаление). Скрывает нативный\n * `<input type=\"file\">`, value хранит как `File[]` (одиночный режим = максимум\n * один файл). CVA через общий `RtFormControlBase`. Read-only представление —\n * имена файлов через запятую.\n *\n * Без drag-drop (MVP). `accept` пробрасывается в нативный input, `multiple`\n * включает множественный выбор.\n */\n@Component({\n selector: 'rt-file-input',\n templateUrl: './rt-file-input.component.html',\n styleUrls: ['./rt-file-input.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtButtonDirective,\n RtFileCardComponent,\n RtFileListComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-input--disabled]': 'isDisabled()',\n '[class.rt-file-input--invalid]': 'isInvalid()',\n '[class.rt-file-input--readonly]': 'isReadonly()',\n },\n})\nexport class RtFileInputComponent extends RtFormControlBase<File[]> {\n readonly #t_uiChooseFile: Signal<string> = rtKitLabel('uiChooseFile');\n\n protected readonly fileEl: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fileEl');\n\n protected readonly buttonText: Signal<string> = computed((): string => this.buttonLabel() || this.#t_uiChooseFile());\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value().length > 0);\n\n public readonly displayText: Signal<string> = computed((): string =>\n this.value()\n .map((f: File): string => f.name)\n .join(', ')\n );\n\n public readonly multiple: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly accept: InputSignal<string | null> = input<string | null>(null);\n\n /**\n * Выбор каталога целиком вместо отдельных файлов. Браузер отдаёт\n * относительные пути (`webkitRelativePath`), по ним вызывающая сторона\n * восстанавливает структуру — иначе пользователю пришлось бы выбирать\n * десятки файлов по одному.\n */\n public readonly directory: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly buttonLabel: InputSignal<string> = input<string>('');\n\n protected getEmptyValue(): File[] {\n return [];\n }\n\n protected focusAfterClear(): void {\n // Скрытый native input фокусировать бессмысленно — фокус остаётся на кнопке.\n }\n\n protected openPicker(): void {\n if (this.isDisabled()) {\n return;\n }\n this.fileEl()?.nativeElement.click();\n }\n\n protected onFiles(event: Event): void {\n const list: FileList | null = (event.target as HTMLInputElement).files;\n const files: File[] = list ? Array.from(list) : [];\n const next: File[] = this.multiple() ? files : files.slice(0, 1);\n this.value.set(next);\n this.emitChange(next);\n this.markTouched();\n }\n\n protected removeFile(index: number): void {\n if (this.isDisabled()) {\n return;\n }\n const next: File[] = this.value().filter((_: File, i: number): boolean => i !== index);\n this.value.set(next);\n this.emitChange(next);\n // Сбрасываем native input, иначе повторный выбор того же файла не сработает.\n const el: HTMLInputElement | undefined = this.fileEl()?.nativeElement;\n if (el) {\n el.value = '';\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n"],"mappings":"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"}