@alfakit/vue 0.1.2 → 0.1.7

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 (281) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/AlfakitRoot.js.map +1 -1
  3. package/dist/AlfakitRoot.vue.d.ts.map +1 -1
  4. package/dist/AlfakitRoot.vue_vue_type_script_setup_true_lang.js +3 -1
  5. package/dist/AlfakitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/actions/ActionGroupMenu.js.map +1 -1
  7. package/dist/components/actions/ActionGroupMenu.vue.d.ts.map +1 -1
  8. package/dist/components/actions/ActionGroupMenu.vue_vue_type_script_setup_true_lang.js +69 -65
  9. package/dist/components/actions/ActionGroupMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/actions/ActionModal.js.map +1 -1
  11. package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
  12. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +17 -15
  13. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/ai/AiCopilot.js.map +1 -1
  15. package/dist/components/ai/AiCopilot.vue.d.ts +2 -0
  16. package/dist/components/ai/AiCopilot.vue.d.ts.map +1 -1
  17. package/dist/components/ai/AiCopilot.vue_vue_type_script_setup_true_lang.js +7 -2
  18. package/dist/components/ai/AiCopilot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/cms/CmsPage.vue_vue_type_script_setup_true_lang.js +19 -19
  20. package/dist/components/cms/CmsPage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/cms/LivePreview.js.map +1 -1
  22. package/dist/components/cms/LivePreview.vue.d.ts.map +1 -1
  23. package/dist/components/cms/LivePreview.vue_vue_type_script_setup_true_lang.js +83 -83
  24. package/dist/components/cms/LivePreview.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/fields/BuilderField.js.map +1 -1
  26. package/dist/components/fields/BuilderField.vue.d.ts.map +1 -1
  27. package/dist/components/fields/BuilderField.vue_vue_type_script_setup_true_lang.js +162 -157
  28. package/dist/components/fields/BuilderField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  29. package/dist/components/fields/ImageEditorDialog.js.map +1 -1
  30. package/dist/components/fields/ImageEditorDialog.vue.d.ts.map +1 -1
  31. package/dist/components/fields/ImageEditorDialog.vue_vue_type_script_setup_true_lang.js +46 -46
  32. package/dist/components/fields/ImageEditorDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/fields/KeyValueField.js.map +1 -1
  34. package/dist/components/fields/KeyValueField.vue.d.ts.map +1 -1
  35. package/dist/components/fields/KeyValueField.vue_vue_type_script_setup_true_lang.js +66 -66
  36. package/dist/components/fields/KeyValueField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/fields/ModalTablePicker.js.map +1 -1
  38. package/dist/components/fields/ModalTablePicker.vue.d.ts.map +1 -1
  39. package/dist/components/fields/ModalTablePicker.vue_vue_type_script_setup_true_lang.js +113 -113
  40. package/dist/components/fields/ModalTablePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/fields/RepeaterField.js.map +1 -1
  42. package/dist/components/fields/RepeaterField.vue.d.ts.map +1 -1
  43. package/dist/components/fields/RepeaterField.vue_vue_type_script_setup_true_lang.js +12 -12
  44. package/dist/components/fields/RepeaterField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/fields/RichEditorInput.js.map +1 -1
  46. package/dist/components/fields/RichEditorInput.vue.d.ts.map +1 -1
  47. package/dist/components/fields/RichEditorInput.vue_vue_type_script_setup_true_lang.js +166 -165
  48. package/dist/components/fields/RichEditorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/fields/SliderField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/fields/item-actions.d.ts +2 -2
  51. package/dist/components/fields/item-actions.d.ts.map +1 -1
  52. package/dist/components/fields/item-actions.js +31 -31
  53. package/dist/components/fields/item-actions.js.map +1 -1
  54. package/dist/components/form/FormBlock.js.map +1 -1
  55. package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
  56. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +1 -1
  57. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/form/form-context.js +25 -25
  59. package/dist/components/form/form-context.js.map +1 -1
  60. package/dist/components/kanban/KanbanBoard.js.map +1 -1
  61. package/dist/components/kanban/KanbanBoard.vue.d.ts.map +1 -1
  62. package/dist/components/kanban/KanbanBoard.vue_vue_type_script_setup_true_lang.js +5 -2
  63. package/dist/components/kanban/KanbanBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/kanban/KanbanColumnHeader.js.map +1 -1
  65. package/dist/components/kanban/KanbanColumnHeader.vue.d.ts.map +1 -1
  66. package/dist/components/kanban/KanbanColumnHeader.vue_vue_type_script_setup_true_lang.js +64 -64
  67. package/dist/components/kanban/KanbanColumnHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/layout/SectionComponent.js.map +1 -1
  69. package/dist/components/layout/SectionComponent.vue.d.ts.map +1 -1
  70. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js +23 -23
  71. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/panel/DebugPanel.vue_vue_type_script_setup_true_lang.js +8 -8
  73. package/dist/components/panel/DebugPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/panel/GlobalSearchPalette.js.map +1 -1
  75. package/dist/components/panel/GlobalSearchPalette.vue.d.ts.map +1 -1
  76. package/dist/components/panel/GlobalSearchPalette.vue_vue_type_script_setup_true_lang.js +102 -96
  77. package/dist/components/panel/GlobalSearchPalette.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js +10 -10
  79. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/panel/NavGroupFlyout.vue_vue_type_script_setup_true_lang.js +9 -9
  81. package/dist/components/panel/NavGroupFlyout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js +16 -16
  83. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js +10 -10
  85. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  86. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js +35 -35
  87. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/panel/Topbar.vue_vue_type_script_setup_true_lang.js +11 -11
  89. package/dist/components/panel/Topbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  90. package/dist/components/realtime/use-live-updates.d.ts.map +1 -1
  91. package/dist/components/realtime/use-live-updates.js +24 -23
  92. package/dist/components/realtime/use-live-updates.js.map +1 -1
  93. package/dist/components/table/BooleanCell.vue_vue_type_script_setup_true_lang.js +2 -1
  94. package/dist/components/table/BooleanCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/table/ColumnHeader.js.map +1 -1
  96. package/dist/components/table/ColumnHeader.vue.d.ts.map +1 -1
  97. package/dist/components/table/ColumnHeader.vue_vue_type_script_setup_true_lang.js +55 -49
  98. package/dist/components/table/ColumnHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/table/ColumnManager.js.map +1 -1
  100. package/dist/components/table/ColumnManager.vue.d.ts.map +1 -1
  101. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js +5 -4
  102. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js.map +1 -1
  103. package/dist/components/table/ContentLayoutSort.js.map +1 -1
  104. package/dist/components/table/ContentLayoutSort.vue.d.ts.map +1 -1
  105. package/dist/components/table/ContentLayoutSort.vue_vue_type_script_setup_true_lang.js +5 -5
  106. package/dist/components/table/ContentLayoutSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js +2 -1
  108. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/table/SelectComboboxCell.vue_vue_type_script_setup_true_lang.js +2 -1
  110. package/dist/components/table/SelectComboboxCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  111. package/dist/components/table/TableCellContent.js.map +1 -1
  112. package/dist/components/table/TableCellContent.vue.d.ts.map +1 -1
  113. package/dist/components/table/TableCellContent.vue_vue_type_script_setup_true_lang.js +4 -3
  114. package/dist/components/table/TableCellContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/table/TablePagination.js.map +1 -1
  116. package/dist/components/table/TablePagination.vue.d.ts.map +1 -1
  117. package/dist/components/table/TablePagination.vue_vue_type_script_setup_true_lang.js +87 -87
  118. package/dist/components/table/TablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  119. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js +2 -1
  120. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  121. package/dist/components/table/cell-update.d.ts +6 -0
  122. package/dist/components/table/cell-update.d.ts.map +1 -1
  123. package/dist/components/table/cell-update.js.map +1 -1
  124. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
  125. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/components/ui/CommandAutoHighlight.js +7 -0
  127. package/dist/components/ui/CommandAutoHighlight.js.map +1 -0
  128. package/dist/components/ui/CommandAutoHighlight.vue.d.ts +21 -0
  129. package/dist/components/ui/CommandAutoHighlight.vue.d.ts.map +1 -0
  130. package/dist/components/ui/CommandAutoHighlight.vue_vue_type_script_setup_true_lang.js +18 -0
  131. package/dist/components/ui/CommandAutoHighlight.vue_vue_type_script_setup_true_lang.js.map +1 -0
  132. package/dist/components/ui/DialogContent.js.map +1 -1
  133. package/dist/components/ui/DialogContent.vue.d.ts.map +1 -1
  134. package/dist/components/ui/DialogContent.vue_vue_type_script_setup_true_lang.js +13 -12
  135. package/dist/components/ui/DialogContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/ui/PopoverContent.js.map +1 -1
  137. package/dist/components/ui/PopoverContent.vue.d.ts.map +1 -1
  138. package/dist/components/ui/PopoverContent.vue_vue_type_script_setup_true_lang.js +9 -8
  139. package/dist/components/ui/PopoverContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/components/ui/SheetContent.js.map +1 -1
  141. package/dist/components/ui/SheetContent.vue.d.ts.map +1 -1
  142. package/dist/components/ui/SheetContent.vue_vue_type_script_setup_true_lang.js +13 -12
  143. package/dist/components/ui/SheetContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/ui/TooltipContent.js.map +1 -1
  145. package/dist/components/ui/TooltipContent.vue.d.ts.map +1 -1
  146. package/dist/components/ui/TooltipContent.vue_vue_type_script_setup_true_lang.js +9 -8
  147. package/dist/components/ui/TooltipContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  148. package/dist/context.d.ts +7 -0
  149. package/dist/context.d.ts.map +1 -1
  150. package/dist/context.js +29 -26
  151. package/dist/context.js.map +1 -1
  152. package/dist/create-alfakit.d.ts.map +1 -1
  153. package/dist/create-alfakit.js +33 -31
  154. package/dist/create-alfakit.js.map +1 -1
  155. package/dist/eject-manifest.json +11 -2
  156. package/dist/index.d.ts +1 -0
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +219 -217
  159. package/dist/layouts/AppLayout.vue_vue_type_script_setup_true_lang.js +8 -8
  160. package/dist/layouts/AppLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  161. package/dist/layouts/AuthLayout.vue_vue_type_script_setup_true_lang.js +9 -9
  162. package/dist/layouts/FullscreenLayout.vue_vue_type_script_setup_true_lang.js +8 -8
  163. package/dist/layouts/FullscreenLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js +15 -15
  165. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  166. package/dist/layouts/lazy-layouts.d.ts +10 -0
  167. package/dist/layouts/lazy-layouts.d.ts.map +1 -0
  168. package/dist/layouts/lazy-layouts.js +8 -0
  169. package/dist/layouts/lazy-layouts.js.map +1 -0
  170. package/dist/layouts/panel-layouts.d.ts +8 -0
  171. package/dist/layouts/panel-layouts.d.ts.map +1 -0
  172. package/dist/layouts/panel-layouts.js +15 -0
  173. package/dist/layouts/panel-layouts.js.map +1 -0
  174. package/dist/lib/lazy.d.ts.map +1 -1
  175. package/dist/lib/lazy.js +2 -2
  176. package/dist/lib/lazy.js.map +1 -1
  177. package/dist/pages/PageShell.js.map +1 -1
  178. package/dist/pages/PageShell.vue.d.ts.map +1 -1
  179. package/dist/pages/PageShell.vue_vue_type_script_setup_true_lang.js +39 -42
  180. package/dist/pages/PageShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/standalone/AlfakitComponent.js.map +1 -1
  182. package/dist/standalone/AlfakitComponent.vue.d.ts.map +1 -1
  183. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js +56 -52
  184. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  185. package/dist/standalone.css +7 -0
  186. package/dist/starter-kit/AlfakitStarterKitRoot.js.map +1 -1
  187. package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts +2 -2
  188. package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts.map +1 -1
  189. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js +17 -12
  190. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/starter-kit/dashboard-widgets.d.ts +54 -0
  192. package/dist/starter-kit/dashboard-widgets.d.ts.map +1 -0
  193. package/dist/starter-kit/dashboard-widgets.js +54 -0
  194. package/dist/starter-kit/dashboard-widgets.js.map +1 -0
  195. package/dist/starter-kit/index.d.ts +2 -1
  196. package/dist/starter-kit/index.d.ts.map +1 -1
  197. package/dist/starter-kit/index.js +5 -4
  198. package/dist/starter-kit/runtime.d.ts +6 -0
  199. package/dist/starter-kit/runtime.d.ts.map +1 -1
  200. package/dist/starter-kit/runtime.js +19 -15
  201. package/dist/starter-kit/runtime.js.map +1 -1
  202. package/dist/starter-kit/starter-kit.d.ts.map +1 -1
  203. package/dist/starter-kit/starter-kit.js +8 -8
  204. package/dist/starter-kit/starter-kit.js.map +1 -1
  205. package/dist/starter-kit/widgets/CopilotTrigger.js +7 -0
  206. package/dist/starter-kit/widgets/CopilotTrigger.js.map +1 -0
  207. package/dist/starter-kit/widgets/CopilotTrigger.vue.d.ts +12 -0
  208. package/dist/starter-kit/widgets/CopilotTrigger.vue.d.ts.map +1 -0
  209. package/dist/starter-kit/widgets/CopilotTrigger.vue_vue_type_script_setup_true_lang.js +23 -0
  210. package/dist/starter-kit/widgets/CopilotTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/starter-kit/widgets/LoadedCopilot.js +7 -0
  212. package/dist/starter-kit/widgets/LoadedCopilot.js.map +1 -0
  213. package/dist/starter-kit/widgets/LoadedCopilot.vue.d.ts +8 -0
  214. package/dist/starter-kit/widgets/LoadedCopilot.vue.d.ts.map +1 -0
  215. package/dist/starter-kit/widgets/LoadedCopilot.vue_vue_type_script_setup_true_lang.js +31 -0
  216. package/dist/starter-kit/widgets/LoadedCopilot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  217. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.js +7 -0
  218. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.js.map +1 -0
  219. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue.d.ts +8 -0
  220. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue.d.ts.map +1 -0
  221. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue_vue_type_script_setup_true_lang.js +34 -0
  222. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  223. package/dist/starter-kit/widgets/index.d.ts +40 -9
  224. package/dist/starter-kit/widgets/index.d.ts.map +1 -1
  225. package/dist/starter-kit/widgets/index.js +21 -18
  226. package/dist/starter-kit/widgets/index.js.map +1 -1
  227. package/dist/starter-kit/widgets/loaded.d.ts +10 -0
  228. package/dist/starter-kit/widgets/loaded.d.ts.map +1 -0
  229. package/dist/starter-kit/widgets/loaded.js +5 -0
  230. package/dist/styles.css +9 -2
  231. package/dist/themes.css +6 -1
  232. package/package.json +2 -2
  233. package/src/AlfakitRoot.vue +9 -1
  234. package/src/components/actions/ActionGroupMenu.vue +13 -1
  235. package/src/components/actions/ActionModal.vue +9 -0
  236. package/src/components/ai/AiCopilot.vue +7 -1
  237. package/src/components/cms/LivePreview.vue +8 -2
  238. package/src/components/fields/BuilderField.vue +15 -2
  239. package/src/components/fields/ImageEditorDialog.vue +7 -3
  240. package/src/components/fields/KeyValueField.vue +3 -2
  241. package/src/components/fields/ModalTablePicker.vue +7 -2
  242. package/src/components/fields/RepeaterField.vue +2 -3
  243. package/src/components/fields/RichEditorInput.vue +3 -0
  244. package/src/components/fields/item-actions.ts +31 -10
  245. package/src/components/form/FormBlock.vue +2 -1
  246. package/src/components/form/form-context.ts +2 -2
  247. package/src/components/kanban/KanbanBoard.vue +15 -3
  248. package/src/components/kanban/KanbanColumnHeader.vue +6 -4
  249. package/src/components/layout/SectionComponent.vue +10 -4
  250. package/src/components/panel/GlobalSearchPalette.vue +2 -0
  251. package/src/components/realtime/use-live-updates.ts +3 -1
  252. package/src/components/table/ColumnHeader.vue +23 -12
  253. package/src/components/table/ColumnManager.vue +12 -8
  254. package/src/components/table/ContentLayoutSort.vue +7 -1
  255. package/src/components/table/TableCellContent.vue +4 -2
  256. package/src/components/table/TablePagination.vue +12 -7
  257. package/src/components/table/cell-update.ts +6 -0
  258. package/src/components/ui/CommandAutoHighlight.vue +27 -0
  259. package/src/components/ui/DialogContent.vue +5 -1
  260. package/src/components/ui/PopoverContent.vue +5 -1
  261. package/src/components/ui/SheetContent.vue +5 -1
  262. package/src/components/ui/TooltipContent.vue +5 -1
  263. package/src/context.ts +10 -0
  264. package/src/create-alfakit.ts +5 -0
  265. package/src/index.ts +2 -0
  266. package/src/layouts/lazy-layouts.ts +14 -0
  267. package/src/layouts/panel-layouts.ts +17 -0
  268. package/src/lib/lazy.ts +11 -1
  269. package/src/pages/PageShell.vue +5 -6
  270. package/src/standalone/AlfakitComponent.vue +17 -6
  271. package/src/starter-kit/AlfakitStarterKitRoot.vue +12 -3
  272. package/src/starter-kit/dashboard-widgets.ts +93 -0
  273. package/src/starter-kit/index.ts +7 -1
  274. package/src/starter-kit/runtime.ts +17 -1
  275. package/src/starter-kit/starter-kit.ts +2 -1
  276. package/src/starter-kit/widgets/CopilotTrigger.vue +58 -0
  277. package/src/starter-kit/widgets/LoadedCopilot.vue +29 -0
  278. package/src/starter-kit/widgets/StarterKitImpersonationBanner.vue +57 -0
  279. package/src/starter-kit/widgets/index.ts +56 -11
  280. package/src/starter-kit/widgets/loaded.ts +9 -0
  281. package/src/styles.css +9 -2
