@tulip-systems/core 0.5.2 → 0.5.3

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 (366) hide show
  1. package/dist/components/common/icons.d.mts +2 -2
  2. package/dist/components/common/status.d.mts +3 -3
  3. package/dist/components/editor/components/content.client.d.mts +2 -2
  4. package/dist/components/editor/components/editor.client.d.mts +2 -2
  5. package/dist/components/editor/components/editor.client.mjs +2 -2
  6. package/dist/components/editor/components/editor.client.mjs.map +1 -1
  7. package/dist/components/editor/components/menu.client.d.mts +3 -3
  8. package/dist/components/editor/components/menu.client.mjs +3 -0
  9. package/dist/components/editor/components/menu.client.mjs.map +1 -1
  10. package/dist/components/editor/extensions/file-handler/extension.d.mts +21 -0
  11. package/dist/components/editor/extensions/file-handler/extension.d.mts.map +1 -0
  12. package/dist/components/editor/extensions/file-handler/extension.mjs +40 -0
  13. package/dist/components/editor/extensions/file-handler/extension.mjs.map +1 -0
  14. package/dist/components/editor/extensions/file-handler/strategy.d.mts +29 -0
  15. package/dist/components/editor/extensions/file-handler/strategy.d.mts.map +1 -0
  16. package/dist/components/editor/extensions/file-handler/strategy.mjs +111 -0
  17. package/dist/components/editor/extensions/file-handler/strategy.mjs.map +1 -0
  18. package/dist/components/editor/extensions/file-handler/utils.mjs +50 -0
  19. package/dist/components/editor/extensions/file-handler/utils.mjs.map +1 -0
  20. package/dist/components/editor/extensions/image/extension.d.mts +8 -0
  21. package/dist/components/editor/extensions/image/extension.d.mts.map +1 -0
  22. package/dist/components/editor/extensions/image/extension.mjs +52 -0
  23. package/dist/components/editor/extensions/image/extension.mjs.map +1 -0
  24. package/dist/components/editor/extensions/skeleton/extension.mjs +41 -0
  25. package/dist/components/editor/extensions/skeleton/extension.mjs.map +1 -0
  26. package/dist/components/editor/extensions/skeleton/renderer.mjs +25 -0
  27. package/dist/components/editor/extensions/skeleton/renderer.mjs.map +1 -0
  28. package/dist/components/editor/lib/constants.d.mts +29 -26
  29. package/dist/components/editor/lib/constants.d.mts.map +1 -1
  30. package/dist/components/editor/lib/constants.mjs +14 -2
  31. package/dist/components/editor/lib/constants.mjs.map +1 -1
  32. package/dist/components/editor/lib/extensions.d.mts +5 -1
  33. package/dist/components/editor/lib/extensions.d.mts.map +1 -1
  34. package/dist/components/editor/lib/extensions.mjs.map +1 -1
  35. package/dist/components/editor/lib/variants.mjs +10 -2
  36. package/dist/components/editor/lib/variants.mjs.map +1 -1
  37. package/dist/components/header/back-button.client.d.mts +2 -2
  38. package/dist/components/header/bottom-bar.client.d.mts +3 -3
  39. package/dist/components/header/breadcrumbs.client.d.mts +7 -7
  40. package/dist/components/header/header.client.d.mts +2 -2
  41. package/dist/components/header/mobile-nav-switcher.client.d.mts +2 -2
  42. package/dist/components/header/top-bar.client.d.mts +4 -4
  43. package/dist/components/layouts/admin-content.client.d.mts +2 -2
  44. package/dist/components/layouts/admin-layout.d.mts +2 -2
  45. package/dist/components/layouts/admin-layout.d.mts.map +1 -1
  46. package/dist/components/layouts/admin-loading.d.mts +2 -2
  47. package/dist/components/layouts/empty-page.d.mts +4 -4
  48. package/dist/components/layouts/list-layout.d.mts +2 -2
  49. package/dist/components/layouts/not-found-page.d.mts +3 -3
  50. package/dist/components/layouts/providers.client.d.mts +2 -2
  51. package/dist/components/layouts/root-layout.server.d.mts +2 -2
  52. package/dist/components/layouts/root-loading.d.mts +2 -2
  53. package/dist/components/layouts/tab-layout.d.mts +2 -2
  54. package/dist/components/lists/data-list.d.mts +5 -5
  55. package/dist/components/lists/data-stack.d.mts +8 -8
  56. package/dist/components/lists/data-stack.d.mts.map +1 -1
  57. package/dist/components/navigation/admin-sidebar-paths.client.d.mts +10 -10
  58. package/dist/components/ui/accordion.d.mts +5 -5
  59. package/dist/components/ui/accordion.d.mts.map +1 -1
  60. package/dist/components/ui/alert-dialog.d.mts +12 -12
  61. package/dist/components/ui/alert-dialog.d.mts.map +1 -1
  62. package/dist/components/ui/alert.d.mts +4 -4
  63. package/dist/components/ui/alert.d.mts.map +1 -1
  64. package/dist/components/ui/aspect-ratio.d.mts +2 -2
  65. package/dist/components/ui/aspect-ratio.d.mts.map +1 -1
  66. package/dist/components/ui/avatar.client.d.mts +4 -4
  67. package/dist/components/ui/badge.d.mts +2 -2
  68. package/dist/components/ui/badge.d.mts.map +1 -1
  69. package/dist/components/ui/breadcrumb.d.mts +8 -8
  70. package/dist/components/ui/breadcrumb.d.mts.map +1 -1
  71. package/dist/components/ui/button.d.mts +2 -2
  72. package/dist/components/ui/button.d.mts.map +1 -1
  73. package/dist/components/ui/calendar.d.mts +3 -3
  74. package/dist/components/ui/calendar.d.mts.map +1 -1
  75. package/dist/components/ui/card.d.mts +7 -7
  76. package/dist/components/ui/card.d.mts.map +1 -1
  77. package/dist/components/ui/carousel.d.mts +6 -6
  78. package/dist/components/ui/carousel.d.mts.map +1 -1
  79. package/dist/components/ui/chart.client.d.mts +5 -5
  80. package/dist/components/ui/checkbox.d.mts +2 -2
  81. package/dist/components/ui/checkbox.d.mts.map +1 -1
  82. package/dist/components/ui/collapsible.client.d.mts +4 -4
  83. package/dist/components/ui/color-picker.client.d.mts +2 -2
  84. package/dist/components/ui/combobox-dropdown.client.d.mts +2 -2
  85. package/dist/components/ui/combobox.client.d.mts +2 -2
  86. package/dist/components/ui/command.d.mts +10 -10
  87. package/dist/components/ui/command.d.mts.map +1 -1
  88. package/dist/components/ui/context-menu.d.mts +16 -16
  89. package/dist/components/ui/context-menu.d.mts.map +1 -1
  90. package/dist/components/ui/date-picker.client.d.mts +2 -2
  91. package/dist/components/ui/dialog.client.d.mts +11 -11
  92. package/dist/components/ui/drawer.client.d.mts +11 -11
  93. package/dist/components/ui/dropdown-menu.d.mts +16 -16
  94. package/dist/components/ui/form.client.d.mts +7 -7
  95. package/dist/components/ui/hover-card.client.d.mts +4 -4
  96. package/dist/components/ui/input-recipient.d.mts +2 -2
  97. package/dist/components/ui/input.d.mts +2 -2
  98. package/dist/components/ui/label.d.mts +2 -2
  99. package/dist/components/ui/navigation-menu.d.mts +9 -9
  100. package/dist/components/ui/pagination.d.mts +8 -8
  101. package/dist/components/ui/popover.d.mts +5 -5
  102. package/dist/components/ui/popover.d.mts.map +1 -1
  103. package/dist/components/ui/progress.client.d.mts +2 -2
  104. package/dist/components/ui/radio-group.d.mts +3 -3
  105. package/dist/components/ui/resizable.client.d.mts +4 -4
  106. package/dist/components/ui/scroll-area.d.mts +3 -3
  107. package/dist/components/ui/select.client.d.mts +11 -11
  108. package/dist/components/ui/separator.d.mts +2 -2
  109. package/dist/components/ui/sheet.client.d.mts +9 -9
  110. package/dist/components/ui/sidebar.client.d.mts +24 -24
  111. package/dist/components/ui/skeleton.d.mts +2 -2
  112. package/dist/components/ui/slider.d.mts +2 -2
  113. package/dist/components/ui/sonner.client.d.mts +2 -2
  114. package/dist/components/ui/switch.d.mts +2 -2
  115. package/dist/components/ui/tabs.d.mts +5 -5
  116. package/dist/components/ui/textarea.d.mts +2 -2
  117. package/dist/components/ui/time-input.client.d.mts +2 -2
  118. package/dist/components/ui/toggle-group.client.d.mts +3 -3
  119. package/dist/components/ui/toggle.d.mts +2 -2
  120. package/dist/components/ui/tooltip.client.d.mts +5 -5
  121. package/dist/components.d.mts +2 -1
  122. package/dist/components.mjs +3 -2
  123. package/dist/data-tables.d.mts +2 -2
  124. package/dist/data-tables.mjs +2 -2
  125. package/dist/inline-edit/client.d.mts +2 -3
  126. package/dist/inline-edit/client.mjs +1 -2
  127. package/dist/lib/client.d.mts +2 -2
  128. package/dist/lib/client.mjs +2 -2
  129. package/dist/lib/hooks/use-action.d.mts +2 -2
  130. package/dist/lib/hooks/use-indicator.d.mts +11 -3
  131. package/dist/lib/hooks/use-indicator.d.mts.map +1 -1
  132. package/dist/lib/hooks/use-indicator.mjs +19 -8
  133. package/dist/lib/hooks/use-indicator.mjs.map +1 -1
  134. package/dist/modules/auth/components/allowed.client.d.mts +2 -2
  135. package/dist/modules/auth/components/allowed.client.d.mts.map +1 -1
  136. package/dist/modules/auth/components/auth-layout.server.d.mts +2 -2
  137. package/dist/modules/auth/components/auth-layout.server.d.mts.map +1 -1
  138. package/dist/modules/auth/components/auth-loading.d.mts +2 -2
  139. package/dist/modules/auth/components/create-first-user-page.client.d.mts +2 -2
  140. package/dist/modules/auth/components/create-first-user-page.client.d.mts.map +1 -1
  141. package/dist/modules/auth/components/forget-password-page.client.d.mts +2 -2
  142. package/dist/modules/auth/components/forget-password-page.client.d.mts.map +1 -1
  143. package/dist/modules/auth/components/guard-first-user.server.d.mts +2 -2
  144. package/dist/modules/auth/components/guard-first-user.server.d.mts.map +1 -1
  145. package/dist/modules/auth/components/guard.server.d.mts +2 -2
  146. package/dist/modules/auth/components/guard.server.d.mts.map +1 -1
  147. package/dist/modules/auth/components/login-page.client.d.mts +2 -2
  148. package/dist/modules/auth/components/login-page.client.d.mts.map +1 -1
  149. package/dist/modules/auth/components/reset-password-page.client.d.mts +2 -2
  150. package/dist/modules/auth/components/reset-password-page.client.d.mts.map +1 -1
  151. package/dist/modules/auth/components/update-password-command.d.mts +2 -2
  152. package/dist/modules/auth/components/update-password-command.d.mts.map +1 -1
  153. package/dist/modules/auth/db/schema.d.mts +73 -73
  154. package/dist/modules/auth/db/schema.d.mts.map +1 -1
  155. package/dist/modules/auth/handler/client.client.d.mts +6 -6
  156. package/dist/modules/auth/hooks/use-permission.d.mts +2 -2
  157. package/dist/modules/auth/hooks/use-session.d.mts +4 -4
  158. package/dist/modules/auth/lib/validators.d.mts +2 -2
  159. package/dist/modules/auth/lib/validators.d.mts.map +1 -1
  160. package/dist/modules/commands/components/alert-dialog-command.client.d.mts +10 -10
  161. package/dist/modules/commands/components/alert-dialog-command.client.d.mts.map +1 -1
  162. package/dist/modules/commands/components/click-command.client.d.mts +2 -2
  163. package/dist/modules/commands/components/click-command.client.d.mts.map +1 -1
  164. package/dist/modules/commands/components/command-trigger.client.d.mts +6 -6
  165. package/dist/modules/commands/components/command-trigger.client.d.mts.map +1 -1
  166. package/dist/modules/commands/components/dialog-command.client.d.mts +8 -8
  167. package/dist/modules/commands/components/dialog-command.client.d.mts.map +1 -1
  168. package/dist/modules/commands/components/dropdown-command.client.d.mts +5 -5
  169. package/dist/modules/commands/components/dropdown-command.client.d.mts.map +1 -1
  170. package/dist/modules/commands/components/empty-command.client.d.mts +2 -2
  171. package/dist/modules/commands/components/empty-command.client.d.mts.map +1 -1
  172. package/dist/modules/commands/components/form-dialog-command.client.d.mts +11 -11
  173. package/dist/modules/commands/components/form-dialog-command.client.d.mts.map +1 -1
  174. package/dist/modules/commands/hooks/use-command-mutation.client.d.mts +2 -2
  175. package/dist/modules/commands/menus/context-menu.client.d.mts +2 -2
  176. package/dist/modules/commands/menus/context-menu.client.d.mts.map +1 -1
  177. package/dist/modules/commands/menus/dropdown-menu.client.d.mts +3 -3
  178. package/dist/modules/commands/menus/dropdown-menu.client.d.mts.map +1 -1
  179. package/dist/modules/commands/menus/inline-menu.client.d.mts +3 -3
  180. package/dist/modules/commands/menus/inline-menu.client.d.mts.map +1 -1
  181. package/dist/modules/commands/menus/responsive-menu.client.d.mts +3 -3
  182. package/dist/modules/commands/menus/responsive-menu.client.d.mts.map +1 -1
  183. package/dist/modules/commands/utils/archive-command.client.d.mts +3 -3
  184. package/dist/modules/commands/utils/archive-command.client.d.mts.map +1 -1
  185. package/dist/modules/commands/utils/delete-command.client.d.mts +3 -3
  186. package/dist/modules/commands/utils/delete-command.client.d.mts.map +1 -1
  187. package/dist/modules/config/db/helpers.d.mts +5 -5
  188. package/dist/modules/config/db/helpers.d.mts.map +1 -1
  189. package/dist/modules/data-tables/components/cell/common.client.d.mts +5 -5
  190. package/dist/modules/data-tables/components/column-header.d.mts +2 -2
  191. package/dist/modules/data-tables/components/column-header.d.mts.map +1 -1
  192. package/dist/modules/data-tables/components/filters/combobox.client.d.mts +2 -2
  193. package/dist/modules/data-tables/components/filters/slider.client.d.mts +2 -2
  194. package/dist/modules/data-tables/components/header.d.mts +4 -4
  195. package/dist/modules/data-tables/components/header.d.mts.map +1 -1
  196. package/dist/modules/data-tables/components/layout.d.mts +2 -2
  197. package/dist/modules/data-tables/components/layout.d.mts.map +1 -1
  198. package/dist/modules/data-tables/components/search-input.client.d.mts +2 -2
  199. package/dist/modules/data-tables/components/skeleton.d.mts +2 -2
  200. package/dist/modules/data-tables/components/skeleton.d.mts.map +1 -1
  201. package/dist/modules/data-tables/components/table.d.mts +7 -7
  202. package/dist/modules/data-tables/components/table.d.mts.map +1 -1
  203. package/dist/modules/data-tables/components/toolbar.d.mts +3 -3
  204. package/dist/modules/data-tables/components/toolbar.d.mts.map +1 -1
  205. package/dist/modules/data-tables/hooks/use-context.client.d.mts +2 -2
  206. package/dist/modules/data-tables/lib/filters/parsers.d.mts +6 -1
  207. package/dist/modules/data-tables/lib/filters/parsers.d.mts.map +1 -1
  208. package/dist/modules/data-tables/lib/filters/parsers.mjs +6 -1
  209. package/dist/modules/data-tables/lib/filters/parsers.mjs.map +1 -1
  210. package/dist/modules/data-tables/tables/data-table/components/table.d.mts +2 -2
  211. package/dist/modules/data-tables/tables/inline-table/components/cells/common.d.mts +2 -2
  212. package/dist/modules/data-tables/tables/inline-table/components/cells/drag-handle.client.d.mts +2 -2
  213. package/dist/modules/data-tables/tables/inline-table/components/inputs/advanced-select.client.d.mts +2 -2
  214. package/dist/modules/data-tables/tables/inline-table/components/inputs/combobox.client.d.mts +2 -2
  215. package/dist/modules/data-tables/tables/inline-table/components/inputs/input.client.d.mts +3 -3
  216. package/dist/modules/data-tables/tables/inline-table/components/inputs/read-only.d.mts +2 -2
  217. package/dist/modules/data-tables/tables/inline-table/components/inputs/select.client.d.mts +2 -2
  218. package/dist/modules/data-tables/tables/inline-table/components/table.d.mts +2 -2
  219. package/dist/modules/data-tables/tables/inline-table/hooks/context.client.d.mts +2 -2
  220. package/dist/modules/inline-edit/components/combobox-dropdown.client.d.mts +6 -4
  221. package/dist/modules/inline-edit/components/combobox-dropdown.client.d.mts.map +1 -1
  222. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs +11 -6
  223. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs.map +1 -1
  224. package/dist/modules/inline-edit/components/combobox.client.d.mts +6 -4
  225. package/dist/modules/inline-edit/components/combobox.client.d.mts.map +1 -1
  226. package/dist/modules/inline-edit/components/combobox.client.mjs +7 -5
  227. package/dist/modules/inline-edit/components/combobox.client.mjs.map +1 -1
  228. package/dist/modules/inline-edit/components/date-input.client.d.mts +5 -3
  229. package/dist/modules/inline-edit/components/date-input.client.d.mts.map +1 -1
  230. package/dist/modules/inline-edit/components/date-input.client.mjs +26 -13
  231. package/dist/modules/inline-edit/components/date-input.client.mjs.map +1 -1
  232. package/dist/modules/inline-edit/components/date-picker.client.d.mts +6 -4
  233. package/dist/modules/inline-edit/components/date-picker.client.d.mts.map +1 -1
  234. package/dist/modules/inline-edit/components/date-picker.client.mjs +12 -7
  235. package/dist/modules/inline-edit/components/date-picker.client.mjs.map +1 -1
  236. package/dist/modules/inline-edit/components/editor.client.d.mts +6 -4
  237. package/dist/modules/inline-edit/components/editor.client.d.mts.map +1 -1
  238. package/dist/modules/inline-edit/components/editor.client.mjs +11 -6
  239. package/dist/modules/inline-edit/components/editor.client.mjs.map +1 -1
  240. package/dist/modules/inline-edit/components/input-recipient.client.d.mts +6 -4
  241. package/dist/modules/inline-edit/components/input-recipient.client.d.mts.map +1 -1
  242. package/dist/modules/inline-edit/components/input-recipient.client.mjs +11 -6
  243. package/dist/modules/inline-edit/components/input-recipient.client.mjs.map +1 -1
  244. package/dist/modules/inline-edit/components/input-toggle.client.d.mts +6 -4
  245. package/dist/modules/inline-edit/components/input-toggle.client.d.mts.map +1 -1
  246. package/dist/modules/inline-edit/components/input-toggle.client.mjs +9 -7
  247. package/dist/modules/inline-edit/components/input-toggle.client.mjs.map +1 -1
  248. package/dist/modules/inline-edit/components/input.client.d.mts +13 -10
  249. package/dist/modules/inline-edit/components/input.client.d.mts.map +1 -1
  250. package/dist/modules/inline-edit/components/input.client.mjs +35 -19
  251. package/dist/modules/inline-edit/components/input.client.mjs.map +1 -1
  252. package/dist/modules/inline-edit/components/select.client.d.mts +10 -9
  253. package/dist/modules/inline-edit/components/select.client.d.mts.map +1 -1
  254. package/dist/modules/inline-edit/components/select.client.mjs +14 -7
  255. package/dist/modules/inline-edit/components/select.client.mjs.map +1 -1
  256. package/dist/modules/inline-edit/components/switch.client.d.mts +5 -3
  257. package/dist/modules/inline-edit/components/switch.client.d.mts.map +1 -1
  258. package/dist/modules/inline-edit/components/switch.client.mjs +8 -6
  259. package/dist/modules/inline-edit/components/switch.client.mjs.map +1 -1
  260. package/dist/modules/inline-edit/components/toggle.client.d.mts +6 -4
  261. package/dist/modules/inline-edit/components/toggle.client.d.mts.map +1 -1
  262. package/dist/modules/inline-edit/components/toggle.client.mjs +9 -7
  263. package/dist/modules/inline-edit/components/toggle.client.mjs.map +1 -1
  264. package/dist/modules/inline-edit/hooks/context.client.d.mts +2 -2
  265. package/dist/modules/inline-edit/hooks/context.client.d.mts.map +1 -1
  266. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts +35 -3
  267. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts.map +1 -1
  268. package/dist/modules/inline-edit/hooks/use-inline.client.mjs +71 -9
  269. package/dist/modules/inline-edit/hooks/use-inline.client.mjs.map +1 -1
  270. package/dist/modules/inline-edit/lib/variants.d.mts +1 -0
  271. package/dist/modules/inline-edit/lib/variants.d.mts.map +1 -1
  272. package/dist/modules/inline-edit/lib/variants.mjs +12 -4
  273. package/dist/modules/inline-edit/lib/variants.mjs.map +1 -1
  274. package/dist/modules/router/handler/init.server.d.mts +6 -6
  275. package/dist/modules/router/handler/init.server.d.mts.map +1 -1
  276. package/dist/modules/router/lib/query-client.server.d.mts +2 -2
  277. package/dist/modules/router/lib/query-client.server.d.mts.map +1 -1
  278. package/dist/modules/storage/components/dropzone-context.client.d.mts +2 -2
  279. package/dist/modules/storage/components/dropzone.client.d.mts +5 -5
  280. package/dist/modules/storage/components/dropzone.client.mjs +1 -1
  281. package/dist/modules/storage/components/image-grid.client.d.mts +3 -3
  282. package/dist/modules/storage/components/image-grid.client.mjs +3 -3
  283. package/dist/modules/storage/components/image-grid.client.mjs.map +1 -1
  284. package/dist/modules/storage/components/upload-zone-context.client.d.mts +3 -11
  285. package/dist/modules/storage/components/upload-zone-context.client.d.mts.map +1 -1
  286. package/dist/modules/storage/components/upload-zone-context.client.mjs.map +1 -1
  287. package/dist/modules/storage/components/upload-zone.client.d.mts +10 -33
  288. package/dist/modules/storage/components/upload-zone.client.d.mts.map +1 -1
  289. package/dist/modules/storage/components/upload-zone.client.mjs +19 -93
  290. package/dist/modules/storage/components/upload-zone.client.mjs.map +1 -1
  291. package/dist/modules/storage/config/filters.d.mts +1 -0
  292. package/dist/modules/storage/config/filters.d.mts.map +1 -1
  293. package/dist/modules/storage/config/filters.mjs +1 -0
  294. package/dist/modules/storage/config/filters.mjs.map +1 -1
  295. package/dist/modules/storage/lib/create-upload.client.d.mts +56 -0
  296. package/dist/modules/storage/lib/create-upload.client.d.mts.map +1 -0
  297. package/dist/modules/storage/lib/create-upload.client.mjs +98 -0
  298. package/dist/modules/storage/lib/create-upload.client.mjs.map +1 -0
  299. package/dist/modules/storage/lib/helpers.d.mts +1 -1
  300. package/dist/modules/storage/lib/router.server.d.mts +3265 -2345
  301. package/dist/modules/storage/lib/router.server.d.mts.map +1 -1
  302. package/dist/modules/storage/lib/router.server.mjs +5 -2
  303. package/dist/modules/storage/lib/router.server.mjs.map +1 -1
  304. package/dist/modules/storage/lib/schema.d.mts +124 -90
  305. package/dist/modules/storage/lib/schema.d.mts.map +1 -1
  306. package/dist/modules/storage/lib/schema.mjs +2 -1
  307. package/dist/modules/storage/lib/schema.mjs.map +1 -1
  308. package/dist/modules/storage/lib/service.server.d.mts +31 -42
  309. package/dist/modules/storage/lib/service.server.d.mts.map +1 -1
  310. package/dist/modules/storage/lib/service.server.mjs +5 -5
  311. package/dist/modules/storage/lib/service.server.mjs.map +1 -1
  312. package/dist/modules/storage/lib/validators.d.mts +170 -90
  313. package/dist/modules/storage/lib/validators.d.mts.map +1 -1
  314. package/dist/modules/storage/lib/validators.mjs +2 -1
  315. package/dist/modules/storage/lib/validators.mjs.map +1 -1
  316. package/dist/storage/client.d.mts +2 -1
  317. package/dist/storage/client.mjs +2 -8
  318. package/dist/storage.d.mts +2 -2
  319. package/dist/storage.mjs +1 -1
  320. package/package.json +4 -3
  321. package/src/components/editor/components/editor.client.tsx +7 -2
  322. package/src/components/editor/components/menu.client.tsx +26 -0
  323. package/src/components/editor/extensions/file-handler/extension.ts +69 -0
  324. package/src/components/editor/extensions/file-handler/strategy.ts +167 -0
  325. package/src/components/editor/extensions/file-handler/utils.ts +51 -0
  326. package/src/components/editor/extensions/image/extension.ts +57 -0
  327. package/src/components/editor/extensions/skeleton/extension.ts +35 -0
  328. package/src/components/editor/extensions/skeleton/renderer.tsx +14 -0
  329. package/src/components/editor/lib/constants.ts +16 -2
  330. package/src/components/editor/lib/extensions.ts +4 -1
  331. package/src/components/editor/lib/utils.ts +32 -0
  332. package/src/components/editor/lib/variants.ts +72 -1
  333. package/src/components/entry.ts +2 -1
  334. package/src/lib/hooks/use-indicator.tsx +27 -18
  335. package/src/modules/data-tables/lib/filters/parsers.ts +14 -0
  336. package/src/modules/inline-edit/components/combobox-dropdown.client.tsx +21 -12
  337. package/src/modules/inline-edit/components/combobox.client.tsx +13 -6
  338. package/src/modules/inline-edit/components/date-input.client.tsx +29 -13
  339. package/src/modules/inline-edit/components/date-picker.client.tsx +13 -9
  340. package/src/modules/inline-edit/components/editor.client.tsx +14 -14
  341. package/src/modules/inline-edit/components/input-recipient.client.tsx +15 -8
  342. package/src/modules/inline-edit/components/input-toggle.client.tsx +16 -9
  343. package/src/modules/inline-edit/components/input.client.tsx +38 -24
  344. package/src/modules/inline-edit/components/select.client.tsx +16 -9
  345. package/src/modules/inline-edit/components/switch.client.tsx +10 -6
  346. package/src/modules/inline-edit/components/toggle.client.tsx +13 -9
  347. package/src/modules/inline-edit/entry.client.ts +0 -1
  348. package/src/modules/inline-edit/hooks/use-inline.client copy.tsx +97 -0
  349. package/src/modules/inline-edit/hooks/use-inline.client.tsx +139 -20
  350. package/src/modules/inline-edit/lib/variants.ts +7 -0
  351. package/src/modules/storage/components/image-grid.client.tsx +2 -2
  352. package/src/modules/storage/components/upload-zone-context.client.tsx +3 -4
  353. package/src/modules/storage/components/upload-zone.client.tsx +17 -116
  354. package/src/modules/storage/config/filters.ts +1 -0
  355. package/src/modules/storage/entry.client.ts +2 -1
  356. package/src/modules/storage/lib/create-upload.client.ts +134 -0
  357. package/src/modules/storage/lib/router.server.ts +1 -0
  358. package/src/modules/storage/lib/schema.ts +1 -0
  359. package/src/modules/storage/lib/service.server.ts +10 -4
  360. package/src/modules/storage/lib/validators.ts +1 -0
  361. package/dist/modules/inline-edit/components/deprecated-editor.client.d.mts +0 -21
  362. package/dist/modules/inline-edit/components/deprecated-editor.client.d.mts.map +0 -1
  363. package/dist/modules/inline-edit/components/deprecated-editor.client.mjs +0 -37
  364. package/dist/modules/inline-edit/components/deprecated-editor.client.mjs.map +0 -1
  365. package/dist/storage/client.mjs.map +0 -1
  366. package/src/modules/inline-edit/components/deprecated-editor.client.tsx +0 -48
