@alfakit/vue 0.1.2 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/AlfakitRoot.js.map +1 -1
  3. package/dist/AlfakitRoot.vue.d.ts.map +1 -1
  4. package/dist/AlfakitRoot.vue_vue_type_script_setup_true_lang.js +3 -1
  5. package/dist/AlfakitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/actions/ActionGroupMenu.js.map +1 -1
  7. package/dist/components/actions/ActionGroupMenu.vue.d.ts.map +1 -1
  8. package/dist/components/actions/ActionGroupMenu.vue_vue_type_script_setup_true_lang.js +69 -65
  9. package/dist/components/actions/ActionGroupMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/actions/ActionModal.js.map +1 -1
  11. package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
  12. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +17 -15
  13. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/ai/AiCopilot.js.map +1 -1
  15. package/dist/components/ai/AiCopilot.vue.d.ts +2 -0
  16. package/dist/components/ai/AiCopilot.vue.d.ts.map +1 -1
  17. package/dist/components/ai/AiCopilot.vue_vue_type_script_setup_true_lang.js +7 -2
  18. package/dist/components/ai/AiCopilot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/cms/CmsPage.vue_vue_type_script_setup_true_lang.js +19 -19
  20. package/dist/components/cms/CmsPage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/cms/LivePreview.js.map +1 -1
  22. package/dist/components/cms/LivePreview.vue.d.ts.map +1 -1
  23. package/dist/components/cms/LivePreview.vue_vue_type_script_setup_true_lang.js +83 -83
  24. package/dist/components/cms/LivePreview.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/fields/BuilderField.js.map +1 -1
  26. package/dist/components/fields/BuilderField.vue.d.ts.map +1 -1
  27. package/dist/components/fields/BuilderField.vue_vue_type_script_setup_true_lang.js +162 -157
  28. package/dist/components/fields/BuilderField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  29. package/dist/components/fields/ImageEditorDialog.js.map +1 -1
  30. package/dist/components/fields/ImageEditorDialog.vue.d.ts.map +1 -1
  31. package/dist/components/fields/ImageEditorDialog.vue_vue_type_script_setup_true_lang.js +46 -46
  32. package/dist/components/fields/ImageEditorDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/fields/KeyValueField.js.map +1 -1
  34. package/dist/components/fields/KeyValueField.vue.d.ts.map +1 -1
  35. package/dist/components/fields/KeyValueField.vue_vue_type_script_setup_true_lang.js +66 -66
  36. package/dist/components/fields/KeyValueField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/fields/ModalTablePicker.js.map +1 -1
  38. package/dist/components/fields/ModalTablePicker.vue.d.ts.map +1 -1
  39. package/dist/components/fields/ModalTablePicker.vue_vue_type_script_setup_true_lang.js +113 -113
  40. package/dist/components/fields/ModalTablePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/fields/RepeaterField.js.map +1 -1
  42. package/dist/components/fields/RepeaterField.vue.d.ts.map +1 -1
  43. package/dist/components/fields/RepeaterField.vue_vue_type_script_setup_true_lang.js +12 -12
  44. package/dist/components/fields/RepeaterField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/fields/RichEditorInput.js.map +1 -1
  46. package/dist/components/fields/RichEditorInput.vue.d.ts.map +1 -1
  47. package/dist/components/fields/RichEditorInput.vue_vue_type_script_setup_true_lang.js +166 -165
  48. package/dist/components/fields/RichEditorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/fields/SliderField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/fields/item-actions.d.ts +2 -2
  51. package/dist/components/fields/item-actions.d.ts.map +1 -1
  52. package/dist/components/fields/item-actions.js +31 -31
  53. package/dist/components/fields/item-actions.js.map +1 -1
  54. package/dist/components/form/FormBlock.js.map +1 -1
  55. package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
  56. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +1 -1
  57. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/form/form-context.js +25 -25
  59. package/dist/components/form/form-context.js.map +1 -1
  60. package/dist/components/kanban/KanbanBoard.js.map +1 -1
  61. package/dist/components/kanban/KanbanBoard.vue.d.ts.map +1 -1
  62. package/dist/components/kanban/KanbanBoard.vue_vue_type_script_setup_true_lang.js +5 -2
  63. package/dist/components/kanban/KanbanBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/kanban/KanbanColumnHeader.js.map +1 -1
  65. package/dist/components/kanban/KanbanColumnHeader.vue.d.ts.map +1 -1
  66. package/dist/components/kanban/KanbanColumnHeader.vue_vue_type_script_setup_true_lang.js +64 -64
  67. package/dist/components/kanban/KanbanColumnHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/layout/SectionComponent.js.map +1 -1
  69. package/dist/components/layout/SectionComponent.vue.d.ts.map +1 -1
  70. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js +23 -23
  71. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/panel/DebugPanel.vue_vue_type_script_setup_true_lang.js +8 -8
  73. package/dist/components/panel/DebugPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/panel/GlobalSearchPalette.js.map +1 -1
  75. package/dist/components/panel/GlobalSearchPalette.vue.d.ts.map +1 -1
  76. package/dist/components/panel/GlobalSearchPalette.vue_vue_type_script_setup_true_lang.js +102 -96
  77. package/dist/components/panel/GlobalSearchPalette.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js +10 -10
  79. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/panel/NavGroupFlyout.vue_vue_type_script_setup_true_lang.js +9 -9
  81. package/dist/components/panel/NavGroupFlyout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js +16 -16
  83. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js +10 -10
  85. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  86. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js +35 -35
  87. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/panel/Topbar.vue_vue_type_script_setup_true_lang.js +11 -11
  89. package/dist/components/panel/Topbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  90. package/dist/components/realtime/use-live-updates.d.ts.map +1 -1
  91. package/dist/components/realtime/use-live-updates.js +24 -23
  92. package/dist/components/realtime/use-live-updates.js.map +1 -1
  93. package/dist/components/table/BooleanCell.vue_vue_type_script_setup_true_lang.js +2 -1
  94. package/dist/components/table/BooleanCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/table/ColumnHeader.js.map +1 -1
  96. package/dist/components/table/ColumnHeader.vue.d.ts.map +1 -1
  97. package/dist/components/table/ColumnHeader.vue_vue_type_script_setup_true_lang.js +55 -49
  98. package/dist/components/table/ColumnHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/table/ColumnManager.js.map +1 -1
  100. package/dist/components/table/ColumnManager.vue.d.ts.map +1 -1
  101. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js +5 -4
  102. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js.map +1 -1
  103. package/dist/components/table/ContentLayoutSort.js.map +1 -1
  104. package/dist/components/table/ContentLayoutSort.vue.d.ts.map +1 -1
  105. package/dist/components/table/ContentLayoutSort.vue_vue_type_script_setup_true_lang.js +5 -5
  106. package/dist/components/table/ContentLayoutSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js +2 -1
  108. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/table/SelectComboboxCell.vue_vue_type_script_setup_true_lang.js +2 -1
  110. package/dist/components/table/SelectComboboxCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  111. package/dist/components/table/TableCellContent.js.map +1 -1
  112. package/dist/components/table/TableCellContent.vue.d.ts.map +1 -1
  113. package/dist/components/table/TableCellContent.vue_vue_type_script_setup_true_lang.js +4 -3
  114. package/dist/components/table/TableCellContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/table/TablePagination.js.map +1 -1
  116. package/dist/components/table/TablePagination.vue.d.ts.map +1 -1
  117. package/dist/components/table/TablePagination.vue_vue_type_script_setup_true_lang.js +87 -87
  118. package/dist/components/table/TablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  119. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js +2 -1
  120. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  121. package/dist/components/table/cell-update.d.ts +6 -0
  122. package/dist/components/table/cell-update.d.ts.map +1 -1
  123. package/dist/components/table/cell-update.js.map +1 -1
  124. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
  125. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/components/ui/CommandAutoHighlight.js +7 -0
  127. package/dist/components/ui/CommandAutoHighlight.js.map +1 -0
  128. package/dist/components/ui/CommandAutoHighlight.vue.d.ts +21 -0
  129. package/dist/components/ui/CommandAutoHighlight.vue.d.ts.map +1 -0
  130. package/dist/components/ui/CommandAutoHighlight.vue_vue_type_script_setup_true_lang.js +18 -0
  131. package/dist/components/ui/CommandAutoHighlight.vue_vue_type_script_setup_true_lang.js.map +1 -0
  132. package/dist/components/ui/DialogContent.js.map +1 -1
  133. package/dist/components/ui/DialogContent.vue.d.ts.map +1 -1
  134. package/dist/components/ui/DialogContent.vue_vue_type_script_setup_true_lang.js +13 -12
  135. package/dist/components/ui/DialogContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/ui/PopoverContent.js.map +1 -1
  137. package/dist/components/ui/PopoverContent.vue.d.ts.map +1 -1
  138. package/dist/components/ui/PopoverContent.vue_vue_type_script_setup_true_lang.js +9 -8
  139. package/dist/components/ui/PopoverContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/components/ui/SheetContent.js.map +1 -1
  141. package/dist/components/ui/SheetContent.vue.d.ts.map +1 -1
  142. package/dist/components/ui/SheetContent.vue_vue_type_script_setup_true_lang.js +13 -12
  143. package/dist/components/ui/SheetContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/ui/TooltipContent.js.map +1 -1
  145. package/dist/components/ui/TooltipContent.vue.d.ts.map +1 -1
  146. package/dist/components/ui/TooltipContent.vue_vue_type_script_setup_true_lang.js +9 -8
  147. package/dist/components/ui/TooltipContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  148. package/dist/context.d.ts +7 -0
  149. package/dist/context.d.ts.map +1 -1
  150. package/dist/context.js +29 -26
  151. package/dist/context.js.map +1 -1
  152. package/dist/create-alfakit.d.ts.map +1 -1
  153. package/dist/create-alfakit.js +33 -31
  154. package/dist/create-alfakit.js.map +1 -1
  155. package/dist/eject-manifest.json +11 -2
  156. package/dist/index.d.ts +1 -0
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +219 -217
  159. package/dist/layouts/AppLayout.vue_vue_type_script_setup_true_lang.js +8 -8
  160. package/dist/layouts/AppLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  161. package/dist/layouts/AuthLayout.vue_vue_type_script_setup_true_lang.js +9 -9
  162. package/dist/layouts/FullscreenLayout.vue_vue_type_script_setup_true_lang.js +8 -8
  163. package/dist/layouts/FullscreenLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js +15 -15
  165. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  166. package/dist/layouts/lazy-layouts.d.ts +10 -0
  167. package/dist/layouts/lazy-layouts.d.ts.map +1 -0
  168. package/dist/layouts/lazy-layouts.js +8 -0
  169. package/dist/layouts/lazy-layouts.js.map +1 -0
  170. package/dist/layouts/panel-layouts.d.ts +8 -0
  171. package/dist/layouts/panel-layouts.d.ts.map +1 -0
  172. package/dist/layouts/panel-layouts.js +15 -0
  173. package/dist/layouts/panel-layouts.js.map +1 -0
  174. package/dist/lib/lazy.d.ts.map +1 -1
  175. package/dist/lib/lazy.js +2 -2
  176. package/dist/lib/lazy.js.map +1 -1
  177. package/dist/pages/PageShell.js.map +1 -1
  178. package/dist/pages/PageShell.vue.d.ts.map +1 -1
  179. package/dist/pages/PageShell.vue_vue_type_script_setup_true_lang.js +39 -42
  180. package/dist/pages/PageShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/standalone/AlfakitComponent.js.map +1 -1
  182. package/dist/standalone/AlfakitComponent.vue.d.ts.map +1 -1
  183. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js +56 -52
  184. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  185. package/dist/standalone.css +7 -0
  186. package/dist/starter-kit/AlfakitStarterKitRoot.js.map +1 -1
  187. package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts +2 -2
  188. package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts.map +1 -1
  189. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js +17 -12
  190. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/starter-kit/dashboard-widgets.d.ts +54 -0
  192. package/dist/starter-kit/dashboard-widgets.d.ts.map +1 -0
  193. package/dist/starter-kit/dashboard-widgets.js +54 -0
  194. package/dist/starter-kit/dashboard-widgets.js.map +1 -0
  195. package/dist/starter-kit/index.d.ts +2 -1
  196. package/dist/starter-kit/index.d.ts.map +1 -1
  197. package/dist/starter-kit/index.js +5 -4
  198. package/dist/starter-kit/runtime.d.ts +6 -0
  199. package/dist/starter-kit/runtime.d.ts.map +1 -1
  200. package/dist/starter-kit/runtime.js +19 -15
  201. package/dist/starter-kit/runtime.js.map +1 -1
  202. package/dist/starter-kit/starter-kit.d.ts.map +1 -1
  203. package/dist/starter-kit/starter-kit.js +8 -8
  204. package/dist/starter-kit/starter-kit.js.map +1 -1
  205. package/dist/starter-kit/widgets/CopilotTrigger.js +7 -0
  206. package/dist/starter-kit/widgets/CopilotTrigger.js.map +1 -0
  207. package/dist/starter-kit/widgets/CopilotTrigger.vue.d.ts +12 -0
  208. package/dist/starter-kit/widgets/CopilotTrigger.vue.d.ts.map +1 -0
  209. package/dist/starter-kit/widgets/CopilotTrigger.vue_vue_type_script_setup_true_lang.js +23 -0
  210. package/dist/starter-kit/widgets/CopilotTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/starter-kit/widgets/LoadedCopilot.js +7 -0
  212. package/dist/starter-kit/widgets/LoadedCopilot.js.map +1 -0
  213. package/dist/starter-kit/widgets/LoadedCopilot.vue.d.ts +8 -0
  214. package/dist/starter-kit/widgets/LoadedCopilot.vue.d.ts.map +1 -0
  215. package/dist/starter-kit/widgets/LoadedCopilot.vue_vue_type_script_setup_true_lang.js +31 -0
  216. package/dist/starter-kit/widgets/LoadedCopilot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  217. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.js +7 -0
  218. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.js.map +1 -0
  219. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue.d.ts +8 -0
  220. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue.d.ts.map +1 -0
  221. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue_vue_type_script_setup_true_lang.js +34 -0
  222. package/dist/starter-kit/widgets/StarterKitImpersonationBanner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  223. package/dist/starter-kit/widgets/index.d.ts +40 -9
  224. package/dist/starter-kit/widgets/index.d.ts.map +1 -1
  225. package/dist/starter-kit/widgets/index.js +21 -18
  226. package/dist/starter-kit/widgets/index.js.map +1 -1
  227. package/dist/starter-kit/widgets/loaded.d.ts +10 -0
  228. package/dist/starter-kit/widgets/loaded.d.ts.map +1 -0
  229. package/dist/starter-kit/widgets/loaded.js +5 -0
  230. package/dist/styles.css +9 -2
  231. package/dist/themes.css +6 -1
  232. package/package.json +2 -2
  233. package/src/AlfakitRoot.vue +9 -1
  234. package/src/components/actions/ActionGroupMenu.vue +13 -1
  235. package/src/components/actions/ActionModal.vue +9 -0
  236. package/src/components/ai/AiCopilot.vue +7 -1
  237. package/src/components/cms/LivePreview.vue +8 -2
  238. package/src/components/fields/BuilderField.vue +15 -2
  239. package/src/components/fields/ImageEditorDialog.vue +7 -3
  240. package/src/components/fields/KeyValueField.vue +3 -2
  241. package/src/components/fields/ModalTablePicker.vue +7 -2
  242. package/src/components/fields/RepeaterField.vue +2 -3
  243. package/src/components/fields/RichEditorInput.vue +3 -0
  244. package/src/components/fields/item-actions.ts +31 -10
  245. package/src/components/form/FormBlock.vue +2 -1
  246. package/src/components/form/form-context.ts +2 -2
  247. package/src/components/kanban/KanbanBoard.vue +15 -3
  248. package/src/components/kanban/KanbanColumnHeader.vue +6 -4
  249. package/src/components/layout/SectionComponent.vue +10 -4
  250. package/src/components/panel/GlobalSearchPalette.vue +2 -0
  251. package/src/components/realtime/use-live-updates.ts +3 -1
  252. package/src/components/table/ColumnHeader.vue +23 -12
  253. package/src/components/table/ColumnManager.vue +12 -8
  254. package/src/components/table/ContentLayoutSort.vue +7 -1
  255. package/src/components/table/TableCellContent.vue +4 -2
  256. package/src/components/table/TablePagination.vue +12 -7
  257. package/src/components/table/cell-update.ts +6 -0
  258. package/src/components/ui/CommandAutoHighlight.vue +27 -0
  259. package/src/components/ui/DialogContent.vue +5 -1
  260. package/src/components/ui/PopoverContent.vue +5 -1
  261. package/src/components/ui/SheetContent.vue +5 -1
  262. package/src/components/ui/TooltipContent.vue +5 -1
  263. package/src/context.ts +10 -0
  264. package/src/create-alfakit.ts +5 -0
  265. package/src/index.ts +2 -0
  266. package/src/layouts/lazy-layouts.ts +14 -0
  267. package/src/layouts/panel-layouts.ts +17 -0
  268. package/src/lib/lazy.ts +11 -1
  269. package/src/pages/PageShell.vue +5 -6
  270. package/src/standalone/AlfakitComponent.vue +17 -6
  271. package/src/starter-kit/AlfakitStarterKitRoot.vue +12 -3
  272. package/src/starter-kit/dashboard-widgets.ts +93 -0
  273. package/src/starter-kit/index.ts +7 -1
  274. package/src/starter-kit/runtime.ts +17 -1
  275. package/src/starter-kit/starter-kit.ts +2 -1
  276. package/src/starter-kit/widgets/CopilotTrigger.vue +58 -0
  277. package/src/starter-kit/widgets/LoadedCopilot.vue +29 -0
  278. package/src/starter-kit/widgets/StarterKitImpersonationBanner.vue +57 -0
  279. package/src/starter-kit/widgets/index.ts +56 -11
  280. package/src/starter-kit/widgets/loaded.ts +9 -0
  281. package/src/styles.css +9 -2