@@ -1 +1 @@
1
- {"version":3,"file":"BuilderField.vue_vue_type_script_setup_true_lang.js","names":["_resolveComponent","_unref","_openBlock","_createBlock","DeferredSchema","_withCtx","_createVNode","FieldWrapper","_createElementVNode","_toDisplayString","_createElementBlock","BuilderBlockPickerPanel","_createCommentVNode","CollapseAllActions","_normalizeStyle","_normalizeClass","_Fragment","_renderList","Collapsible","Icon","ItemHeaderActions","Button","BuilderBlockActionsMenu","CollapsibleContent","_withKeys","_withModifiers","_resolveDynamicComponent","SchemaRenderer","AddActionRow","BuilderBlockPicker","_createTextVNode","Icon_default","Button_default","SchemaRenderer_default","Collapsible_default","CollapsibleContent_default","DeferredSchema_default","FieldWrapper_default","AddActionRow_default","CollapseAllActions_default","ItemHeaderActions_default","BuilderBlockActionsMenu_default","BuilderBlockPickerPanel_default","BuilderBlockPicker_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","BuilderField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","formatter","useFormatter","registry","useOptionalRegistry","form","useOptionalFormStore","context","useFieldActionContext","runItemAction","useRunItemAction","fallbacks","useItemActionFallbacks","serverItemOf","server","index","items","resolve","resolveItemAction","name","fieldDisabled","useField","locked","computed","readOnly","builderItems","value","collapsed","ref","editing","dragIndex","virtual","useVirtualList","virtualizeOptions","VIRTUAL_ESTIMATES","visibleItems","blockOf","block","type","isCollapsed","canAdd","canDelete","canClone","item","canAddBuilderBlock","draggable","buttons","addAction","showEmptyPicker","menu","runner","useActionRunner","onMenuAction","moves","cloneItem","removeItem","onMenuExtra","action","itemActionContext","update","setValue","next","moveItem","moveRepeaterItem","from","to","moveIndexedState","useItemMoves","builderItemLabel","moveAnnouncement","moveContainer","removeRepeaterItem","removeIndexedState","cloneRepeaterItem","cloneIndexedState","addBlock","insertBuilderItem","onDrop","reorderedItemKeys","setAllCollapsed","previewComponentOf","hasPreview","showPreview","toggleEditing","open","openEditor","previewIsButton","_component_BuilderField","resolveComponent","unref","isDeferredPlaceholder","openBlock","createBlock","withCtx","loaded","createVNode","id","error","createElementVNode","toDisplayString","createElementBlock","createCommentVNode","_cache","fieldIds","aria","normalizeStyle","normalizeClass","cn","Fragment","renderList","$event","PencilIcon","withKeys","withModifiers","resolveDynamicComponent","builderItemSchema","createTextVNode"],"sources":["../../../src/components/fields/BuilderField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BuilderBlockSchema, BuilderItemState, BuilderSchema } from '@alfakit/core'\nimport {\n isDeferredPlaceholder,\n VIRTUAL_ESTIMATES,\n builderItemLabel,\n builderItems,\n builderItemSchema,\n canAddBuilderBlock,\n cloneIndexedState,\n cloneRepeaterItem,\n fieldIds,\n insertBuilderItem,\n itemActionContext,\n moveIndexedState,\n moveRepeaterItem,\n removeIndexedState,\n removeRepeaterItem,\n reorderedItemKeys,\n resolveItemAction,\n virtualizeOptions,\n type ActionSchema,\n type ItemActionName,\n} from '@alfakit/core'\nimport { PencilIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { useScrollToErroredItem, useVirtualList } from '../../composables/use-virtual-list'\nimport { useActionRunner, useFormatter, useOptionalRegistry, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport DeferredSchema from '../layout/DeferredSchema.vue'\nimport { useField, useOptionalFormStore } from '../form/form-context'\nimport { useFieldActionContext } from '../schema/field-actions'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Collapsible from '../ui/Collapsible.vue'\nimport CollapsibleContent from '../ui/CollapsibleContent.vue'\nimport AddActionRow from './AddActionRow.vue'\nimport CollapseAllActions from './CollapseAllActions.vue'\nimport ItemHeaderActions from './ItemHeaderActions.vue'\nimport { useItemActionFallbacks, useItemMoves, useRunItemAction } from './item-actions'\nimport BuilderBlockActionsMenu from './BuilderBlockActionsMenu.vue'\nimport BuilderBlockPicker from './BuilderBlockPicker.vue'\nimport BuilderBlockPickerPanel from './BuilderBlockPickerPanel.vue'\n\n/**\n * A list of blocks, each with its own schema. Items use the server's per-item schema\n * when it describes the same block, else the block's template (fresh, moved or cloned\n * items the server has not seen yet).\n */\nconst props = defineProps<{ component: BuilderSchema }>()\nconst t = useT()\nconst formatter = useFormatter()\nconst registry = useOptionalRegistry()\nconst form = useOptionalFormStore()\nconst context = useFieldActionContext(() => props.component)\nconst runItemAction = useRunItemAction(context)\nconst fallbacks = useItemActionFallbacks()\nconst serverItemOf = (index: number) => {\n const server = props.component.items[index]\n\n return server && server.type === items.value[index]?.type ? server : undefined\n}\nconst resolve = (name: ItemActionName, index?: number) =>\n resolveItemAction(\n name,\n props.component,\n index === undefined ? undefined : serverItemOf(index),\n name === 'add' ? { ...fallbacks.add, label: props.component.addActionLabel } : fallbacks[name],\n )\n\nconst {\n value,\n setValue,\n error,\n id,\n disabled: fieldDisabled,\n readOnly,\n aria,\n} = useField<unknown>(() => props.component)\nconst locked = computed(() => fieldDisabled.value || readOnly.value)\nconst items = computed(() => builderItems(value.value))\nconst collapsed = ref<Record<number, boolean>>({})\nconst editing = ref<Record<number, boolean>>({})\nconst dragIndex = ref<number | null>(null)\n// Long lists render only the visible blocks (plus a few around them).\nconst virtual = useVirtualList(\n () => items.value.length,\n () => virtualizeOptions(props.component.virtualize, VIRTUAL_ESTIMATES.item, 12),\n)\nuseScrollToErroredItem(virtual, () => props.component.statePath)\nconst visibleItems = computed(() =>\n virtual.indexes.value.map((index) => ({ item: items.value[index] as BuilderItemState, index })),\n)\n\nconst blockOf = (type: string) => props.component.blocks.find((block) => block.name === type)\nconst isCollapsed = (index: number) => collapsed.value[index] ?? props.component.collapsed ?? false\nconst canAdd = computed(\n () =>\n props.component.addable &&\n !locked.value &&\n (props.component.maxItems == null || items.value.length < props.component.maxItems),\n)\nconst canDelete = computed(\n () =>\n props.component.deletable &&\n !locked.value &&\n (props.component.minItems == null || items.value.length > props.component.minItems),\n)\nconst canClone = (item: BuilderItemState) => {\n const block = blockOf(item.type)\n\n return Boolean(\n props.component.cloneable &&\n canAdd.value &&\n block &&\n canAddBuilderBlock(props.component, block, items.value),\n )\n}\n\nconst draggable = computed(\n () =>\n props.component.reorderable &&\n props.component.reorderableWithDragAndDrop !== false &&\n !locked.value &&\n resolve('reorder') !== null,\n)\nconst buttons = computed(\n () =>\n props.component.reorderable &&\n props.component.reorderableWithButtons !== false &&\n !locked.value,\n)\nconst addAction = computed(() => resolve('add'))\nconst showEmptyPicker = computed(\n () =>\n canAdd.value &&\n addAction.value !== null &&\n !addAction.value.disabled &&\n props.component.blocks.length > 0,\n)\nconst menu = computed(() => Boolean(props.component.blockActionsMenu) && !locked.value)\nconst runner = useActionRunner()\n// `blockActionsMenu()`: built-in actions run in the browser unless customised.\nconst onMenuAction = (name: ItemActionName, index: number) =>\n runItemAction(resolve(name, index), { item: String(index) }, () => {\n if (name === 'moveUp') moves.moveWithButton(index, index - 1)\n else if (name === 'moveDown') moves.moveWithButton(index, index + 1)\n else if (name === 'clone') cloneItem(index)\n else if (name === 'delete') removeItem(index)\n })\nconst onMenuExtra = (action: ActionSchema, index: number) =>\n void runner.trigger(action, itemActionContext(context.value, { item: String(index) }))\n\nconst update = (next: unknown[]) => setValue(next as BuilderItemState[])\nconst moveItem = (from: number, to: number) => {\n update(moveRepeaterItem(items.value, from, to))\n collapsed.value = moveIndexedState(collapsed.value, from, to)\n editing.value = moveIndexedState(editing.value, from, to)\n}\n// Move buttons: announced, one at a time, focus kept on the moved item.\nconst moves = useItemMoves(\n value,\n (from, to) => moveItem(from, to),\n (index) => builderItemLabel(props.component, items.value, index),\n () => items.value.length,\n)\nconst moveAnnouncement = moves.announcement\nconst moveContainer = moves.container\nconst removeItem = (index: number) => {\n update(removeRepeaterItem(items.value, index))\n collapsed.value = removeIndexedState(collapsed.value, index)\n editing.value = removeIndexedState(editing.value, index)\n}\nconst cloneItem = (index: number) => {\n update(cloneRepeaterItem(items.value, index))\n collapsed.value = cloneIndexedState(collapsed.value, index)\n editing.value = cloneIndexedState(editing.value, index)\n}\nconst addBlock = (block: BuilderBlockSchema) =>\n runItemAction(addAction.value, { block: block.name }, () =>\n update(insertBuilderItem(items.value, block)),\n )\n// A drop runs the reorder action: in the browser, or on the server when customised.\nconst onDrop = (index: number) => {\n const from = dragIndex.value\n dragIndex.value = null\n if (from === null || from === index) return\n runItemAction(\n resolve('reorder'),\n { items: reorderedItemKeys(items.value.length, from, index) },\n () => moveItem(from, index),\n )\n}\nconst setAllCollapsed = (value: boolean) => {\n collapsed.value = Object.fromEntries(items.value.map((_, index) => [index, value]))\n}\n\n// Previews (`blockPreviews()`): server HTML or a registered `builder-preview:{name}`.\nconst previewComponentOf = (index: number) => {\n const name =\n serverItemOf(index)?.previewComponent ??\n blockOf(items.value[index]?.type ?? '')?.previewComponent\n\n return name ? registry?.resolve(`builder-preview:${name}`) : undefined\n}\nconst hasPreview = (index: number) =>\n props.component.blockPreviews === true &&\n (previewComponentOf(index) !== undefined || Boolean(serverItemOf(index)?.preview))\nconst showPreview = (index: number) => hasPreview(index) && !editing.value[index]\n// Closing the editor re-renders the previews from the server.\nconst toggleEditing = (index: number) => {\n const open = !editing.value[index]\n editing.value = { ...editing.value, [index]: open }\n if (!open) void form?.refresh(props.component.statePath)\n}\nconst openEditor = (index: number) => {\n if (!locked.value) toggleEditing(index)\n}\nconst previewIsButton = computed(() => !props.component.interactivePreviews && !locked.value)\n</script>\n\n<template>\n <!-- `deferLoading()`: a skeleton until the field scrolls into view. -->\n <DeferredSchema\n v-if=\"isDeferredPlaceholder(props.component)\"\n v-slot=\"{ component: loaded }\"\n :component=\"props.component\"\n >\n <BuilderField :component=\"loaded\" />\n </DeferredSchema>\n <FieldWrapper v-else :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div ref=\"moveContainer\" class=\"flex flex-col gap-3\" data-slot=\"builder\">\n <span aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\" data-slot=\"item-move-status\">{{\n moveAnnouncement\n }}</span>\n <!-- No blocks yet: the picker is right there instead of behind a button. -->\n <div\n v-if=\"items.length === 0 && showEmptyPicker\"\n data-slot=\"builder-empty\"\n class=\"bg-muted/30 flex flex-col gap-3 rounded-lg border border-dashed p-3 sm:p-4\"\n >\n <div class=\"px-1\">\n <p class=\"text-sm font-medium\">\n {{ t('builder.empty_heading', {}, 'Add your first block') }}\n </p>\n <p class=\"text-muted-foreground text-sm\">\n {{\n t(\n 'builder.empty_description',\n {},\n 'Pick one to start. You can add more, reorder and remove them at any time.',\n )\n }}\n </p>\n </div>\n <BuilderBlockPickerPanel\n :component=\"props.component\"\n :items=\"items\"\n class=\"bg-card max-h-[28rem] rounded-md border\"\n @pick=\"addBlock\"\n />\n </div>\n <p\n v-else-if=\"items.length === 0\"\n class=\"text-muted-foreground rounded-lg border border-dashed p-4 text-center text-sm\"\n >\n {{ t('builder.empty', {}, 'No blocks yet.') }}\n </p>\n <CollapseAllActions\n v-if=\"props.component.collapsible && items.length > 0\"\n :context=\"context\"\n :collapse-all=\"resolve('collapseAll')\"\n :expand-all=\"resolve('expandAll')\"\n @collapse-all=\"setAllCollapsed(true)\"\n @expand-all=\"setAllCollapsed(false)\"\n />\n <ul\n :id=\"id\"\n :ref=\"virtual.attach\"\n :aria-labelledby=\"props.component.label ? fieldIds(id).label : undefined\"\n :aria-describedby=\"aria['aria-describedby']\"\n :style=\"virtual.style.value\"\n :class=\"cn('grid gap-3', items.length === 0 && 'hidden')\"\n >\n <li\n v-for=\"{ item, index } in visibleItems\"\n :key=\"index\"\n :ref=\"virtual.item\"\n :data-index=\"index\"\n :aria-setsize=\"virtual.range.value.active ? items.length : undefined\"\n :aria-posinset=\"virtual.range.value.active ? index + 1 : undefined\"\n :data-block=\"item.type\"\n :draggable=\"draggable\"\n :class=\"\n cn('bg-card min-w-0 rounded-lg border shadow-xs', dragIndex === index && 'opacity-50')\n \"\n @dragstart=\"dragIndex = index\"\n @dragover=\"draggable && $event.preventDefault()\"\n @drop=\"onDrop(index)\"\n @dragend=\"dragIndex = null\"\n >\n <Collapsible :open=\"!isCollapsed(index)\">\n <div\n class=\"flex flex-wrap items-center gap-1 border-b px-2 py-1.5\"\n data-slot=\"item-header\"\n >\n <span\n v-if=\"draggable\"\n class=\"text-muted-foreground cursor-grab\"\n :title=\"resolve('reorder')?.label ?? undefined\"\n aria-hidden=\"true\"\n ><Icon :name=\"resolve('reorder')?.icon ?? 'grip-vertical'\"\n /></span>\n <Icon\n v-if=\"\n props.component.blockIcons &&\n (blockOf(item.type)?.icon ?? props.component.items[index]?.icon)\n \"\n :name=\"blockOf(item.type)?.icon ?? props.component.items[index]?.icon\"\n class=\"text-muted-foreground size-4\"\n />\n <span\n v-if=\"props.component.blockNumbers\"\n class=\"text-muted-foreground text-xs tabular-nums\"\n >{{ formatter.number(index + 1) }}</span\n >\n <span class=\"flex min-w-0 flex-1 items-baseline gap-2\">\n <span\n v-if=\"props.component.blockLabels\"\n dir=\"auto\"\n class=\"min-w-0 shrink-0 truncate text-sm font-medium sm:max-w-[60%]\"\n >{{ builderItemLabel(props.component, items, index) }}</span\n >\n <span\n v-if=\"serverItemOf(index)?.summary\"\n dir=\"auto\"\n class=\"text-muted-foreground min-w-0 truncate text-sm\"\n data-slot=\"builder-item-summary\"\n >{{ serverItemOf(index)?.summary }}</span\n >\n </span>\n <ItemHeaderActions\n :context=\"context\"\n :item-key=\"String(index)\"\n :index=\"index\"\n :count=\"items.length\"\n :resolve=\"(name: ItemActionName) => resolve(name, index)\"\n :extra-actions=\"menu || locked ? undefined : serverItemOf(index)?.actions\"\n :buttons=\"buttons && !menu\"\n :can-clone=\"canClone(item) && !menu\"\n :can-delete=\"canDelete && !menu\"\n :collapsible=\"Boolean(props.component.collapsible)\"\n :collapsed=\"isCollapsed(index)\"\n @move=\"moves.moveWithButton\"\n @clone=\"cloneItem(index)\"\n @delete=\"removeItem(index)\"\n @toggle=\"collapsed = { ...collapsed, [index]: !isCollapsed(index) }\"\n >\n <Button\n v-if=\"hasPreview(index) && !locked\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('builder.edit_block', {}, 'Edit block')\"\n :aria-pressed=\"Boolean(editing[index])\"\n @click=\"toggleEditing(index)\"\n ><Icon\n name=\"alfakit::forms.components.builder.actions.edit\"\n :fallback=\"PencilIcon\"\n /></Button>\n <BuilderBlockActionsMenu\n v-if=\"menu\"\n :label=\"builderItemLabel(props.component, items, index) ?? ''\"\n :resolve=\"(name: ItemActionName) => resolve(name, index)\"\n :can-move-up=\"buttons && index > 0\"\n :can-move-down=\"buttons && index < items.length - 1\"\n :can-clone=\"canClone(item)\"\n :can-delete=\"canDelete\"\n :extra-actions=\"serverItemOf(index)?.actions\"\n @action=\"(name: ItemActionName) => onMenuAction(name, index)\"\n @extra=\"(action: ActionSchema) => onMenuExtra(action, index)\"\n />\n </ItemHeaderActions>\n </div>\n <CollapsibleContent>\n <div\n v-if=\"showPreview(index)\"\n data-slot=\"builder-preview\"\n :class=\"cn('p-4', previewIsButton && 'cursor-pointer')\"\n :role=\"previewIsButton ? 'button' : undefined\"\n :tabindex=\"previewIsButton ? 0 : undefined\"\n :aria-label=\"\n previewIsButton ? t('builder.edit_block', {}, 'Edit block') : undefined\n \"\n @click=\"previewIsButton && openEditor(index)\"\n @keydown.enter.prevent=\"previewIsButton && openEditor(index)\"\n @keydown.space.prevent=\"previewIsButton && openEditor(index)\"\n >\n <div :class=\"cn(!props.component.interactivePreviews && 'pointer-events-none')\">\n <component\n :is=\"previewComponentOf(index)\"\n v-if=\"previewComponentOf(index)\"\n :data=\"item.data\"\n :block=\"item.type\"\n :index=\"index\"\n />\n <!-- Server-rendered `Block::preview()` HTML (Blade escapes the data). -->\n <!-- eslint-disable-next-line vue/no-v-html -->\n <div v-else v-html=\"serverItemOf(index)?.preview ?? ''\" />\n </div>\n </div>\n <div v-else class=\"p-4\">\n <SchemaRenderer\n :components=\"builderItemSchema(props.component, items, index)\"\n :columns=\"\n blockOf(item.type)?.columns ??\n props.component.items[index]?.columns ?? { default: 1 }\n \"\n />\n </div>\n </CollapsibleContent>\n </Collapsible>\n </li>\n </ul>\n <AddActionRow\n v-if=\"canAdd && addAction && props.component.blocks.length > 0 && items.length > 0\"\n :alignment=\"props.component.addActionAlignment\"\n >\n <BuilderBlockPicker :component=\"props.component\" :items=\"items\" @pick=\"addBlock\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"addAction?.disabled\"\n data-slot=\"builder-add\"\n ><Icon v-if=\"addAction?.icon\" :name=\"addAction.icon\" /> {{ addAction?.label }}</Button\n >\n </BuilderBlockPicker>\n </AddActionRow>\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"BuilderField.vue_vue_type_script_setup_true_lang.js","names":["_resolveComponent","_unref","_openBlock","_createBlock","DeferredSchema","_withCtx","_createVNode","FieldWrapper","_createElementVNode","_toDisplayString","_createElementBlock","BuilderBlockPickerPanel","_createCommentVNode","CollapseAllActions","_normalizeStyle","_normalizeClass","_Fragment","_renderList","Collapsible","Icon","ItemHeaderActions","Button","BuilderBlockActionsMenu","CollapsibleContent","_withKeys","_withModifiers","_resolveDynamicComponent","SchemaRenderer","AddActionRow","BuilderBlockPicker","_createTextVNode","Icon_default","Button_default","SchemaRenderer_default","DeferredSchema_default","FieldWrapper_default","Collapsible_default","CollapsibleContent_default","AddActionRow_default","CollapseAllActions_default","ItemHeaderActions_default","BuilderBlockActionsMenu_default","BuilderBlockPickerPanel_default","BuilderBlockPicker_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","BuilderField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","formatter","useFormatter","registry","useOptionalRegistry","form","useOptionalFormStore","context","useFieldActionContext","runItemAction","useRunItemAction","fallbacks","useItemActionFallbacks","serverItemOf","server","index","items","resolve","resolveItemAction","name","fieldDisabled","useField","locked","computed","readOnly","builderItems","value","collapsed","ref","editing","dragIndex","virtual","useVirtualList","virtualizeOptions","VIRTUAL_ESTIMATES","visibleItems","blockOf","block","type","isCollapsed","canAdd","canDelete","canClone","item","canAddBuilderBlock","draggable","buttons","addAction","showEmptyPicker","menu","runner","useActionRunner","onMenuAction","moves","cloneItem","removeItem","onMenuExtra","action","itemActionContext","update","setValue","next","moveItem","moveRepeaterItem","from","to","moveIndexedState","useItemMoves","builderItemLabel","moveAnnouncement","moveContainer","removeRepeaterItem","removeIndexedState","cloneRepeaterItem","cloneIndexedState","addBlock","insertBuilderItem","onDrop","reorderedItemKeys","setAllCollapsed","refreshSummaries","indexes","toggleCollapsed","collapse","previewComponentOf","hasPreview","showPreview","toggleEditing","open","openEditor","previewIsButton","_component_BuilderField","resolveComponent","unref","isDeferredPlaceholder","openBlock","createBlock","withCtx","loaded","createVNode","id","error","createElementVNode","toDisplayString","createElementBlock","createCommentVNode","_cache","fieldIds","aria","normalizeStyle","normalizeClass","cn","Fragment","renderList","$event","PencilIcon","withKeys","withModifiers","resolveDynamicComponent","builderItemSchema","createTextVNode"],"sources":["../../../src/components/fields/BuilderField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { BuilderBlockSchema, BuilderItemState, BuilderSchema } from '@alfakit/core'\nimport {\n isDeferredPlaceholder,\n VIRTUAL_ESTIMATES,\n builderItemLabel,\n builderItems,\n builderItemSchema,\n canAddBuilderBlock,\n cloneIndexedState,\n cloneRepeaterItem,\n fieldIds,\n insertBuilderItem,\n itemActionContext,\n moveIndexedState,\n moveRepeaterItem,\n removeIndexedState,\n removeRepeaterItem,\n reorderedItemKeys,\n resolveItemAction,\n virtualizeOptions,\n type ActionSchema,\n type ItemActionName,\n} from '@alfakit/core'\nimport { PencilIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { useScrollToErroredItem, useVirtualList } from '../../composables/use-virtual-list'\nimport { useActionRunner, useFormatter, useOptionalRegistry, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport DeferredSchema from '../layout/DeferredSchema.vue'\nimport { useField, useOptionalFormStore } from '../form/form-context'\nimport { useFieldActionContext } from '../schema/field-actions'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Collapsible from '../ui/Collapsible.vue'\nimport CollapsibleContent from '../ui/CollapsibleContent.vue'\nimport AddActionRow from './AddActionRow.vue'\nimport CollapseAllActions from './CollapseAllActions.vue'\nimport ItemHeaderActions from './ItemHeaderActions.vue'\nimport { useItemActionFallbacks, useItemMoves, useRunItemAction } from './item-actions'\nimport BuilderBlockActionsMenu from './BuilderBlockActionsMenu.vue'\nimport BuilderBlockPicker from './BuilderBlockPicker.vue'\nimport BuilderBlockPickerPanel from './BuilderBlockPickerPanel.vue'\n\n/**\n * A list of blocks, each with its own schema. Items use the server's per-item schema\n * when it describes the same block, else the block's template (fresh, moved or cloned\n * items the server has not seen yet).\n */\nconst props = defineProps<{ component: BuilderSchema }>()\nconst t = useT()\nconst formatter = useFormatter()\nconst registry = useOptionalRegistry()\nconst form = useOptionalFormStore()\nconst context = useFieldActionContext(() => props.component)\nconst runItemAction = useRunItemAction(context)\nconst fallbacks = useItemActionFallbacks('builder')\nconst serverItemOf = (index: number) => {\n const server = props.component.items[index]\n\n return server && server.type === items.value[index]?.type ? server : undefined\n}\nconst resolve = (name: ItemActionName, index?: number) =>\n resolveItemAction(\n name,\n props.component,\n index === undefined ? undefined : serverItemOf(index),\n name === 'add' ? { ...fallbacks.add, label: props.component.addActionLabel } : fallbacks[name],\n )\n\nconst {\n value,\n setValue,\n error,\n id,\n disabled: fieldDisabled,\n readOnly,\n aria,\n} = useField<unknown>(() => props.component)\nconst locked = computed(() => fieldDisabled.value || readOnly.value)\nconst items = computed(() => builderItems(value.value))\nconst collapsed = ref<Record<number, boolean>>({})\nconst editing = ref<Record<number, boolean>>({})\nconst dragIndex = ref<number | null>(null)\n// Long lists render only the visible blocks (plus a few around them).\nconst virtual = useVirtualList(\n () => items.value.length,\n () => virtualizeOptions(props.component.virtualize, VIRTUAL_ESTIMATES.item, 12),\n)\nuseScrollToErroredItem(virtual, () => props.component.statePath)\nconst visibleItems = computed(() =>\n virtual.indexes.value.map((index) => ({ item: items.value[index] as BuilderItemState, index })),\n)\n\nconst blockOf = (type: string) => props.component.blocks.find((block) => block.name === type)\nconst isCollapsed = (index: number) => collapsed.value[index] ?? props.component.collapsed ?? false\nconst canAdd = computed(\n () =>\n props.component.addable &&\n !locked.value &&\n (props.component.maxItems == null || items.value.length < props.component.maxItems),\n)\nconst canDelete = computed(\n () =>\n props.component.deletable &&\n !locked.value &&\n (props.component.minItems == null || items.value.length > props.component.minItems),\n)\nconst canClone = (item: BuilderItemState) => {\n const block = blockOf(item.type)\n\n return Boolean(\n props.component.cloneable &&\n canAdd.value &&\n block &&\n canAddBuilderBlock(props.component, block, items.value),\n )\n}\n\nconst draggable = computed(\n () =>\n props.component.reorderable &&\n props.component.reorderableWithDragAndDrop !== false &&\n !locked.value &&\n resolve('reorder') !== null,\n)\nconst buttons = computed(\n () =>\n props.component.reorderable &&\n props.component.reorderableWithButtons !== false &&\n !locked.value,\n)\nconst addAction = computed(() => resolve('add'))\nconst showEmptyPicker = computed(\n () =>\n canAdd.value &&\n addAction.value !== null &&\n !addAction.value.disabled &&\n props.component.blocks.length > 0,\n)\nconst menu = computed(() => Boolean(props.component.blockActionsMenu) && !locked.value)\nconst runner = useActionRunner()\n// `blockActionsMenu()`: built-in actions run in the browser unless customised.\nconst onMenuAction = (name: ItemActionName, index: number) =>\n runItemAction(resolve(name, index), { item: String(index) }, () => {\n if (name === 'moveUp') moves.moveWithButton(index, index - 1)\n else if (name === 'moveDown') moves.moveWithButton(index, index + 1)\n else if (name === 'clone') cloneItem(index)\n else if (name === 'delete') removeItem(index)\n })\nconst onMenuExtra = (action: ActionSchema, index: number) =>\n void runner.trigger(action, itemActionContext(context.value, { item: String(index) }))\n\nconst update = (next: unknown[]) => setValue(next as BuilderItemState[])\nconst moveItem = (from: number, to: number) => {\n update(moveRepeaterItem(items.value, from, to))\n collapsed.value = moveIndexedState(collapsed.value, from, to)\n editing.value = moveIndexedState(editing.value, from, to)\n}\n// Move buttons: announced, one at a time, focus kept on the moved item.\nconst moves = useItemMoves(\n value,\n (from, to) => moveItem(from, to),\n (index) => builderItemLabel(props.component, items.value, index),\n () => items.value.length,\n)\nconst moveAnnouncement = moves.announcement\nconst moveContainer = moves.container\nconst removeItem = (index: number) => {\n update(removeRepeaterItem(items.value, index))\n collapsed.value = removeIndexedState(collapsed.value, index)\n editing.value = removeIndexedState(editing.value, index)\n}\nconst cloneItem = (index: number) => {\n update(cloneRepeaterItem(items.value, index))\n collapsed.value = cloneIndexedState(collapsed.value, index)\n editing.value = cloneIndexedState(editing.value, index)\n}\nconst addBlock = (block: BuilderBlockSchema) =>\n runItemAction(addAction.value, { block: block.name }, () =>\n update(insertBuilderItem(items.value, block)),\n )\n// A drop runs the reorder action: in the browser, or on the server when customised.\nconst onDrop = (index: number) => {\n const from = dragIndex.value\n dragIndex.value = null\n if (from === null || from === index) return\n runItemAction(\n resolve('reorder'),\n { items: reorderedItemKeys(items.value.length, from, index) },\n () => moveItem(from, index),\n )\n}\nconst setAllCollapsed = (value: boolean) => {\n collapsed.value = Object.fromEntries(items.value.map((_, index) => [index, value]))\n if (value) refreshSummaries(items.value.map((_, index) => index))\n}\n// Summaries are made on the server: collapsing items whose block has one brings them up\n// to date with the edits.\nconst refreshSummaries = (indexes: number[]) => {\n if (indexes.some((index) => blockOf(items.value[index]?.type ?? '')?.summary)) {\n void form?.refresh(props.component.statePath)\n }\n}\nconst toggleCollapsed = (index: number) => {\n const collapse = !isCollapsed(index)\n collapsed.value = { ...collapsed.value, [index]: collapse }\n if (collapse) refreshSummaries([index])\n}\n\n// Previews (`blockPreviews()`): server HTML or a registered `builder-preview:{name}`.\nconst previewComponentOf = (index: number) => {\n const name =\n serverItemOf(index)?.previewComponent ??\n blockOf(items.value[index]?.type ?? '')?.previewComponent\n\n return name ? registry?.resolve(`builder-preview:${name}`) : undefined\n}\nconst hasPreview = (index: number) =>\n props.component.blockPreviews === true &&\n (previewComponentOf(index) !== undefined || Boolean(serverItemOf(index)?.preview))\nconst showPreview = (index: number) => hasPreview(index) && !editing.value[index]\n// Closing the editor re-renders the previews from the server.\nconst toggleEditing = (index: number) => {\n const open = !editing.value[index]\n editing.value = { ...editing.value, [index]: open }\n if (!open) void form?.refresh(props.component.statePath)\n}\nconst openEditor = (index: number) => {\n if (!locked.value) toggleEditing(index)\n}\nconst previewIsButton = computed(() => !props.component.interactivePreviews && !locked.value)\n</script>\n\n<template>\n <!-- `deferLoading()`: a skeleton until the field scrolls into view. -->\n <DeferredSchema\n v-if=\"isDeferredPlaceholder(props.component)\"\n v-slot=\"{ component: loaded }\"\n :component=\"props.component\"\n >\n <BuilderField :component=\"loaded\" />\n </DeferredSchema>\n <FieldWrapper v-else :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div ref=\"moveContainer\" class=\"flex flex-col gap-3\" data-slot=\"builder\">\n <span aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\" data-slot=\"item-move-status\">{{\n moveAnnouncement\n }}</span>\n <!-- No blocks yet: the picker is right there instead of behind a button. -->\n <div\n v-if=\"items.length === 0 && showEmptyPicker\"\n data-slot=\"builder-empty\"\n class=\"bg-muted/30 flex flex-col gap-3 rounded-lg border border-dashed p-3 sm:p-4\"\n >\n <div class=\"px-1\">\n <p class=\"text-sm font-medium\">\n {{ t('builder.empty_heading', {}, 'Add your first block') }}\n </p>\n <p class=\"text-muted-foreground text-sm\">\n {{\n t(\n 'builder.empty_description',\n {},\n 'Pick one to start. You can add more, reorder and remove them at any time.',\n )\n }}\n </p>\n </div>\n <BuilderBlockPickerPanel\n :component=\"props.component\"\n :items=\"items\"\n class=\"bg-card max-h-[28rem] rounded-md border\"\n @pick=\"addBlock\"\n />\n </div>\n <p\n v-else-if=\"items.length === 0\"\n class=\"text-muted-foreground rounded-lg border border-dashed p-4 text-center text-sm\"\n >\n {{ t('builder.empty', {}, 'No blocks yet.') }}\n </p>\n <CollapseAllActions\n v-if=\"props.component.collapsible && items.length > 0\"\n :context=\"context\"\n :collapse-all=\"resolve('collapseAll')\"\n :expand-all=\"resolve('expandAll')\"\n @collapse-all=\"setAllCollapsed(true)\"\n @expand-all=\"setAllCollapsed(false)\"\n />\n <ul\n :id=\"id\"\n :ref=\"virtual.attach\"\n :aria-labelledby=\"props.component.label ? fieldIds(id).label : undefined\"\n :aria-describedby=\"aria['aria-describedby']\"\n :style=\"virtual.style.value\"\n :class=\"cn('grid gap-3', items.length === 0 && 'hidden')\"\n >\n <li\n v-for=\"{ item, index } in visibleItems\"\n :key=\"index\"\n :ref=\"virtual.item\"\n :data-index=\"index\"\n :aria-setsize=\"virtual.range.value.active ? items.length : undefined\"\n :aria-posinset=\"virtual.range.value.active ? index + 1 : undefined\"\n :data-block=\"item.type\"\n :draggable=\"draggable\"\n :class=\"\n cn('bg-card min-w-0 rounded-lg border shadow-xs', dragIndex === index && 'opacity-50')\n \"\n @dragstart=\"dragIndex = index\"\n @dragover=\"draggable && $event.preventDefault()\"\n @drop=\"onDrop(index)\"\n @dragend=\"dragIndex = null\"\n >\n <Collapsible :open=\"!isCollapsed(index)\">\n <div\n class=\"flex flex-wrap items-center gap-1 border-b px-2 py-1.5\"\n data-slot=\"item-header\"\n >\n <span\n v-if=\"draggable\"\n class=\"text-muted-foreground cursor-grab\"\n :title=\"resolve('reorder')?.label ?? undefined\"\n aria-hidden=\"true\"\n ><Icon :name=\"resolve('reorder')?.icon ?? 'grip-vertical'\"\n /></span>\n <Icon\n v-if=\"\n props.component.blockIcons &&\n (blockOf(item.type)?.icon ?? props.component.items[index]?.icon)\n \"\n :name=\"blockOf(item.type)?.icon ?? props.component.items[index]?.icon\"\n class=\"text-muted-foreground size-4\"\n />\n <span\n v-if=\"props.component.blockNumbers\"\n class=\"text-muted-foreground text-xs tabular-nums\"\n >{{ formatter.number(index + 1) }}</span\n >\n <span class=\"flex min-w-0 flex-1 items-baseline gap-2\">\n <span\n v-if=\"props.component.blockLabels\"\n dir=\"auto\"\n class=\"min-w-0 shrink-0 truncate text-sm font-medium sm:max-w-[60%]\"\n >{{ builderItemLabel(props.component, items, index) }}</span\n >\n <span\n v-if=\"serverItemOf(index)?.summary\"\n dir=\"auto\"\n class=\"text-muted-foreground min-w-0 truncate text-sm\"\n data-slot=\"builder-item-summary\"\n >{{ serverItemOf(index)?.summary }}</span\n >\n </span>\n <ItemHeaderActions\n :context=\"context\"\n :item-key=\"String(index)\"\n :index=\"index\"\n :count=\"items.length\"\n :resolve=\"(name: ItemActionName) => resolve(name, index)\"\n :extra-actions=\"menu || locked ? undefined : serverItemOf(index)?.actions\"\n :buttons=\"buttons && !menu\"\n :can-clone=\"canClone(item) && !menu\"\n :can-delete=\"canDelete && !menu\"\n :collapsible=\"Boolean(props.component.collapsible)\"\n :collapsed=\"isCollapsed(index)\"\n @move=\"moves.moveWithButton\"\n @clone=\"cloneItem(index)\"\n @delete=\"removeItem(index)\"\n @toggle=\"toggleCollapsed(index)\"\n >\n <Button\n v-if=\"hasPreview(index) && !locked\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('builder.edit_block', {}, 'Edit block')\"\n :aria-pressed=\"Boolean(editing[index])\"\n @click=\"toggleEditing(index)\"\n ><Icon\n name=\"alfakit::forms.components.builder.actions.edit\"\n :fallback=\"PencilIcon\"\n /></Button>\n <BuilderBlockActionsMenu\n v-if=\"menu\"\n :label=\"builderItemLabel(props.component, items, index) ?? ''\"\n :resolve=\"(name: ItemActionName) => resolve(name, index)\"\n :can-move-up=\"buttons && index > 0\"\n :can-move-down=\"buttons && index < items.length - 1\"\n :can-clone=\"canClone(item)\"\n :can-delete=\"canDelete\"\n :extra-actions=\"serverItemOf(index)?.actions\"\n @action=\"(name: ItemActionName) => onMenuAction(name, index)\"\n @extra=\"(action: ActionSchema) => onMenuExtra(action, index)\"\n />\n </ItemHeaderActions>\n </div>\n <CollapsibleContent>\n <div\n v-if=\"showPreview(index)\"\n data-slot=\"builder-preview\"\n :class=\"cn('p-4', previewIsButton && 'cursor-pointer')\"\n :role=\"previewIsButton ? 'button' : undefined\"\n :tabindex=\"previewIsButton ? 0 : undefined\"\n :aria-label=\"\n previewIsButton ? t('builder.edit_block', {}, 'Edit block') : undefined\n \"\n @click=\"previewIsButton && openEditor(index)\"\n @keydown.enter.prevent=\"previewIsButton && openEditor(index)\"\n @keydown.space.prevent=\"previewIsButton && openEditor(index)\"\n >\n <div :class=\"cn(!props.component.interactivePreviews && 'pointer-events-none')\">\n <component\n :is=\"previewComponentOf(index)\"\n v-if=\"previewComponentOf(index)\"\n :data=\"item.data\"\n :block=\"item.type\"\n :index=\"index\"\n />\n <!-- Server-rendered `Block::preview()` HTML (Blade escapes the data). -->\n <!-- eslint-disable-next-line vue/no-v-html -->\n <div v-else v-html=\"serverItemOf(index)?.preview ?? ''\" />\n </div>\n </div>\n <div v-else class=\"p-4\">\n <SchemaRenderer\n :components=\"builderItemSchema(props.component, items, index)\"\n :columns=\"\n blockOf(item.type)?.columns ??\n props.component.items[index]?.columns ?? { default: 1 }\n \"\n />\n </div>\n </CollapsibleContent>\n </Collapsible>\n </li>\n </ul>\n <AddActionRow\n v-if=\"canAdd && addAction && props.component.blocks.length > 0 && items.length > 0\"\n :alignment=\"props.component.addActionAlignment\"\n >\n <BuilderBlockPicker :component=\"props.component\" :items=\"items\" @pick=\"addBlock\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n :disabled=\"addAction?.disabled\"\n data-slot=\"builder-add\"\n ><Icon v-if=\"addAction?.icon\" :name=\"addAction.icon\" /> {{ addAction?.label }}</Button\n >\n </BuilderBlockPicker>\n </AddActionRow>\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageEditorDialog.js","names":["_sfc_main","ImageEditorDialog_vue_vue_type_script_setup_true_lang_default","ImageEditorDialog_default"],"sources":["../../../src/components/fields/ImageEditorDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * `FileUpload::imageEditor()`: crop, zoom, rotate and flip an image before it is uploaded\n * (or to replace an uploaded one). Resolves the request with the edited file, or null\n * when cancelled.\n */\nimport type {\n CropHandle,\n FileUploadImageEditorSchema,\n ImageEditorData,\n ImageEditorDragMode,\n ImageEditorState,\n} from '@alfakit/core'\nimport { ImageEditor, loadEditorImage } from '@alfakit/core'\nimport {\n FlipHorizontal2Icon,\n FlipVertical2Icon,\n RotateCcwIcon,\n RotateCwIcon,\n Undo2Icon,\n ZoomInIcon,\n ZoomOutIcon,\n} from '@lucide/vue'\nimport { computed, onScopeDispose, ref, shallowRef, useId, watch, type Component } from 'vue'\nimport { useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Input from '../ui/Input.vue'\nimport Spinner from '../ui/Spinner.vue'\n\nexport interface ImageEditRequest {\n file: File\n resolve: (file: File | null) => void\n}\n\nconst HANDLES: CropHandle[] = ['nw', 'ne', 'sw', 'se']\n\n/** The numeric inputs, in the order Filament shows them. */\nconst NUMERIC_FIELDS = [\n ['x', 'image_editor.x', 'X'],\n ['y', 'image_editor.y', 'Y'],\n ['width', 'image_editor.width', 'Width'],\n ['height', 'image_editor.height', 'Height'],\n ['rotate', 'image_editor.rotation', 'Rotation'],\n] as const satisfies ReadonlyArray<readonly [keyof ImageEditorData, string, string]>\n\nconst SCALES = [\n ['x', 'image_editor.scale_x', 'Scale X'],\n ['y', 'image_editor.scale_y', 'Scale Y'],\n] as const\n\nconst props = defineProps<{\n request: ImageEditRequest | null\n options: FileUploadImageEditorSchema\n}>()\n\nconst t = useT()\nconst loaded = shallowRef<{ bitmap: ImageBitmap; editor: ImageEditor } | null>(null)\nconst state = shallowRef<ImageEditorState | null>(null)\nconst saving = ref(false)\nconst hintId = useId()\nconst inputsId = useId()\nconst canvas = ref<HTMLCanvasElement | null>(null)\nconst frame = ref<HTMLDivElement | null>(null)\nlet unsubscribe: (() => void) | null = null\nlet stopObserving: (() => void) | null = null\n\nconst release = () => {\n unsubscribe?.()\n unsubscribe = null\n stopObserving?.()\n stopObserving = null\n loaded.value?.bitmap.close()\n loaded.value = null\n state.value = null\n}\n\nwatch(\n () => [props.request, props.options] as const,\n ([request, options], _previous, onCleanup) => {\n if (!request) return\n\n let cancelled = false\n\n loadEditorImage(request.file)\n .then((bitmap) => {\n if (cancelled) return bitmap.close()\n\n const editor = new ImageEditor({\n width: bitmap.width,\n height: bitmap.height,\n aspectRatios: options.aspectRatios,\n circle: options.circle,\n mode: options.mode,\n emptyFillColor: options.emptyFillColor,\n viewportWidth: options.viewportWidth,\n viewportHeight: options.viewportHeight,\n })\n\n loaded.value = { bitmap, editor }\n state.value = editor.store.get()\n unsubscribe = editor.store.subscribe((next) => {\n state.value = next\n })\n })\n // Undecodable: upload the file as it is.\n .catch(() => !cancelled && request.resolve(request.file))\n\n onCleanup(() => {\n cancelled = true\n release()\n })\n },\n { immediate: true },\n)\n\nonScopeDispose(release)\n\n// Redraw on every change (crop, zoom, rotation, flips, container size).\nwatch(\n () => [canvas.value, state.value] as const,\n ([element]) => {\n if (element && loaded.value) {\n loaded.value.editor.drawPreview(\n element,\n loaded.value.bitmap,\n globalThis.devicePixelRatio || 1,\n )\n }\n },\n { flush: 'post' },\n)\n\n// Measure the container and follow its size; zoom with the wheel and trackpad pinch.\nwatch(\n () => [frame.value, loaded.value?.editor] as const,\n ([element, editor]) => {\n stopObserving?.()\n stopObserving = null\n\n if (!element || !editor) return\n\n const measure = () => editor.setContainer(element.clientWidth, element.clientHeight)\n measure()\n\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure)\n observer?.observe(element)\n\n const onWheel = (event: WheelEvent) => {\n const rect = element.getBoundingClientRect()\n\n if (editor.wheel(event, { x: event.clientX - rect.left, y: event.clientY - rect.top })) {\n event.preventDefault()\n }\n }\n\n element.addEventListener('wheel', onWheel, { passive: false })\n\n stopObserving = () => {\n observer?.disconnect()\n element.removeEventListener('wheel', onWheel)\n }\n },\n { flush: 'post' },\n)\n\nconst data = computed<ImageEditorData | null>(() => {\n void state.value\n\n return loaded.value?.editor.getData() ?? null\n})\n\n// Numeric inputs apply on change (blur, Enter, spinner); invalid values snap back.\nconst commit = (field: keyof ImageEditorData, event: Event) => {\n const editor = loaded.value?.editor\n const input = event.target as HTMLInputElement | null\n\n if (!editor || !input) return\n\n const value = input.value.trim() === '' ? Number.NaN : Number(input.value)\n editor.setData({ [field]: value })\n input.value = String(editor.getData()[field])\n}\n\nconst box = computed(() => {\n void state.value\n\n return loaded.value?.editor.cropBox() ?? { left: 0, top: 0, width: 0, height: 0 }\n})\n\nconst finish = (file: File | null) => {\n props.request?.resolve(file)\n}\n\nconst save = async () => {\n const request = props.request\n const current = loaded.value\n\n if (!request || !current) return\n\n saving.value = true\n\n try {\n finish(await current.editor.export(current.bitmap, request.file))\n } catch {\n finish(request.file)\n } finally {\n saving.value = false\n }\n}\n\nconst start = (mode: ImageEditorDragMode, event: PointerEvent) => {\n const editor = loaded.value?.editor\n\n if (!editor) return\n\n event.preventDefault()\n event.stopPropagation()\n ;(event.currentTarget as HTMLElement | null)?.setPointerCapture?.(event.pointerId)\n editor.startDrag(mode, event.clientX, event.clientY, undefined, event.pointerId ?? 0)\n}\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (loaded.value?.editor.handleKey(event)) event.preventDefault()\n}\n\nconst ratioLabel = (ratio: string | null) => ratio ?? t('image_editor.free', {}, 'Free')\n\nconst tools = computed<\n Array<{ label: string; icon: Component; run: () => void; disabled?: boolean }>\n>(() => [\n {\n label: t('image_editor.zoom_out', {}, 'Zoom out'),\n icon: ZoomOutIcon,\n run: () => loaded.value?.editor.zoomOut(),\n disabled: !(state.value && loaded.value?.editor.canZoomOut),\n },\n {\n label: t('image_editor.zoom_in', {}, 'Zoom in'),\n icon: ZoomInIcon,\n run: () => loaded.value?.editor.zoomIn(),\n disabled: !(state.value && loaded.value?.editor.canZoomIn),\n },\n {\n label: t('image_editor.rotate_left', {}, 'Rotate left'),\n icon: RotateCcwIcon,\n run: () => loaded.value?.editor.rotate(-1),\n },\n {\n label: t('image_editor.rotate_right', {}, 'Rotate right'),\n icon: RotateCwIcon,\n run: () => loaded.value?.editor.rotate(1),\n },\n {\n label: t('image_editor.flip_horizontal', {}, 'Flip horizontally'),\n icon: FlipHorizontal2Icon,\n run: () => loaded.value?.editor.flip('x'),\n },\n {\n label: t('image_editor.flip_vertical', {}, 'Flip vertically'),\n icon: FlipVertical2Icon,\n run: () => loaded.value?.editor.flip('y'),\n },\n {\n label: t('image_editor.reset', {}, 'Reset'),\n icon: Undo2Icon,\n run: () => loaded.value?.editor.reset(),\n },\n])\n</script>\n\n<template>\n <Dialog :open=\"props.request !== null\" @update:open=\"(open) => !open && finish(null)\">\n <DialogContent class=\"sm:max-w-3xl\" data-slot=\"image-editor\">\n <DialogHeader>\n <DialogTitle>{{ t('image_editor.title', {}, 'Edit image') }}</DialogTitle>\n <DialogDescription class=\"sr-only\">\n <span :id=\"hintId\"\n >{{\n t(\n 'image_editor.keyboard_hint',\n {},\n 'Arrow keys move the crop area. Shift and arrow keys resize it.',\n )\n }}\n {{ t('image_editor.zoom_hint', {}, 'Plus and minus keys zoom the image.') }}</span\n >\n </DialogDescription>\n </DialogHeader>\n <div v-if=\"loaded && state && data\" class=\"flex flex-col gap-4 md:flex-row\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <!-- Image space: left is the image's left in every reading direction. -->\n <div\n ref=\"frame\"\n dir=\"ltr\"\n data-slot=\"image-editor-viewport\"\n class=\"bg-muted/40 relative h-72 w-full cursor-grab touch-none overflow-hidden rounded-md select-none sm:h-96\"\n @pointerdown=\"start('pan', $event)\"\n @pointermove=\"\n loaded.editor.dragTo($event.clientX, $event.clientY, $event.pointerId ?? 0)\n \"\n @pointerup=\"loaded.editor.endDrag($event.pointerId ?? 0)\"\n @pointercancel=\"loaded.editor.endDrag($event.pointerId ?? 0)\"\n >\n <canvas ref=\"canvas\" class=\"pointer-events-none absolute inset-0 block size-full\" />\n <!-- Runtime geometry: no Tailwind class can hold these values. -->\n <div\n role=\"group\"\n tabindex=\"0\"\n :aria-label=\"t('image_editor.crop_area', {}, 'Crop area')\"\n :aria-describedby=\"hintId\"\n data-slot=\"image-editor-crop\"\n :class=\"\n cn(\n 'ring-ring/50 absolute cursor-move border-2 border-white shadow-[0_0_0_9999px_rgb(0_0_0/0.5)] outline-none focus-visible:ring-[3px]',\n loaded.editor.circle && 'rounded-full',\n )\n \"\n :style=\"{\n left: `${box.left}%`,\n top: `${box.top}%`,\n width: `${box.width}%`,\n height: `${box.height}%`,\n }\"\n @pointerdown=\"start('move', $event)\"\n @keydown=\"onKeydown\"\n >\n <span\n v-for=\"handle in HANDLES\"\n :key=\"handle\"\n :data-handle=\"handle\"\n aria-hidden=\"true\"\n class=\"absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-sm border border-black/40 bg-white\"\n :style=\"{\n left: handle.endsWith('w') ? '0%' : '100%',\n top: handle.startsWith('n') ? '0%' : '100%',\n cursor: handle === 'nw' || handle === 'se' ? 'nwse-resize' : 'nesw-resize',\n }\"\n @pointerdown=\"start(handle, $event)\"\n />\n </div>\n </div>\n <div class=\"flex flex-wrap items-center justify-between gap-2\">\n <div\n v-if=\"loaded.editor.aspectRatios.length > 1\"\n role=\"group\"\n :aria-label=\"t('image_editor.aspect_ratio', {}, 'Aspect ratio')\"\n class=\"flex flex-wrap gap-1\"\n >\n <Button\n v-for=\"ratio in loaded.editor.aspectRatios\"\n :key=\"ratio ?? 'free'\"\n type=\"button\"\n size=\"sm\"\n :variant=\"state.aspectRatio === ratio ? 'default' : 'outline'\"\n :aria-pressed=\"String(state.aspectRatio === ratio)\"\n @click=\"loaded.editor.setAspectRatio(ratio)\"\n >\n {{ ratioLabel(ratio) }}\n </Button>\n </div>\n <span v-else />\n <div class=\"flex flex-wrap gap-1\">\n <Button\n v-for=\"tool in tools\"\n :key=\"tool.label\"\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n :aria-label=\"tool.label\"\n :title=\"tool.label\"\n :disabled=\"tool.disabled\"\n @click=\"tool.run()\"\n >\n <component :is=\"tool.icon\" />\n </Button>\n </div>\n </div>\n </div>\n <!-- Numeric inputs: beside the image from md up, under it on phones. -->\n <div\n role=\"group\"\n :aria-label=\"t('image_editor.inputs', {}, 'Position and size')\"\n data-slot=\"image-editor-inputs\"\n class=\"grid grid-cols-2 content-start gap-x-3 gap-y-2 sm:grid-cols-4 md:w-40 md:shrink-0 md:grid-cols-1\"\n >\n <div\n v-for=\"[field, key, fallback] in NUMERIC_FIELDS\"\n :key=\"field\"\n class=\"flex flex-col gap-1\"\n >\n <label :for=\"`${inputsId}-${field}`\" class=\"text-muted-foreground text-xs\">\n {{ t(key, {}, fallback) }}\n </label>\n <Input\n :id=\"`${inputsId}-${field}`\"\n type=\"number\"\n inputmode=\"decimal\"\n step=\"1\"\n :data-field=\"field\"\n class=\"h-8 tabular-nums\"\n :model-value=\"data[field]\"\n @change=\"commit(field, $event)\"\n @keydown.enter.prevent=\"commit(field, $event)\"\n />\n </div>\n <div class=\"col-span-2 flex gap-1 sm:col-span-4 md:col-span-1\">\n <Button\n v-for=\"[axis, key, fallback] in SCALES\"\n :key=\"axis\"\n type=\"button\"\n size=\"sm\"\n :variant=\"(axis === 'x' ? state.flipX : state.flipY) ? 'default' : 'outline'\"\n :aria-pressed=\"String(axis === 'x' ? state.flipX : state.flipY)\"\n :data-field=\"`scale${axis.toUpperCase()}`\"\n class=\"flex-1\"\n @click=\"loaded.editor.flip(axis)\"\n >\n {{ t(key, {}, fallback) }}\n </Button>\n </div>\n </div>\n </div>\n <div v-else class=\"flex h-48 items-center justify-center\">\n <Spinner />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" @click=\"finish(null)\">\n {{ t('image_editor.cancel', {}, 'Cancel') }}\n </Button>\n <Button type=\"button\" :disabled=\"!loaded || saving\" @click=\"void save()\">\n <Spinner v-if=\"saving\" />\n {{ t('image_editor.save', {}, 'Apply') }}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ImageEditorDialog.js","names":["_sfc_main","ImageEditorDialog_vue_vue_type_script_setup_true_lang_default","ImageEditorDialog_default"],"sources":["../../../src/components/fields/ImageEditorDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * `FileUpload::imageEditor()`: crop, zoom, rotate and flip an image before it is uploaded\n * (or to replace an uploaded one). Resolves the request with the edited file, or null\n * when cancelled.\n */\nimport type {\n CropHandle,\n FileUploadImageEditorSchema,\n ImageEditorData,\n ImageEditorDragMode,\n ImageEditorState,\n} from '@alfakit/core'\nimport { ImageEditor, imageEditorOptionsKey, loadEditorImage } from '@alfakit/core'\nimport {\n FlipHorizontal2Icon,\n FlipVertical2Icon,\n RotateCcwIcon,\n RotateCwIcon,\n Undo2Icon,\n ZoomInIcon,\n ZoomOutIcon,\n} from '@lucide/vue'\nimport { computed, onScopeDispose, ref, shallowRef, useId, watch, type Component } from 'vue'\nimport { useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Input from '../ui/Input.vue'\nimport Spinner from '../ui/Spinner.vue'\n\nexport interface ImageEditRequest {\n file: File\n resolve: (file: File | null) => void\n}\n\nconst HANDLES: CropHandle[] = ['nw', 'ne', 'sw', 'se']\n\n/** The numeric inputs, in the order Filament shows them. */\nconst NUMERIC_FIELDS = [\n ['x', 'image_editor.x', 'X'],\n ['y', 'image_editor.y', 'Y'],\n ['width', 'image_editor.width', 'Width'],\n ['height', 'image_editor.height', 'Height'],\n ['rotate', 'image_editor.rotation', 'Rotation'],\n] as const satisfies ReadonlyArray<readonly [keyof ImageEditorData, string, string]>\n\nconst SCALES = [\n ['x', 'image_editor.scale_x', 'Scale X'],\n ['y', 'image_editor.scale_y', 'Scale Y'],\n] as const\n\nconst props = defineProps<{\n request: ImageEditRequest | null\n options: FileUploadImageEditorSchema\n}>()\n\nconst t = useT()\nconst loaded = shallowRef<{ bitmap: ImageBitmap; editor: ImageEditor } | null>(null)\nconst state = shallowRef<ImageEditorState | null>(null)\nconst saving = ref(false)\nconst hintId = useId()\nconst inputsId = useId()\nconst canvas = ref<HTMLCanvasElement | null>(null)\nconst frame = ref<HTMLDivElement | null>(null)\nlet unsubscribe: (() => void) | null = null\nlet stopObserving: (() => void) | null = null\n\nconst release = () => {\n unsubscribe?.()\n unsubscribe = null\n stopObserving?.()\n stopObserving = null\n loaded.value?.bitmap.close()\n loaded.value = null\n state.value = null\n}\n\n// Restart only for another image or other settings: the schema object itself is new on\n// every render of a template item (a new builder block), which kept restarting the load.\nwatch(\n [() => props.request, () => imageEditorOptionsKey(props.options)],\n ([request], _previous, onCleanup) => {\n if (!request) return\n\n const options = props.options\n\n let cancelled = false\n\n loadEditorImage(request.file)\n .then((bitmap) => {\n if (cancelled) return bitmap.close()\n\n const editor = new ImageEditor({\n width: bitmap.width,\n height: bitmap.height,\n aspectRatios: options.aspectRatios,\n circle: options.circle,\n mode: options.mode,\n emptyFillColor: options.emptyFillColor,\n viewportWidth: options.viewportWidth,\n viewportHeight: options.viewportHeight,\n })\n\n loaded.value = { bitmap, editor }\n state.value = editor.store.get()\n unsubscribe = editor.store.subscribe((next) => {\n state.value = next\n })\n })\n // Undecodable: upload the file as it is.\n .catch(() => !cancelled && request.resolve(request.file))\n\n onCleanup(() => {\n cancelled = true\n release()\n })\n },\n { immediate: true },\n)\n\nonScopeDispose(release)\n\n// Redraw on every change (crop, zoom, rotation, flips, container size).\nwatch(\n () => [canvas.value, state.value] as const,\n ([element]) => {\n if (element && loaded.value) {\n loaded.value.editor.drawPreview(\n element,\n loaded.value.bitmap,\n globalThis.devicePixelRatio || 1,\n )\n }\n },\n { flush: 'post' },\n)\n\n// Measure the container and follow its size; zoom with the wheel and trackpad pinch.\nwatch(\n () => [frame.value, loaded.value?.editor] as const,\n ([element, editor]) => {\n stopObserving?.()\n stopObserving = null\n\n if (!element || !editor) return\n\n const measure = () => editor.setContainer(element.clientWidth, element.clientHeight)\n measure()\n\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure)\n observer?.observe(element)\n\n const onWheel = (event: WheelEvent) => {\n const rect = element.getBoundingClientRect()\n\n if (editor.wheel(event, { x: event.clientX - rect.left, y: event.clientY - rect.top })) {\n event.preventDefault()\n }\n }\n\n element.addEventListener('wheel', onWheel, { passive: false })\n\n stopObserving = () => {\n observer?.disconnect()\n element.removeEventListener('wheel', onWheel)\n }\n },\n { flush: 'post' },\n)\n\nconst data = computed<ImageEditorData | null>(() => {\n void state.value\n\n return loaded.value?.editor.getData() ?? null\n})\n\n// Numeric inputs apply on change (blur, Enter, spinner); invalid values snap back.\nconst commit = (field: keyof ImageEditorData, event: Event) => {\n const editor = loaded.value?.editor\n const input = event.target as HTMLInputElement | null\n\n if (!editor || !input) return\n\n const value = input.value.trim() === '' ? Number.NaN : Number(input.value)\n editor.setData({ [field]: value })\n input.value = String(editor.getData()[field])\n}\n\nconst box = computed(() => {\n void state.value\n\n return loaded.value?.editor.cropBox() ?? { left: 0, top: 0, width: 0, height: 0 }\n})\n\nconst finish = (file: File | null) => {\n props.request?.resolve(file)\n}\n\nconst save = async () => {\n const request = props.request\n const current = loaded.value\n\n if (!request || !current) return\n\n saving.value = true\n\n try {\n finish(await current.editor.export(current.bitmap, request.file))\n } catch {\n finish(request.file)\n } finally {\n saving.value = false\n }\n}\n\nconst start = (mode: ImageEditorDragMode, event: PointerEvent) => {\n const editor = loaded.value?.editor\n\n if (!editor) return\n\n event.preventDefault()\n event.stopPropagation()\n ;(event.currentTarget as HTMLElement | null)?.setPointerCapture?.(event.pointerId)\n editor.startDrag(mode, event.clientX, event.clientY, undefined, event.pointerId ?? 0)\n}\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (loaded.value?.editor.handleKey(event)) event.preventDefault()\n}\n\nconst ratioLabel = (ratio: string | null) => ratio ?? t('image_editor.free', {}, 'Free')\n\nconst tools = computed<\n Array<{ label: string; icon: Component; run: () => void; disabled?: boolean }>\n>(() => [\n {\n label: t('image_editor.zoom_out', {}, 'Zoom out'),\n icon: ZoomOutIcon,\n run: () => loaded.value?.editor.zoomOut(),\n disabled: !(state.value && loaded.value?.editor.canZoomOut),\n },\n {\n label: t('image_editor.zoom_in', {}, 'Zoom in'),\n icon: ZoomInIcon,\n run: () => loaded.value?.editor.zoomIn(),\n disabled: !(state.value && loaded.value?.editor.canZoomIn),\n },\n {\n label: t('image_editor.rotate_left', {}, 'Rotate left'),\n icon: RotateCcwIcon,\n run: () => loaded.value?.editor.rotate(-1),\n },\n {\n label: t('image_editor.rotate_right', {}, 'Rotate right'),\n icon: RotateCwIcon,\n run: () => loaded.value?.editor.rotate(1),\n },\n {\n label: t('image_editor.flip_horizontal', {}, 'Flip horizontally'),\n icon: FlipHorizontal2Icon,\n run: () => loaded.value?.editor.flip('x'),\n },\n {\n label: t('image_editor.flip_vertical', {}, 'Flip vertically'),\n icon: FlipVertical2Icon,\n run: () => loaded.value?.editor.flip('y'),\n },\n {\n label: t('image_editor.reset', {}, 'Reset'),\n icon: Undo2Icon,\n run: () => loaded.value?.editor.reset(),\n },\n])\n</script>\n\n<template>\n <Dialog :open=\"props.request !== null\" @update:open=\"(open) => !open && finish(null)\">\n <DialogContent class=\"sm:max-w-3xl\" data-slot=\"image-editor\">\n <DialogHeader>\n <DialogTitle>{{ t('image_editor.title', {}, 'Edit image') }}</DialogTitle>\n <DialogDescription class=\"sr-only\">\n <span :id=\"hintId\"\n >{{\n t(\n 'image_editor.keyboard_hint',\n {},\n 'Arrow keys move the crop area. Shift and arrow keys resize it.',\n )\n }}\n {{ t('image_editor.zoom_hint', {}, 'Plus and minus keys zoom the image.') }}</span\n >\n </DialogDescription>\n </DialogHeader>\n <div v-if=\"loaded && state && data\" class=\"flex flex-col gap-4 md:flex-row\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <!-- Image space: left is the image's left in every reading direction. -->\n <div\n ref=\"frame\"\n dir=\"ltr\"\n data-slot=\"image-editor-viewport\"\n class=\"bg-muted/40 relative h-72 w-full cursor-grab touch-none overflow-hidden rounded-md select-none sm:h-96\"\n @pointerdown=\"start('pan', $event)\"\n @pointermove=\"\n loaded.editor.dragTo($event.clientX, $event.clientY, $event.pointerId ?? 0)\n \"\n @pointerup=\"loaded.editor.endDrag($event.pointerId ?? 0)\"\n @pointercancel=\"loaded.editor.endDrag($event.pointerId ?? 0)\"\n >\n <canvas ref=\"canvas\" class=\"pointer-events-none absolute inset-0 block size-full\" />\n <!-- Runtime geometry: no Tailwind class can hold these values. -->\n <div\n role=\"group\"\n tabindex=\"0\"\n :aria-label=\"t('image_editor.crop_area', {}, 'Crop area')\"\n :aria-describedby=\"hintId\"\n data-slot=\"image-editor-crop\"\n :class=\"\n cn(\n 'ring-ring/50 absolute cursor-move border-2 border-white shadow-[0_0_0_9999px_rgb(0_0_0/0.5)] outline-none focus-visible:ring-[3px]',\n loaded.editor.circle && 'rounded-full',\n )\n \"\n :style=\"{\n left: `${box.left}%`,\n top: `${box.top}%`,\n width: `${box.width}%`,\n height: `${box.height}%`,\n }\"\n @pointerdown=\"start('move', $event)\"\n @keydown=\"onKeydown\"\n >\n <span\n v-for=\"handle in HANDLES\"\n :key=\"handle\"\n :data-handle=\"handle\"\n aria-hidden=\"true\"\n class=\"absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-sm border border-black/40 bg-white\"\n :style=\"{\n left: handle.endsWith('w') ? '0%' : '100%',\n top: handle.startsWith('n') ? '0%' : '100%',\n cursor: handle === 'nw' || handle === 'se' ? 'nwse-resize' : 'nesw-resize',\n }\"\n @pointerdown=\"start(handle, $event)\"\n />\n </div>\n </div>\n <div class=\"flex flex-wrap items-center justify-between gap-2\">\n <div\n v-if=\"loaded.editor.aspectRatios.length > 1\"\n role=\"group\"\n :aria-label=\"t('image_editor.aspect_ratio', {}, 'Aspect ratio')\"\n class=\"flex flex-wrap gap-1\"\n >\n <Button\n v-for=\"ratio in loaded.editor.aspectRatios\"\n :key=\"ratio ?? 'free'\"\n type=\"button\"\n size=\"sm\"\n :variant=\"state.aspectRatio === ratio ? 'default' : 'outline'\"\n :aria-pressed=\"String(state.aspectRatio === ratio)\"\n @click=\"loaded.editor.setAspectRatio(ratio)\"\n >\n {{ ratioLabel(ratio) }}\n </Button>\n </div>\n <span v-else />\n <div class=\"flex flex-wrap gap-1\">\n <Button\n v-for=\"tool in tools\"\n :key=\"tool.label\"\n type=\"button\"\n variant=\"outline\"\n size=\"icon-sm\"\n :aria-label=\"tool.label\"\n :title=\"tool.label\"\n :disabled=\"tool.disabled\"\n @click=\"tool.run()\"\n >\n <component :is=\"tool.icon\" />\n </Button>\n </div>\n </div>\n </div>\n <!-- Numeric inputs: beside the image from md up, under it on phones. -->\n <div\n role=\"group\"\n :aria-label=\"t('image_editor.inputs', {}, 'Position and size')\"\n data-slot=\"image-editor-inputs\"\n class=\"grid grid-cols-2 content-start gap-x-3 gap-y-2 sm:grid-cols-4 md:w-40 md:shrink-0 md:grid-cols-1\"\n >\n <div\n v-for=\"[field, key, fallback] in NUMERIC_FIELDS\"\n :key=\"field\"\n class=\"flex flex-col gap-1\"\n >\n <label :for=\"`${inputsId}-${field}`\" class=\"text-muted-foreground text-xs\">\n {{ t(key, {}, fallback) }}\n </label>\n <Input\n :id=\"`${inputsId}-${field}`\"\n type=\"number\"\n inputmode=\"decimal\"\n step=\"1\"\n :data-field=\"field\"\n class=\"h-8 tabular-nums\"\n :model-value=\"data[field]\"\n @change=\"commit(field, $event)\"\n @keydown.enter.prevent=\"commit(field, $event)\"\n />\n </div>\n <div class=\"col-span-2 flex gap-1 sm:col-span-4 md:col-span-1\">\n <Button\n v-for=\"[axis, key, fallback] in SCALES\"\n :key=\"axis\"\n type=\"button\"\n size=\"sm\"\n :variant=\"(axis === 'x' ? state.flipX : state.flipY) ? 'default' : 'outline'\"\n :aria-pressed=\"String(axis === 'x' ? state.flipX : state.flipY)\"\n :data-field=\"`scale${axis.toUpperCase()}`\"\n class=\"flex-1\"\n @click=\"loaded.editor.flip(axis)\"\n >\n {{ t(key, {}, fallback) }}\n </Button>\n </div>\n </div>\n </div>\n <div v-else class=\"flex h-48 items-center justify-center\">\n <Spinner />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" @click=\"finish(null)\">\n {{ t('image_editor.cancel', {}, 'Cancel') }}\n </Button>\n <Button type=\"button\" :disabled=\"!loaded || saving\" @click=\"void save()\">\n <Spinner v-if=\"saving\" />\n {{ t('image_editor.save', {}, 'Apply') }}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageEditorDialog.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ImageEditorDialog.vue"],"names":[],"mappings":"AA8bA;;;;GAIG;AACH,OAAO,KAAK,EAEV,2BAA2B,EAI5B,MAAM,eAAe,CAAA;AAwBtB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAA;CACrC;AAkBD,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,2BAA2B,CAAA;CACrC,CAAC;;AA2uBF,wBAMG"}
1
+ {"version":3,"file":"ImageEditorDialog.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/ImageEditorDialog.vue"],"names":[],"mappings":"AAkcA;;;;GAIG;AACH,OAAO,KAAK,EAEV,2BAA2B,EAI5B,MAAM,eAAe,CAAA;AAwBtB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAA;CACrC;AAkBD,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,2BAA2B,CAAA;CACrC,CAAC;;AA+uBF,wBAMG"}
@@ -9,14 +9,14 @@ import ne from "../ui/DialogDescription.js";
9
9
  import re from "../ui/DialogHeader.js";
10
10
  import ie from "../ui/DialogTitle.js";
11
11
  import ae from "../ui/DialogFooter.js";
12
- import { ImageEditor as a, loadEditorImage as oe } from "@alfakit/core";
13
- import { Fragment as o, computed as s, createBlock as c, createCommentVNode as se, createElementBlock as l, createElementVNode as u, createTextVNode as d, createVNode as f, defineComponent as p, normalizeClass as ce, normalizeStyle as m, onScopeDispose as le, openBlock as h, ref as g, renderList as _, resolveDynamicComponent as ue, shallowRef as v, toDisplayString as y, unref as b, useId as x, watch as S, withCtx as C, withKeys as de, withModifiers as fe } from "vue";
14
- import { FlipHorizontal2Icon as pe, FlipVertical2Icon as me, RotateCcwIcon as he, RotateCwIcon as ge, Undo2Icon as _e, ZoomInIcon as ve, ZoomOutIcon as ye } from "@lucide/vue";
12
+ import { ImageEditor as a, imageEditorOptionsKey as oe, loadEditorImage as se } from "@alfakit/core";
13
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as ce, createElementBlock as l, createElementVNode as u, createTextVNode as d, createVNode as f, defineComponent as p, normalizeClass as le, normalizeStyle as m, onScopeDispose as ue, openBlock as h, ref as g, renderList as _, resolveDynamicComponent as de, shallowRef as v, toDisplayString as y, unref as b, useId as x, watch as S, withCtx as C, withKeys as fe, withModifiers as pe } from "vue";
14
+ import { FlipHorizontal2Icon as me, FlipVertical2Icon as he, RotateCcwIcon as ge, RotateCwIcon as _e, Undo2Icon as ve, ZoomInIcon as ye, ZoomOutIcon as w } from "@lucide/vue";
15
15
  //#region src/components/fields/ImageEditorDialog.vue?vue&type=script&setup=true&lang.ts
16
- var w = ["id"], T = {
16
+ var T = ["id"], E = {
17
17
  key: 0,
18
18
  class: "flex flex-col gap-4 md:flex-row"
19
- }, E = { class: "flex min-w-0 flex-1 flex-col gap-3" }, D = ["aria-label", "aria-describedby"], O = ["data-handle", "onPointerdown"], k = { class: "flex flex-wrap items-center justify-between gap-2" }, A = ["aria-label"], j = { key: 1 }, M = { class: "flex flex-wrap gap-1" }, N = ["aria-label"], P = ["for"], F = { class: "col-span-2 flex gap-1 sm:col-span-4 md:col-span-1" }, be = {
19
+ }, D = { class: "flex min-w-0 flex-1 flex-col gap-3" }, O = ["aria-label", "aria-describedby"], k = ["data-handle", "onPointerdown"], A = { class: "flex flex-wrap items-center justify-between gap-2" }, j = ["aria-label"], M = { key: 1 }, N = { class: "flex flex-wrap gap-1" }, P = ["aria-label"], F = ["for"], be = { class: "col-span-2 flex gap-1 sm:col-span-4 md:col-span-1" }, xe = {
20
20
  key: 1,
21
21
  class: "flex h-48 items-center justify-center"
22
22
  }, I = /*@__PURE__*/ p({
@@ -31,7 +31,7 @@ var w = ["id"], T = {
31
31
  "ne",
32
32
  "sw",
33
33
  "se"
34
- ], xe = [
34
+ ], Se = [
35
35
  [
36
36
  "x",
37
37
  "image_editor.x",
@@ -57,7 +57,7 @@ var w = ["id"], T = {
57
57
  "image_editor.rotation",
58
58
  "Rotation"
59
59
  ]
60
- ], Se = [[
60
+ ], Ce = [[
61
61
  "x",
62
62
  "image_editor.scale_x",
63
63
  "Scale X"
@@ -68,31 +68,31 @@ var w = ["id"], T = {
68
68
  ]], L = p, R = e(), z = v(null), B = v(null), V = g(!1), H = x(), U = x(), W = g(null), G = g(null), K = null, q = null, J = () => {
69
69
  K?.(), K = null, q?.(), q = null, z.value?.bitmap.close(), z.value = null, B.value = null;
70
70
  };
71
- S(() => [L.request, L.options], ([e, t], n, r) => {
71
+ S([() => L.request, () => oe(L.options)], ([e], t, n) => {
72
72
  if (!e) return;
73
- let i = !1;
74
- oe(e.file).then((e) => {
73
+ let r = L.options, i = !1;
74
+ se(e.file).then((e) => {
75
75
  if (i) return e.close();
76
- let n = new a({
76
+ let t = new a({
77
77
  width: e.width,
78
78
  height: e.height,
79
- aspectRatios: t.aspectRatios,
80
- circle: t.circle,
81
- mode: t.mode,
82
- emptyFillColor: t.emptyFillColor,
83
- viewportWidth: t.viewportWidth,
84
- viewportHeight: t.viewportHeight
79
+ aspectRatios: r.aspectRatios,
80
+ circle: r.circle,
81
+ mode: r.mode,
82
+ emptyFillColor: r.emptyFillColor,
83
+ viewportWidth: r.viewportWidth,
84
+ viewportHeight: r.viewportHeight
85
85
  });
86
86
  z.value = {
87
87
  bitmap: e,
88
- editor: n
89
- }, B.value = n.store.get(), K = n.store.subscribe((e) => {
88
+ editor: t
89
+ }, B.value = t.store.get(), K = t.store.subscribe((e) => {
90
90
  B.value = e;
91
91
  });
92
- }).catch(() => !i && e.resolve(e.file)), r(() => {
92
+ }).catch(() => !i && e.resolve(e.file)), n(() => {
93
93
  i = !0, J();
94
94
  });
95
- }, { immediate: !0 }), le(J), S(() => [W.value, B.value], ([e]) => {
95
+ }, { immediate: !0 }), ue(J), S(() => [W.value, B.value], ([e]) => {
96
96
  e && z.value && z.value.editor.drawPreview(e, z.value.bitmap, globalThis.devicePixelRatio || 1);
97
97
  }, { flush: "post" }), S(() => [G.value, z.value?.editor], ([e, t]) => {
98
98
  if (q?.(), q = null, !e || !t) return;
@@ -123,7 +123,7 @@ var w = ["id"], T = {
123
123
  height: 0
124
124
  })), Q = (e) => {
125
125
  L.request?.resolve(e);
126
- }, Ce = async () => {
126
+ }, we = async () => {
127
127
  let e = L.request, t = z.value;
128
128
  if (e && t) {
129
129
  V.value = !0;
@@ -138,44 +138,44 @@ var w = ["id"], T = {
138
138
  }, $ = (e, t) => {
139
139
  let n = z.value?.editor;
140
140
  n && (t.preventDefault(), t.stopPropagation(), t.currentTarget?.setPointerCapture?.(t.pointerId), n.startDrag(e, t.clientX, t.clientY, void 0, t.pointerId ?? 0));
141
- }, we = (e) => {
141
+ }, Te = (e) => {
142
142
  z.value?.editor.handleKey(e) && e.preventDefault();
143
- }, Te = (e) => e ?? R("image_editor.free", {}, "Free"), Ee = s(() => [
143
+ }, Ee = (e) => e ?? R("image_editor.free", {}, "Free"), De = s(() => [
144
144
  {
145
145
  label: R("image_editor.zoom_out", {}, "Zoom out"),
146
- icon: ye,
146
+ icon: w,
147
147
  run: () => z.value?.editor.zoomOut(),
148
148
  disabled: !(B.value && z.value?.editor.canZoomOut)
149
149
  },
150
150
  {
151
151
  label: R("image_editor.zoom_in", {}, "Zoom in"),
152
- icon: ve,
152
+ icon: ye,
153
153
  run: () => z.value?.editor.zoomIn(),
154
154
  disabled: !(B.value && z.value?.editor.canZoomIn)
155
155
  },
156
156
  {
157
157
  label: R("image_editor.rotate_left", {}, "Rotate left"),
158
- icon: he,
158
+ icon: ge,
159
159
  run: () => z.value?.editor.rotate(-1)
160
160
  },
161
161
  {
162
162
  label: R("image_editor.rotate_right", {}, "Rotate right"),
163
- icon: ge,
163
+ icon: _e,
164
164
  run: () => z.value?.editor.rotate(1)
165
165
  },
166
166
  {
167
167
  label: R("image_editor.flip_horizontal", {}, "Flip horizontally"),
168
- icon: pe,
168
+ icon: me,
169
169
  run: () => z.value?.editor.flip("x")
170
170
  },
171
171
  {
172
172
  label: R("image_editor.flip_vertical", {}, "Flip vertically"),
173
- icon: me,
173
+ icon: he,
174
174
  run: () => z.value?.editor.flip("y")
175
175
  },
176
176
  {
177
177
  label: R("image_editor.reset", {}, "Reset"),
178
- icon: _e,
178
+ icon: ve,
179
179
  run: () => z.value?.editor.reset()
180
180
  }
181
181
  ]);
@@ -193,12 +193,12 @@ var w = ["id"], T = {
193
193
  default: C(() => [d(y(b(R)("image_editor.title", {}, "Edit image")), 1)]),
194
194
  _: 1
195
195
  }), f(ne, { class: "sr-only" }, {
196
- default: C(() => [u("span", { id: b(H) }, y(b(R)("image_editor.keyboard_hint", {}, "Arrow keys move the crop area. Shift and arrow keys resize it.")) + " " + y(b(R)("image_editor.zoom_hint", {}, "Plus and minus keys zoom the image.")), 9, w)]),
196
+ default: C(() => [u("span", { id: b(H) }, y(b(R)("image_editor.keyboard_hint", {}, "Arrow keys move the crop area. Shift and arrow keys resize it.")) + " " + y(b(R)("image_editor.zoom_hint", {}, "Plus and minus keys zoom the image.")), 9, T)]),
197
197
  _: 1
198
198
  })]),
199
199
  _: 1
200
200
  }),
201
- z.value && B.value && Y.value ? (h(), l("div", T, [u("div", E, [u("div", {
201
+ z.value && B.value && Y.value ? (h(), l("div", E, [u("div", D, [u("div", {
202
202
  ref_key: "frame",
203
203
  ref: G,
204
204
  dir: "ltr",
@@ -218,7 +218,7 @@ var w = ["id"], T = {
218
218
  "aria-label": b(R)("image_editor.crop_area", {}, "Crop area"),
219
219
  "aria-describedby": b(H),
220
220
  "data-slot": "image-editor-crop",
221
- class: ce(b(t)("ring-ring/50 absolute cursor-move border-2 border-white shadow-[0_0_0_9999px_rgb(0_0_0/0.5)] outline-none focus-visible:ring-[3px]", z.value.editor.circle && "rounded-full")),
221
+ class: le(b(t)("ring-ring/50 absolute cursor-move border-2 border-white shadow-[0_0_0_9999px_rgb(0_0_0/0.5)] outline-none focus-visible:ring-[3px]", z.value.editor.circle && "rounded-full")),
222
222
  style: m({
223
223
  left: `${Z.value.left}%`,
224
224
  top: `${Z.value.top}%`,
@@ -226,7 +226,7 @@ var w = ["id"], T = {
226
226
  height: `${Z.value.height}%`
227
227
  }),
228
228
  onPointerdown: a[0] ||= (e) => $("move", e),
229
- onKeydown: we
229
+ onKeydown: Te
230
230
  }, [(h(), l(o, null, _(I, (e) => u("span", {
231
231
  key: e,
232
232
  "data-handle": e,
@@ -238,7 +238,7 @@ var w = ["id"], T = {
238
238
  cursor: e === "nw" || e === "se" ? "nwse-resize" : "nesw-resize"
239
239
  }),
240
240
  onPointerdown: (t) => $(e, t)
241
- }, null, 44, O)), 64))], 46, D)], 544), u("div", k, [z.value.editor.aspectRatios.length > 1 ? (h(), l("div", {
241
+ }, null, 44, k)), 64))], 46, O)], 544), u("div", A, [z.value.editor.aspectRatios.length > 1 ? (h(), l("div", {
242
242
  key: 0,
243
243
  role: "group",
244
244
  "aria-label": b(R)("image_editor.aspect_ratio", {}, "Aspect ratio"),
@@ -251,13 +251,13 @@ var w = ["id"], T = {
251
251
  "aria-pressed": String(B.value.aspectRatio === e),
252
252
  onClick: (t) => z.value.editor.setAspectRatio(e)
253
253
  }, {
254
- default: C(() => [d(y(Te(e)), 1)]),
254
+ default: C(() => [d(y(Ee(e)), 1)]),
255
255
  _: 2
256
256
  }, 1032, [
257
257
  "variant",
258
258
  "aria-pressed",
259
259
  "onClick"
260
- ]))), 128))], 8, A)) : (h(), l("span", j)), u("div", M, [(h(!0), l(o, null, _(Ee.value, (e) => (h(), c(n, {
260
+ ]))), 128))], 8, j)) : (h(), l("span", M)), u("div", N, [(h(!0), l(o, null, _(De.value, (e) => (h(), c(n, {
261
261
  key: e.label,
262
262
  type: "button",
263
263
  variant: "outline",
@@ -267,7 +267,7 @@ var w = ["id"], T = {
267
267
  disabled: e.disabled,
268
268
  onClick: (t) => e.run()
269
269
  }, {
270
- default: C(() => [(h(), c(ue(e.icon)))]),
270
+ default: C(() => [(h(), c(de(e.icon)))]),
271
271
  _: 2
272
272
  }, 1032, [
273
273
  "aria-label",
@@ -279,13 +279,13 @@ var w = ["id"], T = {
279
279
  "aria-label": b(R)("image_editor.inputs", {}, "Position and size"),
280
280
  "data-slot": "image-editor-inputs",
281
281
  class: "grid grid-cols-2 content-start gap-x-3 gap-y-2 sm:grid-cols-4 md:w-40 md:shrink-0 md:grid-cols-1"
282
- }, [(h(), l(o, null, _(xe, ([e, t, n]) => u("div", {
282
+ }, [(h(), l(o, null, _(Se, ([e, t, n]) => u("div", {
283
283
  key: e,
284
284
  class: "flex flex-col gap-1"
285
285
  }, [u("label", {
286
286
  for: `${b(U)}-${e}`,
287
287
  class: "text-muted-foreground text-xs"
288
- }, y(b(R)(t, {}, n)), 9, P), f(i, {
288
+ }, y(b(R)(t, {}, n)), 9, F), f(i, {
289
289
  id: `${b(U)}-${e}`,
290
290
  type: "number",
291
291
  inputmode: "decimal",
@@ -294,14 +294,14 @@ var w = ["id"], T = {
294
294
  class: "h-8 tabular-nums",
295
295
  "model-value": Y.value[e],
296
296
  onChange: (t) => X(e, t),
297
- onKeydown: de(fe((t) => X(e, t), ["prevent"]), ["enter"])
297
+ onKeydown: fe(pe((t) => X(e, t), ["prevent"]), ["enter"])
298
298
  }, null, 8, [
299
299
  "id",
300
300
  "data-field",
301
301
  "model-value",
302
302
  "onChange",
303
303
  "onKeydown"
304
- ])])), 64)), u("div", F, [(h(), l(o, null, _(Se, ([e, t, r]) => f(n, {
304
+ ])])), 64)), u("div", be, [(h(), l(o, null, _(Ce, ([e, t, r]) => f(n, {
305
305
  key: e,
306
306
  type: "button",
307
307
  size: "sm",
@@ -318,7 +318,7 @@ var w = ["id"], T = {
318
318
  "aria-pressed",
319
319
  "data-field",
320
320
  "onClick"
321
- ])), 64))])], 8, N)])) : (h(), l("div", be, [f(r)])),
321
+ ])), 64))])], 8, P)])) : (h(), l("div", xe, [f(r)])),
322
322
  f(ae, null, {
323
323
  default: C(() => [f(n, {
324
324
  type: "button",
@@ -330,9 +330,9 @@ var w = ["id"], T = {
330
330
  }), f(n, {
331
331
  type: "button",
332
332
  disabled: !z.value || V.value,
333
- onClick: a[6] ||= (e) => void Ce()
333
+ onClick: a[6] ||= (e) => void we()
334
334
  }, {
335
- default: C(() => [V.value ? (h(), c(r, { key: 0 })) : se("", !0), d(" " + y(b(R)("image_editor.save", {}, "Apply")), 1)]),
335
+ default: C(() => [V.value ? (h(), c(r, { key: 0 })) : ce("", !0), d(" " + y(b(R)("image_editor.save", {}, "Apply")), 1)]),
336
336
  _: 1
337
337
  }, 8, ["disabled"])]),
338
338
  _: 1