@@ -7,30 +7,37 @@ import { CheckIcon, XIcon } from "lucide-react";
7
7
  import { ComponentProps, useState } from "react";
8
8
  import { useInlineEdit, useInlineEditOptions } from "../hooks/use-inline.client";
9
9
 
10
- type InlineStringInputToggleProps<TValue> = Omit<ComponentProps<typeof Input>, "type"> &
11
- useInlineEditOptions<TValue>;
10
+ type InlineStringInputToggleProps<Required extends boolean = false> = Omit<
11
+ ComponentProps<typeof Input>,
12
+ "type"
13
+ > &
14
+ useInlineEditOptions<string, Required>;
12
15
 
13
- export function InlineStringInputToggle({
16
+ export function InlineStringInputToggle<Required extends boolean>({
14
17
  initialValue,
15
18
  action,
16
19
  disabled,
17
20
  permission,
21
+ updateStrategy,
22
+ isRequired,
18
23
  className,
19
24
  ...props
20
- }: InlineStringInputToggleProps<string>) {
25
+ }: InlineStringInputToggleProps<Required>) {
21
26
  const [enabled, setEnabled] = useState(!!initialValue);
22
27
 
23
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit({
28
+ const { value, handleChange, handleBlur, isAllowed } = useInlineEdit({
24
29
  initialValue,
25
30
  action,
26
31
  permission,
32
+ updateStrategy,
33
+ isRequired,
27
34
  });
28
35
 
29
36
  function handleToggle() {
30
37
  setEnabled(!enabled);
31
38
  if (!enabled) return;
32
39
 
33
- handleUpdate("");
40
+ handleBlur(null);
34
41
  }
35
42
 
36
43
  const isDisabled = !enabled || disabled || !isAllowed;
@@ -40,10 +47,10 @@ export function InlineStringInputToggle({
40
47
  <Input
41
48
  {...props}
42
49
  type="text"
43
- value={value}
50
+ value={value ?? undefined}
44
51
  disabled={isDisabled}
45
- onChange={(e) => setValue(e.target.value)}
46
- onBlur={(e) => handleUpdate(e.target.value)}
52
+ onChange={(e) => handleChange(e.target.value ? e.target.value : null)}
53
+ onBlur={(e) => handleBlur(e.target.value ? e.target.value : null)}
47
54
  className={cn("border-border/70 hover:border-border w-full", className)}
48
55
  />
49
56
 
@@ -6,39 +6,46 @@ import { ComponentProps } from "react";
6
6
  import { useInlineEdit, type useInlineEditOptions } from "../hooks/use-inline.client";
7
7
  import { inlineEditVariants, InlineEditVariantsProps } from "../lib/variants";
8
8
 
9
- type InlineEditInputProps<TValue> = Omit<ComponentProps<typeof Input>, "type"> &
10
- useInlineEditOptions<TValue> &
9
+ type InlineEditInputProps<TValue, Required extends boolean = false> = Omit<
10
+ ComponentProps<typeof Input>,
11
+ "type"
12
+ > &
13
+ useInlineEditOptions<TValue, Required> &
11
14
  InlineEditVariantsProps;
12
15
 
13
16
  /**
14
17
  * The inline edit string input component.
15
18
  */
16
- export function InlineStringInput({
19
+ export function InlineStringInput<Required extends boolean = false>({
17
20
  initialValue,
18
21
  action,
19
22
  variant,
20
23
  className,
21
24
  permission,
25
+ updateStrategy,
26
+ isRequired,
22
27
  disabled,
23
28
  ...props
24
- }: InlineEditInputProps<string | undefined>) {
25
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit<string | undefined>({
29
+ }: InlineEditInputProps<string, Required>) {
30
+ const { value, handleChange, handleBlur, isAllowed, status } = useInlineEdit({
26
31
  initialValue,
27
32
  action,
28
33
  permission,
34
+ updateStrategy,
35
+ isRequired,
29
36
  });
30
37
 
31
38
  return (
32
39
  <Input
33
40
  {...props}
34
41
  type="text"
35
- value={value}
42
+ value={value ?? undefined}
36
43
  disabled={disabled || !isAllowed}
37
- onChange={(e) => setValue(e.target.value)}
38
- onBlur={(e) => handleUpdate(e.target.value)}
44
+ onChange={(e) => handleChange(e.target.value ? e.target.value : null)}
45
+ onBlur={(e) => handleBlur(e.target.value ? e.target.value : null)}
39
46
  className={cn(
40
47
  "border-border/70 hover:border-border w-full",
41
- inlineEditVariants({ variant }),
48
+ inlineEditVariants({ variant, status }),
42
49
  className,
43
50
  )}
44
51
  />
@@ -48,19 +55,26 @@ export function InlineStringInput({
48
55
  /**
49
56
  * The inline edit number input component.
50
57
  */
51
- export function InlineNumberInput({
58
+ const parseValueAsNumber = (valueAsNumber: number): number | null =>
59
+ !isNaN(Number(valueAsNumber)) ? valueAsNumber : null;
60
+
61
+ export function InlineNumberInput<Required extends boolean = false>({
52
62
  initialValue,
53
63
  action,
54
64
  variant,
55
65
  className,
56
66
  permission,
67
+ updateStrategy,
68
+ isRequired,
57
69
  disabled,
58
70
  ...props
59
- }: InlineEditInputProps<number | undefined>) {
60
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit<number | undefined>({
71
+ }: InlineEditInputProps<number, Required>) {
72
+ const { value, handleChange, handleBlur, isAllowed, status } = useInlineEdit({
61
73
  initialValue,
62
74
  action,
63
75
  permission,
76
+ updateStrategy,
77
+ isRequired,
64
78
  });
65
79
 
66
80
  return (
@@ -69,15 +83,11 @@ export function InlineNumberInput({
69
83
  type="number"
70
84
  value={value ?? undefined}
71
85
  disabled={disabled || !isAllowed}
72
- onChange={(e) =>
73
- setValue(!isNaN(e.target.valueAsNumber) ? e.target.valueAsNumber : undefined)
74
- }
75
- onBlur={(e) =>
76
- handleUpdate(!isNaN(e.target.valueAsNumber) ? e.target.valueAsNumber : undefined)
77
- }
86
+ onChange={(e) => handleChange(parseValueAsNumber(e.target.valueAsNumber))}
87
+ onBlur={(e) => handleBlur(parseValueAsNumber(e.target.valueAsNumber))}
78
88
  className={cn(
79
89
  "border-border/70 hover:border-border w-full",
80
- inlineEditVariants({ variant }),
90
+ inlineEditVariants({ variant, status }),
81
91
  className,
82
92
  )}
83
93
  />
@@ -93,13 +103,17 @@ export function InlineDecimalInput({
93
103
  variant,
94
104
  className,
95
105
  permission,
106
+ updateStrategy,
107
+ isRequired,
96
108
  disabled,
97
109
  ...props
98
- }: InlineEditInputProps<string | undefined>) {
99
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit<string | undefined>({
110
+ }: InlineEditInputProps<string>) {
111
+ const { value, handleChange, handleBlur, isAllowed, status } = useInlineEdit({
100
112
  initialValue,
101
113
  action,
102
114
  permission,
115
+ updateStrategy,
116
+ isRequired,
103
117
  });
104
118
 
105
119
  return (
@@ -108,11 +122,11 @@ export function InlineDecimalInput({
108
122
  type="number"
109
123
  value={value ?? undefined}
110
124
  disabled={disabled || !isAllowed}
111
- onChange={(e) => setValue(e.target.value)}
112
- onBlur={(e) => handleUpdate(e.target.value ? e.target.value : undefined)}
125
+ onChange={(e) => handleChange(e.target.value ? e.target.value : null)}
126
+ onBlur={(e) => handleBlur(e.target.value ? e.target.value : null)}
113
127
  className={cn(
114
128
  "border-border/70 hover:border-border w-full",
115
- inlineEditVariants({ variant }),
129
+ inlineEditVariants({ variant, status }),
116
130
  className,
117
131
  )}
118
132
  />
@@ -7,6 +7,7 @@ import {
7
7
  SelectTrigger,
8
8
  SelectValue,
9
9
  } from "@/components/ui/select.client";
10
+ import { useIndicator } from "@/lib/entry.client";
10
11
  import { cn } from "@/lib/utils/cn";
11
12
  import type {
12
13
  SelectContentProps,
@@ -18,29 +19,31 @@ import type {
18
19
  import { useInlineEdit, type useInlineEditOptions } from "../hooks/use-inline.client";
19
20
  import { inlineEditVariants, InlineEditVariantsProps } from "../lib/variants";
20
21
 
21
- export type InlineSelectProps = SelectProps & useInlineEditOptions<string>;
22
-
23
- export function InlineSelect({
22
+ export function InlineSelect<Required extends boolean = false>({
24
23
  initialValue,
25
24
  action,
26
25
  permission,
26
+ updateStrategy,
27
+ isRequired,
27
28
  disabled,
28
29
  ...props
29
- }: InlineSelectProps) {
30
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit({
30
+ }: SelectProps & useInlineEditOptions<string, Required>) {
31
+ const { value, handleChange, handleBlur, isAllowed } = useInlineEdit({
31
32
  initialValue,
32
33
  action,
33
34
  permission,
35
+ updateStrategy,
36
+ isRequired,
34
37
  });
35
38
 
36
39
  return (
37
40
  <Select
38
41
  {...props}
39
42
  disabled={disabled || !isAllowed}
40
- defaultValue={value}
43
+ defaultValue={value ?? undefined}
41
44
  onValueChange={(value) => {
42
- setValue(value);
43
- handleUpdate(value);
45
+ handleChange(value ? value : null);
46
+ handleBlur(value ? value : null);
44
47
  }}
45
48
  />
46
49
  );
@@ -53,7 +56,11 @@ export function InlineSelectTrigger({
53
56
  className,
54
57
  ...props
55
58
  }: InlineSelectTriggerProps & InlineEditVariantsProps) {
56
- return <SelectTrigger {...props} className={cn(inlineEditVariants({ variant }), className)} />;
59
+ const { status } = useIndicator();
60
+
61
+ return (
62
+ <SelectTrigger {...props} className={cn(inlineEditVariants({ variant, status }), className)} />
63
+ );
57
64
  }
58
65
 
59
66
  export type InlineSelectContentProps = SelectContentProps;
@@ -4,27 +4,31 @@ import { Switch } from "@/components/ui/switch";
4
4
  import { type SwitchProps } from "@radix-ui/react-switch";
5
5
  import { useInlineEdit, type useInlineEditOptions } from "../hooks/use-inline.client";
6
6
 
7
- export function InlineSwitch({
7
+ export function InlineSwitch<Required extends boolean = false>({
8
8
  initialValue,
9
9
  action,
10
10
  permission,
11
+ updateStrategy,
12
+ isRequired,
11
13
  disabled,
12
14
  ...props
13
- }: SwitchProps & useInlineEditOptions<boolean>) {
14
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit({
15
+ }: SwitchProps & useInlineEditOptions<boolean, Required>) {
16
+ const { value, handleChange, handleBlur, isAllowed } = useInlineEdit({
15
17
  initialValue,
16
18
  action,
17
19
  permission,
20
+ updateStrategy,
21
+ isRequired,
18
22
  });
19
23
 
20
24
  return (
21
25
  <Switch
22
26
  {...props}
23
27
  disabled={disabled || !isAllowed}
24
- defaultChecked={value}
28
+ defaultChecked={value ?? undefined}
25
29
  onCheckedChange={(checked) => {
26
- setValue(checked);
27
- handleUpdate(checked);
30
+ handleChange(checked ?? null);
31
+ handleBlur(checked ?? null);
28
32
  }}
29
33
  />
30
34
  );
@@ -5,21 +5,25 @@ import { cn } from "@/lib/utils/cn";
5
5
  import type React from "react";
6
6
  import { useInlineEdit, type useInlineEditOptions } from "../hooks/use-inline.client";
7
7
 
8
- export type InlineEditToggleProps = React.HTMLAttributes<HTMLDivElement> &
9
- useInlineEditOptions<boolean>;
8
+ export type InlineEditToggleProps<Required extends boolean = false> =
9
+ React.HTMLAttributes<HTMLDivElement> & useInlineEditOptions<boolean, Required>;
10
10
 
11
- export function InlineToggle({
11
+ export function InlineToggle<Required extends boolean = false>({
12
12
  initialValue,
13
13
  action,
14
14
  children,
15
15
  permission,
16
+ updateStrategy,
17
+ isRequired,
16
18
  className,
17
19
  ...props
18
- }: InlineEditToggleProps) {
19
- const { value, setValue, handleUpdate, isAllowed } = useInlineEdit({
20
+ }: InlineEditToggleProps<Required>) {
21
+ const { value, handleChange, handleBlur, isAllowed } = useInlineEdit({
20
22
  initialValue,
21
23
  action,
22
24
  permission,
25
+ updateStrategy,
26
+ isRequired,
23
27
  });
24
28
 
25
29
  return (
@@ -27,11 +31,11 @@ export function InlineToggle({
27
31
  <Toggle
28
32
  disabled={!isAllowed}
29
33
  variant="outline"
30
- pressed={value}
31
- defaultChecked={initialValue}
34
+ pressed={value ?? undefined}
35
+ defaultChecked={initialValue ?? undefined}
32
36
  onPressedChange={(value) => {
33
- setValue(value);
34
- handleUpdate(value);
37
+ handleChange(value);
38
+ handleBlur(value);
35
39
  }}
36
40
  >
37
41
  {children}
@@ -2,7 +2,6 @@ export * from "./components/combobox-dropdown.client";
2
2
  export * from "./components/combobox.client";
3
3
  export * from "./components/date-input.client";
4
4
  export * from "./components/date-picker.client";
5
- export * from "./components/deprecated-editor.client";
6
5
  export * from "./components/editor.client";
7
6
  export * from "./components/input-recipient.client";
8
7
  export * from "./components/input-toggle.client";
@@ -0,0 +1,97 @@
1
+ "use client";
2
+
3
+ import { EditorJSONContent } from "@/components/entry";
4
+ import { useAction } from "@/lib/hooks/use-action";
5
+ import { usePermission } from "@/modules/auth/hooks/use-permission";
6
+ import { Permission } from "@/modules/auth/lib/permissions";
7
+ import { useState } from "react";
8
+ import { toast } from "sonner";
9
+ import { useInlineEditContext } from "./context.client";
10
+
11
+ type UpdateStrategy = {
12
+ trigger: "change" | "blur";
13
+ delay?: number;
14
+ };
15
+
16
+ const defaultUpdateStrategy: UpdateStrategy = {
17
+ trigger: "blur",
18
+ };
19
+
20
+ export type useInlineEditOptions<TValue> = {
21
+ initialValue?: TValue;
22
+ action: (value: { id: string; value: TValue }) => Promise<unknown>;
23
+ permission?: Permission;
24
+ /**
25
+ * Update strategy
26
+ * - trigger: when to update the value (default: "blur")
27
+ * - delay: delay in milliseconds before updating the value (only for "change" trigger)
28
+ * @default { trigger: "blur" }
29
+ */
30
+ updateStrategy?: UpdateStrategy;
31
+ };
32
+
33
+ export function useInlineEdit<
34
+ TValue extends string | number | Date | boolean | JSON | EditorJSONContent | undefined,
35
+ >(props: useInlineEditOptions<TValue>) {
36
+ const strategy = props.updateStrategy ?? defaultUpdateStrategy;
37
+ /**
38
+ * The inline edit context.
39
+ */
40
+ const context = useInlineEditContext();
41
+
42
+ const { data } = usePermission(props.permission ?? context.permission);
43
+ const isAllowed = data?.success;
44
+
45
+ /**
46
+ * The current value of the inline edit.
47
+ */
48
+ const [value, setValue] = useState(props.initialValue);
49
+
50
+ /**
51
+ * Execute the action to update the value.
52
+ */
53
+ const { mutate, status } = useAction({
54
+ mutationFn: props.action,
55
+ onError: (error) => {
56
+ setValue(props.initialValue);
57
+ toast.error("Er is iets misgegaan", {
58
+ description: error instanceof Error ? error.message : undefined,
59
+ });
60
+ },
61
+ });
62
+
63
+ /**
64
+ * Handle the update of the value.
65
+ */
66
+ const handleUpdate = (value: TValue) => {
67
+ if (!isAllowed) {
68
+ toast.error("Je hebt geen toestemming om dit te bewerken");
69
+ return;
70
+ }
71
+
72
+ // If the value is the same as the initial value, do nothing
73
+ if (value === props.initialValue) return;
74
+
75
+ return mutate({ id: context.id, value });
76
+ };
77
+
78
+ /**
79
+ * Handle change updates
80
+ */
81
+ function handleChange(value: TValue) {
82
+ setValue(value);
83
+
84
+ // if the strategy is change, update the value after the delay
85
+ }
86
+
87
+ /**
88
+ * Handle blur updates
89
+ */
90
+ function handleBlur(value: TValue) {
91
+ setValue(value);
92
+
93
+ // if the strategy is blur, update the value
94
+ }
95
+
96
+ return { value, setValue, handleUpdate, status, isAllowed };
97
+ }
@@ -1,40 +1,105 @@
1
1
  "use client";
2
2
 
3
3
  import { EditorJSONContent } from "@/components/entry";
4
+ import { useLocalIndicator } from "@/lib/entry.client";
4
5
  import { useAction } from "@/lib/hooks/use-action";
5
6
  import { usePermission } from "@/modules/auth/hooks/use-permission";
6
7
  import { Permission } from "@/modules/auth/lib/permissions";
7
- import { useState } from "react";
8
+ import { useCallback, useState } from "react";
8
9
  import { toast } from "sonner";
10
+ import { useDebouncedCallback } from "use-debounce";
9
11
  import { useInlineEditContext } from "./context.client";
10
12
 
11
- export type useInlineEditOptions<TValue> = {
12
- initialValue?: TValue;
13
- action: (value: { id: string; value: TValue }) => Promise<unknown>;
13
+ type UpdateStrategy =
14
+ | {
15
+ mode: "change";
16
+ delay?: number;
17
+ }
18
+ | {
19
+ mode: "blur";
20
+ };
21
+
22
+ const defaultUpdateStrategy: UpdateStrategy = {
23
+ mode: "blur",
24
+ };
25
+
26
+ type MaybeValue<TValue, Required extends boolean> = Required extends true ? TValue : TValue | null;
27
+
28
+ /**
29
+ * Use the inline edit hook options.
30
+ */
31
+ export type useInlineEditOptions<TValue, Required extends boolean = false> = {
32
+ /**
33
+ * Initial value
34
+ */
35
+ initialValue?: MaybeValue<TValue, Required>;
36
+ /**
37
+ * Action to execute on update
38
+ */
39
+ action: (value: { id: string; value: MaybeValue<TValue, Required> }) => Promise<unknown>;
40
+ /**
41
+ * Permission required to edit
42
+ */
14
43
  permission?: Permission;
44
+ /**
45
+ * Update strategy
46
+ * - trigger: when to update the value (default: "blur")
47
+ * - delay: delay in milliseconds before updating the value (only for "change" trigger)
48
+ * @default { trigger: "blur" }
49
+ */
50
+ updateStrategy?: UpdateStrategy;
51
+ /**
52
+ * Is the value required
53
+ * @default false
54
+ */
55
+ isRequired?: Required;
15
56
  };
16
57
 
58
+ /**
59
+ * Use the inline edit hook.
60
+ */
17
61
  export function useInlineEdit<
18
- TValue extends string | number | Date | boolean | JSON | EditorJSONContent | undefined,
19
- >(props: useInlineEditOptions<TValue>) {
62
+ TValue extends string | number | Date | boolean | JSON | EditorJSONContent,
63
+ Required extends boolean = false,
64
+ >(props: useInlineEditOptions<TValue, Required>) {
65
+ /**
66
+ * The update strategy.
67
+ */
68
+ const strategy = props.updateStrategy ?? defaultUpdateStrategy;
69
+ const delay = strategy.mode === "change" ? (strategy.delay ?? 0) : 0;
70
+
20
71
  /**
21
72
  * The inline edit context.
22
73
  */
23
74
  const context = useInlineEditContext();
24
75
 
25
- const { data } = usePermission(props.permission ?? context.permission);
26
- const isAllowed = data?.success;
27
-
28
76
  /**
29
77
  * The current value of the inline edit.
30
78
  */
31
- const [value, setValue] = useState(props.initialValue);
79
+ const [value, setValue] = useState<MaybeValue<TValue, Required> | undefined>(props.initialValue);
80
+
81
+ /**
82
+ * The indicator status.
83
+ */
84
+ const { status, setStatus } = useLocalIndicator();
85
+
86
+ /**
87
+ * Permission guard
88
+ */
89
+ const { data } = usePermission(props.permission ?? context.permission);
90
+ const isAllowed = data?.success;
32
91
 
33
92
  /**
34
93
  * Execute the action to update the value.
35
94
  */
36
- const { mutate, status } = useAction({
95
+ const mutation = useAction({
37
96
  mutationFn: props.action,
97
+ onMutate: () => {
98
+ setStatus("pending");
99
+ },
100
+ onSuccess: () => {
101
+ setStatus("success");
102
+ },
38
103
  onError: (error) => {
39
104
  setValue(props.initialValue);
40
105
  toast.error("Er is iets misgegaan", {
@@ -44,19 +109,73 @@ export function useInlineEdit<
44
109
  });
45
110
 
46
111
  /**
47
- * Handle the update of the value.
112
+ * Handle instant mutate
113
+ */
114
+ const handleMutateInstant = useCallback(
115
+ (value: MaybeValue<TValue, Required>) => {
116
+ // Permission guard
117
+ if (!isAllowed) {
118
+ toast.error("Je hebt geen toestemming om dit te bewerken");
119
+ return;
120
+ }
121
+
122
+ // If the value is the same as the initial value, do nothing
123
+ if (value === props.initialValue) return;
124
+
125
+ // Update the value
126
+ return mutation.mutate({ id: context.id, value });
127
+ },
128
+ [isAllowed, props.initialValue, mutation, context.id],
129
+ );
130
+
131
+ /**
132
+ * Handle mutate with debounce
48
133
  */
49
- const handleUpdate = (value: TValue) => {
50
- if (!isAllowed) {
51
- toast.error("Je hebt geen toestemming om dit te bewerken");
134
+ const handleMutateDebounced = useDebouncedCallback(handleMutateInstant, delay);
135
+
136
+ /**
137
+ * Handle change updates
138
+ */
139
+ function handleChange(next: MaybeValue<TValue, Required> | null) {
140
+ // Set value in state
141
+ setValue(next ?? undefined);
142
+
143
+ // If the strategy is not change, exit
144
+ if (strategy.mode !== "change") return;
145
+
146
+ // If it is required and the value is null or empty, reset to initial value
147
+ if (props.isRequired && next === null) {
148
+ setValue(props.initialValue ?? undefined);
149
+ setStatus("error");
150
+ toast.error("Dit veld is verplicht");
52
151
  return;
53
152
  }
54
153
 
55
- // If the value is the same as the initial value, do nothing
56
- if (value === props.initialValue) return;
154
+ // If the strategy is change, update the value after the delay
155
+ handleMutateDebounced(next as MaybeValue<TValue, Required>);
156
+ }
157
+
158
+ /**
159
+ * Handle blur updates
160
+ */
161
+ function handleBlur(next: MaybeValue<TValue, Required> | null) {
162
+ // Set value in state
163
+ setValue(next ?? undefined);
164
+
165
+ // If the strategy is not blur, exit
166
+ if (strategy.mode !== "blur") return;
167
+
168
+ // If it is required and the value is null or empty, reset to initial value
169
+ if (props.isRequired && next === null) {
170
+ setValue(props.initialValue ?? undefined);
171
+ setStatus("error");
172
+ toast.error("Dit veld is verplicht");
173
+ return;
174
+ }
57
175
 
58
- return mutate({ id: context.id, value });
59
- };
176
+ // If the strategy is blur, update the value
177
+ handleMutateInstant(next as MaybeValue<TValue, Required>);
178
+ }
60
179
 
61
- return { value, setValue, handleUpdate, status, isAllowed };
180
+ return { value, setValue, handleChange, handleBlur, status, isAllowed };
62
181
  }
@@ -7,9 +7,16 @@ export const inlineEditVariants = cva("", {
7
7
  table:
8
8
  "min-h-9 px-3 py-1 text-base md:text-sm rounded-none h-full w-full border-none outline-none ring-0 focus:border-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0",
9
9
  },
10
+ status: {
11
+ idle: "",
12
+ pending: "opacity-70 animate-pulse",
13
+ success: "",
14
+ error: "border-destructive text-destructive",
15
+ },
10
16
  },
11
17
  defaultVariants: {
12
18
  variant: "default",
19
+ // status: "idle",
13
20
  },
14
21
  });
15
22
 
@@ -156,7 +156,7 @@ type ImageGridItemProps = {
156
156
  };
157
157
 
158
158
  function ImageGridItem({ node, index, setCurrent }: ImageGridItemProps) {
159
- const { deleteMutation } = useUploadZone();
159
+ const { uploadClient } = useUploadZone();
160
160
 
161
161
  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: node.id });
162
162
 
@@ -198,7 +198,7 @@ function ImageGridItem({ node, index, setCurrent }: ImageGridItemProps) {
198
198
  type="button"
199
199
  variant="destructive"
200
200
  size="icon"
201
- onClick={() => deleteMutation({ ids: [node.id] })}
201
+ onClick={() => uploadClient.deleteFiles([node.id])}
202
202
  className="absolute left-2 top-2 hidden p-1 group-hover:flex"
203
203
  >
204
204
  <Icons.trash className="size-4" />