@alfakit/vue 0.1.2 → 0.1.6

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 +8 -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":"RichEditorInput.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createElementBlock","_normalizeStyle","_createVNode","RichEditorToolbarEntries","_createCommentVNode","_Fragment","_renderList","_withModifiers","Button","RichEditorSidePanel","RichEditorSuggestions","_toDisplayString","Button_default","FieldWrapper_default","RichEditorSidePanel_default","RichEditorSuggestions_default","RichEditorToolbarEntries_default","Image","Link","Placeholder","StarterKit","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","RESIZE_HANDLE_CLASSES","RichEditorInput_vue_vue_type_script_setup_true_lang_default","imageExtension","resizable","resizableImageAttributes","resizableImageOptions","toolbarExtensions","has","names","buttons","name","extensions","TableKit","markdown","Mark","highlightMarkConfig","subscriptMarkConfig","superscriptMarkConfig","textColorMarkConfig","Extension","textAlignExtensionConfig","detailsNodeConfigs","Node","config","smallMarkConfig","leadExtensionConfig","gridNodeConfigs","props","__props","t","useT","panel","usePanel","runner","useActionRunner","useField","fileInput","ref","isMarkdown","computed","editable","disabled","readOnly","attachments","EditorAttachments","isJson","liveEditor","shallowRef","rich","useRichEditorExtensions","openPanel","sidePanel","initial","attachmentError","selectionTick","stickyTop","sticky","updateStickyTop","resolveStickyOffset","onMounted","watch","commands","toolbarCommands","tool","args","stateToContent","document","toEditorDocument","state","editorToState","instance","html","htmlToMarkdown","toolbarElements","toolbars","setToolbar","current","slot","element","attachToolbarKeyboard","editor","useEditor","linkExtensionOptions","allToolbarButtons","value","isToolbarShortcut","event","focusToolbar","cn","fieldIds","id","aria","attribute","blur","next","isEditable","hasFloatingToolbars","onScroll","onCleanup","pickImage","uploadImage","problem","fileAttachmentError","file","response","uploadTemporaryFile","panelUploadOptions","error","src","onFilePicked","accept","translate","key","fallback","runCommand","button","message","target","toggleSidePanel","insertMergeTag","tagId","currentTextColor","showTableToolbar","showsTableToolbar","floating","resolveFloatingToolbar","applyColor","setTextColor","color","close","openBlock","createBlock","unref","withCtx","createElementVNode","normalizeClass","createElementBlock","normalizeStyle","createVNode","createCommentVNode","toolbarButtonLabel","Fragment","renderList","_cache","withModifiers","$event","EraserIcon","TABLE_TOOLBAR_BUTTONS","EditorContent","blockId","floatingToolbarStyle","toDisplayString"],"sources":["../../../src/components/fields/RichEditorInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { LoadedRichEditorExtensions, RichEditorPanel, RichEditorSchema } from '@alfakit/core'\nimport {\n allToolbarButtons,\n attachToolbarKeyboard,\n focusToolbar,\n isToolbarShortcut,\n detailsNodeConfigs,\n gridNodeConfigs,\n leadExtensionConfig,\n linkExtensionOptions,\n smallMarkConfig,\n EditorAttachments,\n fieldIds,\n fileAttachmentError,\n floatingToolbarStyle,\n highlightMarkConfig,\n htmlToMarkdown,\n resizableImageAttributes,\n resizableImageOptions,\n resolveFloatingToolbar,\n resolveStickyOffset,\n setTextColor,\n showsTableToolbar,\n subscriptMarkConfig,\n superscriptMarkConfig,\n TABLE_TOOLBAR_BUTTONS,\n textAlignExtensionConfig,\n textColorMarkConfig,\n toEditorDocument,\n toolbarButtonLabel,\n toolbarCommands,\n panelUploadOptions,\n uploadTemporaryFile,\n} from '@alfakit/core'\nimport { EraserIcon } from '@lucide/vue'\nimport Image from '@tiptap/extension-image'\nimport Link from '@tiptap/extension-link'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport { TableKit } from '@tiptap/extension-table'\nimport StarterKit from '@tiptap/starter-kit'\nimport {\n EditorContent,\n Extension,\n Mark,\n Node,\n useEditor,\n type Editor,\n type Extensions,\n} from '@tiptap/vue-3'\nimport { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'\nimport { useActionRunner, usePanel, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Button from '../ui/Button.vue'\nimport { useRichEditorExtensions } from './rich-editor-extensions'\nimport RichEditorSidePanel from './RichEditorSidePanel.vue'\nimport RichEditorSuggestions from './RichEditorSuggestions.vue'\nimport RichEditorToolbarEntries from './RichEditorToolbarEntries.vue'\n\ntype MarkConfig = Parameters<typeof Mark.create>[0]\ntype NodeConfig = Parameters<typeof Node.create>[0]\ntype ExtensionConfig = Parameters<typeof Extension.create>[0]\n\n/**\n * Resize handles of `resizableImages()` (Tiptap's node view adds bare `data-resize-handle`\n * elements): round dots on the corners, shown on hover and while the image is selected.\n */\nconst RESIZE_HANDLE_CLASSES =\n '[&_[data-resize-handle]]:z-10 [&_[data-resize-handle]]:size-3 [&_[data-resize-handle]]:rounded-full [&_[data-resize-handle]]:border-2 [&_[data-resize-handle]]:border-background [&_[data-resize-handle]]:bg-primary [&_[data-resize-handle]]:opacity-0 [&_[data-resize-container]:hover_[data-resize-handle]]:opacity-100 [&_.ProseMirror-selectednode_[data-resize-handle]]:opacity-100 [&_[data-resize-handle=bottom-right]]:cursor-nwse-resize [&_[data-resize-handle=top-left]]:cursor-nwse-resize [&_[data-resize-handle=bottom-left]]:cursor-nesw-resize [&_[data-resize-handle=top-right]]:cursor-nesw-resize'\n\n/** The image extension, with drag handles for `resizableImages()`. */\nfunction imageExtension(resizable: boolean) {\n if (!resizable) return Image\n\n return Image.extend({\n addAttributes() {\n return resizableImageAttributes(this.parent?.() ?? {})\n },\n }).configure(resizableImageOptions())\n}\n\n/** Extensions for the extra toolbar buttons (only those the toolbar uses are loaded). */\nfunction toolbarExtensions(buttons: string[], markdown: boolean): Extensions {\n const has = (...names: string[]) => names.some((name) => buttons.includes(name))\n const extensions: Extensions = []\n\n if (has('table')) extensions.push(TableKit.configure({ table: { resizable: false } }))\n // Markdown has no syntax for these.\n if (markdown) return extensions\n\n if (has('highlight')) extensions.push(Mark.create(highlightMarkConfig() as MarkConfig))\n if (has('subscript')) extensions.push(Mark.create(subscriptMarkConfig() as MarkConfig))\n if (has('superscript')) extensions.push(Mark.create(superscriptMarkConfig() as MarkConfig))\n if (has('textColor')) extensions.push(Mark.create(textColorMarkConfig() as MarkConfig))\n if (has('alignStart', 'alignCenter', 'alignEnd', 'alignJustify')) {\n extensions.push(Extension.create(textAlignExtensionConfig() as ExtensionConfig))\n }\n if (has('details')) {\n extensions.push(...detailsNodeConfigs().map((config) => Node.create(config as NodeConfig)))\n }\n if (has('small')) extensions.push(Mark.create(smallMarkConfig() as MarkConfig))\n if (has('lead')) extensions.push(Extension.create(leadExtensionConfig() as ExtensionConfig))\n if (has('grid', 'gridDelete', 'gridAddColumnBefore', 'gridAddColumnAfter', 'gridDeleteColumn')) {\n extensions.push(...gridNodeConfigs().map((config) => Node.create(config as NodeConfig)))\n }\n\n return extensions\n}\n\nconst props = defineProps<{ component: RichEditorSchema; plugins: LoadedRichEditorExtensions }>()\nconst t = useT()\nconst panel = usePanel()\nconst runner = useActionRunner()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<unknown>(\n () => props.component,\n)\nconst fileInput = ref<HTMLInputElement | null>(null)\nconst isMarkdown = computed(() => props.component.type === 'MarkdownEditor')\nconst editable = computed(() => !disabled.value && !readOnly.value)\n// Uploaded images preview from a local URL but are stored by their `tmp:` key.\nconst attachments = new EditorAttachments()\nconst isJson = computed(() => Boolean(props.component.json) && !isMarkdown.value)\n// The editor's live instance, for the custom block node views and suggestions.\nconst liveEditor = shallowRef<Editor | undefined>()\nconst rich = useRichEditorExtensions(() => props.component, liveEditor)\n// The open toolbar panel (the text colour palette).\nconst openPanel = ref<'textColor' | null>(null)\n// The open side panel (custom blocks or merge tags).\nconst initialSidePanel = (): RichEditorPanel | null => {\n const initial = props.component.activePanel ?? null\n\n if (initial === 'customBlocks') return props.component.customBlocks?.length ? initial : null\n if (initial === 'mergeTags') return props.component.mergeTags?.length ? initial : null\n\n return null\n}\nconst sidePanel = ref<RichEditorPanel | null>(initialSidePanel())\nconst attachmentError = ref<string | null>(null)\n// Bumped on every transaction so active states and the table row follow the cursor.\nconst selectionTick = ref(0)\nconst stickyTop = ref<string | null>(null)\nconst sticky = computed(() =>\n Boolean(props.component.stickyToolbar || props.component.stickyPanels),\n)\n\nconst updateStickyTop = () => {\n stickyTop.value = sticky.value ? resolveStickyOffset(props.component.stickyOffset) : null\n}\n\nonMounted(updateStickyTop)\nwatch([sticky, () => props.component.stickyOffset], updateStickyTop)\n\n// Built-in buttons, plugin tools and commands of plugin JavaScript extensions.\nconst commands = computed(() =>\n toolbarCommands(\n props.component.editorTools,\n {\n runAction: (tool, args) =>\n tool.action\n ? runner.runField(tool.action, { ...rich.context.value, arguments: args })\n : Promise.resolve(undefined),\n editor: () => liveEditor.value ?? null,\n },\n props.plugins.commands,\n ),\n)\n\n// Field state ↔ editor content: HTML, Markdown (loaded from the server's HTML) or a\n// Tiptap JSON document. `tmp:` upload keys become local preview URLs and back.\nconst stateToContent = (state: unknown): string | Record<string, unknown> => {\n if (isJson.value) {\n const document = toEditorDocument(state)\n\n return document ? JSON.parse(attachments.toEditor(JSON.stringify(document))) : ''\n }\n\n return attachments.toEditor(\n ((isMarkdown.value\n ? typeof props.component.html === 'string'\n ? props.component.html\n : null\n : state) as string | null) ?? '',\n )\n}\nconst editorToState = (instance: Pick<Editor, 'isEmpty' | 'getJSON' | 'getHTML'>): unknown => {\n if (instance.isEmpty) return null\n if (isJson.value) return JSON.parse(attachments.toState(JSON.stringify(instance.getJSON())))\n\n const html = instance.getHTML()\n\n return attachments.toState(isMarkdown.value ? htmlToMarkdown(html) : html)\n}\n\nonBeforeUnmount(() => attachments.destroy())\n\n// Keyboard access to the toolbars (roving tabindex, arrows, Escape, Alt+F10).\ntype ToolbarSlot = 'main' | 'table' | 'floating'\nconst toolbarElements: Record<ToolbarSlot, { element: HTMLElement; detach: () => void } | null> = {\n main: null,\n table: null,\n floating: null,\n}\nconst toolbars = () => [\n toolbarElements.floating?.element,\n toolbarElements.main?.element,\n toolbarElements.table?.element,\n]\nconst setToolbar = (slot: ToolbarSlot, element: unknown) => {\n const current = toolbarElements[slot]\n\n if (current?.element === element) return\n\n current?.detach()\n toolbarElements[slot] =\n element instanceof HTMLElement\n ? {\n element,\n detach: attachToolbarKeyboard(element, {\n onEscape: () => liveEditor.value?.commands.focus(),\n toolbars,\n }),\n }\n : null\n}\n\nonBeforeUnmount(() => {\n for (const slot of ['main', 'table', 'floating'] as const) setToolbar(slot, null)\n})\n\nconst editor = useEditor({\n extensions: [\n StarterKit.configure({ link: false }),\n Link.configure(linkExtensionOptions(props.component.linkProtocols)),\n imageExtension(Boolean(props.component.resizableImages) && !isMarkdown.value),\n Placeholder.configure({ placeholder: props.component.placeholder ?? '' }),\n ...toolbarExtensions(allToolbarButtons(props.component), isMarkdown.value),\n ...(isMarkdown.value ? [] : rich.extensions),\n ...(isMarkdown.value ? [] : (props.plugins.extensions as Extensions)),\n ],\n // Markdown is loaded from the server's HTML rendering of it, never parsed as HTML.\n content: stateToContent(value.value),\n editable: editable.value,\n editorProps: {\n // The mention / merge tag popup takes the arrow, Enter, Tab and Escape keys.\n handleKeyDown: (_view, event) => {\n // Alt+F10: into the floating toolbar, else the main one.\n if (isToolbarShortcut(event)) return focusToolbar(toolbars())\n\n return liveEditor.value ? rich.suggestions.handleKeyDown(event, liveEditor.value) : false\n },\n // ProseMirror reads its DOM attributes on every view update, so they follow `aria`.\n attributes: () => ({\n class: cn(\n 'alfakit-prose min-h-32 px-3 py-2 text-sm outline-none',\n props.component.resizableImages && RESIZE_HANDLE_CLASSES,\n ),\n // Runtime sizes cannot be Tailwind classes (they would never be generated).\n ...(props.component.minHeight ? { style: `min-height: ${props.component.minHeight}px` } : {}),\n id,\n // Each paragraph follows its own script, so Arabic and English mix correctly.\n dir: 'auto',\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(props.component.label ? { 'aria-labelledby': fieldIds(id).label } : {}),\n ...Object.fromEntries(\n Object.entries(aria.value).map(([name, attribute]) => [name, String(attribute)]),\n ),\n }),\n },\n onUpdate: ({ editor: instance }) => {\n setValue(editorToState(instance))\n },\n onTransaction: ({ editor: instance }) => {\n rich.suggestions.update(instance)\n selectionTick.value++\n },\n onBlur: () => {\n rich.suggestions.close()\n blur()\n },\n})\n\nwatch(\n editor,\n (instance) => {\n liveEditor.value = instance\n },\n { immediate: true },\n)\n\n// Keep editor in sync when the server refreshes the state.\nwatch(value, (next) => {\n const instance = editor.value\n\n if (!instance) return\n\n const current = editorToState(instance)\n const same = isJson.value\n ? JSON.stringify(toEditorDocument(next)) === JSON.stringify(current)\n : (next ?? '') === (current ?? '')\n\n if (!same) {\n instance.commands.setContent(stateToContent(next), { emitUpdate: false })\n }\n})\n\nwatch(editable, (isEditable) => {\n editor.value?.setEditable(isEditable)\n})\n\n// Re-apply the editable element's attributes when the error or description changes.\nwatch(aria, () => {\n if (editor.value && !editor.value.isDestroyed) {\n editor.value.view.setProps({})\n }\n})\n\n// A floating toolbar follows its selection while the page scrolls.\nwatch(\n () => Boolean(props.component.floatingToolbars),\n (hasFloatingToolbars, _previous, onCleanup) => {\n if (!hasFloatingToolbars || typeof window === 'undefined') return\n\n const onScroll = () => selectionTick.value++\n\n window.addEventListener('scroll', onScroll, { capture: true, passive: true })\n onCleanup(() => window.removeEventListener('scroll', onScroll, { capture: true }))\n },\n { immediate: true },\n)\n\nconst pickImage = () => fileInput.value?.click()\n\nconst uploadImage = async (file: File) => {\n if (!panel.value.endpoints.upload || !editor.value) return\n\n // The server checks again when the form is saved.\n const problem = fileAttachmentError(file, props.component.fileAttachments)\n\n if (problem) {\n attachmentError.value =\n problem === 'too_large'\n ? t('form.file_too_large', {}, 'This file is too large.')\n : t('form.file_invalid_type', {}, 'This file type is not allowed.')\n\n return\n }\n\n attachmentError.value = null\n\n let response: { key: string }\n\n try {\n // Large attachments go in resumable chunks.\n response = await uploadTemporaryFile(\n panel.value.endpoints.upload,\n file,\n panelUploadOptions(panel.value, props.component.fileAttachments.uploadPolicy),\n )\n } catch (error) {\n attachmentError.value =\n (error as { errors?: Record<string, string[]> }).errors?.file?.[0] ??\n t('form.upload_failed', {}, 'The file could not be uploaded.')\n\n return\n }\n\n const src = attachments.add(response.key, file)\n\n editor.value.chain().focus().setImage({ src, alt: file.name }).run()\n}\n\nconst onFilePicked = (event: Event) => {\n const file = (event.target as HTMLInputElement).files?.[0]\n\n if (file) void uploadImage(file)\n}\n\nconst accept = computed(() =>\n (props.component.fileAttachments.acceptedFileTypes ?? ['image/*']).join(','),\n)\n\nconst translate = (key: string, fallback: string) => t(key, {}, fallback)\n\nconst runCommand = (name: string) => {\n const button = commands.value[name]\n\n if (!button || !editor.value) return\n\n button.run(editor.value, {\n // Messages arrive translated (`form.link_prompt`, `editor.grid_columns`).\n prompt: (message) => window.prompt(message),\n pickImage,\n togglePanel: (target) => {\n openPanel.value = openPanel.value === target ? null : target\n },\n t: translate,\n })\n}\n\nconst toggleSidePanel = (target: RichEditorPanel) => {\n sidePanel.value = sidePanel.value === target ? null : target\n}\n\nconst insertMergeTag = (tagId: string) => {\n editor.value\n ?.chain()\n .focus()\n .insertContent({ type: 'mergeTag', attrs: { id: tagId } })\n .run()\n}\n\nconst currentTextColor = () => {\n void selectionTick.value\n\n return editor.value?.getAttributes('textColor').color\n}\n\n// A `table` floating toolbar replaces the table row of buttons.\nconst showTableToolbar = () => {\n void selectionTick.value\n\n return Boolean(\n editor.value &&\n editable.value &&\n !props.component.floatingToolbars?.table &&\n showsTableToolbar(allToolbarButtons(props.component), editor.value),\n )\n}\n\nconst floating = computed(() => {\n void selectionTick.value\n\n return editable.value\n ? resolveFloatingToolbar(editor.value ?? null, props.component.floatingToolbars)\n : null\n})\n\nconst applyColor = (color: string | null, close = true) => {\n if (!editor.value) return\n\n setTextColor(editor.value, color)\n\n if (close) openPanel.value = null\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div\n :class=\"\n cn(\n 'border-input dark:bg-input/30 focus-within:border-ring focus-within:ring-ring/50 rounded-md border shadow-xs focus-within:ring-[3px]',\n error && 'border-destructive',\n disabled && 'opacity-60',\n )\n \"\n >\n <!-- The sticky offset is a runtime value: no Tailwind class can hold it. -->\n <div\n v-if=\"props.component.toolbarButtons.length > 0 && editor\"\n :ref=\"(element) => setToolbar('main', element)\"\n role=\"toolbar\"\n :aria-label=\"t('editor.toolbar', {}, 'Formatting')\"\n aria-keyshortcuts=\"Alt+F10\"\n data-slot=\"rich-editor-toolbar\"\n :class=\"\n cn(\n 'flex flex-wrap items-center gap-0.5 border-b p-1',\n props.component.stickyToolbar && 'bg-background sticky z-10 rounded-t-md',\n )\n \"\n :style=\"props.component.stickyToolbar ? { top: stickyTop ?? '0px' } : undefined\"\n >\n <RichEditorToolbarEntries\n :names=\"props.component.toolbarButtons\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <div\n v-if=\"editor && openPanel === 'textColor'\"\n role=\"group\"\n :aria-label=\"toolbarButtonLabel('textColor', translate)\"\n class=\"flex flex-wrap items-center gap-1 border-b p-1\"\n data-slot=\"rich-editor-text-colors\"\n >\n <!-- Palette colours are runtime values: no Tailwind class can hold them. -->\n <button\n v-for=\"color in props.component.textColors ?? []\"\n :key=\"color.value\"\n type=\"button\"\n :title=\"color.label\"\n :aria-label=\"color.label\"\n :aria-pressed=\"currentTextColor() === color.value ? 'true' : 'false'\"\n class=\"focus-visible:ring-ring/50 size-6 rounded-full border shadow-xs outline-none focus-visible:ring-[3px] aria-pressed:ring-2\"\n :style=\"{ backgroundColor: color.value }\"\n @mousedown.prevent\n @click=\"applyColor(color.value)\"\n />\n <input\n v-if=\"props.component.customTextColors\"\n type=\"color\"\n :aria-label=\"t('editor.custom_color', {}, 'Custom color')\"\n :title=\"t('editor.custom_color', {}, 'Custom color')\"\n class=\"size-6 cursor-pointer rounded border bg-transparent p-0\"\n @input=\"applyColor(($event.target as HTMLInputElement).value, false)\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :aria-label=\"t('editor.remove_color', {}, 'Remove color')\"\n :title=\"t('editor.remove_color', {}, 'Remove color')\"\n @mousedown.prevent\n @click=\"applyColor(null)\"\n >\n <EraserIcon />\n </Button>\n </div>\n <div\n v-if=\"editor && showTableToolbar()\"\n :ref=\"(element) => setToolbar('table', element)\"\n role=\"toolbar\"\n :aria-label=\"toolbarButtonLabel('table', translate)\"\n class=\"flex flex-wrap items-center gap-0.5 border-b p-1\"\n data-slot=\"rich-editor-table-toolbar\"\n >\n <RichEditorToolbarEntries\n :names=\"TABLE_TOOLBAR_BUTTONS\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <div class=\"@container\">\n <div class=\"flex flex-col-reverse @2xl:flex-row\">\n <EditorContent\n :editor=\"editor\"\n class=\"min-w-0 flex-1\"\n :style=\"\n props.component.maxHeight\n ? { maxHeight: `${props.component.maxHeight}px`, overflowY: 'auto' }\n : undefined\n \"\n />\n <RichEditorSidePanel\n v-if=\"editor && sidePanel\"\n :panel=\"sidePanel\"\n :component=\"props.component\"\n :editable=\"editable\"\n :sticky=\"props.component.stickyPanels ? (stickyTop ?? '0px') : null\"\n @insert-block=\"(blockId: string) => void rich.insertBlock(blockId)\"\n @insert-merge-tag=\"insertMergeTag\"\n @close=\"sidePanel = null\"\n />\n </div>\n </div>\n <!-- Runtime coordinates cannot be Tailwind classes. -->\n <div\n v-if=\"editor && floating && floating.buttons.length > 0\"\n :ref=\"(element) => setToolbar('floating', element)\"\n role=\"toolbar\"\n :aria-label=\"t('editor.floating_toolbar', {}, 'Selection formatting')\"\n data-slot=\"rich-editor-floating-toolbar\"\n :data-node=\"floating.node\"\n class=\"bg-popover text-popover-foreground fixed z-50 flex items-center gap-0.5 rounded-md border p-1 shadow-md\"\n :style=\"floatingToolbarStyle(floating.coords)\"\n >\n <RichEditorToolbarEntries\n :names=\"floating.buttons\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <RichEditorSuggestions\n :id=\"`${id}-suggestions`\"\n :suggestions=\"rich.suggestions\"\n :editor=\"editor\"\n />\n <p v-if=\"attachmentError\" role=\"alert\" class=\"text-destructive px-3 pb-2 text-xs\">\n {{ attachmentError }}\n </p>\n <input\n ref=\"fileInput\"\n type=\"file\"\n :accept=\"accept\"\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n @change=\"onFilePicked\"\n />\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RichEditorInput.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createElementBlock","_normalizeStyle","_createVNode","RichEditorToolbarEntries","_createCommentVNode","_Fragment","_renderList","_withModifiers","Button","RichEditorSidePanel","RichEditorSuggestions","_toDisplayString","Button_default","FieldWrapper_default","RichEditorSidePanel_default","RichEditorSuggestions_default","RichEditorToolbarEntries_default","Image","Link","Placeholder","StarterKit","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","RESIZE_HANDLE_CLASSES","RichEditorInput_vue_vue_type_script_setup_true_lang_default","imageExtension","resizable","resizableImageAttributes","resizableImageOptions","toolbarExtensions","has","names","buttons","name","extensions","TableKit","markdown","Mark","highlightMarkConfig","subscriptMarkConfig","superscriptMarkConfig","textColorMarkConfig","Extension","textAlignExtensionConfig","detailsNodeConfigs","Node","config","smallMarkConfig","leadExtensionConfig","gridNodeConfigs","props","__props","t","useT","panel","usePanel","runner","useActionRunner","useField","fileInput","ref","isMarkdown","computed","editable","disabled","readOnly","attachments","EditorAttachments","isJson","liveEditor","shallowRef","rich","useRichEditorExtensions","openPanel","sidePanel","initial","attachmentError","selectionTick","stickyTop","sticky","updateStickyTop","resolveStickyOffset","onMounted","watch","commands","toolbarCommands","tool","args","stateToContent","document","toEditorDocument","state","editorToState","instance","html","htmlToMarkdown","toolbarElements","toolbars","setToolbar","current","slot","element","attachToolbarKeyboard","editor","useEditor","documentNonce","linkExtensionOptions","allToolbarButtons","value","isToolbarShortcut","event","focusToolbar","cn","fieldIds","id","aria","attribute","blur","next","isEditable","hasFloatingToolbars","onScroll","onCleanup","pickImage","uploadImage","problem","fileAttachmentError","file","response","uploadTemporaryFile","panelUploadOptions","error","src","onFilePicked","accept","translate","key","fallback","runCommand","button","message","target","toggleSidePanel","insertMergeTag","tagId","currentTextColor","showTableToolbar","showsTableToolbar","floating","resolveFloatingToolbar","applyColor","setTextColor","color","close","openBlock","createBlock","unref","withCtx","createElementVNode","normalizeClass","createElementBlock","normalizeStyle","createVNode","createCommentVNode","toolbarButtonLabel","Fragment","renderList","_cache","withModifiers","$event","EraserIcon","TABLE_TOOLBAR_BUTTONS","EditorContent","blockId","floatingToolbarStyle","toDisplayString"],"sources":["../../../src/components/fields/RichEditorInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { LoadedRichEditorExtensions, RichEditorPanel, RichEditorSchema } from '@alfakit/core'\nimport {\n allToolbarButtons,\n attachToolbarKeyboard,\n focusToolbar,\n isToolbarShortcut,\n detailsNodeConfigs,\n gridNodeConfigs,\n leadExtensionConfig,\n linkExtensionOptions,\n smallMarkConfig,\n EditorAttachments,\n fieldIds,\n fileAttachmentError,\n floatingToolbarStyle,\n highlightMarkConfig,\n htmlToMarkdown,\n resizableImageAttributes,\n resizableImageOptions,\n resolveFloatingToolbar,\n resolveStickyOffset,\n setTextColor,\n showsTableToolbar,\n subscriptMarkConfig,\n superscriptMarkConfig,\n TABLE_TOOLBAR_BUTTONS,\n textAlignExtensionConfig,\n textColorMarkConfig,\n toEditorDocument,\n toolbarButtonLabel,\n toolbarCommands,\n panelUploadOptions,\n uploadTemporaryFile,\n documentNonce,\n} from '@alfakit/core'\nimport { EraserIcon } from '@lucide/vue'\nimport Image from '@tiptap/extension-image'\nimport Link from '@tiptap/extension-link'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport { TableKit } from '@tiptap/extension-table'\nimport StarterKit from '@tiptap/starter-kit'\nimport {\n EditorContent,\n Extension,\n Mark,\n Node,\n useEditor,\n type Editor,\n type Extensions,\n} from '@tiptap/vue-3'\nimport { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'\nimport { useActionRunner, usePanel, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Button from '../ui/Button.vue'\nimport { useRichEditorExtensions } from './rich-editor-extensions'\nimport RichEditorSidePanel from './RichEditorSidePanel.vue'\nimport RichEditorSuggestions from './RichEditorSuggestions.vue'\nimport RichEditorToolbarEntries from './RichEditorToolbarEntries.vue'\n\ntype MarkConfig = Parameters<typeof Mark.create>[0]\ntype NodeConfig = Parameters<typeof Node.create>[0]\ntype ExtensionConfig = Parameters<typeof Extension.create>[0]\n\n/**\n * Resize handles of `resizableImages()` (Tiptap's node view adds bare `data-resize-handle`\n * elements): round dots on the corners, shown on hover and while the image is selected.\n */\nconst RESIZE_HANDLE_CLASSES =\n '[&_[data-resize-handle]]:z-10 [&_[data-resize-handle]]:size-3 [&_[data-resize-handle]]:rounded-full [&_[data-resize-handle]]:border-2 [&_[data-resize-handle]]:border-background [&_[data-resize-handle]]:bg-primary [&_[data-resize-handle]]:opacity-0 [&_[data-resize-container]:hover_[data-resize-handle]]:opacity-100 [&_.ProseMirror-selectednode_[data-resize-handle]]:opacity-100 [&_[data-resize-handle=bottom-right]]:cursor-nwse-resize [&_[data-resize-handle=top-left]]:cursor-nwse-resize [&_[data-resize-handle=bottom-left]]:cursor-nesw-resize [&_[data-resize-handle=top-right]]:cursor-nesw-resize'\n\n/** The image extension, with drag handles for `resizableImages()`. */\nfunction imageExtension(resizable: boolean) {\n if (!resizable) return Image\n\n return Image.extend({\n addAttributes() {\n return resizableImageAttributes(this.parent?.() ?? {})\n },\n }).configure(resizableImageOptions())\n}\n\n/** Extensions for the extra toolbar buttons (only those the toolbar uses are loaded). */\nfunction toolbarExtensions(buttons: string[], markdown: boolean): Extensions {\n const has = (...names: string[]) => names.some((name) => buttons.includes(name))\n const extensions: Extensions = []\n\n if (has('table')) extensions.push(TableKit.configure({ table: { resizable: false } }))\n // Markdown has no syntax for these.\n if (markdown) return extensions\n\n if (has('highlight')) extensions.push(Mark.create(highlightMarkConfig() as MarkConfig))\n if (has('subscript')) extensions.push(Mark.create(subscriptMarkConfig() as MarkConfig))\n if (has('superscript')) extensions.push(Mark.create(superscriptMarkConfig() as MarkConfig))\n if (has('textColor')) extensions.push(Mark.create(textColorMarkConfig() as MarkConfig))\n if (has('alignStart', 'alignCenter', 'alignEnd', 'alignJustify')) {\n extensions.push(Extension.create(textAlignExtensionConfig() as ExtensionConfig))\n }\n if (has('details')) {\n extensions.push(...detailsNodeConfigs().map((config) => Node.create(config as NodeConfig)))\n }\n if (has('small')) extensions.push(Mark.create(smallMarkConfig() as MarkConfig))\n if (has('lead')) extensions.push(Extension.create(leadExtensionConfig() as ExtensionConfig))\n if (has('grid', 'gridDelete', 'gridAddColumnBefore', 'gridAddColumnAfter', 'gridDeleteColumn')) {\n extensions.push(...gridNodeConfigs().map((config) => Node.create(config as NodeConfig)))\n }\n\n return extensions\n}\n\nconst props = defineProps<{ component: RichEditorSchema; plugins: LoadedRichEditorExtensions }>()\nconst t = useT()\nconst panel = usePanel()\nconst runner = useActionRunner()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<unknown>(\n () => props.component,\n)\nconst fileInput = ref<HTMLInputElement | null>(null)\nconst isMarkdown = computed(() => props.component.type === 'MarkdownEditor')\nconst editable = computed(() => !disabled.value && !readOnly.value)\n// Uploaded images preview from a local URL but are stored by their `tmp:` key.\nconst attachments = new EditorAttachments()\nconst isJson = computed(() => Boolean(props.component.json) && !isMarkdown.value)\n// The editor's live instance, for the custom block node views and suggestions.\nconst liveEditor = shallowRef<Editor | undefined>()\nconst rich = useRichEditorExtensions(() => props.component, liveEditor)\n// The open toolbar panel (the text colour palette).\nconst openPanel = ref<'textColor' | null>(null)\n// The open side panel (custom blocks or merge tags).\nconst initialSidePanel = (): RichEditorPanel | null => {\n const initial = props.component.activePanel ?? null\n\n if (initial === 'customBlocks') return props.component.customBlocks?.length ? initial : null\n if (initial === 'mergeTags') return props.component.mergeTags?.length ? initial : null\n\n return null\n}\nconst sidePanel = ref<RichEditorPanel | null>(initialSidePanel())\nconst attachmentError = ref<string | null>(null)\n// Bumped on every transaction so active states and the table row follow the cursor.\nconst selectionTick = ref(0)\nconst stickyTop = ref<string | null>(null)\nconst sticky = computed(() =>\n Boolean(props.component.stickyToolbar || props.component.stickyPanels),\n)\n\nconst updateStickyTop = () => {\n stickyTop.value = sticky.value ? resolveStickyOffset(props.component.stickyOffset) : null\n}\n\nonMounted(updateStickyTop)\nwatch([sticky, () => props.component.stickyOffset], updateStickyTop)\n\n// Built-in buttons, plugin tools and commands of plugin JavaScript extensions.\nconst commands = computed(() =>\n toolbarCommands(\n props.component.editorTools,\n {\n runAction: (tool, args) =>\n tool.action\n ? runner.runField(tool.action, { ...rich.context.value, arguments: args })\n : Promise.resolve(undefined),\n editor: () => liveEditor.value ?? null,\n },\n props.plugins.commands,\n ),\n)\n\n// Field state ↔ editor content: HTML, Markdown (loaded from the server's HTML) or a\n// Tiptap JSON document. `tmp:` upload keys become local preview URLs and back.\nconst stateToContent = (state: unknown): string | Record<string, unknown> => {\n if (isJson.value) {\n const document = toEditorDocument(state)\n\n return document ? JSON.parse(attachments.toEditor(JSON.stringify(document))) : ''\n }\n\n return attachments.toEditor(\n ((isMarkdown.value\n ? typeof props.component.html === 'string'\n ? props.component.html\n : null\n : state) as string | null) ?? '',\n )\n}\nconst editorToState = (instance: Pick<Editor, 'isEmpty' | 'getJSON' | 'getHTML'>): unknown => {\n if (instance.isEmpty) return null\n if (isJson.value) return JSON.parse(attachments.toState(JSON.stringify(instance.getJSON())))\n\n const html = instance.getHTML()\n\n return attachments.toState(isMarkdown.value ? htmlToMarkdown(html) : html)\n}\n\nonBeforeUnmount(() => attachments.destroy())\n\n// Keyboard access to the toolbars (roving tabindex, arrows, Escape, Alt+F10).\ntype ToolbarSlot = 'main' | 'table' | 'floating'\nconst toolbarElements: Record<ToolbarSlot, { element: HTMLElement; detach: () => void } | null> = {\n main: null,\n table: null,\n floating: null,\n}\nconst toolbars = () => [\n toolbarElements.floating?.element,\n toolbarElements.main?.element,\n toolbarElements.table?.element,\n]\nconst setToolbar = (slot: ToolbarSlot, element: unknown) => {\n const current = toolbarElements[slot]\n\n if (current?.element === element) return\n\n current?.detach()\n toolbarElements[slot] =\n element instanceof HTMLElement\n ? {\n element,\n detach: attachToolbarKeyboard(element, {\n onEscape: () => liveEditor.value?.commands.focus(),\n toolbars,\n }),\n }\n : null\n}\n\nonBeforeUnmount(() => {\n for (const slot of ['main', 'table', 'floating'] as const) setToolbar(slot, null)\n})\n\nconst editor = useEditor({\n // TipTap injects its base CSS; with the page's CSP nonce a nonce-based policy allows it.\n injectNonce: documentNonce(),\n extensions: [\n StarterKit.configure({ link: false }),\n Link.configure(linkExtensionOptions(props.component.linkProtocols)),\n imageExtension(Boolean(props.component.resizableImages) && !isMarkdown.value),\n Placeholder.configure({ placeholder: props.component.placeholder ?? '' }),\n ...toolbarExtensions(allToolbarButtons(props.component), isMarkdown.value),\n ...(isMarkdown.value ? [] : rich.extensions),\n ...(isMarkdown.value ? [] : (props.plugins.extensions as Extensions)),\n ],\n // Markdown is loaded from the server's HTML rendering of it, never parsed as HTML.\n content: stateToContent(value.value),\n editable: editable.value,\n editorProps: {\n // The mention / merge tag popup takes the arrow, Enter, Tab and Escape keys.\n handleKeyDown: (_view, event) => {\n // Alt+F10: into the floating toolbar, else the main one.\n if (isToolbarShortcut(event)) return focusToolbar(toolbars())\n\n return liveEditor.value ? rich.suggestions.handleKeyDown(event, liveEditor.value) : false\n },\n // ProseMirror reads its DOM attributes on every view update, so they follow `aria`.\n attributes: () => ({\n class: cn(\n 'alfakit-prose min-h-32 px-3 py-2 text-sm outline-none',\n props.component.resizableImages && RESIZE_HANDLE_CLASSES,\n ),\n // Runtime sizes cannot be Tailwind classes (they would never be generated).\n ...(props.component.minHeight ? { style: `min-height: ${props.component.minHeight}px` } : {}),\n id,\n // Each paragraph follows its own script, so Arabic and English mix correctly.\n dir: 'auto',\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(props.component.label ? { 'aria-labelledby': fieldIds(id).label } : {}),\n ...Object.fromEntries(\n Object.entries(aria.value).map(([name, attribute]) => [name, String(attribute)]),\n ),\n }),\n },\n onUpdate: ({ editor: instance }) => {\n setValue(editorToState(instance))\n },\n onTransaction: ({ editor: instance }) => {\n rich.suggestions.update(instance)\n selectionTick.value++\n },\n onBlur: () => {\n rich.suggestions.close()\n blur()\n },\n})\n\nwatch(\n editor,\n (instance) => {\n liveEditor.value = instance\n },\n { immediate: true },\n)\n\n// Keep editor in sync when the server refreshes the state.\nwatch(value, (next) => {\n const instance = editor.value\n\n if (!instance) return\n\n const current = editorToState(instance)\n const same = isJson.value\n ? JSON.stringify(toEditorDocument(next)) === JSON.stringify(current)\n : (next ?? '') === (current ?? '')\n\n if (!same) {\n instance.commands.setContent(stateToContent(next), { emitUpdate: false })\n }\n})\n\nwatch(editable, (isEditable) => {\n editor.value?.setEditable(isEditable)\n})\n\n// Re-apply the editable element's attributes when the error or description changes.\nwatch(aria, () => {\n if (editor.value && !editor.value.isDestroyed) {\n editor.value.view.setProps({})\n }\n})\n\n// A floating toolbar follows its selection while the page scrolls.\nwatch(\n () => Boolean(props.component.floatingToolbars),\n (hasFloatingToolbars, _previous, onCleanup) => {\n if (!hasFloatingToolbars || typeof window === 'undefined') return\n\n const onScroll = () => selectionTick.value++\n\n window.addEventListener('scroll', onScroll, { capture: true, passive: true })\n onCleanup(() => window.removeEventListener('scroll', onScroll, { capture: true }))\n },\n { immediate: true },\n)\n\nconst pickImage = () => fileInput.value?.click()\n\nconst uploadImage = async (file: File) => {\n if (!panel.value.endpoints.upload || !editor.value) return\n\n // The server checks again when the form is saved.\n const problem = fileAttachmentError(file, props.component.fileAttachments)\n\n if (problem) {\n attachmentError.value =\n problem === 'too_large'\n ? t('form.file_too_large', {}, 'This file is too large.')\n : t('form.file_invalid_type', {}, 'This file type is not allowed.')\n\n return\n }\n\n attachmentError.value = null\n\n let response: { key: string }\n\n try {\n // Large attachments go in resumable chunks.\n response = await uploadTemporaryFile(\n panel.value.endpoints.upload,\n file,\n panelUploadOptions(panel.value, props.component.fileAttachments.uploadPolicy),\n )\n } catch (error) {\n attachmentError.value =\n (error as { errors?: Record<string, string[]> }).errors?.file?.[0] ??\n t('form.upload_failed', {}, 'The file could not be uploaded.')\n\n return\n }\n\n const src = attachments.add(response.key, file)\n\n editor.value.chain().focus().setImage({ src, alt: file.name }).run()\n}\n\nconst onFilePicked = (event: Event) => {\n const file = (event.target as HTMLInputElement).files?.[0]\n\n if (file) void uploadImage(file)\n}\n\nconst accept = computed(() =>\n (props.component.fileAttachments.acceptedFileTypes ?? ['image/*']).join(','),\n)\n\nconst translate = (key: string, fallback: string) => t(key, {}, fallback)\n\nconst runCommand = (name: string) => {\n const button = commands.value[name]\n\n if (!button || !editor.value) return\n\n button.run(editor.value, {\n // Messages arrive translated (`form.link_prompt`, `editor.grid_columns`).\n prompt: (message) => window.prompt(message),\n pickImage,\n togglePanel: (target) => {\n openPanel.value = openPanel.value === target ? null : target\n },\n t: translate,\n })\n}\n\nconst toggleSidePanel = (target: RichEditorPanel) => {\n sidePanel.value = sidePanel.value === target ? null : target\n}\n\nconst insertMergeTag = (tagId: string) => {\n editor.value\n ?.chain()\n .focus()\n .insertContent({ type: 'mergeTag', attrs: { id: tagId } })\n .run()\n}\n\nconst currentTextColor = () => {\n void selectionTick.value\n\n return editor.value?.getAttributes('textColor').color\n}\n\n// A `table` floating toolbar replaces the table row of buttons.\nconst showTableToolbar = () => {\n void selectionTick.value\n\n return Boolean(\n editor.value &&\n editable.value &&\n !props.component.floatingToolbars?.table &&\n showsTableToolbar(allToolbarButtons(props.component), editor.value),\n )\n}\n\nconst floating = computed(() => {\n void selectionTick.value\n\n return editable.value\n ? resolveFloatingToolbar(editor.value ?? null, props.component.floatingToolbars)\n : null\n})\n\nconst applyColor = (color: string | null, close = true) => {\n if (!editor.value) return\n\n setTextColor(editor.value, color)\n\n if (close) openPanel.value = null\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div\n :class=\"\n cn(\n 'border-input dark:bg-input/30 focus-within:border-ring focus-within:ring-ring/50 rounded-md border shadow-xs focus-within:ring-[3px]',\n error && 'border-destructive',\n disabled && 'opacity-60',\n )\n \"\n >\n <!-- The sticky offset is a runtime value: no Tailwind class can hold it. -->\n <div\n v-if=\"props.component.toolbarButtons.length > 0 && editor\"\n :ref=\"(element) => setToolbar('main', element)\"\n role=\"toolbar\"\n :aria-label=\"t('editor.toolbar', {}, 'Formatting')\"\n aria-keyshortcuts=\"Alt+F10\"\n data-slot=\"rich-editor-toolbar\"\n :class=\"\n cn(\n 'flex flex-wrap items-center gap-0.5 border-b p-1',\n props.component.stickyToolbar && 'bg-background sticky z-10 rounded-t-md',\n )\n \"\n :style=\"props.component.stickyToolbar ? { top: stickyTop ?? '0px' } : undefined\"\n >\n <RichEditorToolbarEntries\n :names=\"props.component.toolbarButtons\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <div\n v-if=\"editor && openPanel === 'textColor'\"\n role=\"group\"\n :aria-label=\"toolbarButtonLabel('textColor', translate)\"\n class=\"flex flex-wrap items-center gap-1 border-b p-1\"\n data-slot=\"rich-editor-text-colors\"\n >\n <!-- Palette colours are runtime values: no Tailwind class can hold them. -->\n <button\n v-for=\"color in props.component.textColors ?? []\"\n :key=\"color.value\"\n type=\"button\"\n :title=\"color.label\"\n :aria-label=\"color.label\"\n :aria-pressed=\"currentTextColor() === color.value ? 'true' : 'false'\"\n class=\"focus-visible:ring-ring/50 size-6 rounded-full border shadow-xs outline-none focus-visible:ring-[3px] aria-pressed:ring-2\"\n :style=\"{ backgroundColor: color.value }\"\n @mousedown.prevent\n @click=\"applyColor(color.value)\"\n />\n <input\n v-if=\"props.component.customTextColors\"\n type=\"color\"\n :aria-label=\"t('editor.custom_color', {}, 'Custom color')\"\n :title=\"t('editor.custom_color', {}, 'Custom color')\"\n class=\"size-6 cursor-pointer rounded border bg-transparent p-0\"\n @input=\"applyColor(($event.target as HTMLInputElement).value, false)\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :aria-label=\"t('editor.remove_color', {}, 'Remove color')\"\n :title=\"t('editor.remove_color', {}, 'Remove color')\"\n @mousedown.prevent\n @click=\"applyColor(null)\"\n >\n <EraserIcon />\n </Button>\n </div>\n <div\n v-if=\"editor && showTableToolbar()\"\n :ref=\"(element) => setToolbar('table', element)\"\n role=\"toolbar\"\n :aria-label=\"toolbarButtonLabel('table', translate)\"\n class=\"flex flex-wrap items-center gap-0.5 border-b p-1\"\n data-slot=\"rich-editor-table-toolbar\"\n >\n <RichEditorToolbarEntries\n :names=\"TABLE_TOOLBAR_BUTTONS\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <div class=\"@container\">\n <div class=\"flex flex-col-reverse @2xl:flex-row\">\n <EditorContent\n :editor=\"editor\"\n class=\"min-w-0 flex-1\"\n :style=\"\n props.component.maxHeight\n ? { maxHeight: `${props.component.maxHeight}px`, overflowY: 'auto' }\n : undefined\n \"\n />\n <RichEditorSidePanel\n v-if=\"editor && sidePanel\"\n :panel=\"sidePanel\"\n :component=\"props.component\"\n :editable=\"editable\"\n :sticky=\"props.component.stickyPanels ? (stickyTop ?? '0px') : null\"\n @insert-block=\"(blockId: string) => void rich.insertBlock(blockId)\"\n @insert-merge-tag=\"insertMergeTag\"\n @close=\"sidePanel = null\"\n />\n </div>\n </div>\n <!-- Runtime coordinates cannot be Tailwind classes. -->\n <div\n v-if=\"editor && floating && floating.buttons.length > 0\"\n :ref=\"(element) => setToolbar('floating', element)\"\n role=\"toolbar\"\n :aria-label=\"t('editor.floating_toolbar', {}, 'Selection formatting')\"\n data-slot=\"rich-editor-floating-toolbar\"\n :data-node=\"floating.node\"\n class=\"bg-popover text-popover-foreground fixed z-50 flex items-center gap-0.5 rounded-md border p-1 shadow-md\"\n :style=\"floatingToolbarStyle(floating.coords)\"\n >\n <RichEditorToolbarEntries\n :names=\"floating.buttons\"\n :component=\"props.component\"\n :editor=\"editor\"\n :editable=\"editable\"\n :commands=\"commands\"\n :tick=\"selectionTick\"\n :open-panel=\"openPanel\"\n :side-panel=\"sidePanel\"\n @run=\"runCommand\"\n @toggle-panel=\"toggleSidePanel\"\n />\n </div>\n <RichEditorSuggestions\n :id=\"`${id}-suggestions`\"\n :suggestions=\"rich.suggestions\"\n :editor=\"editor\"\n />\n <p v-if=\"attachmentError\" role=\"alert\" class=\"text-destructive px-3 pb-2 text-xs\">\n {{ attachmentError }}\n </p>\n <input\n ref=\"fileInput\"\n type=\"file\"\n :accept=\"accept\"\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n @change=\"onFilePicked\"\n />\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SliderField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createVNode","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_toDisplayString","_createCommentVNode","FieldWrapper_default","SliderField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","panelDir","useDirection","dir","computed","sliderDirection","formatter","useFormatter","useField","values","sliderValues","value","pips","sliderPips","vertical","topToBottom","behavior","sliderBehavior","smooth","ref","primitive","sliderPrimitive","locked","disabled","readOnly","change","setValue","sliderState","sliderNextValues","next","onModelValue","sliderFromPrimitive","onCommit","sliderSnap","thumb","blur","onPointerDownCapture","target","event","track","sliderBlocksTap","fillSections","sliderFillSections","fill","format","number","thumbLabel","index","pipStyle","percent","openBlock","createBlock","unref","id","error","withCtx","createElementVNode","normalizeClass","cn","sliderHasTooltips","createVNode","SliderRoot","sliderToPrimitive","SliderTrack","createElementBlock","Fragment","renderList","section","normalizeStyle","sliderFillStyle","SliderRange","SliderThumb","fieldIds","aria","sliderShowsTooltip","toDisplayString","createCommentVNode","pip"],"sources":["../../../src/components/fields/SliderField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SliderSchema } from '@alfakit/core'\nimport {\n fieldIds,\n sliderBehavior,\n sliderBlocksTap,\n sliderDirection,\n sliderFillSections,\n sliderFillStyle,\n sliderFromPrimitive,\n sliderHasTooltips,\n sliderNextValues,\n sliderPips,\n sliderPrimitive,\n sliderShowsTooltip,\n sliderSnap,\n sliderState,\n sliderToPrimitive,\n sliderValues,\n startSliderRangeDrag,\n} from '@alfakit/core'\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'\nimport { computed, ref } from 'vue'\nimport { useDirection, useFormatter, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\n\n/**\n * A slider with one thumb, or several for a range. Built on Reka Slider, which handles\n * pointer and keyboard input and mirrors itself in right-to-left layouts (`dir`). Values,\n * tooltips and pips are formatted with the panel's locale.\n */\nconst props = defineProps<{ component: SliderSchema }>()\nconst t = useT()\nconst panelDir = useDirection()\n// `rtl()` overrides the panel's direction.\nconst dir = computed(() => sliderDirection(props.component, panelDir.value))\nconst formatter = useFormatter()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<unknown>(\n () => props.component,\n)\nconst values = computed(() => sliderValues(value.value, props.component))\nconst pips = computed(() => (props.component.pips ? sliderPips(props.component) : []))\nconst vertical = computed(() => Boolean(props.component.vertical))\n// `vertical(isTopToBottom: true)`: the minimum at the top.\nconst topToBottom = computed(() => vertical.value && Boolean(props.component.topToBottom))\nconst behavior = computed(() => sliderBehavior(props.component))\n// `Behavior::SmoothSteps`: no snapping while a pointer drags a thumb.\nconst smooth = ref(false)\nconst primitive = computed(() => sliderPrimitive(props.component, smooth.value))\nconst locked = computed(() => disabled.value || readOnly.value)\n\nconst change = (next: number[]) =>\n setValue(sliderState(sliderNextValues(values.value, next, props.component), props.component))\n\nconst onModelValue = (next: number[] | undefined) => {\n if (next) change(sliderFromPrimitive(next, props.component, !smooth.value))\n}\n\nconst onCommit = () => {\n if (smooth.value) {\n smooth.value = false\n change(values.value.map((thumb) => sliderSnap(thumb, props.component)))\n }\n\n blur()\n}\n\n// Before the primitive sees the press: start a range drag, or swallow taps on the track.\nconst onPointerDownCapture = (event: PointerEvent) => {\n if (locked.value) return\n\n const target = event.target as Element\n const track = (event.currentTarget as HTMLElement).querySelector<HTMLElement>(\n '[data-slot=\"slider-track\"]',\n )\n\n if (behavior.value.has('drag') && target.closest('[data-slot=\"slider-range\"]') && track) {\n startSliderRangeDrag(event, {\n track,\n values: values.value,\n schema: props.component,\n direction: dir.value,\n vertical: vertical.value,\n topToBottom: topToBottom.value,\n onChange: (next) => setValue(sliderState(next, props.component)),\n onEnd: () => blur(),\n })\n\n return\n }\n\n if (sliderBlocksTap(target, props.component)) {\n event.stopPropagation()\n\n return\n }\n\n if (behavior.value.has('smooth-steps') && target.closest('[role=\"slider\"]')) smooth.value = true\n}\n// `fillTrack([…])`: chosen sections are drawn here; the primitive's range stays clear.\nconst fillSections = computed(() => sliderFillSections(values.value, props.component))\nconst fill = computed(\n () =>\n fillSections.value === null && (props.component.fillTrack === true || values.value.length > 1),\n)\n\nconst format = (number: number) =>\n formatter.value.number(number, {\n maximumFractionDigits: props.component.decimalPlaces ?? 10,\n minimumFractionDigits: props.component.decimalPlaces ?? 0,\n })\n\nconst thumbLabel = (index: number) => {\n if (values.value.length === 1) return undefined\n if (values.value.length === 2) {\n return index === 0 ? t('slider.minimum', {}, 'Minimum') : t('slider.maximum', {}, 'Maximum')\n }\n\n return t('slider.thumb', { number: index + 1 }, 'Value :number')\n}\n\n// Reka puts the minimum at the bottom of a vertical slider and at the inline start of a\n// horizontal one (the right in RTL).\nconst pipStyle = (percent: number) =>\n vertical.value\n ? topToBottom.value\n ? { top: `${percent}%` }\n : { bottom: `${percent}%` }\n : dir.value === 'rtl'\n ? { right: `${percent}%` }\n : { left: `${percent}%` }\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"`${id}-thumb-0`\" :error=\"error\">\n <div\n data-slot=\"slider\"\n :class=\"\n cn(\n 'px-2',\n sliderHasTooltips(props.component) && !vertical && 'pt-7',\n pips.length > 0 && 'pb-6',\n )\n \"\n @pointerdown.capture=\"onPointerDownCapture\"\n >\n <SliderRoot\n :id=\"id\"\n :dir=\"dir\"\n :min=\"primitive.min\"\n :max=\"primitive.max\"\n :step=\"primitive.step\"\n :min-steps-between-thumbs=\"\n props.component.minDifference && !primitive.nonLinear\n ? Math.round(props.component.minDifference / props.component.step)\n : 0\n \"\n :orientation=\"vertical ? 'vertical' : 'horizontal'\"\n :inverted=\"topToBottom\"\n :disabled=\"locked\"\n :model-value=\"sliderToPrimitive(values, props.component)\"\n :class=\"\n cn(\n 'relative flex touch-none items-center select-none data-[disabled]:opacity-50',\n vertical ? 'h-48 w-5 flex-col' : 'w-full',\n readOnly && 'data-[disabled]:opacity-100',\n )\n \"\n @update:model-value=\"onModelValue\"\n @value-commit=\"onCommit\"\n >\n <SliderTrack\n data-slot=\"slider-track\"\n :class=\"\n cn(\n 'bg-muted relative grow overflow-hidden rounded-full',\n vertical ? 'h-full w-1.5' : 'h-1.5 w-full',\n )\n \"\n >\n <span\n v-for=\"section in fillSections ?? []\"\n :key=\"`${section.start}-${section.end}`\"\n data-slot=\"slider-fill\"\n aria-hidden=\"true\"\n :class=\"cn('bg-primary absolute', vertical ? 'w-full' : 'h-full')\"\n :style=\"sliderFillStyle(section, { vertical, topToBottom, direction: dir })\"\n />\n <SliderRange\n data-slot=\"slider-range\"\n :class=\"\n cn(\n 'absolute',\n fill ? 'bg-primary' : 'bg-transparent',\n vertical ? 'w-full' : 'h-full',\n behavior.has('drag') && values.length > 1 && !locked && 'cursor-grab',\n )\n \"\n />\n </SliderTrack>\n <SliderThumb\n v-for=\"(thumb, index) in values\"\n :id=\"`${id}-thumb-${index}`\"\n :key=\"index\"\n :aria-label=\"thumbLabel(index)\"\n :aria-labelledby=\"\n values.length === 1 && props.component.label ? fieldIds(id).label : undefined\n \"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-valuetext=\"format(thumb)\"\n class=\"border-primary bg-background ring-ring/50 relative block size-4 shrink-0 rounded-full border shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none\"\n >\n <span\n v-if=\"sliderShowsTooltip(props.component, index)\"\n aria-hidden=\"true\"\n :class=\"\n cn(\n 'bg-foreground text-background pointer-events-none absolute rounded px-1.5 py-0.5 text-xs whitespace-nowrap tabular-nums',\n vertical\n ? 'start-6 top-1/2 -translate-y-1/2'\n : 'bottom-6 left-1/2 -translate-x-1/2',\n )\n \"\n >{{ format(thumb) }}</span\n >\n </SliderThumb>\n <div\n v-if=\"pips.length > 0\"\n aria-hidden=\"true\"\n :class=\"\n cn('pointer-events-none absolute', vertical ? 'inset-y-0 start-6' : 'inset-x-0 top-4')\n \"\n >\n <span\n v-for=\"pip in pips\"\n :key=\"pip.value\"\n :style=\"pipStyle(pip.percent)\"\n :class=\"\n cn(\n 'absolute flex items-center gap-1',\n vertical\n ? cn('flex-row', topToBottom ? '-translate-y-1/2' : 'translate-y-1/2')\n : 'flex-col',\n !vertical && (dir === 'rtl' ? 'translate-x-1/2' : '-translate-x-1/2'),\n )\n \"\n >\n <span\n :class=\"\n cn(\n 'bg-border block',\n vertical ? 'h-px' : 'w-px',\n pip.labelled && !pip.small\n ? vertical\n ? 'w-2'\n : 'h-2'\n : vertical\n ? 'w-1'\n : 'h-1',\n )\n \"\n />\n <span\n v-if=\"pip.labelled\"\n :class=\"\n cn('text-muted-foreground tabular-nums', pip.small ? 'text-[0.625rem]' : 'text-xs')\n \"\n >{{ format(pip.value) }}</span\n >\n </span>\n </div>\n </SliderRoot>\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"SliderField.vue_vue_type_script_setup_true_lang.js","names":["useDirection","_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createVNode","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_toDisplayString","_createCommentVNode","useDirection$1","FieldWrapper_default","SliderField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","panelDir","dir","computed","sliderDirection","formatter","useFormatter","useField","values","sliderValues","value","pips","sliderPips","vertical","topToBottom","behavior","sliderBehavior","smooth","ref","primitive","sliderPrimitive","locked","disabled","readOnly","change","setValue","sliderState","sliderNextValues","next","onModelValue","sliderFromPrimitive","onCommit","sliderSnap","thumb","blur","onPointerDownCapture","target","event","track","sliderBlocksTap","fillSections","sliderFillSections","fill","format","number","thumbLabel","index","pipStyle","percent","openBlock","createBlock","unref","id","error","withCtx","createElementVNode","normalizeClass","cn","sliderHasTooltips","createVNode","SliderRoot","sliderToPrimitive","SliderTrack","createElementBlock","Fragment","renderList","section","normalizeStyle","sliderFillStyle","SliderRange","SliderThumb","fieldIds","aria","sliderShowsTooltip","toDisplayString","createCommentVNode","pip"],"sources":["../../../src/components/fields/SliderField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SliderSchema } from '@alfakit/core'\nimport {\n fieldIds,\n sliderBehavior,\n sliderBlocksTap,\n sliderDirection,\n sliderFillSections,\n sliderFillStyle,\n sliderFromPrimitive,\n sliderHasTooltips,\n sliderNextValues,\n sliderPips,\n sliderPrimitive,\n sliderShowsTooltip,\n sliderSnap,\n sliderState,\n sliderToPrimitive,\n sliderValues,\n startSliderRangeDrag,\n} from '@alfakit/core'\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui'\nimport { computed, ref } from 'vue'\nimport { useDirection, useFormatter, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\n\n/**\n * A slider with one thumb, or several for a range. Built on Reka Slider, which handles\n * pointer and keyboard input and mirrors itself in right-to-left layouts (`dir`). Values,\n * tooltips and pips are formatted with the panel's locale.\n */\nconst props = defineProps<{ component: SliderSchema }>()\nconst t = useT()\nconst panelDir = useDirection()\n// `rtl()` overrides the panel's direction.\nconst dir = computed(() => sliderDirection(props.component, panelDir.value))\nconst formatter = useFormatter()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<unknown>(\n () => props.component,\n)\nconst values = computed(() => sliderValues(value.value, props.component))\nconst pips = computed(() => (props.component.pips ? sliderPips(props.component) : []))\nconst vertical = computed(() => Boolean(props.component.vertical))\n// `vertical(isTopToBottom: true)`: the minimum at the top.\nconst topToBottom = computed(() => vertical.value && Boolean(props.component.topToBottom))\nconst behavior = computed(() => sliderBehavior(props.component))\n// `Behavior::SmoothSteps`: no snapping while a pointer drags a thumb.\nconst smooth = ref(false)\nconst primitive = computed(() => sliderPrimitive(props.component, smooth.value))\nconst locked = computed(() => disabled.value || readOnly.value)\n\nconst change = (next: number[]) =>\n setValue(sliderState(sliderNextValues(values.value, next, props.component), props.component))\n\nconst onModelValue = (next: number[] | undefined) => {\n if (next) change(sliderFromPrimitive(next, props.component, !smooth.value))\n}\n\nconst onCommit = () => {\n if (smooth.value) {\n smooth.value = false\n change(values.value.map((thumb) => sliderSnap(thumb, props.component)))\n }\n\n blur()\n}\n\n// Before the primitive sees the press: start a range drag, or swallow taps on the track.\nconst onPointerDownCapture = (event: PointerEvent) => {\n if (locked.value) return\n\n const target = event.target as Element\n const track = (event.currentTarget as HTMLElement).querySelector<HTMLElement>(\n '[data-slot=\"slider-track\"]',\n )\n\n if (behavior.value.has('drag') && target.closest('[data-slot=\"slider-range\"]') && track) {\n startSliderRangeDrag(event, {\n track,\n values: values.value,\n schema: props.component,\n direction: dir.value,\n vertical: vertical.value,\n topToBottom: topToBottom.value,\n onChange: (next) => setValue(sliderState(next, props.component)),\n onEnd: () => blur(),\n })\n\n return\n }\n\n if (sliderBlocksTap(target, props.component)) {\n event.stopPropagation()\n\n return\n }\n\n if (behavior.value.has('smooth-steps') && target.closest('[role=\"slider\"]')) smooth.value = true\n}\n// `fillTrack([…])`: chosen sections are drawn here; the primitive's range stays clear.\nconst fillSections = computed(() => sliderFillSections(values.value, props.component))\nconst fill = computed(\n () =>\n fillSections.value === null && (props.component.fillTrack === true || values.value.length > 1),\n)\n\nconst format = (number: number) =>\n formatter.value.number(number, {\n maximumFractionDigits: props.component.decimalPlaces ?? 10,\n minimumFractionDigits: props.component.decimalPlaces ?? 0,\n })\n\nconst thumbLabel = (index: number) => {\n if (values.value.length === 1) return undefined\n if (values.value.length === 2) {\n return index === 0 ? t('slider.minimum', {}, 'Minimum') : t('slider.maximum', {}, 'Maximum')\n }\n\n return t('slider.thumb', { number: index + 1 }, 'Value :number')\n}\n\n// Reka puts the minimum at the bottom of a vertical slider and at the inline start of a\n// horizontal one (the right in RTL).\nconst pipStyle = (percent: number) =>\n vertical.value\n ? topToBottom.value\n ? { top: `${percent}%` }\n : { bottom: `${percent}%` }\n : dir.value === 'rtl'\n ? { right: `${percent}%` }\n : { left: `${percent}%` }\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"`${id}-thumb-0`\" :error=\"error\">\n <div\n data-slot=\"slider\"\n :class=\"\n cn(\n 'px-2',\n sliderHasTooltips(props.component) && !vertical && 'pt-7',\n pips.length > 0 && 'pb-6',\n )\n \"\n @pointerdown.capture=\"onPointerDownCapture\"\n >\n <SliderRoot\n :id=\"id\"\n :dir=\"dir\"\n :min=\"primitive.min\"\n :max=\"primitive.max\"\n :step=\"primitive.step\"\n :min-steps-between-thumbs=\"\n props.component.minDifference && !primitive.nonLinear\n ? Math.round(props.component.minDifference / props.component.step)\n : 0\n \"\n :orientation=\"vertical ? 'vertical' : 'horizontal'\"\n :inverted=\"topToBottom\"\n :disabled=\"locked\"\n :model-value=\"sliderToPrimitive(values, props.component)\"\n :class=\"\n cn(\n 'relative flex touch-none items-center select-none data-[disabled]:opacity-50',\n vertical ? 'h-48 w-5 flex-col' : 'w-full',\n readOnly && 'data-[disabled]:opacity-100',\n )\n \"\n @update:model-value=\"onModelValue\"\n @value-commit=\"onCommit\"\n >\n <SliderTrack\n data-slot=\"slider-track\"\n :class=\"\n cn(\n 'bg-muted relative grow overflow-hidden rounded-full',\n vertical ? 'h-full w-1.5' : 'h-1.5 w-full',\n )\n \"\n >\n <span\n v-for=\"section in fillSections ?? []\"\n :key=\"`${section.start}-${section.end}`\"\n data-slot=\"slider-fill\"\n aria-hidden=\"true\"\n :class=\"cn('bg-primary absolute', vertical ? 'w-full' : 'h-full')\"\n :style=\"sliderFillStyle(section, { vertical, topToBottom, direction: dir })\"\n />\n <SliderRange\n data-slot=\"slider-range\"\n :class=\"\n cn(\n 'absolute',\n fill ? 'bg-primary' : 'bg-transparent',\n vertical ? 'w-full' : 'h-full',\n behavior.has('drag') && values.length > 1 && !locked && 'cursor-grab',\n )\n \"\n />\n </SliderTrack>\n <SliderThumb\n v-for=\"(thumb, index) in values\"\n :id=\"`${id}-thumb-${index}`\"\n :key=\"index\"\n :aria-label=\"thumbLabel(index)\"\n :aria-labelledby=\"\n values.length === 1 && props.component.label ? fieldIds(id).label : undefined\n \"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-valuetext=\"format(thumb)\"\n class=\"border-primary bg-background ring-ring/50 relative block size-4 shrink-0 rounded-full border shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none\"\n >\n <span\n v-if=\"sliderShowsTooltip(props.component, index)\"\n aria-hidden=\"true\"\n :class=\"\n cn(\n 'bg-foreground text-background pointer-events-none absolute rounded px-1.5 py-0.5 text-xs whitespace-nowrap tabular-nums',\n vertical\n ? 'start-6 top-1/2 -translate-y-1/2'\n : 'bottom-6 left-1/2 -translate-x-1/2',\n )\n \"\n >{{ format(thumb) }}</span\n >\n </SliderThumb>\n <div\n v-if=\"pips.length > 0\"\n aria-hidden=\"true\"\n :class=\"\n cn('pointer-events-none absolute', vertical ? 'inset-y-0 start-6' : 'inset-x-0 top-4')\n \"\n >\n <span\n v-for=\"pip in pips\"\n :key=\"pip.value\"\n :style=\"pipStyle(pip.percent)\"\n :class=\"\n cn(\n 'absolute flex items-center gap-1',\n vertical\n ? cn('flex-row', topToBottom ? '-translate-y-1/2' : 'translate-y-1/2')\n : 'flex-col',\n !vertical && (dir === 'rtl' ? 'translate-x-1/2' : '-translate-x-1/2'),\n )\n \"\n >\n <span\n :class=\"\n cn(\n 'bg-border block',\n vertical ? 'h-px' : 'w-px',\n pip.labelled && !pip.small\n ? vertical\n ? 'w-2'\n : 'h-2'\n : vertical\n ? 'w-1'\n : 'h-1',\n )\n \"\n />\n <span\n v-if=\"pip.labelled\"\n :class=\"\n cn('text-muted-foreground tabular-nums', pip.small ? 'text-[0.625rem]' : 'text-xs')\n \"\n >{{ format(pip.value) }}</span\n >\n </span>\n </div>\n </SliderRoot>\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { ActionContext, ItemActionFallback, ItemActionName, ItemActionSchema } from '@alfakit/core';
2
2
  import { type MaybeRefOrGetter } from 'vue';
3
- /** Default looks of the built-in item actions, for payloads without `itemActions`. */
4
- export declare function useItemActionFallbacks(): Record<ItemActionName, ItemActionFallback>;
3
+ /** Default looks of the built-in item actions, for payloads without `itemActions` (icons follow their `alfakit::` aliases). */
4
+ export declare function useItemActionFallbacks(kind?: 'repeater' | 'builder'): Record<ItemActionName, ItemActionFallback>;
5
5
  /** Run a built-in action: on the server when customised, else `onClient`. */
6
6
  export declare function useRunItemAction(context: MaybeRefOrGetter<ActionContext>): (action: ItemActionSchema | null, args: Record<string, unknown>, onClient: () => void) => void;
7
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"item-actions.d.ts","sourceRoot":"","sources":["../../../src/components/fields/item-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EACjB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAiC,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAG1E,sFAAsF;AACtF,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAuBnF;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,aAAa,CAAC,IAIrE,QAAQ,gBAAgB,GAAG,IAAI,EAC/B,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,MAAM,IAAI,KACnB,IAAI,CAKR;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EACtD,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;2BAcD,MAAM,MAAM,MAAM;;;EAsBjD"}
1
+ {"version":3,"file":"item-actions.d.ts","sourceRoot":"","sources":["../../../src/components/fields/item-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EACjB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAiC,KAAK,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAG1E,+HAA+H;AAC/H,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,UAAU,GAAG,SAAsB,GACxC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CA0C5C;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,aAAa,CAAC,IAIrE,QAAQ,gBAAgB,GAAG,IAAI,EAC/B,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,MAAM,IAAI,KACnB,IAAI,CAKR;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EACtD,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;2BAcD,MAAM,MAAM,MAAM;;;EAsBjD"}
@@ -1,9 +1,9 @@
1
1
  import { useActionRunner as e, useT as t } from "../../context.js";
2
- import { ItemMoveTracker as n, itemActionContext as r } from "@alfakit/core";
3
- import { nextTick as i, ref as a, toValue as o, watch as s } from "vue";
2
+ import { ItemMoveTracker as n, itemActionContext as r, itemActionIcon as i } from "@alfakit/core";
3
+ import { nextTick as a, ref as o, toValue as s, watch as c } from "vue";
4
4
  //#region src/components/fields/item-actions.ts
5
- function c() {
6
- let e = t();
5
+ function l(e = "repeater") {
6
+ let n = t();
7
7
  return {
8
8
  add: {
9
9
  label: "",
@@ -11,63 +11,63 @@ function c() {
11
11
  variant: "outline"
12
12
  },
13
13
  delete: {
14
- label: e("form.remove_item", {}, "Remove"),
15
- icon: "trash-2",
14
+ label: n("form.remove_item", {}, "Remove"),
15
+ icon: i(e, "delete", "trash-2"),
16
16
  color: "danger"
17
17
  },
18
18
  clone: {
19
- label: e("form.clone", {}, "Clone"),
20
- icon: "copy"
19
+ label: n("form.clone", {}, "Clone"),
20
+ icon: i(e, "clone", "copy")
21
21
  },
22
22
  reorder: {
23
- label: e("form.reorder_item", {}, "Reorder"),
24
- icon: "grip-vertical"
23
+ label: n("form.reorder_item", {}, "Reorder"),
24
+ icon: i(e, "reorder", "grip-vertical")
25
25
  },
26
26
  moveUp: {
27
- label: e("form.move_up", {}, "Move up"),
28
- icon: "chevron-up"
27
+ label: n("form.move_up", {}, "Move up"),
28
+ icon: i(e, "move-up", "chevron-up")
29
29
  },
30
30
  moveDown: {
31
- label: e("form.move_down", {}, "Move down"),
32
- icon: "chevron-down"
31
+ label: n("form.move_down", {}, "Move down"),
32
+ icon: i(e, "move-down", "chevron-down")
33
33
  },
34
34
  collapse: {
35
- label: e("form.collapse_item", {}, "Collapse"),
36
- icon: "chevron-up"
35
+ label: n("form.collapse_item", {}, "Collapse"),
36
+ icon: i(e, "collapse", "chevron-up")
37
37
  },
38
38
  expand: {
39
- label: e("form.expand_item", {}, "Expand"),
40
- icon: "chevron-down"
39
+ label: n("form.expand_item", {}, "Expand"),
40
+ icon: i(e, "expand", "chevron-down")
41
41
  },
42
42
  collapseAll: {
43
- label: e("form.collapse_all", {}, "Collapse all"),
43
+ label: n("form.collapse_all", {}, "Collapse all"),
44
44
  icon: "chevrons-down-up",
45
45
  variant: "link"
46
46
  },
47
47
  expandAll: {
48
- label: e("form.expand_all", {}, "Expand all"),
48
+ label: n("form.expand_all", {}, "Expand all"),
49
49
  icon: "chevrons-up-down",
50
50
  variant: "link"
51
51
  }
52
52
  };
53
53
  }
54
- function l(t) {
54
+ function u(t) {
55
55
  let n = e();
56
56
  return (e, i, a) => {
57
- e && (e.server ? n.trigger(e, r(o(t), i)) : a());
57
+ e && (e.server ? n.trigger(e, r(s(t), i)) : a());
58
58
  };
59
59
  }
60
- function u(e, r, c, l) {
61
- let u = t(), d = new n(), f = a(""), p = a(null);
62
- return s(() => o(e), () => {
63
- d.isMoving && i(() => d.finish(p.value));
60
+ function d(e, r, i, l) {
61
+ let u = t(), d = new n(), f = o(""), p = o(null);
62
+ return c(() => s(e), () => {
63
+ d.isMoving && a(() => d.finish(p.value));
64
64
  }), {
65
65
  moveWithButton: (e, t) => {
66
- let n = o(l);
66
+ let n = s(l);
67
67
  if (t < 0 || t >= n || !d.begin(e, t)) return;
68
- let i = c(e);
69
- r(e, t), f.value = i ? u("form.labelled_item_moved", {
70
- item: i,
68
+ let a = i(e);
69
+ r(e, t), f.value = a ? u("form.labelled_item_moved", {
70
+ item: a,
71
71
  position: t + 1,
72
72
  total: n
73
73
  }, ":item moved to position :position of :total") : u("form.item_moved", {
@@ -80,6 +80,6 @@ function u(e, r, c, l) {
80
80
  };
81
81
  }
82
82
  //#endregion
83
- export { c as useItemActionFallbacks, u as useItemMoves, l as useRunItemAction };
83
+ export { l as useItemActionFallbacks, d as useItemMoves, u as useRunItemAction };
84
84
 
85
85
  //# sourceMappingURL=item-actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"item-actions.js","names":["useItemActionFallbacks","t","useT","useRunItemAction","runner","useActionRunner","action","itemActionContext","toValue","context","args","onClient","useItemMoves","tracker","ItemMoveTracker","announcement","ref","container","watch","value","nextTick","total","count","to","from","label","labelFor","move"],"sources":["../../../src/components/fields/item-actions.ts"],"sourcesContent":["import type {\n ActionContext,\n ItemActionFallback,\n ItemActionName,\n ItemActionSchema,\n} from '@alfakit/core'\nimport { ItemMoveTracker, itemActionContext } from '@alfakit/core'\nimport { nextTick, ref, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport { useActionRunner, useT } from '../../context'\n\n/** Default looks of the built-in item actions, for payloads without `itemActions`. */\nexport function useItemActionFallbacks(): Record<ItemActionName, ItemActionFallback> {\n const t = useT()\n\n return {\n add: { label: '', icon: 'plus', variant: 'outline' },\n delete: { label: t('form.remove_item', {}, 'Remove'), icon: 'trash-2', color: 'danger' },\n clone: { label: t('form.clone', {}, 'Clone'), icon: 'copy' },\n reorder: { label: t('form.reorder_item', {}, 'Reorder'), icon: 'grip-vertical' },\n moveUp: { label: t('form.move_up', {}, 'Move up'), icon: 'chevron-up' },\n moveDown: { label: t('form.move_down', {}, 'Move down'), icon: 'chevron-down' },\n collapse: { label: t('form.collapse_item', {}, 'Collapse'), icon: 'chevron-up' },\n expand: { label: t('form.expand_item', {}, 'Expand'), icon: 'chevron-down' },\n collapseAll: {\n label: t('form.collapse_all', {}, 'Collapse all'),\n icon: 'chevrons-down-up',\n variant: 'link',\n },\n expandAll: {\n label: t('form.expand_all', {}, 'Expand all'),\n icon: 'chevrons-up-down',\n variant: 'link',\n },\n }\n}\n\n/** Run a built-in action: on the server when customised, else `onClient`. */\nexport function useRunItemAction(context: MaybeRefOrGetter<ActionContext>) {\n const runner = useActionRunner()\n\n return (\n action: ItemActionSchema | null,\n args: Record<string, unknown>,\n onClient: () => void,\n ): void => {\n if (!action) return\n if (action.server) void runner.trigger(action, itemActionContext(toValue(context), args))\n else onClient()\n }\n}\n\n/**\n * Moves made with the item move buttons: one at a time, announced in a live region\n * (`announcement`) and with focus kept on the moved item's move button. Put `container` on\n * an element holding the items (they carry `data-index`).\n */\nexport function useItemMoves(\n value: MaybeRefOrGetter<unknown>,\n move: (from: number, to: number) => void,\n labelFor: (index: number) => string | null | undefined,\n count: MaybeRefOrGetter<number>,\n) {\n const t = useT()\n const tracker = new ItemMoveTracker()\n const announcement = ref('')\n const container = ref<HTMLElement | null>(null)\n\n watch(\n () => toValue(value),\n () => {\n if (tracker.isMoving) void nextTick(() => tracker.finish(container.value))\n },\n )\n\n const moveWithButton = (from: number, to: number) => {\n const total = toValue(count)\n\n if (to < 0 || to >= total || !tracker.begin(from, to)) return\n\n const label = labelFor(from)\n\n move(from, to)\n announcement.value = label\n ? t(\n 'form.labelled_item_moved',\n { item: label, position: to + 1, total },\n ':item moved to position :position of :total',\n )\n : t(\n 'form.item_moved',\n { position: to + 1, total },\n 'Item moved to position :position of :total',\n )\n }\n\n return { moveWithButton, announcement, container }\n}\n"],"mappings":";;;;AAWA,SAAgBA,IAAqE;CACnF,IAAMC,IAAIC,EAAK;CAEf,OAAO;EACL,KAAK;GAAE,OAAO;GAAI,MAAM;GAAQ,SAAS;EAAU;EACnD,QAAQ;GAAE,OAAOD,EAAE,oBAAoB,CAAC,GAAG,QAAQ;GAAG,MAAM;GAAW,OAAO;EAAS;EACvF,OAAO;GAAE,OAAOA,EAAE,cAAc,CAAC,GAAG,OAAO;GAAG,MAAM;EAAO;EAC3D,SAAS;GAAE,OAAOA,EAAE,qBAAqB,CAAC,GAAG,SAAS;GAAG,MAAM;EAAgB;EAC/E,QAAQ;GAAE,OAAOA,EAAE,gBAAgB,CAAC,GAAG,SAAS;GAAG,MAAM;EAAa;EACtE,UAAU;GAAE,OAAOA,EAAE,kBAAkB,CAAC,GAAG,WAAW;GAAG,MAAM;EAAe;EAC9E,UAAU;GAAE,OAAOA,EAAE,sBAAsB,CAAC,GAAG,UAAU;GAAG,MAAM;EAAa;EAC/E,QAAQ;GAAE,OAAOA,EAAE,oBAAoB,CAAC,GAAG,QAAQ;GAAG,MAAM;EAAe;EAC3E,aAAa;GACX,OAAOA,EAAE,qBAAqB,CAAC,GAAG,cAAc;GAChD,MAAM;GACN,SAAS;EACX;EACA,WAAW;GACT,OAAOA,EAAE,mBAAmB,CAAC,GAAG,YAAY;GAC5C,MAAM;GACN,SAAS;EACX;CACF;AACF;AAGA,SAAgBE,EAAiB,GAA0C;CACzE,IAAMC,IAASC,EAAgB;CAE/B,QACE,GACA,GACA,MACS;EACT,AAAKC,MACDA,EAAO,SAAQF,EAAY,QAAQE,GAAQC,EAAkBC,EAAQC,CAAO,GAAGC,CAAI,CAAC,IACnFC,EAAS;CAChB;AACF;AAOA,SAAgBC,EACd,GACA,GACA,GACA,GACA;CACA,IAAMX,IAAIC,EAAK,GACTW,IAAU,IAAIC,EAAgB,GAC9BC,IAAeC,EAAI,EAAE,GACrBC,IAAYD,EAAwB,IAAI;CA8B9C,OA5BAE,QACQV,EAAQW,CAAK,SACb;EACJ,AAAIN,EAAQ,YAAUO,QAAoBP,EAAQ,OAAOI,EAAU,KAAK,CAAC;CAC3E,CACF,GAuBO;EAAE,iBArBe,GAAc,MAAe;GACnD,IAAMI,IAAQb,EAAQc,CAAK;GAE3B,IAAIC,IAAK,KAAKA,KAAMF,KAAS,CAACR,EAAQ,MAAMW,GAAMD,CAAE,GAAG;GAEvD,IAAME,IAAQC,EAASF,CAAI;GAG3B,AADAG,EAAKH,GAAMD,CAAE,GACb,EAAa,QAAQE,IACjBxB,EACE,4BACA;IAAE,MAAMwB;IAAO,UAAUF,IAAK;IAAG;GAAM,GACvC,6CACF,IACAtB,EACE,mBACA;IAAE,UAAUsB,IAAK;IAAG;GAAM,GAC1B,4CACF;EACN;EAEyB;EAAc;CAAU;AACnD"}
1
+ {"version":3,"file":"item-actions.js","names":["useItemActionFallbacks","t","useT","itemActionIcon","kind","useRunItemAction","runner","useActionRunner","action","itemActionContext","toValue","context","args","onClient","useItemMoves","tracker","ItemMoveTracker","announcement","ref","container","watch","value","nextTick","total","count","to","from","label","labelFor","move"],"sources":["../../../src/components/fields/item-actions.ts"],"sourcesContent":["import type {\n ActionContext,\n ItemActionFallback,\n ItemActionName,\n ItemActionSchema,\n} from '@alfakit/core'\nimport { ItemMoveTracker, itemActionContext, itemActionIcon } from '@alfakit/core'\nimport { nextTick, ref, toValue, watch, type MaybeRefOrGetter } from 'vue'\nimport { useActionRunner, useT } from '../../context'\n\n/** Default looks of the built-in item actions, for payloads without `itemActions` (icons follow their `alfakit::` aliases). */\nexport function useItemActionFallbacks(\n kind: 'repeater' | 'builder' = 'repeater',\n): Record<ItemActionName, ItemActionFallback> {\n const t = useT()\n\n return {\n add: { label: '', icon: 'plus', variant: 'outline' },\n delete: {\n label: t('form.remove_item', {}, 'Remove'),\n icon: itemActionIcon(kind, 'delete', 'trash-2'),\n color: 'danger',\n },\n clone: { label: t('form.clone', {}, 'Clone'), icon: itemActionIcon(kind, 'clone', 'copy') },\n reorder: {\n label: t('form.reorder_item', {}, 'Reorder'),\n icon: itemActionIcon(kind, 'reorder', 'grip-vertical'),\n },\n moveUp: {\n label: t('form.move_up', {}, 'Move up'),\n icon: itemActionIcon(kind, 'move-up', 'chevron-up'),\n },\n moveDown: {\n label: t('form.move_down', {}, 'Move down'),\n icon: itemActionIcon(kind, 'move-down', 'chevron-down'),\n },\n collapse: {\n label: t('form.collapse_item', {}, 'Collapse'),\n icon: itemActionIcon(kind, 'collapse', 'chevron-up'),\n },\n expand: {\n label: t('form.expand_item', {}, 'Expand'),\n icon: itemActionIcon(kind, 'expand', 'chevron-down'),\n },\n collapseAll: {\n label: t('form.collapse_all', {}, 'Collapse all'),\n icon: 'chevrons-down-up',\n variant: 'link',\n },\n expandAll: {\n label: t('form.expand_all', {}, 'Expand all'),\n icon: 'chevrons-up-down',\n variant: 'link',\n },\n }\n}\n\n/** Run a built-in action: on the server when customised, else `onClient`. */\nexport function useRunItemAction(context: MaybeRefOrGetter<ActionContext>) {\n const runner = useActionRunner()\n\n return (\n action: ItemActionSchema | null,\n args: Record<string, unknown>,\n onClient: () => void,\n ): void => {\n if (!action) return\n if (action.server) void runner.trigger(action, itemActionContext(toValue(context), args))\n else onClient()\n }\n}\n\n/**\n * Moves made with the item move buttons: one at a time, announced in a live region\n * (`announcement`) and with focus kept on the moved item's move button. Put `container` on\n * an element holding the items (they carry `data-index`).\n */\nexport function useItemMoves(\n value: MaybeRefOrGetter<unknown>,\n move: (from: number, to: number) => void,\n labelFor: (index: number) => string | null | undefined,\n count: MaybeRefOrGetter<number>,\n) {\n const t = useT()\n const tracker = new ItemMoveTracker()\n const announcement = ref('')\n const container = ref<HTMLElement | null>(null)\n\n watch(\n () => toValue(value),\n () => {\n if (tracker.isMoving) void nextTick(() => tracker.finish(container.value))\n },\n )\n\n const moveWithButton = (from: number, to: number) => {\n const total = toValue(count)\n\n if (to < 0 || to >= total || !tracker.begin(from, to)) return\n\n const label = labelFor(from)\n\n move(from, to)\n announcement.value = label\n ? t(\n 'form.labelled_item_moved',\n { item: label, position: to + 1, total },\n ':item moved to position :position of :total',\n )\n : t(\n 'form.item_moved',\n { position: to + 1, total },\n 'Item moved to position :position of :total',\n )\n }\n\n return { moveWithButton, announcement, container }\n}\n"],"mappings":";;;;AAWA,SAAgBA,EACd,IAA+B,YACa;CAC5C,IAAMC,IAAIC,EAAK;CAEf,OAAO;EACL,KAAK;GAAE,OAAO;GAAI,MAAM;GAAQ,SAAS;EAAU;EACnD,QAAQ;GACN,OAAOD,EAAE,oBAAoB,CAAC,GAAG,QAAQ;GACzC,MAAME,EAAeC,GAAM,UAAU,SAAS;GAC9C,OAAO;EACT;EACA,OAAO;GAAE,OAAOH,EAAE,cAAc,CAAC,GAAG,OAAO;GAAG,MAAME,EAAeC,GAAM,SAAS,MAAM;EAAE;EAC1F,SAAS;GACP,OAAOH,EAAE,qBAAqB,CAAC,GAAG,SAAS;GAC3C,MAAME,EAAeC,GAAM,WAAW,eAAe;EACvD;EACA,QAAQ;GACN,OAAOH,EAAE,gBAAgB,CAAC,GAAG,SAAS;GACtC,MAAME,EAAeC,GAAM,WAAW,YAAY;EACpD;EACA,UAAU;GACR,OAAOH,EAAE,kBAAkB,CAAC,GAAG,WAAW;GAC1C,MAAME,EAAeC,GAAM,aAAa,cAAc;EACxD;EACA,UAAU;GACR,OAAOH,EAAE,sBAAsB,CAAC,GAAG,UAAU;GAC7C,MAAME,EAAeC,GAAM,YAAY,YAAY;EACrD;EACA,QAAQ;GACN,OAAOH,EAAE,oBAAoB,CAAC,GAAG,QAAQ;GACzC,MAAME,EAAeC,GAAM,UAAU,cAAc;EACrD;EACA,aAAa;GACX,OAAOH,EAAE,qBAAqB,CAAC,GAAG,cAAc;GAChD,MAAM;GACN,SAAS;EACX;EACA,WAAW;GACT,OAAOA,EAAE,mBAAmB,CAAC,GAAG,YAAY;GAC5C,MAAM;GACN,SAAS;EACX;CACF;AACF;AAGA,SAAgBI,EAAiB,GAA0C;CACzE,IAAMC,IAASC,EAAgB;CAE/B,QACE,GACA,GACA,MACS;EACT,AAAKC,MACDA,EAAO,SAAQF,EAAY,QAAQE,GAAQC,EAAkBC,EAAQC,CAAO,GAAGC,CAAI,CAAC,IACnFC,EAAS;CAChB;AACF;AAOA,SAAgBC,EACd,GACA,GACA,GACA,GACA;CACA,IAAMb,IAAIC,EAAK,GACTa,IAAU,IAAIC,EAAgB,GAC9BC,IAAeC,EAAI,EAAE,GACrBC,IAAYD,EAAwB,IAAI;CA8B9C,OA5BAE,QACQV,EAAQW,CAAK,SACb;EACJ,AAAIN,EAAQ,YAAUO,QAAoBP,EAAQ,OAAOI,EAAU,KAAK,CAAC;CAC3E,CACF,GAuBO;EAAE,iBArBe,GAAc,MAAe;GACnD,IAAMI,IAAQb,EAAQc,CAAK;GAE3B,IAAIC,IAAK,KAAKA,KAAMF,KAAS,CAACR,EAAQ,MAAMW,GAAMD,CAAE,GAAG;GAEvD,IAAME,IAAQC,EAASF,CAAI;GAG3B,AADAG,EAAKH,GAAMD,CAAE,GACb,EAAa,QAAQE,IACjB1B,EACE,4BACA;IAAE,MAAM0B;IAAO,UAAUF,IAAK;IAAG;GAAM,GACvC,6CACF,IACAxB,EACE,mBACA;IAAE,UAAUwB,IAAK;IAAG;GAAM,GAC1B,4CACF;EACN;EAEyB;EAAc;CAAU;AACnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"FormBlock.js","names":["_sfc_main","FormBlock_vue_vue_type_script_setup_true_lang_default","FormBlock_default"],"sources":["../../../src/components/form/FormBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema, FormBlock as FormBlockSchema } from '@alfakit/core'\nimport {\n FormStore,\n applyFormRefresh,\n formActionsVisible,\n formIdentity,\n formRefreshFor,\n isImplicitSubmit,\n isLeavingVisit,\n pageFlash,\n pageFormName,\n registerConflictForm,\n registerFormSubmitter,\n registerPageForm,\n resolvePartialProps,\n shouldResyncForm,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, onBeforeUnmount, onMounted, onScopeDispose, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useAlfakitProps, usePageSchema, usePanel, useT } from '../../context'\nimport ActionList from '../actions/ActionList.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport { showToast } from '../notifications/flash-toasts'\nimport { provideForm } from './form-context'\n\n/**\n * A page form: its state lives in a FormStore, and its buttons are actions that post the\n * current values through the action endpoint.\n */\nconst props = defineProps<{ block: FormBlockSchema }>()\n\nconst panel = usePanel()\nconst page = usePageSchema()\nconst pageProps = useAlfakitProps()\nconst runner = useActionRunner()\nconst t = useT()\nconst token = computed(() => page.value?.token ?? '')\n\nconst store = new FormStore(props.block, {\n token: token.value,\n component: props.block.component,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n // Live dashboard filters are applied by the refresh; the widgets reload to follow.\n onRefreshed: () => {\n if (props.block.liveFilters) router.reload({ only: resolvePartialProps(['page']) })\n },\n})\n\nprovideForm(store)\n\n// Named forms of custom pages (`<PageForm name>`) publish their store for page method calls\n// (browser only: mounted hooks never run during a server render).\nlet unregisterPageForm: (() => void) | undefined\n\nonMounted(() => {\n const name = pageFormName(props.block.component)\n\n if (name) unregisterPageForm = registerPageForm(name, store)\n})\n\n// Edit pages: the conflict banner diffs and merges the main form (`detectConflicts()`).\nlet unregisterConflictForm: (() => void) | undefined\n\nonMounted(() => {\n if (props.block.component === 'form') unregisterConflictForm = registerConflictForm(store)\n})\n\nonBeforeUnmount(() => unregisterConflictForm?.())\n\n// Buttons elsewhere with `formId('form')` (a header \"Save\") submit through this form.\nlet unregisterSubmitter: (() => void) | undefined\n\nonMounted(() => {\n unregisterSubmitter = registerFormSubmitter(props.block.component, (action, ctx) =>\n trigger(action, ctx),\n )\n})\n\nonBeforeUnmount(() => {\n unregisterPageForm?.()\n unregisterSubmitter?.()\n})\n\n// The store survives reloads of the same form (table sorting/paging, polling,\n// relation-manager actions all deliver a new `block` object); only a different form\n// identity starts from server state again. The token is re-issued per response, so it\n// is swapped in place instead of being part of the identity.\nwatch(\n () => formIdentity(page.value, props.block),\n () => store.fill(props.block),\n)\n\nwatch(token, (value) => store.setToken(value))\n\n// After this form's own successful submit, refill from the server's new state. The new\n// block may arrive before or after Inertia's `success` event, so handle both orders.\nlet submittedBlock: FormBlockSchema | null = null\nlet refillPending = false\n// Another action succeeded and its new block has not arrived yet.\nlet resyncPending = false\n// The block when the latest non-GET visit started, to tell whether its response arrived.\nlet visitBlock: FormBlockSchema | null = null\n\nwatch(\n () => props.block,\n (block) => {\n if (refillPending) {\n refillPending = false\n store.fill(block)\n }\n\n if (resyncPending) {\n resyncPending = false\n\n if (!store.isDirty) store.fill(block)\n }\n },\n)\n\nwatch(\n () => pageProps.value.errors,\n (errors) => store.setErrors((errors as Record<string, string>) ?? {}),\n { immediate: true },\n)\n\nconst state = useStore(store.store)\nconst context = computed<ActionContext>(() => ({ token: token.value, component: 'page' }))\nlet submitting = false\n\nconst actions = computed<ActionSchema[]>(() =>\n props.block.actions.map((action) => ({ ...action, hasModal: false })),\n)\nconst primary = computed(() => actions.value[0])\n\n// Wizard forms (`HasWizard` pages) show their buttons on the last step only.\nconst progress = useStore(wizardProgressStore(store))\nconst showActions = computed(() => formActionsVisible(props.block, progress.value))\n\nconst trigger = async (action: ActionSchema, ctx: ActionContext) => {\n if (action.url && !action.hasAction) {\n return runner.trigger(action, ctx)\n }\n\n submitting = true\n submittedBlock = props.block\n store.setProcessing(true)\n runner.execute(action, ctx, store.state.values)\n}\n\n// Track this form's own submit visit so unrelated reloads finishing meanwhile (polling,\n// relation-manager paging) neither end its processing state nor count as its success.\nlet submitVisit: string | null = null\n\nconst offStart = router.on('start', (event) => {\n const visit = event.detail.visit\n\n if (submitting && !submitVisit && visit.method !== 'get') {\n submitVisit = visit.id\n }\n\n if (visit.method !== 'get') visitBlock = props.block\n})\n\nconst offSuccess = router.on('success', (event) => {\n const id = submitVisit\n\n // Another action changed the record: show the server's new form unless it holds edits.\n if (!id && shouldResyncForm(pageFlash(event.detail.page), store)) {\n if (props.block !== visitBlock) {\n store.fill(props.block)\n } else {\n resyncPending = true\n }\n\n return\n }\n\n if (!id || (event.detail.visitId ?? id) !== id) return\n\n // A halted action (rate limit, `halt()`) saved nothing: keep what the user typed.\n if (pageFlash(event.detail.page).alfakitAction?.status === 'halted') return\n\n if (props.block !== submittedBlock) {\n store.fill(props.block)\n } else {\n refillPending = true\n }\n})\n\n// `refreshFormData([...])`: an action changed the record; copy those fields in.\nconst offRefresh = router.on('success', (event) => {\n const refresh = formRefreshFor(pageFlash(event.detail.page), props.block.component)\n\n if (refresh) applyFormRefresh(store, refresh)\n})\n\nconst offFinish = router.on('finish', (event) => {\n if (submitVisit && event.detail.visit.id !== submitVisit) return\n\n store.setProcessing(false)\n submitting = false\n submitVisit = null\n})\n\nconst offBefore = router.on('before', (event) => {\n if (!panel.value.unsavedChangesAlerts) {\n return\n }\n\n if (\n store.isDirty &&\n !submitting &&\n isLeavingVisit(event.detail.visit) &&\n !window.confirm(t('unsaved_changes', {}, 'You have unsaved changes. Leave anyway?'))\n ) {\n event.preventDefault()\n }\n})\n\nonScopeDispose(() => {\n offStart()\n offSuccess()\n offRefresh()\n offFinish()\n offBefore()\n store.destroy()\n})\n\nconst onSubmit = () => {\n if (primary.value && showActions.value) {\n void trigger(primary.value, context.value)\n }\n}\n\n// Enter in a text field runs the primary action (actions are type=\"button\").\nconst onKeydown = (event: KeyboardEvent) => {\n if (\n primary.value &&\n showActions.value &&\n isImplicitSubmit(event, event.currentTarget as HTMLFormElement)\n ) {\n event.preventDefault()\n void trigger(primary.value, context.value)\n }\n}\n</script>\n\n<template>\n <form\n data-slot=\"form-block\"\n class=\"flex flex-col gap-6\"\n @submit.prevent=\"onSubmit\"\n @keydown=\"onKeydown\"\n >\n <fieldset :disabled=\"state.processing || props.block.operation === 'view'\" class=\"contents\">\n <SchemaRenderer :components=\"state.components\" :columns=\"state.columns\" />\n </fieldset>\n <div v-if=\"actions.length > 0 && showActions\" data-slot=\"form-actions\" class=\"border-t pt-6\">\n <ActionList :actions=\"actions\" :context=\"context\" :on-trigger=\"trigger\" />\n </div>\n </form>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"FormBlock.js","names":["_sfc_main","FormBlock_vue_vue_type_script_setup_true_lang_default","FormBlock_default"],"sources":["../../../src/components/form/FormBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema, FormBlock as FormBlockSchema } from '@alfakit/core'\nimport {\n FormStore,\n applyFormRefresh,\n formActionsVisible,\n formIdentity,\n formRefreshFor,\n isImplicitSubmit,\n isLeavingVisit,\n pageFlash,\n pageFormName,\n registerConflictForm,\n registerFormSubmitter,\n registerPageForm,\n resolvePartialProps,\n shouldResyncForm,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, onBeforeUnmount, onMounted, onScopeDispose, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useAlfakitProps, usePageSchema, usePanel, useT } from '../../context'\nimport ActionList from '../actions/ActionList.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport { showToast } from '../notifications/flash-toasts'\nimport { provideForm } from './form-context'\n\n/**\n * A page form: its state lives in a FormStore, and its buttons are actions that post the\n * current values through the action endpoint.\n */\nconst props = defineProps<{ block: FormBlockSchema }>()\n\nconst panel = usePanel()\nconst page = usePageSchema()\nconst pageProps = useAlfakitProps()\nconst runner = useActionRunner()\nconst t = useT()\nconst token = computed(() => page.value?.token ?? '')\n\nconst store = new FormStore(props.block, {\n token: token.value,\n component: props.block.component,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n // Live dashboard filters are applied by the refresh; the widgets reload to follow.\n onRefreshed: () => {\n if (props.block.liveFilters) router.reload({ only: resolvePartialProps(['page']) })\n },\n})\n\nprovideForm(store)\n\n// Named forms of custom pages (`<PageForm name>`) publish their store for page method calls\n// (browser only: mounted hooks never run during a server render).\nlet unregisterPageForm: (() => void) | undefined\n\nonMounted(() => {\n const name = pageFormName(props.block.component)\n\n if (name) unregisterPageForm = registerPageForm(name, store)\n})\n\n// Edit pages: the conflict banner diffs and merges the main form (`detectConflicts()`).\nlet unregisterConflictForm: (() => void) | undefined\n\nonMounted(() => {\n if (props.block.component === 'form') unregisterConflictForm = registerConflictForm(store)\n})\n\nonBeforeUnmount(() => unregisterConflictForm?.())\n\n// Buttons elsewhere with `formId('form')` (a header \"Save\") submit through this form.\nlet unregisterSubmitter: (() => void) | undefined\n\nonMounted(() => {\n unregisterSubmitter = registerFormSubmitter(props.block.component, (action, ctx) =>\n trigger(action, ctx),\n )\n})\n\nonBeforeUnmount(() => {\n unregisterPageForm?.()\n unregisterSubmitter?.()\n})\n\n// The store survives reloads of the same form (table sorting/paging, polling,\n// relation-manager actions all deliver a new `block` object); only a different form\n// identity starts from server state again. The token is re-issued per response, so it\n// is swapped in place instead of being part of the identity.\nwatch(\n () => formIdentity(page.value, props.block),\n () => store.fill(props.block),\n)\n\nwatch(token, (value) => store.setToken(value))\n\n// After this form's own successful submit, refill from the server's new state. The new\n// block may arrive before or after Inertia's `success` event, so handle both orders.\nlet submittedBlock: FormBlockSchema | null = null\nlet refillPending = false\n// Another action succeeded and its new block has not arrived yet.\nlet resyncPending = false\n// The block when the latest non-GET visit started, to tell whether its response arrived.\nlet visitBlock: FormBlockSchema | null = null\n\nwatch(\n () => props.block,\n (block) => {\n if (refillPending) {\n refillPending = false\n store.fill(block)\n }\n\n if (resyncPending) {\n resyncPending = false\n\n if (!store.isDirty) store.fill(block)\n }\n },\n)\n\nwatch(\n () => pageProps.value.errors,\n (errors) => store.setErrors((errors as Record<string, string>) ?? {}),\n { immediate: true },\n)\n\nconst state = useStore(store.store)\nconst context = computed<ActionContext>(() => ({ token: token.value, component: 'page' }))\nlet submitting = false\n\nconst actions = computed<ActionSchema[]>(() =>\n props.block.actions.map((action) => ({ ...action, hasModal: false })),\n)\nconst primary = computed(() => actions.value[0])\n\n// Wizard forms (`HasWizard` pages) show their buttons on the last step only.\nconst progress = useStore(wizardProgressStore(store))\nconst showActions = computed(() => formActionsVisible(props.block, progress.value))\n\nconst trigger = async (action: ActionSchema, ctx: ActionContext) => {\n if (action.url && !action.hasAction) {\n return runner.trigger(action, ctx)\n }\n\n submitting = true\n submittedBlock = props.block\n store.setProcessing(true)\n // A click that blurred a live field started a refresh: send the state it returns.\n store.whenSettled(() => runner.execute(action, ctx, store.state.values))\n}\n\n// Track this form's own submit visit so unrelated reloads finishing meanwhile (polling,\n// relation-manager paging) neither end its processing state nor count as its success.\nlet submitVisit: string | null = null\n\nconst offStart = router.on('start', (event) => {\n const visit = event.detail.visit\n\n if (submitting && !submitVisit && visit.method !== 'get') {\n submitVisit = visit.id\n }\n\n if (visit.method !== 'get') visitBlock = props.block\n})\n\nconst offSuccess = router.on('success', (event) => {\n const id = submitVisit\n\n // Another action changed the record: show the server's new form unless it holds edits.\n if (!id && shouldResyncForm(pageFlash(event.detail.page), store)) {\n if (props.block !== visitBlock) {\n store.fill(props.block)\n } else {\n resyncPending = true\n }\n\n return\n }\n\n if (!id || (event.detail.visitId ?? id) !== id) return\n\n // A halted action (rate limit, `halt()`) saved nothing: keep what the user typed.\n if (pageFlash(event.detail.page).alfakitAction?.status === 'halted') return\n\n if (props.block !== submittedBlock) {\n store.fill(props.block)\n } else {\n refillPending = true\n }\n})\n\n// `refreshFormData([...])`: an action changed the record; copy those fields in.\nconst offRefresh = router.on('success', (event) => {\n const refresh = formRefreshFor(pageFlash(event.detail.page), props.block.component)\n\n if (refresh) applyFormRefresh(store, refresh)\n})\n\nconst offFinish = router.on('finish', (event) => {\n if (submitVisit && event.detail.visit.id !== submitVisit) return\n\n store.setProcessing(false)\n submitting = false\n submitVisit = null\n})\n\nconst offBefore = router.on('before', (event) => {\n if (!panel.value.unsavedChangesAlerts) {\n return\n }\n\n if (\n store.isDirty &&\n !submitting &&\n isLeavingVisit(event.detail.visit) &&\n !window.confirm(t('unsaved_changes', {}, 'You have unsaved changes. Leave anyway?'))\n ) {\n event.preventDefault()\n }\n})\n\nonScopeDispose(() => {\n offStart()\n offSuccess()\n offRefresh()\n offFinish()\n offBefore()\n store.destroy()\n})\n\nconst onSubmit = () => {\n if (primary.value && showActions.value) {\n void trigger(primary.value, context.value)\n }\n}\n\n// Enter in a text field runs the primary action (actions are type=\"button\").\nconst onKeydown = (event: KeyboardEvent) => {\n if (\n primary.value &&\n showActions.value &&\n isImplicitSubmit(event, event.currentTarget as HTMLFormElement)\n ) {\n event.preventDefault()\n void trigger(primary.value, context.value)\n }\n}\n</script>\n\n<template>\n <form\n data-slot=\"form-block\"\n class=\"flex flex-col gap-6\"\n @submit.prevent=\"onSubmit\"\n @keydown=\"onKeydown\"\n >\n <fieldset :disabled=\"state.processing || props.block.operation === 'view'\" class=\"contents\">\n <SchemaRenderer :components=\"state.components\" :columns=\"state.columns\" />\n </fieldset>\n <div v-if=\"actions.length > 0 && showActions\" data-slot=\"form-actions\" class=\"border-t pt-6\">\n <ActionList :actions=\"actions\" :context=\"context\" :on-trigger=\"trigger\" />\n </div>\n </form>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"FormBlock.vue.d.ts","sourceRoot":"","sources":["../../../src/components/form/FormBlock.vue"],"names":[],"mappings":"AA+QA,OAAO,KAAK,EAA+B,SAAS,IAAI,eAAe,EAAE,MAAM,eAAe,CAAA;AA2B9F;;;GAGG;AACH,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;;AA8S9C,wBAMG"}
1
+ {"version":3,"file":"FormBlock.vue.d.ts","sourceRoot":"","sources":["../../../src/components/form/FormBlock.vue"],"names":[],"mappings":"AAgRA,OAAO,KAAK,EAA+B,SAAS,IAAI,eAAe,EAAE,MAAM,eAAe,CAAA;AA2B9F;;;GAGG;AACH,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;;AA+S9C,wBAMG"}
@@ -55,7 +55,7 @@ var O = ["disabled"], k = {
55
55
  hasModal: !1
56
56
  }))), Y = v(() => J.value[0]), de = i(g(L)), X = v(() => a(A.block, de.value)), Z = async (e, t) => {
57
57
  if (e.url && !e.hasAction) return P.trigger(e, t);
58
- q = !0, V = A.block, L.setProcessing(!0), P.execute(e, t, L.state.values);
58
+ q = !0, V = A.block, L.setProcessing(!0), L.whenSettled(() => P.execute(e, t, L.state.values));
59
59
  }, Q = null, fe = _.on("start", (e) => {
60
60
  let t = e.detail.visit;
61
61
  q && !Q && t.method !== "get" && (Q = t.id), t.method !== "get" && (W = A.block);
@@ -1 +1 @@
1
- {"version":3,"file":"FormBlock.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_withModifiers","_createElementVNode","_unref","_createVNode","SchemaRenderer","ActionList","_createCommentVNode","ActionList_default","SchemaRenderer_default","_hoisted_1","_hoisted_2","FormBlock_vue_vue_type_script_setup_true_lang_default","props","__props","panel","usePanel","page","usePageSchema","pageProps","useAlfakitProps","runner","useActionRunner","t","useT","token","computed","store","FormStore","notifications","showToast","n","router","resolvePartialProps","unregisterPageForm","name","pageFormName","registerPageForm","unregisterConflictForm","onMounted","registerConflictForm","onBeforeUnmount","unregisterSubmitter","registerFormSubmitter","trigger","action","ctx","watch","formIdentity","value","submittedBlock","refillPending","resyncPending","visitBlock","block","errors","state","useStore","context","submitting","actions","primary","progress","wizardProgressStore","showActions","formActionsVisible","submitVisit","offStart","visit","event","offSuccess","id","shouldResyncForm","pageFlash","offRefresh","refresh","formRefreshFor","applyFormRefresh","offFinish","offBefore","isLeavingVisit","onSubmit","onKeydown","isImplicitSubmit","openBlock","createElementBlock","withModifiers","createElementVNode","unref","createVNode","createCommentVNode"],"sources":["../../../src/components/form/FormBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema, FormBlock as FormBlockSchema } from '@alfakit/core'\nimport {\n FormStore,\n applyFormRefresh,\n formActionsVisible,\n formIdentity,\n formRefreshFor,\n isImplicitSubmit,\n isLeavingVisit,\n pageFlash,\n pageFormName,\n registerConflictForm,\n registerFormSubmitter,\n registerPageForm,\n resolvePartialProps,\n shouldResyncForm,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, onBeforeUnmount, onMounted, onScopeDispose, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useAlfakitProps, usePageSchema, usePanel, useT } from '../../context'\nimport ActionList from '../actions/ActionList.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport { showToast } from '../notifications/flash-toasts'\nimport { provideForm } from './form-context'\n\n/**\n * A page form: its state lives in a FormStore, and its buttons are actions that post the\n * current values through the action endpoint.\n */\nconst props = defineProps<{ block: FormBlockSchema }>()\n\nconst panel = usePanel()\nconst page = usePageSchema()\nconst pageProps = useAlfakitProps()\nconst runner = useActionRunner()\nconst t = useT()\nconst token = computed(() => page.value?.token ?? '')\n\nconst store = new FormStore(props.block, {\n token: token.value,\n component: props.block.component,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n // Live dashboard filters are applied by the refresh; the widgets reload to follow.\n onRefreshed: () => {\n if (props.block.liveFilters) router.reload({ only: resolvePartialProps(['page']) })\n },\n})\n\nprovideForm(store)\n\n// Named forms of custom pages (`<PageForm name>`) publish their store for page method calls\n// (browser only: mounted hooks never run during a server render).\nlet unregisterPageForm: (() => void) | undefined\n\nonMounted(() => {\n const name = pageFormName(props.block.component)\n\n if (name) unregisterPageForm = registerPageForm(name, store)\n})\n\n// Edit pages: the conflict banner diffs and merges the main form (`detectConflicts()`).\nlet unregisterConflictForm: (() => void) | undefined\n\nonMounted(() => {\n if (props.block.component === 'form') unregisterConflictForm = registerConflictForm(store)\n})\n\nonBeforeUnmount(() => unregisterConflictForm?.())\n\n// Buttons elsewhere with `formId('form')` (a header \"Save\") submit through this form.\nlet unregisterSubmitter: (() => void) | undefined\n\nonMounted(() => {\n unregisterSubmitter = registerFormSubmitter(props.block.component, (action, ctx) =>\n trigger(action, ctx),\n )\n})\n\nonBeforeUnmount(() => {\n unregisterPageForm?.()\n unregisterSubmitter?.()\n})\n\n// The store survives reloads of the same form (table sorting/paging, polling,\n// relation-manager actions all deliver a new `block` object); only a different form\n// identity starts from server state again. The token is re-issued per response, so it\n// is swapped in place instead of being part of the identity.\nwatch(\n () => formIdentity(page.value, props.block),\n () => store.fill(props.block),\n)\n\nwatch(token, (value) => store.setToken(value))\n\n// After this form's own successful submit, refill from the server's new state. The new\n// block may arrive before or after Inertia's `success` event, so handle both orders.\nlet submittedBlock: FormBlockSchema | null = null\nlet refillPending = false\n// Another action succeeded and its new block has not arrived yet.\nlet resyncPending = false\n// The block when the latest non-GET visit started, to tell whether its response arrived.\nlet visitBlock: FormBlockSchema | null = null\n\nwatch(\n () => props.block,\n (block) => {\n if (refillPending) {\n refillPending = false\n store.fill(block)\n }\n\n if (resyncPending) {\n resyncPending = false\n\n if (!store.isDirty) store.fill(block)\n }\n },\n)\n\nwatch(\n () => pageProps.value.errors,\n (errors) => store.setErrors((errors as Record<string, string>) ?? {}),\n { immediate: true },\n)\n\nconst state = useStore(store.store)\nconst context = computed<ActionContext>(() => ({ token: token.value, component: 'page' }))\nlet submitting = false\n\nconst actions = computed<ActionSchema[]>(() =>\n props.block.actions.map((action) => ({ ...action, hasModal: false })),\n)\nconst primary = computed(() => actions.value[0])\n\n// Wizard forms (`HasWizard` pages) show their buttons on the last step only.\nconst progress = useStore(wizardProgressStore(store))\nconst showActions = computed(() => formActionsVisible(props.block, progress.value))\n\nconst trigger = async (action: ActionSchema, ctx: ActionContext) => {\n if (action.url && !action.hasAction) {\n return runner.trigger(action, ctx)\n }\n\n submitting = true\n submittedBlock = props.block\n store.setProcessing(true)\n runner.execute(action, ctx, store.state.values)\n}\n\n// Track this form's own submit visit so unrelated reloads finishing meanwhile (polling,\n// relation-manager paging) neither end its processing state nor count as its success.\nlet submitVisit: string | null = null\n\nconst offStart = router.on('start', (event) => {\n const visit = event.detail.visit\n\n if (submitting && !submitVisit && visit.method !== 'get') {\n submitVisit = visit.id\n }\n\n if (visit.method !== 'get') visitBlock = props.block\n})\n\nconst offSuccess = router.on('success', (event) => {\n const id = submitVisit\n\n // Another action changed the record: show the server's new form unless it holds edits.\n if (!id && shouldResyncForm(pageFlash(event.detail.page), store)) {\n if (props.block !== visitBlock) {\n store.fill(props.block)\n } else {\n resyncPending = true\n }\n\n return\n }\n\n if (!id || (event.detail.visitId ?? id) !== id) return\n\n // A halted action (rate limit, `halt()`) saved nothing: keep what the user typed.\n if (pageFlash(event.detail.page).alfakitAction?.status === 'halted') return\n\n if (props.block !== submittedBlock) {\n store.fill(props.block)\n } else {\n refillPending = true\n }\n})\n\n// `refreshFormData([...])`: an action changed the record; copy those fields in.\nconst offRefresh = router.on('success', (event) => {\n const refresh = formRefreshFor(pageFlash(event.detail.page), props.block.component)\n\n if (refresh) applyFormRefresh(store, refresh)\n})\n\nconst offFinish = router.on('finish', (event) => {\n if (submitVisit && event.detail.visit.id !== submitVisit) return\n\n store.setProcessing(false)\n submitting = false\n submitVisit = null\n})\n\nconst offBefore = router.on('before', (event) => {\n if (!panel.value.unsavedChangesAlerts) {\n return\n }\n\n if (\n store.isDirty &&\n !submitting &&\n isLeavingVisit(event.detail.visit) &&\n !window.confirm(t('unsaved_changes', {}, 'You have unsaved changes. Leave anyway?'))\n ) {\n event.preventDefault()\n }\n})\n\nonScopeDispose(() => {\n offStart()\n offSuccess()\n offRefresh()\n offFinish()\n offBefore()\n store.destroy()\n})\n\nconst onSubmit = () => {\n if (primary.value && showActions.value) {\n void trigger(primary.value, context.value)\n }\n}\n\n// Enter in a text field runs the primary action (actions are type=\"button\").\nconst onKeydown = (event: KeyboardEvent) => {\n if (\n primary.value &&\n showActions.value &&\n isImplicitSubmit(event, event.currentTarget as HTMLFormElement)\n ) {\n event.preventDefault()\n void trigger(primary.value, context.value)\n }\n}\n</script>\n\n<template>\n <form\n data-slot=\"form-block\"\n class=\"flex flex-col gap-6\"\n @submit.prevent=\"onSubmit\"\n @keydown=\"onKeydown\"\n >\n <fieldset :disabled=\"state.processing || props.block.operation === 'view'\" class=\"contents\">\n <SchemaRenderer :components=\"state.components\" :columns=\"state.columns\" />\n </fieldset>\n <div v-if=\"actions.length > 0 && showActions\" data-slot=\"form-actions\" class=\"border-t pt-6\">\n <ActionList :actions=\"actions\" :context=\"context\" :on-trigger=\"trigger\" />\n </div>\n </form>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"FormBlock.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_withModifiers","_createElementVNode","_unref","_createVNode","SchemaRenderer","ActionList","_createCommentVNode","ActionList_default","SchemaRenderer_default","_hoisted_1","_hoisted_2","FormBlock_vue_vue_type_script_setup_true_lang_default","props","__props","panel","usePanel","page","usePageSchema","pageProps","useAlfakitProps","runner","useActionRunner","t","useT","token","computed","store","FormStore","notifications","showToast","n","router","resolvePartialProps","unregisterPageForm","name","pageFormName","registerPageForm","unregisterConflictForm","onMounted","registerConflictForm","onBeforeUnmount","unregisterSubmitter","registerFormSubmitter","trigger","action","ctx","watch","formIdentity","value","submittedBlock","refillPending","resyncPending","visitBlock","block","errors","state","useStore","context","submitting","actions","primary","progress","wizardProgressStore","showActions","formActionsVisible","submitVisit","offStart","visit","event","offSuccess","id","shouldResyncForm","pageFlash","offRefresh","refresh","formRefreshFor","applyFormRefresh","offFinish","offBefore","isLeavingVisit","onSubmit","onKeydown","isImplicitSubmit","openBlock","createElementBlock","withModifiers","createElementVNode","unref","createVNode","createCommentVNode"],"sources":["../../../src/components/form/FormBlock.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema, FormBlock as FormBlockSchema } from '@alfakit/core'\nimport {\n FormStore,\n applyFormRefresh,\n formActionsVisible,\n formIdentity,\n formRefreshFor,\n isImplicitSubmit,\n isLeavingVisit,\n pageFlash,\n pageFormName,\n registerConflictForm,\n registerFormSubmitter,\n registerPageForm,\n resolvePartialProps,\n shouldResyncForm,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, onBeforeUnmount, onMounted, onScopeDispose, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useAlfakitProps, usePageSchema, usePanel, useT } from '../../context'\nimport ActionList from '../actions/ActionList.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport { showToast } from '../notifications/flash-toasts'\nimport { provideForm } from './form-context'\n\n/**\n * A page form: its state lives in a FormStore, and its buttons are actions that post the\n * current values through the action endpoint.\n */\nconst props = defineProps<{ block: FormBlockSchema }>()\n\nconst panel = usePanel()\nconst page = usePageSchema()\nconst pageProps = useAlfakitProps()\nconst runner = useActionRunner()\nconst t = useT()\nconst token = computed(() => page.value?.token ?? '')\n\nconst store = new FormStore(props.block, {\n token: token.value,\n component: props.block.component,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n // Live dashboard filters are applied by the refresh; the widgets reload to follow.\n onRefreshed: () => {\n if (props.block.liveFilters) router.reload({ only: resolvePartialProps(['page']) })\n },\n})\n\nprovideForm(store)\n\n// Named forms of custom pages (`<PageForm name>`) publish their store for page method calls\n// (browser only: mounted hooks never run during a server render).\nlet unregisterPageForm: (() => void) | undefined\n\nonMounted(() => {\n const name = pageFormName(props.block.component)\n\n if (name) unregisterPageForm = registerPageForm(name, store)\n})\n\n// Edit pages: the conflict banner diffs and merges the main form (`detectConflicts()`).\nlet unregisterConflictForm: (() => void) | undefined\n\nonMounted(() => {\n if (props.block.component === 'form') unregisterConflictForm = registerConflictForm(store)\n})\n\nonBeforeUnmount(() => unregisterConflictForm?.())\n\n// Buttons elsewhere with `formId('form')` (a header \"Save\") submit through this form.\nlet unregisterSubmitter: (() => void) | undefined\n\nonMounted(() => {\n unregisterSubmitter = registerFormSubmitter(props.block.component, (action, ctx) =>\n trigger(action, ctx),\n )\n})\n\nonBeforeUnmount(() => {\n unregisterPageForm?.()\n unregisterSubmitter?.()\n})\n\n// The store survives reloads of the same form (table sorting/paging, polling,\n// relation-manager actions all deliver a new `block` object); only a different form\n// identity starts from server state again. The token is re-issued per response, so it\n// is swapped in place instead of being part of the identity.\nwatch(\n () => formIdentity(page.value, props.block),\n () => store.fill(props.block),\n)\n\nwatch(token, (value) => store.setToken(value))\n\n// After this form's own successful submit, refill from the server's new state. The new\n// block may arrive before or after Inertia's `success` event, so handle both orders.\nlet submittedBlock: FormBlockSchema | null = null\nlet refillPending = false\n// Another action succeeded and its new block has not arrived yet.\nlet resyncPending = false\n// The block when the latest non-GET visit started, to tell whether its response arrived.\nlet visitBlock: FormBlockSchema | null = null\n\nwatch(\n () => props.block,\n (block) => {\n if (refillPending) {\n refillPending = false\n store.fill(block)\n }\n\n if (resyncPending) {\n resyncPending = false\n\n if (!store.isDirty) store.fill(block)\n }\n },\n)\n\nwatch(\n () => pageProps.value.errors,\n (errors) => store.setErrors((errors as Record<string, string>) ?? {}),\n { immediate: true },\n)\n\nconst state = useStore(store.store)\nconst context = computed<ActionContext>(() => ({ token: token.value, component: 'page' }))\nlet submitting = false\n\nconst actions = computed<ActionSchema[]>(() =>\n props.block.actions.map((action) => ({ ...action, hasModal: false })),\n)\nconst primary = computed(() => actions.value[0])\n\n// Wizard forms (`HasWizard` pages) show their buttons on the last step only.\nconst progress = useStore(wizardProgressStore(store))\nconst showActions = computed(() => formActionsVisible(props.block, progress.value))\n\nconst trigger = async (action: ActionSchema, ctx: ActionContext) => {\n if (action.url && !action.hasAction) {\n return runner.trigger(action, ctx)\n }\n\n submitting = true\n submittedBlock = props.block\n store.setProcessing(true)\n // A click that blurred a live field started a refresh: send the state it returns.\n store.whenSettled(() => runner.execute(action, ctx, store.state.values))\n}\n\n// Track this form's own submit visit so unrelated reloads finishing meanwhile (polling,\n// relation-manager paging) neither end its processing state nor count as its success.\nlet submitVisit: string | null = null\n\nconst offStart = router.on('start', (event) => {\n const visit = event.detail.visit\n\n if (submitting && !submitVisit && visit.method !== 'get') {\n submitVisit = visit.id\n }\n\n if (visit.method !== 'get') visitBlock = props.block\n})\n\nconst offSuccess = router.on('success', (event) => {\n const id = submitVisit\n\n // Another action changed the record: show the server's new form unless it holds edits.\n if (!id && shouldResyncForm(pageFlash(event.detail.page), store)) {\n if (props.block !== visitBlock) {\n store.fill(props.block)\n } else {\n resyncPending = true\n }\n\n return\n }\n\n if (!id || (event.detail.visitId ?? id) !== id) return\n\n // A halted action (rate limit, `halt()`) saved nothing: keep what the user typed.\n if (pageFlash(event.detail.page).alfakitAction?.status === 'halted') return\n\n if (props.block !== submittedBlock) {\n store.fill(props.block)\n } else {\n refillPending = true\n }\n})\n\n// `refreshFormData([...])`: an action changed the record; copy those fields in.\nconst offRefresh = router.on('success', (event) => {\n const refresh = formRefreshFor(pageFlash(event.detail.page), props.block.component)\n\n if (refresh) applyFormRefresh(store, refresh)\n})\n\nconst offFinish = router.on('finish', (event) => {\n if (submitVisit && event.detail.visit.id !== submitVisit) return\n\n store.setProcessing(false)\n submitting = false\n submitVisit = null\n})\n\nconst offBefore = router.on('before', (event) => {\n if (!panel.value.unsavedChangesAlerts) {\n return\n }\n\n if (\n store.isDirty &&\n !submitting &&\n isLeavingVisit(event.detail.visit) &&\n !window.confirm(t('unsaved_changes', {}, 'You have unsaved changes. Leave anyway?'))\n ) {\n event.preventDefault()\n }\n})\n\nonScopeDispose(() => {\n offStart()\n offSuccess()\n offRefresh()\n offFinish()\n offBefore()\n store.destroy()\n})\n\nconst onSubmit = () => {\n if (primary.value && showActions.value) {\n void trigger(primary.value, context.value)\n }\n}\n\n// Enter in a text field runs the primary action (actions are type=\"button\").\nconst onKeydown = (event: KeyboardEvent) => {\n if (\n primary.value &&\n showActions.value &&\n isImplicitSubmit(event, event.currentTarget as HTMLFormElement)\n ) {\n event.preventDefault()\n void trigger(primary.value, context.value)\n }\n}\n</script>\n\n<template>\n <form\n data-slot=\"form-block\"\n class=\"flex flex-col gap-6\"\n @submit.prevent=\"onSubmit\"\n @keydown=\"onKeydown\"\n >\n <fieldset :disabled=\"state.processing || props.block.operation === 'view'\" class=\"contents\">\n <SchemaRenderer :components=\"state.components\" :columns=\"state.columns\" />\n </fieldset>\n <div v-if=\"actions.length > 0 && showActions\" data-slot=\"form-actions\" class=\"border-t pt-6\">\n <ActionList :actions=\"actions\" :context=\"context\" :on-trigger=\"trigger\" />\n </div>\n </form>\n</template>\n"],"mappings":"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"}