@rt-tools/ui-kit-v2 0.23.3 → 0.23.4

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 (348) 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 +2309 -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-prompt-suggestion.mjs +135 -45
  138. package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -1
  139. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +293 -171
  140. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
  141. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +62 -55
  142. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -1
  143. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +3379 -1466
  144. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  145. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +114 -116
  146. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -1
  147. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +406 -299
  148. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  149. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +137 -36
  150. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -1
  151. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +687 -468
  152. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  153. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +2195 -1569
  154. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  155. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +187 -48
  156. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -1
  157. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +242 -122
  158. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -1
  159. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +439 -0
  160. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -0
  161. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +218 -69
  162. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -1
  163. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +292 -91
  164. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -1
  165. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +225 -138
  166. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -1
  167. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +150 -116
  168. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
  169. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2462 -1583
  170. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  171. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +647 -346
  172. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  173. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +335 -121
  174. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  175. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +217 -84
  176. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
  177. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +151 -72
  178. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
  179. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +697 -226
  180. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  181. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +92 -38
  182. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -1
  183. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +752 -338
  184. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  185. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +310 -129
  186. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  187. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +286 -158
  188. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -1
  189. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +270 -134
  190. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  191. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +322 -202
  192. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  193. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +908 -0
  194. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -0
  195. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +785 -0
  196. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -0
  197. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +118 -63
  198. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -1
  199. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +783 -262
  200. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  201. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +633 -294
  202. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  203. package/fesm2022/rt-tools-ui-kit-v2.mjs +100 -103
  204. package/package.json +41 -1
  205. package/src/assets/icons/collapse-all.svg +9 -0
  206. package/src/assets/icons/expand-all.svg +9 -0
  207. package/src/assets/icons-material/collapse-all.fill.svg +5 -0
  208. package/src/assets/icons-material/collapse-all.svg +5 -0
  209. package/src/assets/icons-material/expand-all.fill.svg +5 -0
  210. package/src/assets/icons-material/expand-all.svg +5 -0
  211. package/src/assets/icons-material/undo.fill.svg +5 -0
  212. package/src/assets/icons-material/undo.svg +5 -0
  213. package/src/lib/components/bottom-sheet/CONTEXT.md +20 -2
  214. package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +35 -1
  215. package/src/lib/components/breadcrumbs/CONTEXT.md +37 -0
  216. package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +205 -0
  217. package/src/lib/components/carousel/CONTEXT.md +42 -0
  218. package/src/lib/components/carousel/rt-carousel.component.scss +117 -0
  219. package/src/lib/components/checkbox/CONTEXT.md +3 -0
  220. package/src/lib/components/checkbox/rt-checkbox.component.scss +9 -3
  221. package/src/lib/components/color-palette/CONTEXT.md +49 -0
  222. package/src/lib/components/color-palette/picker/rt-color-picker.component.scss +161 -0
  223. package/src/lib/components/color-palette/rt-color-palette.component.scss +132 -0
  224. package/src/lib/components/draggable-tree/CONTEXT.md +54 -0
  225. package/src/lib/components/draggable-tree/rt-draggable-tree.component.scss +219 -0
  226. package/src/lib/components/hybrid-tree/CONTEXT.md +31 -0
  227. package/src/lib/components/hybrid-tree-selector/CONTEXT.md +25 -0
  228. package/src/lib/components/icon-button/CONTEXT.md +3 -0
  229. package/src/lib/components/inline-edit/CONTEXT.md +41 -0
  230. package/src/lib/components/inline-edit/rt-inline-edit.component.scss +274 -0
  231. package/src/lib/components/popover/CONTEXT.md +3 -0
  232. package/src/lib/components/speed-menu/CONTEXT.md +34 -0
  233. package/src/lib/components/speed-menu/rt-speed-menu.component.scss +118 -0
  234. package/src/lib/components/tag/rt-tag.component.scss +12 -0
  235. package/src/lib/components/thread-list/CONTEXT.md +1 -0
  236. package/src/lib/components/thread-list/rt-thread-list.component.scss +2 -1
  237. package/src/lib/components/toolbar/CONTEXT.md +9 -4
  238. package/src/lib/components/toolbar/rt-toolbar.component.scss +10 -2
  239. package/src/lib/components/tooltip/CONTEXT.md +8 -1
  240. package/src/lib/components/tree/CONTEXT.md +66 -0
  241. package/src/lib/components/tree/rt-tree.component.scss +313 -0
  242. package/src/lib/components/tree-selector/CONTEXT.md +47 -0
  243. package/src/lib/components/tree-selector/rt-tree-selector.component.scss +121 -0
  244. package/src/styles/_primitives.scss +4 -0
  245. package/styles/tokens.css +3 -0
  246. package/types/rt-tools-ui-kit-v2-accordion.d.ts +31 -24
  247. package/types/rt-tools-ui-kit-v2-action-bar.d.ts +112 -91
  248. package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +64 -40
  249. package/types/rt-tools-ui-kit-v2-aside-section.d.ts +13 -10
  250. package/types/rt-tools-ui-kit-v2-aside.d.ts +268 -206
  251. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +102 -61
  252. package/types/rt-tools-ui-kit-v2-bar-list.d.ts +39 -27
  253. package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +31 -20
  254. package/types/rt-tools-ui-kit-v2-breadcrumbs.d.ts +89 -0
  255. package/types/rt-tools-ui-kit-v2-button.d.ts +119 -59
  256. package/types/rt-tools-ui-kit-v2-calendar.d.ts +151 -86
  257. package/types/rt-tools-ui-kit-v2-card.d.ts +42 -21
  258. package/types/rt-tools-ui-kit-v2-carousel.d.ts +76 -0
  259. package/types/rt-tools-ui-kit-v2-checkbox.d.ts +48 -24
  260. package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +28 -20
  261. package/types/rt-tools-ui-kit-v2-color-palette.d.ts +208 -0
  262. package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +104 -47
  263. package/types/rt-tools-ui-kit-v2-container.d.ts +278 -221
  264. package/types/rt-tools-ui-kit-v2-copy-value.d.ts +39 -24
  265. package/types/rt-tools-ui-kit-v2-core.d.ts +856 -865
  266. package/types/rt-tools-ui-kit-v2-counter-row.d.ts +20 -12
  267. package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -38
  268. package/types/rt-tools-ui-kit-v2-data-list.d.ts +429 -264
  269. package/types/rt-tools-ui-kit-v2-data-table.d.ts +500 -351
  270. package/types/rt-tools-ui-kit-v2-date-picker.d.ts +164 -138
  271. package/types/rt-tools-ui-kit-v2-date-range.d.ts +102 -84
  272. package/types/rt-tools-ui-kit-v2-delta-view.d.ts +16 -13
  273. package/types/rt-tools-ui-kit-v2-detail-list.d.ts +23 -16
  274. package/types/rt-tools-ui-kit-v2-dialog.d.ts +130 -101
  275. package/types/rt-tools-ui-kit-v2-dot-field.d.ts +10 -13
  276. package/types/rt-tools-ui-kit-v2-download-link.d.ts +22 -17
  277. package/types/rt-tools-ui-kit-v2-draggable-tree.d.ts +132 -0
  278. package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +185 -96
  279. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +904 -404
  280. package/types/rt-tools-ui-kit-v2-empty-state.d.ts +48 -19
  281. package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +67 -39
  282. package/types/rt-tools-ui-kit-v2-field.d.ts +90 -49
  283. package/types/rt-tools-ui-kit-v2-file-card.d.ts +115 -75
  284. package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -48
  285. package/types/rt-tools-ui-kit-v2-file-input.d.ts +53 -36
  286. package/types/rt-tools-ui-kit-v2-file-list.d.ts +5 -8
  287. package/types/rt-tools-ui-kit-v2-filter-control.d.ts +83 -49
  288. package/types/rt-tools-ui-kit-v2-form-control.d.ts +102 -74
  289. package/types/rt-tools-ui-kit-v2-header.d.ts +40 -22
  290. package/types/rt-tools-ui-kit-v2-hybrid-tree-selector.d.ts +14 -0
  291. package/types/rt-tools-ui-kit-v2-hybrid-tree.d.ts +72 -0
  292. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +190 -90
  293. package/types/rt-tools-ui-kit-v2-icon.d.ts +160 -129
  294. package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +151 -111
  295. package/types/rt-tools-ui-kit-v2-image-upload.d.ts +159 -85
  296. package/types/rt-tools-ui-kit-v2-info-item.d.ts +26 -13
  297. package/types/rt-tools-ui-kit-v2-inline-edit.d.ts +194 -0
  298. package/types/rt-tools-ui-kit-v2-input-number.d.ts +102 -53
  299. package/types/rt-tools-ui-kit-v2-input.d.ts +82 -43
  300. package/types/rt-tools-ui-kit-v2-live-badge.d.ts +30 -17
  301. package/types/rt-tools-ui-kit-v2-logo.d.ts +49 -32
  302. package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +26 -17
  303. package/types/rt-tools-ui-kit-v2-menu.d.ts +272 -155
  304. package/types/rt-tools-ui-kit-v2-message.d.ts +59 -33
  305. package/types/rt-tools-ui-kit-v2-money-list.d.ts +36 -18
  306. package/types/rt-tools-ui-kit-v2-multiselect.d.ts +114 -80
  307. package/types/rt-tools-ui-kit-v2-night-grid.d.ts +34 -25
  308. package/types/rt-tools-ui-kit-v2-note.d.ts +12 -9
  309. package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +37 -16
  310. package/types/rt-tools-ui-kit-v2-page-header.d.ts +218 -150
  311. package/types/rt-tools-ui-kit-v2-pagination.d.ts +99 -63
  312. package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +61 -66
  313. package/types/rt-tools-ui-kit-v2-popover.d.ts +116 -55
  314. package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +26 -16
  315. package/types/rt-tools-ui-kit-v2-radio-button.d.ts +85 -43
  316. package/types/rt-tools-ui-kit-v2-radius.d.ts +18 -15
  317. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +931 -590
  318. package/types/rt-tools-ui-kit-v2-ripple.d.ts +28 -25
  319. package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +60 -58
  320. package/types/rt-tools-ui-kit-v2-section-nav.d.ts +32 -22
  321. package/types/rt-tools-ui-kit-v2-select.d.ts +182 -139
  322. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +452 -349
  323. package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +53 -20
  324. package/types/rt-tools-ui-kit-v2-skeleton.d.ts +55 -26
  325. package/types/rt-tools-ui-kit-v2-speed-menu.d.ts +131 -0
  326. package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -28
  327. package/types/rt-tools-ui-kit-v2-split-button.d.ts +96 -55
  328. package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +88 -60
  329. package/types/rt-tools-ui-kit-v2-stepper.d.ts +50 -37
  330. package/types/rt-tools-ui-kit-v2-table.d.ts +631 -480
  331. package/types/rt-tools-ui-kit-v2-tabs.d.ts +198 -113
  332. package/types/rt-tools-ui-kit-v2-tag.d.ts +106 -53
  333. package/types/rt-tools-ui-kit-v2-textarea.d.ts +48 -25
  334. package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +28 -26
  335. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +154 -94
  336. package/types/rt-tools-ui-kit-v2-timeline.d.ts +30 -28
  337. package/types/rt-tools-ui-kit-v2-toast.d.ts +174 -98
  338. package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +132 -86
  339. package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +88 -50
  340. package/types/rt-tools-ui-kit-v2-toolbar.d.ts +30 -27
  341. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +65 -41
  342. package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +257 -0
  343. package/types/rt-tools-ui-kit-v2-tree.d.ts +282 -0
  344. package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +21 -24
  345. package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +195 -124
  346. package/types/rt-tools-ui-kit-v2-workspace.d.ts +122 -79
  347. package/types/rt-tools-ui-kit-v2.d.ts +100 -90
  348. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +0 -1