package/dist/styles.css CHANGED
@@ -19,6 +19,13 @@
19
19
 
20
20
  @custom-variant dark (&:is(.dark *));
21
21
 
22
+ /*
23
+ * Class lists that live in @alfakit/core (stacked-on-mobile tables, filter and column manager
24
+ * widths in `table.ts`, …): scan core's build too. Relative to this file in
25
+ * node_modules/@alfakit/<renderer>/dist, next to node_modules/@alfakit/core.
26
+ */
27
+ @source '../../core/dist';
28
+
22
29
  /*
23
30
  * Grid classes are composed at runtime from schema breakpoints (`columns`, `columnSpan`),
24
31
  * so force Tailwind to generate every variant the renderers can produce.
@@ -122,10 +129,10 @@
122
129
  --secondary: oklch(0.97 0 0);
123
130
  --secondary-foreground: oklch(0.205 0 0);
124
131
  --muted: oklch(0.97 0 0);
125
- --muted-foreground: oklch(0.556 0 0);
132
+ --muted-foreground: oklch(0.54 0 0);
126
133
  --accent: oklch(0.97 0 0);
127
134
  --accent-foreground: oklch(0.205 0 0);
128
- --destructive: var(--alfakit-danger, oklch(0.55 0.245 27.325));
135
+ --destructive: var(--alfakit-danger, oklch(0.5 0.245 27.325));
129
136
  --destructive-foreground: var(--alfakit-danger-foreground, oklch(0.985 0 0));
130
137
  --border: oklch(0.922 0 0);
131
138
  --input: oklch(0.64 0 0);
package/dist/themes.css CHANGED
@@ -287,7 +287,7 @@
287
287
  --secondary: oklch(0.967 0.003 264.542);
288
288
  --secondary-foreground: oklch(0.21 0.034 264.665);
289
289
  --muted: oklch(0.967 0.003 264.542);
290
- --muted-foreground: oklch(0.551 0.027 264.364);
290
+ --muted-foreground: oklch(0.535 0.027 264.364);
291
291
  --accent: oklch(0.967 0.003 264.542);
292
292
  --accent-foreground: oklch(0.21 0.034 264.665);
293
293
  --border: oklch(0.928 0.006 264.531);
@@ -678,6 +678,11 @@
678
678
  color: var(--primary);
679
679
  }
680
680
 
681
+ /* The schema inspector's round button (dev tools) sits above the bar, not on its last item. */
682
+ :root[data-mobile='bottom'] [data-slot='dev-tools-toggle'] {
683
+ bottom: calc(var(--alfakit-bottom-nav-height) + env(safe-area-inset-bottom, 0px) + 1rem);
684
+ }
685
+
681
686
  /* Room for the bar, sticky actions sit right above it. */