@@ -1,540 +1,713 @@
1
- import { DOCUMENT } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { numberAttribute, inject, DestroyRef, signal, computed, viewChild, input, booleanAttribute, output, effect, untracked, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
4
- import { WINDOW, PlatformService, BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
5
- import { RT_KIT_LABELS } from '@rt-tools/ui-kit-v2/core';
6
- import { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';
7
-
8
- /**
9
- * Чистая логика обрезки: вписывание исходника в поле, рамка в пикселях
10
- * исходника, её движение и растяжение, перевод клавиш и выбор формата.
11
- * Компонент только переводит указатель в сдвиги и рисует то, что вернулось.
12
- */
13
- /** Все восемь ручек по часовой стрелке от левого верхнего угла */
14
- const RT_IMAGE_CROPPER_HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
15
- /** Шаг клавиш в пикселях поля: стрелка и стрелка с Shift */
1
+ import { DOCUMENT } from "@angular/common";
2
+ import * as i0 from "@angular/core";
3
+ import { ChangeDetectionStrategy, Component, DestroyRef, ViewEncapsulation, afterNextRender, booleanAttribute, computed, effect, inject, input, numberAttribute, output, signal, untracked, viewChild } from "@angular/core";
4
+ import { BlockDirective, ElemDirective, ModDirective, PlatformService, WINDOW } from "@rt-tools/core";
5
+ import { RT_KIT_LABELS } from "@rt-tools/ui-kit-v2/core";
6
+ import { RtSpinnerComponent } from "@rt-tools/ui-kit-v2/spinner";
7
+ const RT_IMAGE_CROPPER_HANDLES = [
8
+ "nw",
9
+ "n",
10
+ "ne",
11
+ "e",
12
+ "se",
13
+ "s",
14
+ "sw",
15
+ "w"
16
+ ];
16
17
  const RT_IMAGE_CROPPER_KEY_STEP = 1;
17
18
  const RT_IMAGE_CROPPER_KEY_STEP_LARGE = 10;
18
- /** Качество по умолчанию — то же, что у загрузчика первого кита */
19
19
  const RT_IMAGE_CROPPER_QUALITY = 92;
20
- const OWN_TYPES = ['image/png', 'image/jpeg', 'image/webp'];
20
+ const OWN_TYPES = [
21
+ "image/png",
22
+ "image/jpeg",
23
+ "image/webp"
24
+ ];
21
25
  function clamp(value, min, max) {
22
- return Math.max(min, Math.min(max, value));
26
+ return Math.max(min, Math.min(max, value));
23
27
  }
24
- /**
25
- * Вписывает исходник в поле целиком, с его пропорциями, по центру. Ни одна часть
26
- * картинки не срезается полем, и ни одна не растянута.
27
- */
28
28
  function fitSource(source, field) {
29
- if (source.width <= 0 || source.height <= 0 || field.width <= 0 || field.height <= 0) {
30
- return { scale: 0, offsetX: 0, offsetY: 0, width: 0, height: 0 };
31
- }
32
- const scale = Math.min(field.width / source.width, field.height / source.height);
33
- const width = source.width * scale;
34
- const height = source.height * scale;
35
- return { offsetX: (field.width - width) / 2, offsetY: (field.height - height) / 2, scale, width, height };
29
+ if (source.width <= 0 || source.height <= 0 || field.width <= 0 || field.height <= 0) return {
30
+ scale: 0,
31
+ offsetX: 0,
32
+ offsetY: 0,
33
+ width: 0,
34
+ height: 0
35
+ };
36
+ const scale = Math.min(field.width / source.width, field.height / source.height);
37
+ const width = source.width * scale;
38
+ const height = source.height * scale;
39
+ return {
40
+ offsetX: (field.width - width) / 2,
41
+ offsetY: (field.height - height) / 2,
42
+ scale,
43
+ width,
44
+ height
45
+ };
36
46
  }
37
- /**
38
- * Пропорция, которую держит рамка. Круглый вид держит один к одному при любой
39
- * заданной; заданная не числом или не больше нуля значит свободную рамку.
40
- */
41
47
  function frameRatio(ratio, round) {
42
- if (round) {
43
- return 1;
44
- }
45
- return typeof ratio === 'number' && Number.isFinite(ratio) && ratio > 0 ? ratio : null;
48
+ if (round) return 1;
49
+ return typeof ratio === "number" && Number.isFinite(ratio) && ratio > 0 ? ratio : null;
46
50
  }
47
- /**
48
- * Начальная рамка — наибольшая, какую позволяет пропорция, по центру исходника.
49
- * Свободная начинается как весь исходник.
50
- */
51
51
  function initialFrame(source, ratio) {
52
- if (ratio === null) {
53
- return { x: 0, y: 0, width: source.width, height: source.height };
54
- }
55
- const width = Math.min(source.width, source.height * ratio);
56
- const height = width / ratio;
57
- return { x: (source.width - width) / 2, y: (source.height - height) / 2, width, height };
52
+ if (ratio === null) return {
53
+ x: 0,
54
+ y: 0,
55
+ width: source.width,
56
+ height: source.height
57
+ };
58
+ const width = Math.min(source.width, source.height * ratio);
59
+ const height = width / ratio;
60
+ return {
61
+ x: (source.width - width) / 2,
62
+ y: (source.height - height) / 2,
63
+ width,
64
+ height
65
+ };
58
66
  }
59
- /** Сдвиг рамки целиком: размер тот же, у края исходника рамка останавливается */
60
67
  function moveFrame(frame, delta, source) {
61
- return {
62
- x: clamp(frame.x + delta.dx, 0, Math.max(0, source.width - frame.width)),
63
- y: clamp(frame.y + delta.dy, 0, Math.max(0, source.height - frame.height)),
64
- width: frame.width,
65
- height: frame.height,
66
- };
68
+ return {
69
+ x: clamp(frame.x + delta.dx, 0, Math.max(0, source.width - frame.width)),
70
+ y: clamp(frame.y + delta.dy, 0, Math.max(0, source.height - frame.height)),
71
+ width: frame.width,
72
+ height: frame.height
73
+ };
67
74
  }
68
- /** Знак оси по ручке: к концу оси, к началу, или ось не тянется */
69
75
  function axisSign(handle, forward, backward) {
70
- if (handle.includes(forward)) {
71
- return 1;
72
- }
73
- return handle.includes(backward) ? -1 : 0;
76
+ if (handle.includes(forward)) return 1;
77
+ return handle.includes(backward) ? -1 : 0;
74
78
  }
75
- /** По каким осям и в какую сторону тянет ручка */
76
79
  function handleDirection(handle) {
77
- return { x: axisSign(handle, 'e', 'w'), y: axisSign(handle, 's', 'n') };
80
+ return {
81
+ x: axisSign(handle, "e", "w"),
82
+ y: axisSign(handle, "s", "n")
83
+ };
78
84
  }
79
- /**
80
- * Наибольший размер по оси: от неподвижной стороны до края исходника, а для оси,
81
- * которую ручка не тянет, — удвоенное расстояние от центра до ближнего края.
82
- */
83
85
  function axisRoom(start, size, limit, direction) {
84
- if (direction > 0) {
85
- return limit - start;
86
- }
87
- if (direction < 0) {
88
- return start + size;
89
- }
90
- const centre = start + size / 2;
91
- return 2 * Math.min(centre, limit - centre);
86
+ if (direction > 0) return limit - start;
87
+ if (direction < 0) return start + size;
88
+ const centre = start + size / 2;
89
+ return 2 * Math.min(centre, limit - centre);
92
90
  }
93
- /** Где рамка встаёт на оси: от неподвижной стороны, или вокруг центра для оси, которую ручка не тянет */
94
91
  function axisStart(start, size, next, direction) {
95
- if (direction > 0) {
96
- return start;
97
- }
98
- if (direction < 0) {
99
- return start + size - next;
100
- }
101
- return start + size / 2 - next / 2;
92
+ if (direction > 0) return start;
93
+ if (direction < 0) return start + size - next;
94
+ return start + size / 2 - next / 2;
102
95
  }
103
- /** Свободная рамка: каждая ось тянется сама, ось без ручки остаётся как была */
104
96
  function resizeFree(frame, direction, delta, source, least) {
105
- let { x, y, width, height } = frame;
106
- if (direction.x !== 0) {
107
- const room = axisRoom(frame.x, frame.width, source.width, direction.x);
108
- width = clamp(frame.width + direction.x * delta.dx, Math.min(least, room), room);
109
- x = axisStart(frame.x, frame.width, width, direction.x);
110
- }
111
- if (direction.y !== 0) {
112
- const room = axisRoom(frame.y, frame.height, source.height, direction.y);
113
- height = clamp(frame.height + direction.y * delta.dy, Math.min(least, room), room);
114
- y = axisStart(frame.y, frame.height, height, direction.y);
115
- }
116
- return { x, y, width, height };
97
+ let { x, y, width, height } = frame;
98
+ if (direction.x !== 0) {
99
+ const room = axisRoom(frame.x, frame.width, source.width, direction.x);
100
+ width = clamp(frame.width + direction.x * delta.dx, Math.min(least, room), room);
101
+ x = axisStart(frame.x, frame.width, width, direction.x);
102
+ }
103
+ if (direction.y !== 0) {
104
+ const room = axisRoom(frame.y, frame.height, source.height, direction.y);
105
+ height = clamp(frame.height + direction.y * delta.dy, Math.min(least, room), room);
106
+ y = axisStart(frame.y, frame.height, height, direction.y);
107
+ }
108
+ return {
109
+ x,
110
+ y,
111
+ width,
112
+ height
113
+ };
117
114
  }
118
- /**
119
- * Ширина, которую просит сдвиг при заданной пропорции. Угол берёт ту ось, по
120
- * которой сдвиг больше; сторона — свою ось.
121
- */
122
115
  function wantedRatioWidth(frame, direction, delta, ratio) {
123
- const byWidth = frame.width + direction.x * delta.dx;
124
- const byHeight = (frame.height + direction.y * delta.dy) * ratio;
125
- if (direction.x === 0) {
126
- return byHeight;
127
- }
128
- if (direction.y === 0) {
129
- return byWidth;
130
- }
131
- return Math.abs(delta.dx) >= Math.abs(delta.dy * ratio) ? byWidth : byHeight;
116
+ const byWidth = frame.width + direction.x * delta.dx;
117
+ const byHeight = (frame.height + direction.y * delta.dy) * ratio;
118
+ if (direction.x === 0) return byHeight;
119
+ if (direction.y === 0) return byWidth;
120
+ return Math.abs(delta.dx) >= Math.abs(delta.dy * ratio) ? byWidth : byHeight;
132
121
  }
133
- /**
134
- * Растяжение рамки за ручку. Сторона или угол напротив ручки стоит на месте;
135
- * рамка не выходит за исходник и не становится меньше наименьшего размера; рамка
136
- * с пропорцией держит её, а боковая ручка тянет её вокруг центра второй оси.
137
- */
138
122
  function resizeFrame(frame, handle, delta, source, ratio, minSize) {
139
- const direction = handleDirection(handle);
140
- const least = Math.max(0, minSize);
141
- if (ratio === null) {
142
- return resizeFree(frame, direction, delta, source, least);
143
- }
144
- const roomWidth = Math.min(axisRoom(frame.x, frame.width, source.width, direction.x), axisRoom(frame.y, frame.height, source.height, direction.y) * ratio);
145
- const leastWidth = Math.min(Math.max(least, least * ratio), roomWidth);
146
- const width = clamp(wantedRatioWidth(frame, direction, delta, ratio), leastWidth, roomWidth);
147
- const height = width / ratio;
148
- return {
149
- x: axisStart(frame.x, frame.width, width, direction.x),
150
- y: axisStart(frame.y, frame.height, height, direction.y),
151
- width,
152
- height,
153
- };
123
+ const direction = handleDirection(handle);
124
+ const least = Math.max(0, minSize);
125
+ if (ratio === null) return resizeFree(frame, direction, delta, source, least);
126
+ const roomWidth = Math.min(axisRoom(frame.x, frame.width, source.width, direction.x), axisRoom(frame.y, frame.height, source.height, direction.y) * ratio);
127
+ const leastWidth = Math.min(Math.max(least, least * ratio), roomWidth);
128
+ const width = clamp(wantedRatioWidth(frame, direction, delta, ratio), leastWidth, roomWidth);
129
+ const height = width / ratio;
130
+ return {
131
+ x: axisStart(frame.x, frame.width, width, direction.x),
132
+ y: axisStart(frame.y, frame.height, height, direction.y),
133
+ width,
134
+ height
135
+ };
154
136
  }
155
- /**
156
- * Сдвиг от стрелки клавиатуры в пикселях исходника. Одно нажатие — пиксель поля,
157
- * с Shift десять; не стрелка даёт `null`.
158
- */
159
137
  function keyDelta(key, isLarge, scale) {
160
- if (scale <= 0) {
161
- return null;
162
- }
163
- const step = (isLarge ? RT_IMAGE_CROPPER_KEY_STEP_LARGE : RT_IMAGE_CROPPER_KEY_STEP) / scale;
164
- switch (key) {
165
- case 'ArrowLeft':
166
- return { dx: -step, dy: 0 };
167
- case 'ArrowRight':
168
- return { dx: step, dy: 0 };
169
- case 'ArrowUp':
170
- return { dx: 0, dy: -step };
171
- case 'ArrowDown':
172
- return { dx: 0, dy: step };
173
- default:
174
- return null;
175
- }
138
+ if (scale <= 0) return null;
139
+ const step = (isLarge ? 10 : 1) / scale;
140
+ switch (key) {
141
+ case "ArrowLeft": return {
142
+ dx: -step,
143
+ dy: 0
144
+ };
145
+ case "ArrowRight": return {
146
+ dx: step,
147
+ dy: 0
148
+ };
149
+ case "ArrowUp": return {
150
+ dx: 0,
151
+ dy: -step
152
+ };
153
+ case "ArrowDown": return {
154
+ dx: 0,
155
+ dy: step
156
+ };
157
+ default: return null;
158
+ }
176
159
  }
177
- /** Сдвиг указателя в пикселях поля переводится в пиксели исходника */
178
160
  function fieldDelta(dx, dy, scale) {
179
- return scale > 0 ? { dx: dx / scale, dy: dy / scale } : { dx: 0, dy: 0 };
161
+ return scale > 0 ? {
162
+ dx: dx / scale,
163
+ dy: dy / scale
164
+ } : {
165
+ dx: 0,
166
+ dy: 0
167
+ };
180
168
  }
181
- /** Рамка в пикселях поля — для рисования поверх вписанной картинки */
182
169
  function frameInField(frame, fit) {
183
- return {
184
- x: fit.offsetX + frame.x * fit.scale,
185
- y: fit.offsetY + frame.y * fit.scale,
186
- width: frame.width * fit.scale,
187
- height: frame.height * fit.scale,
188
- };
170
+ return {
171
+ x: fit.offsetX + frame.x * fit.scale,
172
+ y: fit.offsetY + frame.y * fit.scale,
173
+ width: frame.width * fit.scale,
174
+ height: frame.height * fit.scale
175
+ };
189
176
  }
190
- /** Рамка в целых пикселях исходника — то, что вырезает холст; не меньше пикселя */
191
177
  function cropArea(frame, source) {
192
- const x = clamp(Math.round(frame.x), 0, Math.max(0, source.width - 1));
193
- const y = clamp(Math.round(frame.y), 0, Math.max(0, source.height - 1));
194
- return {
195
- x,
196
- y,
197
- width: clamp(Math.round(frame.width), 1, Math.max(1, source.width - x)),
198
- height: clamp(Math.round(frame.height), 1, Math.max(1, source.height - y)),
199
- };
178
+ const x = clamp(Math.round(frame.x), 0, Math.max(0, source.width - 1));
179
+ const y = clamp(Math.round(frame.y), 0, Math.max(0, source.height - 1));
180
+ return {
181
+ x,
182
+ y,
183
+ width: clamp(Math.round(frame.width), 1, Math.max(1, source.width - x)),
184
+ height: clamp(Math.round(frame.height), 1, Math.max(1, source.height - y))
185
+ };
200
186
  }
201
- /**
202
- * Тип результата. Без выбранного формата берётся формат исходника, и png, когда
203
- * он не из трёх.
204
- */
205
187
  function resultType(format, sourceType) {
206
- if (format) {
207
- return `image/${format}`;
208
- }
209
- return OWN_TYPES.includes(sourceType) ? sourceType : 'image/png';
188
+ if (format) return `image/${format}`;
189
+ return OWN_TYPES.includes(sourceType) ? sourceType : "image/png";
210
190
  }
211
- /** Качество холста — доля единицы; вход берёт проценты */
212
191
  function resultQuality(quality) {
213
- return Number.isFinite(quality) ? clamp(quality, 0, 100) / 100 : RT_IMAGE_CROPPER_QUALITY / 100;
192
+ return Number.isFinite(quality) ? clamp(quality, 0, 100) / 100 : 92 / 100;
214
193
  }
215
- /** Имя файла результата: основа имени исходника и расширение по типу результата */
216
194
  function resultFileName(sourceName, type) {
217
- const extension = type === 'image/jpeg' ? 'jpg' : type.replace('image/', '');
218
- const dot = sourceName.lastIndexOf('.');
219
- let base = sourceName || 'image';
220
- if (dot > 0) {
221
- base = sourceName.slice(0, dot);
222
- }
223
- return `${base}.${extension}`;
195
+ const extension = type === "image/jpeg" ? "jpg" : type.replace("image/", "");
196
+ const dot = sourceName.lastIndexOf(".");
197
+ let base = sourceName || "image";
198
+ if (dot > 0) base = sourceName.slice(0, dot);
199
+ return `${base}.${extension}`;
224
200
  }
225
-
226
- const BEM_BLOCK = 'rt-image-cropper';
227
- /** Наименьший размер рамки по умолчанию, в пикселях исходника */
201
+ const BEM_BLOCK = "rt-image-cropper";
228
202
  const DEFAULT_MIN_SIZE = 16;
229
- /** Подпись каждой ручки — ключ словаря кита */
230
203
  const HANDLE_LABELS = {
231
- n: 'uiImageCropperHandleN',
232
- s: 'uiImageCropperHandleS',
233
- e: 'uiImageCropperHandleE',
234
- w: 'uiImageCropperHandleW',
235
- ne: 'uiImageCropperHandleNe',
236
- nw: 'uiImageCropperHandleNw',
237
- se: 'uiImageCropperHandleSe',
238
- sw: 'uiImageCropperHandleSw',
204
+ n: "uiImageCropperHandleN",
205
+ s: "uiImageCropperHandleS",
206
+ e: "uiImageCropperHandleE",
207
+ w: "uiImageCropperHandleW",
208
+ ne: "uiImageCropperHandleNe",
209
+ nw: "uiImageCropperHandleNw",
210
+ se: "uiImageCropperHandleSe",
211
+ sw: "uiImageCropperHandleSw"
239
212
  };
240
213
  function sameRect(a, b) {
241
- return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
214
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
242
215
  }
243
216
  function optionalNumber(value) {
244
- return value === null || value === undefined || value === '' ? null : numberAttribute(value, 0);
217
+ return value === null || value === void 0 || value === "" ? null : numberAttribute(value, 0);
245
218
  }
246
- /**
247
- * Обрезка изображения: исходник вписан в поле целиком, поверх — рамка с восемью
248
- * ручками. Рамка живёт в пикселях исходника и двигается указателем, пальцем и
249
- * стрелками; после прочтения исходника и после каждого законченного изменения
250
- * компонент отдаёт файл, вырезанный рамкой, в выбранном формате и качестве.
251
- *
252
- * Поворот снимка по EXIF делает сам браузер: картинка и холст читают исходник с
253
- * `image-orientation: from-image`, и размеры, которые видит логика, уже
254
- * повёрнутые.
255
- */
256
- class RtImageCropperComponent {
257
- #destroyRef;
258
- #window;
259
- #document;
260
- #platform;
261
- #fieldSize;
262
- #source;
263
- #frame;
264
- #ratio;
265
- #fit;
266
- #image;
267
- /** Картинка, которая сейчас читается: ответ прежней после смены исходника не принимается */
268
- #pending;
269
- #sourceType;
270
- #sourceName;
271
- #drag;
272
- /** Номер последнего запроса результата: поздний ответ холста по старой рамке отбрасывается */
273
- #resultTicket;
274
- constructor() {
275
- this.#destroyRef = inject(DestroyRef);
276
- this.#window = inject(WINDOW);
277
- this.#document = inject(DOCUMENT);
278
- this.#platform = inject(PlatformService);
279
- this.#fieldSize = signal({ width: 0, height: 0 }, /* @ts-ignore */
280
- ...(ngDevMode ? [{ debugName: "#fieldSize" }] : /* istanbul ignore next */ []));
281
- this.#source = signal({ width: 0, height: 0 }, /* @ts-ignore */
282
- ...(ngDevMode ? [{ debugName: "#source" }] : /* istanbul ignore next */ []));
283
- this.#frame = signal({ x: 0, y: 0, width: 0, height: 0 }, /* @ts-ignore */
284
- ...(ngDevMode ? [{ debugName: "#frame" }] : /* istanbul ignore next */ []));
285
- this.#ratio = computed(() => frameRatio(this.ratio(), this.round()), /* @ts-ignore */
286
- ...(ngDevMode ? [{ debugName: "#ratio" }] : /* istanbul ignore next */ []));
287
- this.#fit = computed(() => fitSource(this.#source(), this.#fieldSize()), /* @ts-ignore */
288
- ...(ngDevMode ? [{ debugName: "#fit" }] : /* istanbul ignore next */ []));
289
- this.#image = null;
290
- /** Картинка, которая сейчас читается: ответ прежней после смены исходника не принимается */
291
- this.#pending = null;
292
- this.#sourceType = '';
293
- this.#sourceName = '';
294
- this.#drag = null;
295
- /** Номер последнего запроса результата: поздний ответ холста по старой рамке отбрасывается */
296
- this.#resultTicket = 0;
297
- this.field = viewChild.required('field', /* @ts-ignore */
298
- ...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
299
- this.t = inject(RT_KIT_LABELS);
300
- this.handles = RT_IMAGE_CROPPER_HANDLES;
301
- this.handleLabels = HANDLE_LABELS;
302
- this.state = signal('empty', /* @ts-ignore */
303
- ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
304
- /** Текст пустого поля: свой, если задан, иначе подпись кита */
305
- this.placeholderText = computed(() => this.placeholder() || this.t().uiImageCropperPlaceholder, /* @ts-ignore */
306
- ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
307
- /** Адрес исходника для картинки в поле */
308
- this.url = signal(null, /* @ts-ignore */
309
- ...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
310
- /** Где картинка лежит в поле, в пикселях поля */
311
- this.image = computed(() => {
312
- const fit = this.#fit();
313
- return { x: fit.offsetX, y: fit.offsetY, width: fit.width, height: fit.height };
314
- }, /* @ts-ignore */
315
- ...(ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []));
316
- /** Рамка в пикселях поля */
317
- this.frameBox = computed(() => frameInField(this.#frame(), this.#fit()), /* @ts-ignore */
318
- ...(ngDevMode ? [{ debugName: "frameBox" }] : /* istanbul ignore next */ []));
319
- /** Подсказка пустого поля; пусто — подпись кита `uiImageCropperPlaceholder` */
320
- this.placeholder = input('', /* @ts-ignore */
321
- ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
322
- /** Исходник: файл, который надо обрезать; пусто — поле с подсказкой */
323
- this.file = input(null, /* @ts-ignore */
324
- ...(ngDevMode ? [{ debugName: "file" }] : /* istanbul ignore next */ []));
325
- /** Пропорция рамки, ширина к высоте; пусто — рамка свободная */
326
- this.ratio = input(null, { ...(ngDevMode ? { debugName: "ratio" } : /* istanbul ignore next */ {}), transform: optionalNumber });
327
- /** Круглый вид: маска на экране и пропорция один к одному; результат — квадрат */
328
- this.round = input(false, { ...(ngDevMode ? { debugName: "round" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
329
- /** Наименьший размер рамки в пикселях исходника */
330
- this.minSize = input(DEFAULT_MIN_SIZE, { ...(ngDevMode ? { debugName: "minSize" } : /* istanbul ignore next */ {}), transform: (value) => numberAttribute(value, DEFAULT_MIN_SIZE) });
331
- /** Формат результата; пусто — формат исходника, png, когда он не из трёх */
332
- this.format = input(null, /* @ts-ignore */
333
- ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
334
- /** Качество результата в процентах — для jpeg и webp */
335
- this.quality = input(RT_IMAGE_CROPPER_QUALITY, { ...(ngDevMode ? { debugName: "quality" } : /* istanbul ignore next */ {}), transform: (value) => numberAttribute(value, RT_IMAGE_CROPPER_QUALITY) });
336
- /** Недоступна: рамка видна, но не меняется ни указателем, ни клавишами */
337
- this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
338
- /** Файл, вырезанный рамкой: после прочтения исходника и после каждого законченного изменения */
339
- this.cropped = output();
340
- /** Исходник не прочитался */
341
- this.loadFailed = output();
342
- effect(() => {
343
- const file = this.file();
344
- untracked(() => this.#load(file));
345
- });
346
- effect(() => {
347
- const ratio = this.#ratio();
348
- untracked(() => {
349
- if (this.state() === 'ready') {
350
- this.#frame.set(initialFrame(this.#source(), ratio));
351
- this.#emitResult();
352
- }
353
- });
354
- });
355
- afterNextRender(() => this.#observe(this.field().nativeElement));
356
- this.#destroyRef.onDestroy(() => this.#revoke());
357
- }
358
- onPointerDown(event, handle) {
359
- if (this.disabled() || this.#drag !== null || (event.pointerType === 'mouse' && event.button !== 0)) {
360
- return;
361
- }
362
- event.preventDefault();
363
- event.stopPropagation();
364
- const target = event.currentTarget;
365
- if (target instanceof this.#window.HTMLElement && typeof target.setPointerCapture === 'function') {
366
- target.setPointerCapture(event.pointerId);
367
- }
368
- this.#drag = { pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, startFrame: this.#frame(), handle };
369
- }
370
- onPointerMove(event) {
371
- const drag = this.#drag;
372
- if (drag === null || drag.pointerId !== event.pointerId) {
373
- return;
374
- }
375
- event.preventDefault();
376
- event.stopPropagation();
377
- const delta = fieldDelta(event.clientX - drag.startX, event.clientY - drag.startY, this.#fit().scale);
378
- this.#frame.set(this.#change(drag.startFrame, drag.handle, delta));
379
- }
380
- onPointerUp(event) {
381
- const drag = this.#drag;
382
- if (drag === null || drag.pointerId !== event.pointerId) {
383
- return;
384
- }
385
- event.stopPropagation();
386
- this.#drag = null;
387
- const target = event.currentTarget;
388
- if (target instanceof this.#window.HTMLElement && typeof target.releasePointerCapture === 'function') {
389
- target.releasePointerCapture(event.pointerId);
390
- }
391
- if (!sameRect(drag.startFrame, this.#frame())) {
392
- this.#emitResult();
393
- }
394
- }
395
- onKeyDown(event, handle) {
396
- if (this.disabled()) {
397
- return;
398
- }
399
- const delta = keyDelta(event.key, event.shiftKey, this.#fit().scale);
400
- if (delta === null) {
401
- return;
402
- }
403
- event.preventDefault();
404
- event.stopPropagation();
405
- const before = this.#frame();
406
- const next = this.#change(before, handle, delta);
407
- if (!sameRect(before, next)) {
408
- this.#frame.set(next);
409
- this.#emitResult();
410
- }
411
- }
412
- /** Одна точка для указателя и клавиш: внутри рамки — сдвиг, на ручке — растяжение */
413
- #change(frame, handle, delta) {
414
- return handle === null
415
- ? moveFrame(frame, delta, this.#source())
416
- : resizeFrame(frame, handle, delta, this.#source(), this.#ratio(), this.minSize());
417
- }
418
- #load(file) {
419
- this.#revoke();
420
- this.#image = null;
421
- this.#pending = null;
422
- this.#drag = null;
423
- this.#resultTicket++;
424
- if (file === null || !this.#platform.isPlatformBrowser) {
425
- this.state.set('empty');
426
- return;
427
- }
428
- this.#sourceType = file.type;
429
- this.#sourceName = file instanceof this.#window.File ? file.name : '';
430
- const url = this.#window.URL.createObjectURL(file);
431
- const image = new this.#window.Image();
432
- this.#pending = image;
433
- this.url.set(url);
434
- this.state.set('loading');
435
- image.onload = () => {
436
- if (this.#pending === image) {
437
- this.#pending = null;
438
- this.#ready(image);
439
- }
440
- };
441
- image.onerror = () => {
442
- if (this.#pending === image) {
443
- this.#pending = null;
444
- this.#refuse();
445
- }
446
- };
447
- image.src = url;
448
- }
449
- #ready(image) {
450
- if (image.naturalWidth <= 0 || image.naturalHeight <= 0) {
451
- this.#refuse();
452
- return;
453
- }
454
- this.#image = image;
455
- this.#source.set({ width: image.naturalWidth, height: image.naturalHeight });
456
- this.#frame.set(initialFrame(this.#source(), this.#ratio()));
457
- this.state.set('ready');
458
- this.#emitResult();
459
- }
460
- #refuse() {
461
- this.state.set('refusal');
462
- this.loadFailed.emit();
463
- }
464
- #revoke() {
465
- const url = this.url();
466
- if (url !== null) {
467
- this.#window.URL.revokeObjectURL(url);
468
- this.url.set(null);
469
- }
470
- }
471
- #observe(field) {
472
- const measure = () => this.#fieldSize.set({ width: field.clientWidth, height: field.clientHeight });
473
- measure();
474
- if (typeof this.#window.ResizeObserver !== 'function') {
475
- return;
476
- }
477
- const observer = new this.#window.ResizeObserver(measure);
478
- observer.observe(field);
479
- this.#destroyRef.onDestroy(() => observer.disconnect());
480
- }
481
- /** Вырезает рамку холстом и отдаёт файл; ответ по устаревшей рамке не выходит */
482
- #emitResult() {
483
- const image = this.#image;
484
- if (image === null) {
485
- return;
486
- }
487
- this.#resultTicket++;
488
- const ticket = this.#resultTicket;
489
- const area = cropArea(this.#frame(), this.#source());
490
- const canvas = this.#document.createElement('canvas');
491
- canvas.width = area.width;
492
- canvas.height = area.height;
493
- const context = canvas.getContext('2d');
494
- if (context === null) {
495
- return;
496
- }
497
- context.drawImage(image, area.x, area.y, area.width, area.height, 0, 0, area.width, area.height);
498
- const type = resultType(this.format(), this.#sourceType);
499
- canvas.toBlob((blob) => {
500
- if (blob === null || ticket !== this.#resultTicket) {
501
- return;
502
- }
503
- const file = new this.#window.File([blob], resultFileName(this.#sourceName, type), { type });
504
- this.cropped.emit({ file, frame: area });
505
- }, type, resultQuality(this.quality()));
506
- }
507
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtImageCropperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
508
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtImageCropperComponent, isStandalone: true, selector: "rt-image-cropper", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, file: { classPropertyName: "file", publicName: "file", isSignal: true, isRequired: false, transformFunction: null }, ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, round: { classPropertyName: "round", publicName: "round", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, quality: { classPropertyName: "quality", publicName: "quality", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropped: "cropped", loadFailed: "loadFailed" }, host: { properties: { "class.rt-image-cropper--round": "round()", "class.rt-image-cropper--disabled": "disabled()", "style.--rt-image-cropper-image-x": "image().x + 'px'", "style.--rt-image-cropper-image-y": "image().y + 'px'", "style.--rt-image-cropper-image-width": "image().width + 'px'", "style.--rt-image-cropper-image-height": "image().height + 'px'", "style.--rt-image-cropper-frame-x": "frameBox().x + 'px'", "style.--rt-image-cropper-frame-y": "frameBox().y + 'px'", "style.--rt-image-cropper-frame-width": "frameBox().width + 'px'", "style.--rt-image-cropper-frame-height": "frameBox().height + 'px'" }, classAttribute: "rt-image-cropper" }, viewQueries: [{ propertyName: "field", first: true, predicate: ["field"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-image-cropper\">\n <div #field rtElem=\"field\" qa-dataid=\"image-cropper-field\">\n @switch (state()) {\n @case ('empty') {\n <p rtElem=\"placeholder\" qa-dataid=\"image-cropper-placeholder\">{{ placeholderText() }}</p>\n }\n @case ('loading') {\n <rt-spinner rtElem=\"spinner\" qa-dataid=\"image-cropper-spinner\" />\n }\n @case ('refusal') {\n <p rtElem=\"refusal\" qa-dataid=\"image-cropper-refusal\">{{ t().uiImageCropperRefusal }}</p>\n }\n @case ('ready') {\n <img rtElem=\"image\" qa-dataid=\"image-cropper-image\" alt=\"\" draggable=\"false\" [src]=\"url()\" />\n <div\n rtElem=\"frame\"\n qa-dataid=\"image-cropper-frame\"\n role=\"group\"\n [attr.aria-label]=\"t().uiImageCropperFrame\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, null)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, null)\">\n @for (handle of handles; track handle) {\n <span\n rtElem=\"handle\"\n role=\"button\"\n [attr.qa-dataid]=\"'image-cropper-handle-' + handle\"\n [rtMod]=\"{ side: handle }\"\n [attr.aria-label]=\"t()[handleLabels[handle]]\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, handle)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, handle)\"></span>\n }\n </div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-cropper{--rt-image-cropper-height: calc(var(--rt-size-20) * 4);--rt-image-cropper-radius: var(--rt-radius-md);--rt-image-cropper-frame-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: var(--rt-color-bg-subtle);--rt-image-cropper-shade: var(--rt-overlay-black-50);--rt-image-cropper-rim-width: var(--rt-border-width-thin);--rt-image-cropper-rim-color: var(--rt-overlay-white-50);--rt-image-cropper-dash-style: none;--rt-image-cropper-dash-color: transparent;--rt-image-cropper-dash-opacity: 1;--rt-image-cropper-handle-size: var(--rt-size-3);--rt-image-cropper-handle-bg: var(--rt-color-action-on-primary);--rt-image-cropper-handle-border: var(--rt-color-border-strong);--rt-image-cropper-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-cropper-text-color: var(--rt-color-text-muted);--rt-image-cropper-disabled-opacity: .5;--rt-image-cropper-image-x: 0;--rt-image-cropper-image-y: 0;--rt-image-cropper-image-width: 0;--rt-image-cropper-image-height: 0;--rt-image-cropper-frame-x: 0;--rt-image-cropper-frame-y: 0;--rt-image-cropper-frame-width: 0;--rt-image-cropper-frame-height: 0;display:block;width:100%}.rt-image-cropper__field{position:relative;overflow:hidden;height:var(--rt-image-cropper-height);border-radius:var(--rt-image-cropper-radius);background:var(--rt-image-cropper-field-bg);-webkit-user-select:none;user-select:none}.rt-image-cropper__spinner{position:absolute;inset:50% auto auto 50%;translate:-50% -50%}.rt-image-cropper__placeholder,.rt-image-cropper__refusal{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-md);margin:0;color:var(--rt-image-cropper-text-color);inset:0;text-align:center}.rt-image-cropper__image{position:absolute;top:var(--rt-image-cropper-image-y);left:var(--rt-image-cropper-image-x);width:var(--rt-image-cropper-image-width);max-width:none;height:var(--rt-image-cropper-image-height);image-orientation:from-image;pointer-events:none}.rt-image-cropper__frame{position:absolute;top:var(--rt-image-cropper-frame-y);left:var(--rt-image-cropper-frame-x);width:var(--rt-image-cropper-frame-width);height:var(--rt-image-cropper-frame-height);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-rim-color);border-radius:var(--rt-image-cropper-frame-radius);cursor:move;outline:100vmax solid var(--rt-image-cropper-shade);touch-action:none}.rt-image-cropper__frame:after{position:absolute;border:var(--rt-image-cropper-rim-width) var(--rt-image-cropper-dash-style) var(--rt-image-cropper-dash-color);border-radius:inherit;content:\"\";inset:calc(-1 * var(--rt-image-cropper-rim-width));opacity:var(--rt-image-cropper-dash-opacity);pointer-events:none}.rt-image-cropper__frame:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow)}.rt-image-cropper__handle{position:absolute;width:var(--rt-image-cropper-handle-size);height:var(--rt-image-cropper-handle-size);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-handle-border);background:var(--rt-image-cropper-handle-bg);touch-action:none}.rt-image-cropper__handle:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow);outline:none}.rt-image-cropper__handle--side--nw{top:0;left:0;cursor:nwse-resize}.rt-image-cropper__handle--side--n{top:0;left:50%;cursor:ns-resize;translate:-50% 0}.rt-image-cropper__handle--side--ne{top:0;left:100%;cursor:nesw-resize;translate:-100% 0}.rt-image-cropper__handle--side--e{top:50%;left:100%;cursor:ew-resize;translate:-100% -50%}.rt-image-cropper__handle--side--se{top:100%;left:100%;cursor:nwse-resize;translate:-100% -100%}.rt-image-cropper__handle--side--s{top:100%;left:50%;cursor:ns-resize;translate:-50% -100%}.rt-image-cropper__handle--side--sw{top:100%;left:0;cursor:nesw-resize;translate:0 -100%}.rt-image-cropper__handle--side--w{top:50%;left:0;cursor:ew-resize;translate:0 -50%}:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: transparent;--rt-image-cropper-shade: var(--rt-overlay-white-25);--rt-image-cropper-dash-style: dashed;--rt-image-cropper-dash-color: var(--rt-mat-dark-40);--rt-image-cropper-dash-opacity: .75;--rt-image-cropper-handle-size: var(--rt-size-2);--rt-image-cropper-handle-bg: var(--rt-mat-dark-40);--rt-image-cropper-handle-border: var(--rt-overlay-white-50)}@media(pointer:coarse){:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}.rt-image-cropper--round{--rt-image-cropper-frame-radius: var(--rt-radius-full)}.rt-image-cropper--disabled .rt-image-cropper__frame,.rt-image-cropper--disabled .rt-image-cropper__handle{cursor:default}.rt-image-cropper--disabled .rt-image-cropper__handle,.rt-image-cropper--disabled .rt-image-cropper__image{opacity:var(--rt-image-cropper-disabled-opacity)}@media(pointer:coarse){.rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}}\n"], dependencies: [{ kind: "directive", type:
509
- // standalone components / directives
510
- BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "component", type: RtSpinnerComponent, selector: "rt-spinner", inputs: ["diameter", "color", "appearance", "overlay", "backdrop", "plate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
511
- }
512
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtImageCropperComponent, decorators: [{
513
- type: Component,
514
- args: [{ selector: 'rt-image-cropper', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
515
- // standalone components / directives
516
- BlockDirective,
517
- ElemDirective,
518
- ModDirective,
519
- RtSpinnerComponent,
520
- ], host: {
521
- class: BEM_BLOCK,
522
- '[class.rt-image-cropper--round]': 'round()',
523
- '[class.rt-image-cropper--disabled]': 'disabled()',
524
- '[style.--rt-image-cropper-image-x]': "image().x + 'px'",
525
- '[style.--rt-image-cropper-image-y]': "image().y + 'px'",
526
- '[style.--rt-image-cropper-image-width]': "image().width + 'px'",
527
- '[style.--rt-image-cropper-image-height]': "image().height + 'px'",
528
- '[style.--rt-image-cropper-frame-x]': "frameBox().x + 'px'",
529
- '[style.--rt-image-cropper-frame-y]': "frameBox().y + 'px'",
530
- '[style.--rt-image-cropper-frame-width]': "frameBox().width + 'px'",
531
- '[style.--rt-image-cropper-frame-height]': "frameBox().height + 'px'",
532
- }, template: "<ng-container rtBlock=\"rt-image-cropper\">\n <div #field rtElem=\"field\" qa-dataid=\"image-cropper-field\">\n @switch (state()) {\n @case ('empty') {\n <p rtElem=\"placeholder\" qa-dataid=\"image-cropper-placeholder\">{{ placeholderText() }}</p>\n }\n @case ('loading') {\n <rt-spinner rtElem=\"spinner\" qa-dataid=\"image-cropper-spinner\" />\n }\n @case ('refusal') {\n <p rtElem=\"refusal\" qa-dataid=\"image-cropper-refusal\">{{ t().uiImageCropperRefusal }}</p>\n }\n @case ('ready') {\n <img rtElem=\"image\" qa-dataid=\"image-cropper-image\" alt=\"\" draggable=\"false\" [src]=\"url()\" />\n <div\n rtElem=\"frame\"\n qa-dataid=\"image-cropper-frame\"\n role=\"group\"\n [attr.aria-label]=\"t().uiImageCropperFrame\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, null)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, null)\">\n @for (handle of handles; track handle) {\n <span\n rtElem=\"handle\"\n role=\"button\"\n [attr.qa-dataid]=\"'image-cropper-handle-' + handle\"\n [rtMod]=\"{ side: handle }\"\n [attr.aria-label]=\"t()[handleLabels[handle]]\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, handle)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, handle)\"></span>\n }\n </div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-cropper{--rt-image-cropper-height: calc(var(--rt-size-20) * 4);--rt-image-cropper-radius: var(--rt-radius-md);--rt-image-cropper-frame-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: var(--rt-color-bg-subtle);--rt-image-cropper-shade: var(--rt-overlay-black-50);--rt-image-cropper-rim-width: var(--rt-border-width-thin);--rt-image-cropper-rim-color: var(--rt-overlay-white-50);--rt-image-cropper-dash-style: none;--rt-image-cropper-dash-color: transparent;--rt-image-cropper-dash-opacity: 1;--rt-image-cropper-handle-size: var(--rt-size-3);--rt-image-cropper-handle-bg: var(--rt-color-action-on-primary);--rt-image-cropper-handle-border: var(--rt-color-border-strong);--rt-image-cropper-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-cropper-text-color: var(--rt-color-text-muted);--rt-image-cropper-disabled-opacity: .5;--rt-image-cropper-image-x: 0;--rt-image-cropper-image-y: 0;--rt-image-cropper-image-width: 0;--rt-image-cropper-image-height: 0;--rt-image-cropper-frame-x: 0;--rt-image-cropper-frame-y: 0;--rt-image-cropper-frame-width: 0;--rt-image-cropper-frame-height: 0;display:block;width:100%}.rt-image-cropper__field{position:relative;overflow:hidden;height:var(--rt-image-cropper-height);border-radius:var(--rt-image-cropper-radius);background:var(--rt-image-cropper-field-bg);-webkit-user-select:none;user-select:none}.rt-image-cropper__spinner{position:absolute;inset:50% auto auto 50%;translate:-50% -50%}.rt-image-cropper__placeholder,.rt-image-cropper__refusal{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-md);margin:0;color:var(--rt-image-cropper-text-color);inset:0;text-align:center}.rt-image-cropper__image{position:absolute;top:var(--rt-image-cropper-image-y);left:var(--rt-image-cropper-image-x);width:var(--rt-image-cropper-image-width);max-width:none;height:var(--rt-image-cropper-image-height);image-orientation:from-image;pointer-events:none}.rt-image-cropper__frame{position:absolute;top:var(--rt-image-cropper-frame-y);left:var(--rt-image-cropper-frame-x);width:var(--rt-image-cropper-frame-width);height:var(--rt-image-cropper-frame-height);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-rim-color);border-radius:var(--rt-image-cropper-frame-radius);cursor:move;outline:100vmax solid var(--rt-image-cropper-shade);touch-action:none}.rt-image-cropper__frame:after{position:absolute;border:var(--rt-image-cropper-rim-width) var(--rt-image-cropper-dash-style) var(--rt-image-cropper-dash-color);border-radius:inherit;content:\"\";inset:calc(-1 * var(--rt-image-cropper-rim-width));opacity:var(--rt-image-cropper-dash-opacity);pointer-events:none}.rt-image-cropper__frame:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow)}.rt-image-cropper__handle{position:absolute;width:var(--rt-image-cropper-handle-size);height:var(--rt-image-cropper-handle-size);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-handle-border);background:var(--rt-image-cropper-handle-bg);touch-action:none}.rt-image-cropper__handle:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow);outline:none}.rt-image-cropper__handle--side--nw{top:0;left:0;cursor:nwse-resize}.rt-image-cropper__handle--side--n{top:0;left:50%;cursor:ns-resize;translate:-50% 0}.rt-image-cropper__handle--side--ne{top:0;left:100%;cursor:nesw-resize;translate:-100% 0}.rt-image-cropper__handle--side--e{top:50%;left:100%;cursor:ew-resize;translate:-100% -50%}.rt-image-cropper__handle--side--se{top:100%;left:100%;cursor:nwse-resize;translate:-100% -100%}.rt-image-cropper__handle--side--s{top:100%;left:50%;cursor:ns-resize;translate:-50% -100%}.rt-image-cropper__handle--side--sw{top:100%;left:0;cursor:nesw-resize;translate:0 -100%}.rt-image-cropper__handle--side--w{top:50%;left:0;cursor:ew-resize;translate:0 -50%}:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: transparent;--rt-image-cropper-shade: var(--rt-overlay-white-25);--rt-image-cropper-dash-style: dashed;--rt-image-cropper-dash-color: var(--rt-mat-dark-40);--rt-image-cropper-dash-opacity: .75;--rt-image-cropper-handle-size: var(--rt-size-2);--rt-image-cropper-handle-bg: var(--rt-mat-dark-40);--rt-image-cropper-handle-border: var(--rt-overlay-white-50)}@media(pointer:coarse){:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}.rt-image-cropper--round{--rt-image-cropper-frame-radius: var(--rt-radius-full)}.rt-image-cropper--disabled .rt-image-cropper__frame,.rt-image-cropper--disabled .rt-image-cropper__handle{cursor:default}.rt-image-cropper--disabled .rt-image-cropper__handle,.rt-image-cropper--disabled .rt-image-cropper__image{opacity:var(--rt-image-cropper-disabled-opacity)}@media(pointer:coarse){.rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}}\n"] }]
533
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.ViewChild, args: ['field', { isSignal: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], file: [{ type: i0.Input, args: [{ isSignal: true, alias: "file", required: false }] }], ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], round: [{ type: i0.Input, args: [{ isSignal: true, alias: "round", required: false }] }], minSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], quality: [{ type: i0.Input, args: [{ isSignal: true, alias: "quality", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], cropped: [{ type: i0.Output, args: ["cropped"] }], loadFailed: [{ type: i0.Output, args: ["loadFailed"] }] } });
534
-
535
- /**
536
- * Generated bundle index. Do not edit.
537
- */
538
-
219
+ var RtImageCropperComponent = class RtImageCropperComponent {
220
+ #destroyRef;
221
+ #window;
222
+ #document;
223
+ #platform;
224
+ #fieldSize;
225
+ #source;
226
+ #frame;
227
+ #ratio;
228
+ #fit;
229
+ #image;
230
+ #pending;
231
+ #sourceType;
232
+ #sourceName;
233
+ #drag;
234
+ #resultTicket;
235
+ constructor() {
236
+ this.#destroyRef = inject(DestroyRef);
237
+ this.#window = inject(WINDOW);
238
+ this.#document = inject(DOCUMENT);
239
+ this.#platform = inject(PlatformService);
240
+ this.#fieldSize = signal({
241
+ width: 0,
242
+ height: 0
243
+ }, ...ngDevMode ? [{ debugName: "#fieldSize" }] : /* istanbul ignore next */ []);
244
+ this.#source = signal({
245
+ width: 0,
246
+ height: 0
247
+ }, ...ngDevMode ? [{ debugName: "#source" }] : /* istanbul ignore next */ []);
248
+ this.#frame = signal({
249
+ x: 0,
250
+ y: 0,
251
+ width: 0,
252
+ height: 0
253
+ }, ...ngDevMode ? [{ debugName: "#frame" }] : /* istanbul ignore next */ []);
254
+ this.#ratio = computed(() => frameRatio(this.ratio(), this.round()), ...ngDevMode ? [{ debugName: "#ratio" }] : /* istanbul ignore next */ []);
255
+ this.#fit = computed(() => fitSource(this.#source(), this.#fieldSize()), ...ngDevMode ? [{ debugName: "#fit" }] : /* istanbul ignore next */ []);
256
+ this.#image = null;
257
+ this.#pending = null;
258
+ this.#sourceType = "";
259
+ this.#sourceName = "";
260
+ this.#drag = null;
261
+ this.#resultTicket = 0;
262
+ this.field = viewChild.required("field", ...ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []);
263
+ this.t = inject(RT_KIT_LABELS);
264
+ this.handles = RT_IMAGE_CROPPER_HANDLES;
265
+ this.handleLabels = HANDLE_LABELS;
266
+ this.state = signal("empty", ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
267
+ this.placeholderText = computed(() => this.placeholder() || this.t().uiImageCropperPlaceholder, ...ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []);
268
+ this.url = signal(null, ...ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []);
269
+ this.image = computed(() => {
270
+ const fit = this.#fit();
271
+ return {
272
+ x: fit.offsetX,
273
+ y: fit.offsetY,
274
+ width: fit.width,
275
+ height: fit.height
276
+ };
277
+ }, ...ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []);
278
+ this.frameBox = computed(() => frameInField(this.#frame(), this.#fit()), ...ngDevMode ? [{ debugName: "frameBox" }] : /* istanbul ignore next */ []);
279
+ this.placeholder = input("", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
280
+ this.file = input(null, ...ngDevMode ? [{ debugName: "file" }] : /* istanbul ignore next */ []);
281
+ this.ratio = input(null, {
282
+ ...ngDevMode ? { debugName: "ratio" } : /* istanbul ignore next */ {},
283
+ transform: optionalNumber
284
+ });
285
+ this.round = input(false, {
286
+ ...ngDevMode ? { debugName: "round" } : /* istanbul ignore next */ {},
287
+ transform: booleanAttribute
288
+ });
289
+ this.minSize = input(DEFAULT_MIN_SIZE, {
290
+ ...ngDevMode ? { debugName: "minSize" } : /* istanbul ignore next */ {},
291
+ transform: (value) => numberAttribute(value, DEFAULT_MIN_SIZE)
292
+ });
293
+ this.format = input(null, ...ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []);
294
+ this.quality = input(92, {
295
+ ...ngDevMode ? { debugName: "quality" } : /* istanbul ignore next */ {},
296
+ transform: (value) => numberAttribute(value, 92)
297
+ });
298
+ this.disabled = input(false, {
299
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
300
+ transform: booleanAttribute
301
+ });
302
+ this.cropped = output();
303
+ this.loadFailed = output();
304
+ effect(() => {
305
+ const file = this.file();
306
+ untracked(() => this.#load(file));
307
+ });
308
+ effect(() => {
309
+ const ratio = this.#ratio();
310
+ untracked(() => {
311
+ if (this.state() === "ready") {
312
+ this.#frame.set(initialFrame(this.#source(), ratio));
313
+ this.#emitResult();
314
+ }
315
+ });
316
+ });
317
+ afterNextRender(() => this.#observe(this.field().nativeElement));
318
+ this.#destroyRef.onDestroy(() => this.#revoke());
319
+ }
320
+ onPointerDown(event, handle) {
321
+ if (this.disabled() || this.#drag !== null || event.pointerType === "mouse" && event.button !== 0) return;
322
+ event.preventDefault();
323
+ event.stopPropagation();
324
+ const target = event.currentTarget;
325
+ if (target instanceof this.#window.HTMLElement && typeof target.setPointerCapture === "function") target.setPointerCapture(event.pointerId);
326
+ this.#drag = {
327
+ pointerId: event.pointerId,
328
+ startX: event.clientX,
329
+ startY: event.clientY,
330
+ startFrame: this.#frame(),
331
+ handle
332
+ };
333
+ }
334
+ onPointerMove(event) {
335
+ const drag = this.#drag;
336
+ if (drag === null || drag.pointerId !== event.pointerId) return;
337
+ event.preventDefault();
338
+ event.stopPropagation();
339
+ const delta = fieldDelta(event.clientX - drag.startX, event.clientY - drag.startY, this.#fit().scale);
340
+ this.#frame.set(this.#change(drag.startFrame, drag.handle, delta));
341
+ }
342
+ onPointerUp(event) {
343
+ const drag = this.#drag;
344
+ if (drag === null || drag.pointerId !== event.pointerId) return;
345
+ event.stopPropagation();
346
+ this.#drag = null;
347
+ const target = event.currentTarget;
348
+ if (target instanceof this.#window.HTMLElement && typeof target.releasePointerCapture === "function") target.releasePointerCapture(event.pointerId);
349
+ if (!sameRect(drag.startFrame, this.#frame())) this.#emitResult();
350
+ }
351
+ onKeyDown(event, handle) {
352
+ if (this.disabled()) return;
353
+ const delta = keyDelta(event.key, event.shiftKey, this.#fit().scale);
354
+ if (delta === null) return;
355
+ event.preventDefault();
356
+ event.stopPropagation();
357
+ const before = this.#frame();
358
+ const next = this.#change(before, handle, delta);
359
+ if (!sameRect(before, next)) {
360
+ this.#frame.set(next);
361
+ this.#emitResult();
362
+ }
363
+ }
364
+ #change(frame, handle, delta) {
365
+ return handle === null ? moveFrame(frame, delta, this.#source()) : resizeFrame(frame, handle, delta, this.#source(), this.#ratio(), this.minSize());
366
+ }
367
+ #load(file) {
368
+ this.#revoke();
369
+ this.#image = null;
370
+ this.#pending = null;
371
+ this.#drag = null;
372
+ this.#resultTicket++;
373
+ if (file === null || !this.#platform.isPlatformBrowser) {
374
+ this.state.set("empty");
375
+ return;
376
+ }
377
+ this.#sourceType = file.type;
378
+ this.#sourceName = file instanceof this.#window.File ? file.name : "";
379
+ const url = this.#window.URL.createObjectURL(file);
380
+ const image = new this.#window.Image();
381
+ this.#pending = image;
382
+ this.url.set(url);
383
+ this.state.set("loading");
384
+ image.onload = () => {
385
+ if (this.#pending === image) {
386
+ this.#pending = null;
387
+ this.#ready(image);
388
+ }
389
+ };
390
+ image.onerror = () => {
391
+ if (this.#pending === image) {
392
+ this.#pending = null;
393
+ this.#refuse();
394
+ }
395
+ };
396
+ image.src = url;
397
+ }
398
+ #ready(image) {
399
+ if (image.naturalWidth <= 0 || image.naturalHeight <= 0) {
400
+ this.#refuse();
401
+ return;
402
+ }
403
+ this.#image = image;
404
+ this.#source.set({
405
+ width: image.naturalWidth,
406
+ height: image.naturalHeight
407
+ });
408
+ this.#frame.set(initialFrame(this.#source(), this.#ratio()));
409
+ this.state.set("ready");
410
+ this.#emitResult();
411
+ }
412
+ #refuse() {
413
+ this.state.set("refusal");
414
+ this.loadFailed.emit();
415
+ }
416
+ #revoke() {
417
+ const url = this.url();
418
+ if (url !== null) {
419
+ this.#window.URL.revokeObjectURL(url);
420
+ this.url.set(null);
421
+ }
422
+ }
423
+ #observe(field) {
424
+ const measure = () => this.#fieldSize.set({
425
+ width: field.clientWidth,
426
+ height: field.clientHeight
427
+ });
428
+ measure();
429
+ if (typeof this.#window.ResizeObserver !== "function") return;
430
+ const observer = new this.#window.ResizeObserver(measure);
431
+ observer.observe(field);
432
+ this.#destroyRef.onDestroy(() => observer.disconnect());
433
+ }
434
+ #emitResult() {
435
+ const image = this.#image;
436
+ if (image === null) return;
437
+ this.#resultTicket++;
438
+ const ticket = this.#resultTicket;
439
+ const area = cropArea(this.#frame(), this.#source());
440
+ const canvas = this.#document.createElement("canvas");
441
+ canvas.width = area.width;
442
+ canvas.height = area.height;
443
+ const context = canvas.getContext("2d");
444
+ if (context === null) return;
445
+ context.drawImage(image, area.x, area.y, area.width, area.height, 0, 0, area.width, area.height);
446
+ const type = resultType(this.format(), this.#sourceType);
447
+ canvas.toBlob((blob) => {
448
+ if (blob === null || ticket !== this.#resultTicket) return;
449
+ const file = new this.#window.File([blob], resultFileName(this.#sourceName, type), { type });
450
+ this.cropped.emit({
451
+ file,
452
+ frame: area
453
+ });
454
+ }, type, resultQuality(this.quality()));
455
+ }
456
+ static {
457
+ this.ɵfac = i0.ɵɵngDeclareFactory({
458
+ minVersion: "12.0.0",
459
+ version: "22.2.2",
460
+ ngImport: i0,
461
+ type: RtImageCropperComponent,
462
+ deps: [],
463
+ target: i0.ɵɵFactoryTarget.Component
464
+ });
465
+ }
466
+ static {
467
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
468
+ minVersion: "17.0.0",
469
+ version: "22.2.2",
470
+ type: RtImageCropperComponent,
471
+ isStandalone: true,
472
+ selector: "rt-image-cropper",
473
+ inputs: {
474
+ placeholder: {
475
+ classPropertyName: "placeholder",
476
+ publicName: "placeholder",
477
+ isSignal: true,
478
+ isRequired: false,
479
+ transformFunction: null
480
+ },
481
+ file: {
482
+ classPropertyName: "file",
483
+ publicName: "file",
484
+ isSignal: true,
485
+ isRequired: false,
486
+ transformFunction: null
487
+ },
488
+ ratio: {
489
+ classPropertyName: "ratio",
490
+ publicName: "ratio",
491
+ isSignal: true,
492
+ isRequired: false,
493
+ transformFunction: null
494
+ },
495
+ round: {
496
+ classPropertyName: "round",
497
+ publicName: "round",
498
+ isSignal: true,
499
+ isRequired: false,
500
+ transformFunction: null
501
+ },
502
+ minSize: {
503
+ classPropertyName: "minSize",
504
+ publicName: "minSize",
505
+ isSignal: true,
506
+ isRequired: false,
507
+ transformFunction: null
508
+ },
509
+ format: {
510
+ classPropertyName: "format",
511
+ publicName: "format",
512
+ isSignal: true,
513
+ isRequired: false,
514
+ transformFunction: null
515
+ },
516
+ quality: {
517
+ classPropertyName: "quality",
518
+ publicName: "quality",
519
+ isSignal: true,
520
+ isRequired: false,
521
+ transformFunction: null
522
+ },
523
+ disabled: {
524
+ classPropertyName: "disabled",
525
+ publicName: "disabled",
526
+ isSignal: true,
527
+ isRequired: false,
528
+ transformFunction: null
529
+ }
530
+ },
531
+ outputs: {
532
+ cropped: "cropped",
533
+ loadFailed: "loadFailed"
534
+ },
535
+ host: {
536
+ properties: {
537
+ "class.rt-image-cropper--round": "round()",
538
+ "class.rt-image-cropper--disabled": "disabled()",
539
+ "style.--rt-image-cropper-image-x": "image().x + 'px'",
540
+ "style.--rt-image-cropper-image-y": "image().y + 'px'",
541
+ "style.--rt-image-cropper-image-width": "image().width + 'px'",
542
+ "style.--rt-image-cropper-image-height": "image().height + 'px'",
543
+ "style.--rt-image-cropper-frame-x": "frameBox().x + 'px'",
544
+ "style.--rt-image-cropper-frame-y": "frameBox().y + 'px'",
545
+ "style.--rt-image-cropper-frame-width": "frameBox().width + 'px'",
546
+ "style.--rt-image-cropper-frame-height": "frameBox().height + 'px'"
547
+ },
548
+ classAttribute: "rt-image-cropper"
549
+ },
550
+ viewQueries: [{
551
+ propertyName: "field",
552
+ first: true,
553
+ predicate: ["field"],
554
+ descendants: true,
555
+ isSignal: true
556
+ }],
557
+ ngImport: i0,
558
+ template: "<ng-container rtBlock=\"rt-image-cropper\">\n <div #field rtElem=\"field\" qa-dataid=\"image-cropper-field\">\n @switch (state()) {\n @case ('empty') {\n <p rtElem=\"placeholder\" qa-dataid=\"image-cropper-placeholder\">{{ placeholderText() }}</p>\n }\n @case ('loading') {\n <rt-spinner rtElem=\"spinner\" qa-dataid=\"image-cropper-spinner\" />\n }\n @case ('refusal') {\n <p rtElem=\"refusal\" qa-dataid=\"image-cropper-refusal\">{{ t().uiImageCropperRefusal }}</p>\n }\n @case ('ready') {\n <img rtElem=\"image\" qa-dataid=\"image-cropper-image\" alt=\"\" draggable=\"false\" [src]=\"url()\" />\n <div\n rtElem=\"frame\"\n qa-dataid=\"image-cropper-frame\"\n role=\"group\"\n [attr.aria-label]=\"t().uiImageCropperFrame\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, null)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, null)\">\n @for (handle of handles; track handle) {\n <span\n rtElem=\"handle\"\n role=\"button\"\n [attr.qa-dataid]=\"'image-cropper-handle-' + handle\"\n [rtMod]=\"{ side: handle }\"\n [attr.aria-label]=\"t()[handleLabels[handle]]\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, handle)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, handle)\"></span>\n }\n </div>\n }\n }\n </div>\n</ng-container>\n",
559
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-cropper{--rt-image-cropper-height: calc(var(--rt-size-20) * 4);--rt-image-cropper-radius: var(--rt-radius-md);--rt-image-cropper-frame-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: var(--rt-color-bg-subtle);--rt-image-cropper-shade: var(--rt-overlay-black-50);--rt-image-cropper-rim-width: var(--rt-border-width-thin);--rt-image-cropper-rim-color: var(--rt-overlay-white-50);--rt-image-cropper-dash-style: none;--rt-image-cropper-dash-color: transparent;--rt-image-cropper-dash-opacity: 1;--rt-image-cropper-handle-size: var(--rt-size-3);--rt-image-cropper-handle-bg: var(--rt-color-action-on-primary);--rt-image-cropper-handle-border: var(--rt-color-border-strong);--rt-image-cropper-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-cropper-text-color: var(--rt-color-text-muted);--rt-image-cropper-disabled-opacity: .5;--rt-image-cropper-image-x: 0;--rt-image-cropper-image-y: 0;--rt-image-cropper-image-width: 0;--rt-image-cropper-image-height: 0;--rt-image-cropper-frame-x: 0;--rt-image-cropper-frame-y: 0;--rt-image-cropper-frame-width: 0;--rt-image-cropper-frame-height: 0;display:block;width:100%}.rt-image-cropper__field{position:relative;overflow:hidden;height:var(--rt-image-cropper-height);border-radius:var(--rt-image-cropper-radius);background:var(--rt-image-cropper-field-bg);-webkit-user-select:none;user-select:none}.rt-image-cropper__spinner{position:absolute;inset:50% auto auto 50%;translate:-50% -50%}.rt-image-cropper__placeholder,.rt-image-cropper__refusal{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-md);margin:0;color:var(--rt-image-cropper-text-color);inset:0;text-align:center}.rt-image-cropper__image{position:absolute;top:var(--rt-image-cropper-image-y);left:var(--rt-image-cropper-image-x);width:var(--rt-image-cropper-image-width);max-width:none;height:var(--rt-image-cropper-image-height);image-orientation:from-image;pointer-events:none}.rt-image-cropper__frame{position:absolute;top:var(--rt-image-cropper-frame-y);left:var(--rt-image-cropper-frame-x);width:var(--rt-image-cropper-frame-width);height:var(--rt-image-cropper-frame-height);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-rim-color);border-radius:var(--rt-image-cropper-frame-radius);cursor:move;outline:100vmax solid var(--rt-image-cropper-shade);touch-action:none}.rt-image-cropper__frame:after{position:absolute;border:var(--rt-image-cropper-rim-width) var(--rt-image-cropper-dash-style) var(--rt-image-cropper-dash-color);border-radius:inherit;content:\"\";inset:calc(-1 * var(--rt-image-cropper-rim-width));opacity:var(--rt-image-cropper-dash-opacity);pointer-events:none}.rt-image-cropper__frame:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow)}.rt-image-cropper__handle{position:absolute;width:var(--rt-image-cropper-handle-size);height:var(--rt-image-cropper-handle-size);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-handle-border);background:var(--rt-image-cropper-handle-bg);touch-action:none}.rt-image-cropper__handle:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow);outline:none}.rt-image-cropper__handle--side--nw{top:0;left:0;cursor:nwse-resize}.rt-image-cropper__handle--side--n{top:0;left:50%;cursor:ns-resize;translate:-50% 0}.rt-image-cropper__handle--side--ne{top:0;left:100%;cursor:nesw-resize;translate:-100% 0}.rt-image-cropper__handle--side--e{top:50%;left:100%;cursor:ew-resize;translate:-100% -50%}.rt-image-cropper__handle--side--se{top:100%;left:100%;cursor:nwse-resize;translate:-100% -100%}.rt-image-cropper__handle--side--s{top:100%;left:50%;cursor:ns-resize;translate:-50% -100%}.rt-image-cropper__handle--side--sw{top:100%;left:0;cursor:nesw-resize;translate:0 -100%}.rt-image-cropper__handle--side--w{top:50%;left:0;cursor:ew-resize;translate:0 -50%}:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: transparent;--rt-image-cropper-shade: var(--rt-overlay-white-25);--rt-image-cropper-dash-style: dashed;--rt-image-cropper-dash-color: var(--rt-mat-dark-40);--rt-image-cropper-dash-opacity: .75;--rt-image-cropper-handle-size: var(--rt-size-2);--rt-image-cropper-handle-bg: var(--rt-mat-dark-40);--rt-image-cropper-handle-border: var(--rt-overlay-white-50)}@media(pointer:coarse){:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}.rt-image-cropper--round{--rt-image-cropper-frame-radius: var(--rt-radius-full)}.rt-image-cropper--disabled .rt-image-cropper__frame,.rt-image-cropper--disabled .rt-image-cropper__handle{cursor:default}.rt-image-cropper--disabled .rt-image-cropper__handle,.rt-image-cropper--disabled .rt-image-cropper__image{opacity:var(--rt-image-cropper-disabled-opacity)}@media(pointer:coarse){.rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}}\n"],
560
+ dependencies: [
561
+ {
562
+ kind: "directive",
563
+ type: BlockDirective,
564
+ selector: "[rtBlock]",
565
+ inputs: ["rtMod"]
566
+ },
567
+ {
568
+ kind: "directive",
569
+ type: ElemDirective,
570
+ selector: "[rtElem]",
571
+ inputs: ["rtMod"]
572
+ },
573
+ {
574
+ kind: "directive",
575
+ type: ModDirective,
576
+ selector: "[rtMod]"
577
+ },
578
+ {
579
+ kind: "component",
580
+ type: RtSpinnerComponent,
581
+ selector: "rt-spinner",
582
+ inputs: [
583
+ "diameter",
584
+ "color",
585
+ "appearance",
586
+ "overlay",
587
+ "backdrop",
588
+ "plate"
589
+ ]
590
+ }
591
+ ],
592
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
593
+ encapsulation: i0.ViewEncapsulation.None
594
+ });
595
+ }
596
+ };
597
+ i0.ɵɵngDeclareClassMetadata({
598
+ minVersion: "12.0.0",
599
+ version: "22.2.2",
600
+ ngImport: i0,
601
+ type: RtImageCropperComponent,
602
+ decorators: [{
603
+ type: Component,
604
+ args: [{
605
+ selector: "rt-image-cropper",
606
+ changeDetection: ChangeDetectionStrategy.OnPush,
607
+ encapsulation: ViewEncapsulation.None,
608
+ imports: [
609
+ BlockDirective,
610
+ ElemDirective,
611
+ ModDirective,
612
+ RtSpinnerComponent
613
+ ],
614
+ host: {
615
+ class: BEM_BLOCK,
616
+ "[class.rt-image-cropper--round]": "round()",
617
+ "[class.rt-image-cropper--disabled]": "disabled()",
618
+ "[style.--rt-image-cropper-image-x]": "image().x + 'px'",
619
+ "[style.--rt-image-cropper-image-y]": "image().y + 'px'",
620
+ "[style.--rt-image-cropper-image-width]": "image().width + 'px'",
621
+ "[style.--rt-image-cropper-image-height]": "image().height + 'px'",
622
+ "[style.--rt-image-cropper-frame-x]": "frameBox().x + 'px'",
623
+ "[style.--rt-image-cropper-frame-y]": "frameBox().y + 'px'",
624
+ "[style.--rt-image-cropper-frame-width]": "frameBox().width + 'px'",
625
+ "[style.--rt-image-cropper-frame-height]": "frameBox().height + 'px'"
626
+ },
627
+ template: "<ng-container rtBlock=\"rt-image-cropper\">\n <div #field rtElem=\"field\" qa-dataid=\"image-cropper-field\">\n @switch (state()) {\n @case ('empty') {\n <p rtElem=\"placeholder\" qa-dataid=\"image-cropper-placeholder\">{{ placeholderText() }}</p>\n }\n @case ('loading') {\n <rt-spinner rtElem=\"spinner\" qa-dataid=\"image-cropper-spinner\" />\n }\n @case ('refusal') {\n <p rtElem=\"refusal\" qa-dataid=\"image-cropper-refusal\">{{ t().uiImageCropperRefusal }}</p>\n }\n @case ('ready') {\n <img rtElem=\"image\" qa-dataid=\"image-cropper-image\" alt=\"\" draggable=\"false\" [src]=\"url()\" />\n <div\n rtElem=\"frame\"\n qa-dataid=\"image-cropper-frame\"\n role=\"group\"\n [attr.aria-label]=\"t().uiImageCropperFrame\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, null)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, null)\">\n @for (handle of handles; track handle) {\n <span\n rtElem=\"handle\"\n role=\"button\"\n [attr.qa-dataid]=\"'image-cropper-handle-' + handle\"\n [rtMod]=\"{ side: handle }\"\n [attr.aria-label]=\"t()[handleLabels[handle]]\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, handle)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, handle)\"></span>\n }\n </div>\n }\n }\n </div>\n</ng-container>\n",
628
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-cropper{--rt-image-cropper-height: calc(var(--rt-size-20) * 4);--rt-image-cropper-radius: var(--rt-radius-md);--rt-image-cropper-frame-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: var(--rt-color-bg-subtle);--rt-image-cropper-shade: var(--rt-overlay-black-50);--rt-image-cropper-rim-width: var(--rt-border-width-thin);--rt-image-cropper-rim-color: var(--rt-overlay-white-50);--rt-image-cropper-dash-style: none;--rt-image-cropper-dash-color: transparent;--rt-image-cropper-dash-opacity: 1;--rt-image-cropper-handle-size: var(--rt-size-3);--rt-image-cropper-handle-bg: var(--rt-color-action-on-primary);--rt-image-cropper-handle-border: var(--rt-color-border-strong);--rt-image-cropper-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-cropper-text-color: var(--rt-color-text-muted);--rt-image-cropper-disabled-opacity: .5;--rt-image-cropper-image-x: 0;--rt-image-cropper-image-y: 0;--rt-image-cropper-image-width: 0;--rt-image-cropper-image-height: 0;--rt-image-cropper-frame-x: 0;--rt-image-cropper-frame-y: 0;--rt-image-cropper-frame-width: 0;--rt-image-cropper-frame-height: 0;display:block;width:100%}.rt-image-cropper__field{position:relative;overflow:hidden;height:var(--rt-image-cropper-height);border-radius:var(--rt-image-cropper-radius);background:var(--rt-image-cropper-field-bg);-webkit-user-select:none;user-select:none}.rt-image-cropper__spinner{position:absolute;inset:50% auto auto 50%;translate:-50% -50%}.rt-image-cropper__placeholder,.rt-image-cropper__refusal{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-md);margin:0;color:var(--rt-image-cropper-text-color);inset:0;text-align:center}.rt-image-cropper__image{position:absolute;top:var(--rt-image-cropper-image-y);left:var(--rt-image-cropper-image-x);width:var(--rt-image-cropper-image-width);max-width:none;height:var(--rt-image-cropper-image-height);image-orientation:from-image;pointer-events:none}.rt-image-cropper__frame{position:absolute;top:var(--rt-image-cropper-frame-y);left:var(--rt-image-cropper-frame-x);width:var(--rt-image-cropper-frame-width);height:var(--rt-image-cropper-frame-height);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-rim-color);border-radius:var(--rt-image-cropper-frame-radius);cursor:move;outline:100vmax solid var(--rt-image-cropper-shade);touch-action:none}.rt-image-cropper__frame:after{position:absolute;border:var(--rt-image-cropper-rim-width) var(--rt-image-cropper-dash-style) var(--rt-image-cropper-dash-color);border-radius:inherit;content:\"\";inset:calc(-1 * var(--rt-image-cropper-rim-width));opacity:var(--rt-image-cropper-dash-opacity);pointer-events:none}.rt-image-cropper__frame:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow)}.rt-image-cropper__handle{position:absolute;width:var(--rt-image-cropper-handle-size);height:var(--rt-image-cropper-handle-size);box-sizing:border-box;border:var(--rt-image-cropper-rim-width) solid var(--rt-image-cropper-handle-border);background:var(--rt-image-cropper-handle-bg);touch-action:none}.rt-image-cropper__handle:focus-visible{box-shadow:var(--rt-image-cropper-focus-shadow);outline:none}.rt-image-cropper__handle--side--nw{top:0;left:0;cursor:nwse-resize}.rt-image-cropper__handle--side--n{top:0;left:50%;cursor:ns-resize;translate:-50% 0}.rt-image-cropper__handle--side--ne{top:0;left:100%;cursor:nesw-resize;translate:-100% 0}.rt-image-cropper__handle--side--e{top:50%;left:100%;cursor:ew-resize;translate:-100% -50%}.rt-image-cropper__handle--side--se{top:100%;left:100%;cursor:nwse-resize;translate:-100% -100%}.rt-image-cropper__handle--side--s{top:100%;left:50%;cursor:ns-resize;translate:-50% -100%}.rt-image-cropper__handle--side--sw{top:100%;left:0;cursor:nesw-resize;translate:0 -100%}.rt-image-cropper__handle--side--w{top:50%;left:0;cursor:ew-resize;translate:0 -50%}:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-radius: var(--rt-radius-none);--rt-image-cropper-field-bg: transparent;--rt-image-cropper-shade: var(--rt-overlay-white-25);--rt-image-cropper-dash-style: dashed;--rt-image-cropper-dash-color: var(--rt-mat-dark-40);--rt-image-cropper-dash-opacity: .75;--rt-image-cropper-handle-size: var(--rt-size-2);--rt-image-cropper-handle-bg: var(--rt-mat-dark-40);--rt-image-cropper-handle-border: var(--rt-overlay-white-50)}@media(pointer:coarse){:is(.rt-preset-material,[data-preset=material]) .rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}.rt-image-cropper--round{--rt-image-cropper-frame-radius: var(--rt-radius-full)}.rt-image-cropper--disabled .rt-image-cropper__frame,.rt-image-cropper--disabled .rt-image-cropper__handle{cursor:default}.rt-image-cropper--disabled .rt-image-cropper__handle,.rt-image-cropper--disabled .rt-image-cropper__image{opacity:var(--rt-image-cropper-disabled-opacity)}@media(pointer:coarse){.rt-image-cropper{--rt-image-cropper-handle-size: var(--rt-size-6)}}}\n"]
629
+ }]
630
+ }],
631
+ ctorParameters: () => [],
632
+ propDecorators: {
633
+ field: [{
634
+ type: i0.ViewChild,
635
+ args: ["field", { isSignal: true }]
636
+ }],
637
+ placeholder: [{
638
+ type: i0.Input,
639
+ args: [{
640
+ isSignal: true,
641
+ alias: "placeholder",
642
+ required: false
643
+ }]
644
+ }],
645
+ file: [{
646
+ type: i0.Input,
647
+ args: [{
648
+ isSignal: true,
649
+ alias: "file",
650
+ required: false
651
+ }]
652
+ }],
653
+ ratio: [{
654
+ type: i0.Input,
655
+ args: [{
656
+ isSignal: true,
657
+ alias: "ratio",
658
+ required: false
659
+ }]
660
+ }],
661
+ round: [{
662
+ type: i0.Input,
663
+ args: [{
664
+ isSignal: true,
665
+ alias: "round",
666
+ required: false
667
+ }]
668
+ }],
669
+ minSize: [{
670
+ type: i0.Input,
671
+ args: [{
672
+ isSignal: true,
673
+ alias: "minSize",
674
+ required: false
675
+ }]
676
+ }],
677
+ format: [{
678
+ type: i0.Input,
679
+ args: [{
680
+ isSignal: true,
681
+ alias: "format",
682
+ required: false
683
+ }]
684
+ }],
685
+ quality: [{
686
+ type: i0.Input,
687
+ args: [{
688
+ isSignal: true,
689
+ alias: "quality",
690
+ required: false
691
+ }]
692
+ }],
693
+ disabled: [{
694
+ type: i0.Input,
695
+ args: [{
696
+ isSignal: true,
697
+ alias: "disabled",
698
+ required: false
699
+ }]
700
+ }],
701
+ cropped: [{
702
+ type: i0.Output,
703
+ args: ["cropped"]
704
+ }],
705
+ loadFailed: [{
706
+ type: i0.Output,
707
+ args: ["loadFailed"]
708
+ }]
709
+ }
710
+ });
539
711
  export { RT_IMAGE_CROPPER_HANDLES, RT_IMAGE_CROPPER_KEY_STEP, RT_IMAGE_CROPPER_KEY_STEP_LARGE, RT_IMAGE_CROPPER_QUALITY, RtImageCropperComponent, cropArea, fieldDelta, fitSource, frameInField, frameRatio, handleDirection, initialFrame, keyDelta, moveFrame, resizeFrame, resultFileName, resultQuality, resultType };
540
- //# sourceMappingURL=rt-tools-ui-kit-v2-image-cropper.mjs.map
712
+
713
+ //# sourceMappingURL=rt-tools-ui-kit-v2-image-cropper.mjs.map