682
687
  :root[data-mobile='bottom'] [data-slot='content'] {
683
688
  padding-bottom: calc(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfakit/vue",
3
- "version": "0.1.2",
3
+ "version": "0.1.7",
4
4
  "description": "Vue 3 + shadcn-vue renderer for Alfakit, the Laravel admin panel builder by Alfa Six.",
5
5
  "license": "MIT",
6
6
  "author": "Alfa Six (https://alfasixbh.com)",
@@ -96,7 +96,7 @@
96
96
  "reka-ui": "^2.11.0",
97
97
  "tailwind-merge": "^3.7.0",
98
98
  "vue-sonner": "^2.0.9",
99
- "@alfakit/core": "0.1.2"
99
+ "@alfakit/core": "0.1.7"
100
100
  },
101
101
  "peerDependencies": {
102
102
  "@inertiajs/vue3": "^3.0.0",
@@ -52,7 +52,15 @@ watch(
52
52
  { immediate: true, flush: 'sync' },
53
53
  )
54
54
 
55
- watch(localization, (value) => applyDocumentLocale(value), { immediate: true })
55
+ // Starter kit mode: the host app owns `<html lang dir>` (its own pages and layout are not
56
+ // mirrored); `AlfakitStarterKitRoot` puts the direction on Alfakit's own root element.
57
+ watch(
58
+ localization,
59
+ (value) => {
60
+ if (panel.value?.starterKit !== true) applyDocumentLocale(value)
61
+ },
62
+ { immediate: true },
63
+ )
56
64
  watch(panel, (value) => applyPanelTheme(value), { immediate: true })
57
65
  </script>
58
66
 
@@ -13,7 +13,7 @@ import {
13
13
  registerKeyBindings,
14
14
  resolveActionSize,
15
15
  } from '@alfakit/core'
16
- import { computed, watchEffect } from 'vue'
16
+ import { computed, useTemplateRef, watchEffect } from 'vue'
17
17
  import { useActionRunner, useT } from '../../context'
18
18
  import { colorClass, ghostButtonColorClasses, outlineButtonColorClasses } from '../../lib/colors'
19
19
  import { Icon } from '../../lib/icons'
@@ -40,6 +40,16 @@ const props = withDefaults(
40
40
  { size: 'default' },
41
41
  )
42
42
 
43
+ // With a tooltip, the menu's trigger sits inside the tooltip's popper, so reka-ui hands the
44
+ // trigger to the tooltip as its anchor and the menu would open off screen (at its unpositioned
45
+ // `translate(0, -200%)`): anchor the menu to the button explicitly.
46
+ const tooltipTrigger = useTemplateRef<{ $el?: Element }>('tooltipTrigger')
47
+ const tooltipTriggerElement = computed(() =>
48
+ props.group.tooltip && tooltipTrigger.value?.$el instanceof Element
49
+ ? tooltipTrigger.value.$el
50
+ : undefined,
51
+ )
52
+
43
53
  /** `dropdownWidth()`: widths of the dropdown, spelled out for Tailwind. */
44
54
  const DROPDOWN_WIDTHS: Record<string, string> = {
45
55
  '3xs': 'w-3xs',
@@ -155,6 +165,7 @@ watchEffect((onCleanup) => {
155
165
  <TooltipTrigger as-child>
156
166
  <DropdownMenuTrigger as-child>
157
167
  <Button
168
+ ref="tooltipTrigger"
158
169
  type="button"
159
170
  :variant="props.group.variant === 'button' ? 'outline' : 'ghost'"
160
171
  :size="buttonSize"
@@ -189,6 +200,7 @@ watchEffect((onCleanup) => {
189
200
  </Button>
190
201
  </DropdownMenuTrigger>
191
202
  <DropdownMenuContent
203
+ :reference="tooltipTriggerElement"
192
204
  :side="placement.side"
193
205
  :align="placement.align"
194
206
  :side-offset="props.group.dropdownOffset ?? undefined"
@@ -198,6 +198,15 @@ const passwordError = computed(() => props.modal.errors[PASSWORD_CONFIRMATION_IN
198
198
  const footerContext = nestedActionContext(context, action)
199
199
 
200
200
  const run = (createAnother: boolean) => {
201
+ // A click that blurred a live field started a refresh: send the state it returns.
202
+ if (form) {
203
+ form.whenSettled(() => execute(createAnother))
204
+ } else {
205
+ execute(createAnother)
206
+ }
207
+ }
208
+
209
+ const execute = (createAnother: boolean) => {
201
210
  const values = form?.state.values ?? {}
202
211
  const options = {
203
212
  ...(schema.value.passwordConfirmation ? { password: password.value } : {}),
@@ -11,7 +11,11 @@ import { CopilotPanel, preloadCopilotPanel } from './copilot-lazy'
11
11
  * a chat slide-over. Questions, tools and actions run on the server; proposed actions
12
12
  * run only when the user confirms them in the chat.
13
13
  */
14
- const props = defineProps<{ component: AiCopilotSchema }>()
14
+ const props = defineProps<{
15
+ component: AiCopilotSchema
16
+ /** Open once mounted (starter kit header: clicked or `mod+j` before its code loaded). */
17
+ autoOpen?: boolean
18
+ }>()
15
19
  const t = useT()
16
20
  // One controller per panel: Inertia visits pass new props objects.
17
21
  const controller = new CopilotController(props.component)
@@ -25,6 +29,8 @@ const unsubscribe = controller.subscribe((next) => {
25
29
  if (next.open) mounted.value = true
26
30
  })
27
31
 
32
+ if (props.autoOpen && props.component.canUse !== false) controller.open()
33
+
28
34
  let unregister: (() => void) | undefined
29
35
 
30
36
  watch(
@@ -65,6 +65,12 @@ const status = computed(() =>
65
65
  ? props.component.changedStatus
66
66
  : props.component.status,
67
67
  )
68
+ // "Publish changes" appears as soon as an autosave makes the draft differ.
69
+ const actions = computed(() =>
70
+ snapshot.value.hasChanges && props.component.changedActions
71
+ ? props.component.changedActions
72
+ : props.component.actions,
73
+ )
68
74
  /** Badge colours of the status (the server's `PageState` colours). */
69
75
  const STATUS_COLORS: Record<string, string> = {
70
76
  gray: 'border-border bg-muted text-foreground',
@@ -227,8 +233,8 @@ onBeforeUnmount(() => {
227
233
  : t('cms.live_preview', {}, 'Live preview')
228
234
  }}
229
235
  </Button>
230
- <div v-if="props.component.actions?.length" @pointerdown.capture="autosave?.flush()">
231
- <ActionList :actions="props.component.actions" :context="actionContext" size="sm" />
236
+ <div v-if="actions?.length" @pointerdown.capture="autosave?.flush()">
237
+ <ActionList :actions="actions" :context="actionContext" size="sm" />
232
238
  </div>
233
239
  </div>
234
240
  <section
@@ -56,7 +56,7 @@ const registry = useOptionalRegistry()
56
56
  const form = useOptionalFormStore()
57
57
  const context = useFieldActionContext(() => props.component)
58
58
  const runItemAction = useRunItemAction(context)
59
- const fallbacks = useItemActionFallbacks()
59
+ const fallbacks = useItemActionFallbacks('builder')
60
60
  const serverItemOf = (index: number) => {
61
61
  const server = props.component.items[index]
62
62
 
@@ -195,6 +195,19 @@ const onDrop = (index: number) => {
195
195
  }
196
196
  const setAllCollapsed = (value: boolean) => {
197
197
  collapsed.value = Object.fromEntries(items.value.map((_, index) => [index, value]))
198
+ if (value) refreshSummaries(items.value.map((_, index) => index))
199
+ }
200
+ // Summaries are made on the server: collapsing items whose block has one brings them up
201
+ // to date with the edits.
202
+ const refreshSummaries = (indexes: number[]) => {
203
+ if (indexes.some((index) => blockOf(items.value[index]?.type ?? '')?.summary)) {
204
+ void form?.refresh(props.component.statePath)
205
+ }
206
+ }
207
+ const toggleCollapsed = (index: number) => {
208
+ const collapse = !isCollapsed(index)
209
+ collapsed.value = { ...collapsed.value, [index]: collapse }
210
+ if (collapse) refreshSummaries([index])
198
211
  }
199
212
 
200
213
  // Previews (`blockPreviews()`): server HTML or a registered `builder-preview:{name}`.
@@ -356,7 +369,7 @@ const previewIsButton = computed(() => !props.component.interactivePreviews && !
356
369
  @move="moves.moveWithButton"
357
370
  @clone="cloneItem(index)"
358
371
  @delete="removeItem(index)"
359
- @toggle="collapsed = { ...collapsed, [index]: !isCollapsed(index) }"
372
+ @toggle="toggleCollapsed(index)"
360
373
  >
361
374
  <Button
362
375
  v-if="hasPreview(index) && !locked"
@@ -11,7 +11,7 @@ import type {
11
11
  ImageEditorDragMode,
12
12
  ImageEditorState,
13
13
  } from '@alfakit/core'
14
- import { ImageEditor, loadEditorImage } from '@alfakit/core'
14
+ import { ImageEditor, imageEditorOptionsKey, loadEditorImage } from '@alfakit/core'
15
15
  import {
16
16
  FlipHorizontal2Icon,
17
17
  FlipVertical2Icon,
@@ -81,11 +81,15 @@ const release = () => {
81
81
  state.value = null
82
82
  }
83
83
 
84
+ // Restart only for another image or other settings: the schema object itself is new on
85
+ // every render of a template item (a new builder block), which kept restarting the load.
84
86
  watch(
85
- () => [props.request, props.options] as const,
86
- ([request, options], _previous, onCleanup) => {
87
+ [() => props.request, () => imageEditorOptionsKey(props.options)],
88
+ ([request], _previous, onCleanup) => {
87
89
  if (!request) return
88
90
 
91
+ const options = props.options
92
+
89
93
  let cancelled = false
90
94
 
91
95
  loadEditorImage(request.file)
@@ -5,6 +5,7 @@ import {
5
5
  reorderedItemKeys,
6
6
  resolveItemAction,
7
7
  type KeyValueSchema,
8
+ itemActionIcon,
8
9
  } from '@alfakit/core'
9
10
  import { ChevronDownIcon, ChevronUpIcon } from '@lucide/vue'
10
11
  import { computed, ref } from 'vue'
@@ -60,13 +61,13 @@ const addAction = computed(() =>
60
61
  const deleteAction = computed(() =>
61
62
  resolveItemAction('delete', props.component, undefined, {
62
63
  label: t('form.remove_row', {}, 'Remove row'),
63
- icon: 'trash-2',
64
+ icon: itemActionIcon('key-value', 'delete', 'trash-2'),
64
65
  }),
65
66
  )
66
67
  const reorderAction = computed(() =>
67
68
  resolveItemAction('reorder', props.component, undefined, {
68
69
  label: t('form.reorder_item', {}, 'Reorder'),
69
- icon: 'grip-vertical',
70
+ icon: itemActionIcon('key-value', 'reorder', 'grip-vertical'),
70
71
  }),
71
72
  )
72
73
  const deletable = computed(
@@ -15,7 +15,7 @@ import {
15
15
  SearchIcon,
16
16
  } from '@lucide/vue'
17
17
  import { computed, onScopeDispose, ref, watch } from 'vue'
18
- import { useChoice, useT } from '../../context'
18
+ import { useChoice, useFormatter, useT } from '../../context'
19
19
  import { cn } from '../../lib/utils'
20
20
  import { useFormStore } from '../form/form-context'
21
21
  import TableCellContent from '../table/TableCellContent.vue'
@@ -43,6 +43,7 @@ const emit = defineEmits<{
43
43
  confirm: [keys: string[], labels: Record<string, string>]
44
44
  }>()
45
45
  const t = useT()
46
+ const format = useFormatter()
46
47
  const choice = useChoice()
47
48
  const form = useFormStore()
48
49
  const multiple = computed(() => Boolean(props.component.multiple))
@@ -314,7 +315,11 @@ const confirm = () =>
314
315
  paging.total !== undefined
315
316
  ? t(
316
317
  'table.showing',
317
- { first: paging.from, last: paging.to, total: paging.total },
318
+ {
319
+ first: format.number(paging.from),
320
+ last: format.number(paging.to),
321
+ total: format.number(paging.total),
322
+ },
318
323
  'Showing :first–:last of :total',
319
324
  )
320
325
  : `${paging.from}–${paging.to}`
@@ -13,7 +13,7 @@ import {
13
13
  removeIndexedState,
14
14
  removeRepeaterItem,
15
15
  reorderedItemKeys,
16
- replacePlaceholder,
16
+ templateForIndex,
17
17
  resolveItemAction,
18
18
  virtualizeOptions,
19
19
  type ItemActionName,
@@ -82,8 +82,7 @@ const virtual = useVirtualList(
82
82
  useScrollToErroredItem(virtual, () => props.component.statePath)
83
83
 
84
84
  const schemaFor = (index: number): SchemaComponent[] =>
85
- props.component.items[index]?.schema ??
86
- replacePlaceholder(props.component.template, '__INDEX__', String(index))
85
+ props.component.items[index]?.schema ?? templateForIndex(props.component.template, index)
87
86
  const isCollapsed = (index: number) => collapsed.value[index] ?? props.component.collapsed ?? false
88
87
 
89
88
  const canAdd = computed(
@@ -32,6 +32,7 @@ import {
32
32
  toolbarCommands,
33
33
  panelUploadOptions,
34
34
  uploadTemporaryFile,
35
+ documentNonce,
35
36
  } from '@alfakit/core'
36
37
  import { EraserIcon } from '@lucide/vue'
37
38
  import Image from '@tiptap/extension-image'
@@ -230,6 +231,8 @@ onBeforeUnmount(() => {
230
231
  })
231
232
 
232
233
  const editor = useEditor({
234
+ // TipTap injects its base CSS; with the page's CSP nonce a nonce-based policy allows it.
235
+ injectNonce: documentNonce(),
233
236
  extensions: [
234
237
  StarterKit.configure({ link: false }),
235
238
  Link.configure(linkExtensionOptions(props.component.linkProtocols)),
@@ -4,23 +4,44 @@ import type {
4
4
  ItemActionName,
5
5
  ItemActionSchema,
6
6
  } from '@alfakit/core'
7
- import { ItemMoveTracker, itemActionContext } from '@alfakit/core'
7
+ import { ItemMoveTracker, itemActionContext, itemActionIcon } from '@alfakit/core'
8
8
  import { nextTick, ref, toValue, watch, type MaybeRefOrGetter } from 'vue'
9
9
  import { useActionRunner, useT } from '../../context'
10
10
 
11
- /** Default looks of the built-in item actions, for payloads without `itemActions`. */
12
- export function useItemActionFallbacks(): Record<ItemActionName, ItemActionFallback> {
11
+ /** Default looks of the built-in item actions, for payloads without `itemActions` (icons follow their `alfakit::` aliases). */
12
+ export function useItemActionFallbacks(
13
+ kind: 'repeater' | 'builder' = 'repeater',
14
+ ): Record<ItemActionName, ItemActionFallback> {
13
15
  const t = useT()
14
16
 
15
17
  return {
16
18
  add: { label: '', icon: 'plus', variant: 'outline' },
17
- delete: { label: t('form.remove_item', {}, 'Remove'), icon: 'trash-2', color: 'danger' },
18
- clone: { label: t('form.clone', {}, 'Clone'), icon: 'copy' },
19
- reorder: { label: t('form.reorder_item', {}, 'Reorder'), icon: 'grip-vertical' },
20
- moveUp: { label: t('form.move_up', {}, 'Move up'), icon: 'chevron-up' },
21
- moveDown: { label: t('form.move_down', {}, 'Move down'), icon: 'chevron-down' },
22
- collapse: { label: t('form.collapse_item', {}, 'Collapse'), icon: 'chevron-up' },
23
- expand: { label: t('form.expand_item', {}, 'Expand'), icon: 'chevron-down' },
19
+ delete: {
20
+ label: t('form.remove_item', {}, 'Remove'),
21
+ icon: itemActionIcon(kind, 'delete', 'trash-2'),
22
+ color: 'danger',
23
+ },
24
+ clone: { label: t('form.clone', {}, 'Clone'), icon: itemActionIcon(kind, 'clone', 'copy') },
25
+ reorder: {
26
+ label: t('form.reorder_item', {}, 'Reorder'),
27
+ icon: itemActionIcon(kind, 'reorder', 'grip-vertical'),
28
+ },
29
+ moveUp: {
30
+ label: t('form.move_up', {}, 'Move up'),
31
+ icon: itemActionIcon(kind, 'move-up', 'chevron-up'),
32
+ },
33
+ moveDown: {
34
+ label: t('form.move_down', {}, 'Move down'),
35
+ icon: itemActionIcon(kind, 'move-down', 'chevron-down'),
36
+ },
37
+ collapse: {
38
+ label: t('form.collapse_item', {}, 'Collapse'),
39
+ icon: itemActionIcon(kind, 'collapse', 'chevron-up'),
40
+ },
41
+ expand: {
42
+ label: t('form.expand_item', {}, 'Expand'),
43
+ icon: itemActionIcon(kind, 'expand', 'chevron-down'),
44
+ },
24
45
  collapseAll: {
25
46
  label: t('form.collapse_all', {}, 'Collapse all'),
26
47
  icon: 'chevrons-down-up',
@@ -151,7 +151,8 @@ const trigger = async (action: ActionSchema, ctx: ActionContext) => {
151
151
  submitting = true
152
152
  submittedBlock = props.block
153
153
  store.setProcessing(true)
154
- runner.execute(action, ctx, store.state.values)
154
+ // A click that blurred a live field started a refresh: send the state it returns.
155
+ store.whenSettled(() => runner.execute(action, ctx, store.state.values))
155
156
  }
156
157
 
157
158
  // Track this form's own submit visit so unrelated reloads finishing meanwhile (polling,
@@ -1,5 +1,5 @@
1
1
  import type { BaseField, FieldAriaAttributes, FormState, FormStore } from '@alfakit/core'
2
- import { fieldAria, fieldDomId } from '@alfakit/core'
2
+ import { fieldAria, fieldDomId, fieldError } from '@alfakit/core'
3
3
  import {
4
4
  computed,
5
5
  inject,
@@ -70,7 +70,7 @@ export function useField<T = unknown>(field: MaybeRefOrGetter<BaseField>): Field
70
70
  return current as T
71
71
  })
72
72
 
73
- const error = computed(() => state.value.errors[path]?.[0])
73
+ const error = computed(() => fieldError(state.value.errors, path))
74
74
  // Fields stay enabled during a live refresh: the store keeps edits made while the request
75
75
  // is in flight, so locking inputs would only swallow keystrokes.
76
76
  const disabled = computed(() => Boolean(toValue(field).disabled))
@@ -122,9 +122,21 @@ const template = computed(() =>
122
122
  .join(' '),
123
123
  )
124
124
 
125
- const setCard = (key: string) => (element: unknown) => {
126
- if (element instanceof HTMLElement) cards.set(key, element)
127
- else cards.delete(key)
125
+ // A card moved to another column is mounted there before its old element is unmounted, so
126
+ // an unmount only forgets the element it registered itself (else the moved card would lose
127
+ // its entry and the keyboard focus).
128
+ const setCard = (key: string) => {
129
+ let own: HTMLElement | null = null
130
+
131
+ return (element: unknown) => {
132
+ if (element instanceof HTMLElement) {
133
+ own = element
134
+ cards.set(key, element)
135
+ } else if (own !== null) {
136
+ if (cards.get(key) === own) cards.delete(key)
137
+ own = null
138
+ }
139
+ }
128
140
  }
129
141
 
130
142
  const focus = (key: string | undefined) => {
@@ -3,7 +3,7 @@ import type { KanbanColumnSchema } from '@alfakit/core'
3
3
  import { kanbanWipState } from '@alfakit/core'
4
4
  import { ChevronsLeftRightIcon, ChevronsRightLeftIcon, PlusIcon } from '@lucide/vue'
5
5
  import { computed } from 'vue'
6
- import { useT } from '../../context'
6
+ import { useChoice, useT } from '../../context'
7
7
  import { cssColor } from '../../lib/colors'
8
8
  import { Icon } from '../../lib/icons'
9
9
  import { cn } from '../../lib/utils'
@@ -19,6 +19,7 @@ const props = defineProps<{
19
19
  }>()
20
20
  const emit = defineEmits<{ toggle: []; create: [] }>()
21
21
  const t = useT()
22
+ const choice = useChoice()
22
23
 
23
24
  const wip = computed(() => kanbanWipState(props.column))
24
25
  const shown = computed(() =>
@@ -41,7 +42,7 @@ const countLabel = computed(() => {
41
42
  { shown: column.total, count: column.count },
42
43
  ':shown of :count cards',
43
44
  )
44
- : t('kanban.count', { count: column.count }, ':count cards')
45
+ : choice('kanban.count', column.count, {}, '{1} :count card|[0,*] :count cards')
45
46
  })
46
47
  const style = computed(() =>
47
48
  props.column.color ? { borderTopColor: cssColor(props.column.color) } : undefined,
@@ -147,10 +148,11 @@ const addLabel = computed(() =>
147
148
  </p>
148
149
  <p v-if="wip === 'over'" class="text-destructive text-xs">
149
150
  {{
150
- t(
151
+ choice(
151
152
  'kanban.wip_over',
153
+ props.column.wipLimit ?? 0,
152
154
  { limit: props.column.wipLimit ?? 0 },
153
- 'Over the limit of :limit cards',
155
+ '{1} Over the limit of :limit card|[0,*] Over the limit of :limit cards',
154
156
  )
155
157
  }}
156
158
  </p>
@@ -87,11 +87,14 @@ const t = useT()
87
87
  <component
88
88
  :is="heading"
89
89
  v-if="props.component.heading"
90
- class="text-base leading-6 font-semibold"
90
+ class="text-base leading-6 font-semibold break-words"
91
91
  >
92
92
  {{ props.component.heading }}
93
93
  </component>
94
- <p v-if="props.component.description" class="text-muted-foreground mt-1 text-sm">
94
+ <p
95
+ v-if="props.component.description"
96
+ class="text-muted-foreground mt-1 text-sm break-words"
97
+ >
95
98
  {{ props.component.description }}
96
99
  </p>
97
100
  </div>
@@ -188,11 +191,14 @@ const t = useT()
188
191
  <component
189
192
  :is="heading"
190
193
  v-if="props.component.heading"
191
- class="text-base leading-6 font-semibold"
194
+ class="text-base leading-6 font-semibold break-words"
192
195
  >
193
196
  {{ props.component.heading }}
194
197
  </component>
195
- <p v-if="props.component.description" class="text-muted-foreground mt-1 text-sm">
198
+ <p
199
+ v-if="props.component.description"
200
+ class="text-muted-foreground mt-1 text-sm break-words"
201
+ >
196
202
  {{ props.component.description }}
197
203
  </p>
198
204
  </div>
@@ -30,6 +30,7 @@ import CommandEmpty from '../ui/CommandEmpty.vue'
30
30
  import CommandGroup from '../ui/CommandGroup.vue'
31
31
  import CommandInput from '../ui/CommandInput.vue'
32
32
  import CommandItem from '../ui/CommandItem.vue'
33
+ import CommandAutoHighlight from '../ui/CommandAutoHighlight.vue'
33
34
  import CommandList from '../ui/CommandList.vue'
34
35
  import Spinner from '../ui/Spinner.vue'
35
36
  import ShortcutKeys from './ShortcutKeys.vue'
@@ -276,6 +277,7 @@ const hasResults = computed(() => groups.value.length > 0 || local.value.length
276
277
  @update:model-value="query = $event"
277
278
  />
278
279
  <CommandList>
280
+ <CommandAutoHighlight :items="[groups, local, leading]" />
279
281
  <CommandEmpty v-if="!loading && !hasResults">{{
280
282
  query ? t('no_results', {}, 'No results.') : placeholder
281
283
  }}</CommandEmpty>
@@ -6,7 +6,7 @@ import {
6
6
  type RecordKey,
7
7
  } from '@alfakit/core'
8
8
  import { onMounted, onScopeDispose, shallowRef, watch, type ShallowRef } from 'vue'
9
- import { usePollComponent } from '../../context'
9
+ import { usePollComponent, useRefreshComponents } from '../../context'
10
10
 
11
11
  /**
12
12
  * Follow `live()` updates of a table or widget: refresh it in place when its records
@@ -22,6 +22,7 @@ export function useLiveUpdates(
22
22
  },
23
23
  ): { controller: ShallowRef<LiveUpdates | null>; state: ShallowRef<LiveUpdatesState> } {
24
24
  const poll = usePollComponent()
25
+ const refresh = useRefreshComponents()
25
26
  const controller = shallowRef<LiveUpdates | null>(null)
26
27
  const state = shallowRef<LiveUpdatesState>({ pending: 0, connected: false })
27
28
  let stop: (() => void) | null = null
@@ -68,6 +69,7 @@ export function useLiveUpdates(
68
69
  target,
69
70
  polling,
70
71
  poll,
72
+ refresh,
71
73
  })
72
74
 
73
75
  controller.value = next
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import type { ColumnSchema, TableSchema } from '@alfakit/core'
3
- import { ariaSort, columnVisibilityClasses, visitTable } from '@alfakit/core'
3
+ import { ariaSort, columnVisibilityClasses, debounce, visitTable } from '@alfakit/core'
4
4
  import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon } from '@lucide/vue'
5
5
  import { createReusableTemplate } from '@vueuse/core'
6
- import { ref } from 'vue'
6
+ import { onBeforeUnmount, ref } from 'vue'
7
7
  import { useT } from '../../context'
8
8
  import { Icon } from '../../lib/icons'
9
9
  import { cn } from '../../lib/utils'
@@ -47,17 +47,26 @@ const sort = () => {
47
47
  })
48
48
  }
49
49
 
50
+ // The column search applies after the same pause as the table search; Enter applies at once.
51
+ const pushColumnSearch = debounce(
52
+ (value: string) =>
53
+ visitTable(
54
+ props.table.identifier,
55
+ { columnSearch: { ...(props.table.columnSearches ?? {}), [props.column.name]: value } },
56
+ ['page'],
57
+ ),
58
+ props.table.searchDebounce,
59
+ )
60
+
61
+ onBeforeUnmount(() => pushColumnSearch.cancel())
62
+
63
+ const onColumnSearchInput = (value: string) => {
64
+ if (!props.table.searchOnBlur) pushColumnSearch(value)
65
+ }
66
+
50
67
  const columnSearch = (event: Event) => {
51
- visitTable(
52
- props.table.identifier,
53
- {
54
- columnSearch: {
55
- ...(props.table.columnSearches ?? {}),
56
- [props.column.name]: (event.target as HTMLInputElement).value,
57
- },
58
- },
59
- ['page'],
60
- )
68
+ pushColumnSearch((event.target as HTMLInputElement).value)
69
+ pushColumnSearch.flush()
61
70
  }
62
71
  </script>
63
72
 
@@ -138,6 +147,8 @@ const columnSearch = (event: Event) => {
138
147
  :placeholder="t('search', {}, 'Search')"
139
148
  :aria-label="`${t('search', {}, 'Search')} ${props.column.label}`"
140
149
  class="h-7 text-xs font-normal"
150
+ @update:model-value="onColumnSearchInput"
151
+ @blur="props.table.searchOnBlur && columnSearch($event)"
141
152
  @keydown.enter="columnSearch"
142
153
  />
143
154
  </div>