includio-cms 0.1.4 → 0.5.1

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 (310) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/ROADMAP.md +26 -13
  3. package/dist/admin/api/accept-invite.js +1 -5
  4. package/dist/admin/api/invite.js +7 -16
  5. package/dist/admin/client/account/account-page.svelte +20 -50
  6. package/dist/admin/client/account/lang.d.ts +15 -23
  7. package/dist/admin/client/account/lang.js +51 -67
  8. package/dist/admin/client/account/preferences-section.svelte +26 -84
  9. package/dist/admin/client/account/profile-section.svelte +60 -40
  10. package/dist/admin/client/account/schema.d.ts +11 -3
  11. package/dist/admin/client/account/schema.js +25 -16
  12. package/dist/admin/client/account/security-section.svelte +139 -105
  13. package/dist/admin/client/account/sessions-section.svelte +35 -34
  14. package/dist/admin/client/admin/admin-after-login-layout-content.svelte +3 -5
  15. package/dist/admin/client/admin/admin-layout.svelte +3 -2
  16. package/dist/admin/client/admin/admin-preloader.svelte +36 -0
  17. package/dist/admin/client/admin/admin-preloader.svelte.d.ts +18 -0
  18. package/dist/admin/client/admin/dashboard-page.svelte +35 -67
  19. package/dist/admin/client/collection/a11y-score-cell.svelte +45 -0
  20. package/dist/admin/client/collection/a11y-score-cell.svelte.d.ts +6 -0
  21. package/dist/admin/client/collection/bulk-actions-bar.svelte +100 -0
  22. package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +10 -0
  23. package/dist/admin/client/collection/collection-entries.svelte +277 -258
  24. package/dist/admin/client/collection/collection-view.svelte.d.ts +4 -3
  25. package/dist/admin/client/collection/collection-view.svelte.js +9 -5
  26. package/dist/admin/client/collection/collection.svelte +22 -12
  27. package/dist/admin/client/collection/data-table.svelte +50 -39
  28. package/dist/admin/client/collection/data-table.svelte.d.ts +1 -0
  29. package/dist/admin/client/collection/date-cell.svelte +7 -5
  30. package/dist/admin/client/collection/date-cell.svelte.d.ts +1 -1
  31. package/dist/admin/client/collection/empty-state.svelte +28 -0
  32. package/dist/admin/client/collection/empty-state.svelte.d.ts +9 -0
  33. package/dist/admin/client/collection/entry-link.svelte +10 -4
  34. package/dist/admin/client/collection/entry-link.svelte.d.ts +1 -0
  35. package/dist/admin/client/collection/grid-view.svelte +21 -23
  36. package/dist/admin/client/collection/grid-view.svelte.d.ts +1 -2
  37. package/dist/admin/client/collection/row-actions.svelte +69 -0
  38. package/dist/admin/client/collection/row-actions.svelte.d.ts +10 -0
  39. package/dist/admin/client/collection/status-badge.svelte +7 -8
  40. package/dist/admin/client/collection/table-pagination.svelte +122 -79
  41. package/dist/admin/client/collection/table-pagination.svelte.d.ts +1 -0
  42. package/dist/admin/client/collection/table-toolbar.svelte +108 -88
  43. package/dist/admin/client/collection/table-toolbar.svelte.d.ts +8 -9
  44. package/dist/admin/client/entry/entry-form.svelte +109 -1
  45. package/dist/admin/client/entry/entry-header.svelte +143 -37
  46. package/dist/admin/client/entry/entry-header.svelte.d.ts +8 -0
  47. package/dist/admin/client/entry/entry.svelte +272 -61
  48. package/dist/admin/client/entry/header/a11y-validator.d.ts +47 -0
  49. package/dist/admin/client/entry/header/a11y-validator.js +352 -0
  50. package/dist/admin/client/entry/header/publish-panel.svelte +531 -129
  51. package/dist/admin/client/entry/header/publish-panel.svelte.d.ts +4 -0
  52. package/dist/admin/client/entry/header/save-indicator.svelte +33 -23
  53. package/dist/admin/client/entry/header/schedule-popover.svelte +1 -1
  54. package/dist/admin/client/entry/header/status-badge.svelte +25 -118
  55. package/dist/admin/client/entry/header/version-history-sheet.svelte +322 -98
  56. package/dist/admin/client/form/form-submission/form-submission.svelte +271 -83
  57. package/dist/admin/client/form/form-submission/submission-field.svelte +12 -12
  58. package/dist/admin/client/form/form-submissions.svelte +421 -139
  59. package/dist/admin/client/form/submission-link.svelte +8 -2
  60. package/dist/admin/client/form/submission-link.svelte.d.ts +1 -0
  61. package/dist/admin/client/form/submission-status-badge.svelte +18 -4
  62. package/dist/admin/client/form/submission-status-badge.svelte.d.ts +1 -0
  63. package/dist/admin/client/login/lang.d.ts +32 -0
  64. package/dist/admin/client/login/lang.js +66 -2
  65. package/dist/admin/client/login/login-form.svelte +237 -95
  66. package/dist/admin/client/login/login-form.svelte.d.ts +2 -17
  67. package/dist/admin/client/login/login-page.svelte +34 -98
  68. package/dist/admin/client/login/reset-password-page.svelte +235 -0
  69. package/dist/admin/client/login/reset-password-page.svelte.d.ts +4 -0
  70. package/dist/admin/client/login/schema.d.ts +15 -0
  71. package/dist/admin/client/login/schema.js +21 -0
  72. package/dist/admin/client/users/accept-invite-page.svelte +166 -37
  73. package/dist/admin/client/users/create-user-dialog.svelte +15 -7
  74. package/dist/admin/client/users/delete-user-dialog.svelte +81 -16
  75. package/dist/admin/client/users/delete-user-dialog.svelte.d.ts +4 -1
  76. package/dist/admin/client/users/edit-user-dialog.svelte +3 -0
  77. package/dist/admin/client/users/invite-user-dialog.svelte +16 -3
  78. package/dist/admin/client/users/lang.d.ts +27 -0
  79. package/dist/admin/client/users/lang.js +64 -10
  80. package/dist/admin/client/users/pending-invitations.svelte +59 -23
  81. package/dist/admin/client/users/users-page.svelte +471 -72
  82. package/dist/admin/components/accessibility/accessibility-overview.svelte +2 -7
  83. package/dist/admin/components/dashboard/a11y-gauge.svelte +90 -0
  84. package/dist/admin/components/dashboard/a11y-gauge.svelte.d.ts +18 -0
  85. package/dist/admin/components/dashboard/accessibility-hub.svelte +13 -12
  86. package/dist/admin/components/dashboard/changelog-dialog.svelte +157 -0
  87. package/dist/admin/components/dashboard/changelog-dialog.svelte.d.ts +6 -0
  88. package/dist/admin/components/dashboard/form-submissions-widget.svelte +71 -113
  89. package/dist/admin/components/dashboard/index.d.ts +4 -2
  90. package/dist/admin/components/dashboard/index.js +4 -2
  91. package/dist/admin/components/dashboard/orphaned-entries-notice.svelte +240 -0
  92. package/dist/admin/components/dashboard/orphaned-entries-notice.svelte.d.ts +13 -0
  93. package/dist/admin/components/dashboard/recent-activity.svelte +53 -75
  94. package/dist/admin/components/dashboard/recent-entries.svelte +94 -0
  95. package/dist/admin/components/dashboard/recent-entries.svelte.d.ts +18 -0
  96. package/dist/admin/components/dashboard/stat-card.svelte +2 -2
  97. package/dist/admin/components/dashboard/tip-of-the-day.svelte +109 -0
  98. package/dist/admin/components/dashboard/tip-of-the-day.svelte.d.ts +3 -0
  99. package/dist/admin/components/dashboard/welcome-header.svelte +45 -0
  100. package/dist/admin/components/dashboard/welcome-header.svelte.d.ts +3 -0
  101. package/dist/admin/components/fields/{array-field.svelte → blocks-field.svelte} +4 -4
  102. package/dist/admin/components/fields/{array-field.svelte.d.ts → blocks-field.svelte.d.ts} +5 -5
  103. package/dist/admin/components/fields/content-field.svelte +27 -0
  104. package/dist/admin/components/fields/content-field.svelte.d.ts +31 -0
  105. package/dist/admin/components/fields/field-renderer.svelte +9 -7
  106. package/dist/admin/components/fields/image-field.svelte +2 -2
  107. package/dist/admin/components/fields/media-field.svelte +2 -2
  108. package/dist/admin/components/fields/seo-field.svelte +205 -25
  109. package/dist/admin/components/fields/simple-array-field.svelte +289 -0
  110. package/dist/admin/components/fields/simple-array-field.svelte.d.ts +30 -0
  111. package/dist/admin/components/fields/slug-field.svelte +3 -2
  112. package/dist/admin/components/fields/standalone-field-renderer.svelte +148 -0
  113. package/dist/admin/components/fields/standalone-field-renderer.svelte.d.ts +9 -0
  114. package/dist/admin/components/fields/text-field-wrapper.svelte +147 -3
  115. package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
  116. package/dist/admin/components/fields/url-field.svelte +5 -4
  117. package/dist/admin/components/layout/app-sidebar.svelte +27 -24
  118. package/dist/admin/components/layout/lang.d.ts +6 -0
  119. package/dist/admin/components/layout/lang.js +13 -1
  120. package/dist/admin/components/layout/layout-renderer.svelte +352 -0
  121. package/dist/admin/components/layout/layout-renderer.svelte.d.ts +14 -0
  122. package/dist/admin/components/layout/nav-breadcrumbs.svelte +4 -4
  123. package/dist/admin/components/layout/nav-collections.svelte +65 -36
  124. package/dist/admin/components/layout/nav-footer.svelte +38 -0
  125. package/dist/admin/components/layout/nav-footer.svelte.d.ts +3 -0
  126. package/dist/admin/components/layout/nav-forms.svelte +55 -30
  127. package/dist/admin/components/layout/nav-main.svelte +14 -52
  128. package/dist/admin/components/layout/nav-search.svelte +4 -3
  129. package/dist/admin/components/layout/nav-singletons.svelte +59 -17
  130. package/dist/admin/components/layout/nav-singletons.svelte.d.ts +17 -8
  131. package/dist/admin/components/layout/site-header.svelte +74 -13
  132. package/dist/admin/components/media/alt-input.svelte +32 -22
  133. package/dist/admin/components/media/bulk-action-bar.svelte +139 -150
  134. package/dist/admin/components/media/file/file-details.svelte +299 -217
  135. package/dist/admin/components/media/file/file-miniature.svelte +54 -41
  136. package/dist/admin/components/media/file/file-miniature.svelte.d.ts +1 -0
  137. package/dist/admin/components/media/file/file-preview.svelte +1 -1
  138. package/dist/admin/components/media/file-upload.svelte +24 -26
  139. package/dist/admin/components/media/files-list.svelte +112 -40
  140. package/dist/admin/components/media/files-list.svelte.d.ts +2 -0
  141. package/dist/admin/components/media/focal-point-input.svelte +122 -26
  142. package/dist/admin/components/media/media-library.svelte +127 -70
  143. package/dist/admin/components/media/media-search.svelte +6 -6
  144. package/dist/admin/components/media/media-sort.svelte +3 -1
  145. package/dist/admin/components/media/multi-file-summary.svelte +88 -68
  146. package/dist/admin/components/media/tag-combobox.svelte +141 -66
  147. package/dist/admin/components/media/tag-combobox.svelte.d.ts +1 -0
  148. package/dist/admin/components/media/tag-sidebar.svelte +139 -121
  149. package/dist/admin/components/tiptap/FigureNodeView.svelte +144 -15
  150. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +254 -0
  151. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte.d.ts +4 -0
  152. package/dist/admin/components/tiptap/SlashCommandPopup.svelte +212 -0
  153. package/dist/admin/components/tiptap/SlashCommandPopup.svelte.d.ts +8 -0
  154. package/dist/admin/components/tiptap/content-editor.svelte +280 -0
  155. package/dist/admin/components/tiptap/content-editor.svelte.d.ts +9 -0
  156. package/dist/admin/components/tiptap/editor-toolbar.svelte +230 -0
  157. package/dist/admin/components/tiptap/editor-toolbar.svelte.d.ts +16 -0
  158. package/dist/admin/components/tiptap/heading-a11y-plugin.d.ts +2 -0
  159. package/dist/admin/components/tiptap/heading-a11y-plugin.js +67 -0
  160. package/dist/admin/components/tiptap/image-dialog.svelte +172 -11
  161. package/dist/admin/components/tiptap/inline-block-node.d.ts +19 -0
  162. package/dist/admin/components/tiptap/inline-block-node.js +98 -0
  163. package/dist/admin/components/tiptap/link-dialog.svelte +9 -4
  164. package/dist/admin/components/tiptap/slash-command.d.ts +17 -0
  165. package/dist/admin/components/tiptap/slash-command.js +181 -0
  166. package/dist/admin/components/tiptap/structured-content-utils.d.ts +21 -0
  167. package/dist/admin/components/tiptap/structured-content-utils.js +150 -0
  168. package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -190
  169. package/dist/admin/email/invite-template.d.ts +8 -0
  170. package/dist/admin/email/invite-template.js +99 -0
  171. package/dist/admin/email/reset-password-template.d.ts +7 -0
  172. package/dist/admin/email/reset-password-template.js +96 -0
  173. package/dist/admin/remote/ai.remote.d.ts +1 -0
  174. package/dist/admin/remote/ai.remote.js +4 -1
  175. package/dist/admin/remote/entry.remote.d.ts +9 -0
  176. package/dist/admin/remote/entry.remote.js +58 -8
  177. package/dist/admin/remote/preview.remote.js +2 -1
  178. package/dist/admin/shared/password-schema.d.ts +5 -0
  179. package/dist/admin/shared/password-schema.js +10 -0
  180. package/dist/admin/state/content-language.svelte.d.ts +3 -0
  181. package/dist/admin/state/content-language.svelte.js +8 -0
  182. package/dist/admin/styles/admin.css +1530 -151
  183. package/dist/admin/utils/formatDate.d.ts +1 -0
  184. package/dist/admin/utils/formatDate.js +8 -0
  185. package/dist/admin/utils/roleLabel.d.ts +2 -0
  186. package/dist/admin/utils/roleLabel.js +13 -0
  187. package/dist/admin/utils/translationStatus.d.ts +17 -0
  188. package/dist/admin/utils/translationStatus.js +134 -0
  189. package/dist/ai-claude/index.d.ts +2 -0
  190. package/dist/ai-claude/index.js +56 -0
  191. package/dist/cms/runtime/api.d.ts +6 -1
  192. package/dist/cms/runtime/api.js +3 -0
  193. package/dist/cms/runtime/schemas.d.ts +9 -1
  194. package/dist/cms/runtime/schemas.js +8 -0
  195. package/dist/cms/runtime/types.d.ts +82 -10
  196. package/dist/cms/runtime/types.js +4 -0
  197. package/dist/components/ui/accordion/accordion.stories.svelte +39 -0
  198. package/dist/components/ui/accordion/accordion.stories.svelte.d.ts +27 -0
  199. package/dist/components/ui/alert/alert.stories.svelte +53 -0
  200. package/dist/components/ui/alert/alert.stories.svelte.d.ts +27 -0
  201. package/dist/components/ui/alert/alert.svelte +5 -0
  202. package/dist/components/ui/alert/alert.svelte.d.ts +9 -0
  203. package/dist/components/ui/avatar/avatar.stories.svelte +16 -0
  204. package/dist/components/ui/avatar/avatar.stories.svelte.d.ts +27 -0
  205. package/dist/components/ui/badge/badge.stories.svelte +33 -0
  206. package/dist/components/ui/badge/badge.stories.svelte.d.ts +27 -0
  207. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +33 -0
  208. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte.d.ts +27 -0
  209. package/dist/components/ui/button/button.stories.svelte +43 -0
  210. package/dist/components/ui/button/button.stories.svelte.d.ts +27 -0
  211. package/dist/components/ui/button/button.svelte +1 -2
  212. package/dist/components/ui/button/button.svelte.d.ts +0 -3
  213. package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
  214. package/dist/components/ui/card/card.stories.svelte +42 -0
  215. package/dist/components/ui/card/card.stories.svelte.d.ts +27 -0
  216. package/dist/components/ui/command/command.stories.svelte +51 -0
  217. package/dist/components/ui/command/command.stories.svelte.d.ts +27 -0
  218. package/dist/components/ui/dialog/dialog.stories.svelte +29 -0
  219. package/dist/components/ui/dialog/dialog.stories.svelte.d.ts +27 -0
  220. package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
  221. package/dist/components/ui/field/field.stories.svelte +21 -0
  222. package/dist/components/ui/field/field.stories.svelte.d.ts +27 -0
  223. package/dist/components/ui/input/input.stories.svelte +40 -0
  224. package/dist/components/ui/input/input.stories.svelte.d.ts +27 -0
  225. package/dist/components/ui/input/input.svelte +2 -4
  226. package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
  227. package/dist/components/ui/label/label.stories.svelte +20 -0
  228. package/dist/components/ui/label/label.stories.svelte.d.ts +27 -0
  229. package/dist/components/ui/popover/popover.stories.svelte +29 -0
  230. package/dist/components/ui/popover/popover.stories.svelte.d.ts +27 -0
  231. package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
  232. package/dist/components/ui/select/select.stories.svelte +23 -0
  233. package/dist/components/ui/select/select.stories.svelte.d.ts +27 -0
  234. package/dist/components/ui/separator/separator.stories.svelte +24 -0
  235. package/dist/components/ui/separator/separator.stories.svelte.d.ts +27 -0
  236. package/dist/components/ui/sheet/sheet.stories.svelte +29 -0
  237. package/dist/components/ui/sheet/sheet.stories.svelte.d.ts +27 -0
  238. package/dist/components/ui/sidebar/sidebar-group.svelte +3 -3
  239. package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +2 -2
  240. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +28 -30
  241. package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +7 -7
  242. package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
  243. package/dist/components/ui/sidebar/sidebar-trigger.svelte +4 -4
  244. package/dist/components/ui/sonner/sonner.stories.svelte +22 -0
  245. package/dist/components/ui/sonner/sonner.stories.svelte.d.ts +26 -0
  246. package/dist/components/ui/sonner/sonner.svelte +8 -2
  247. package/dist/components/ui/sonner/toast-demo.svelte +29 -0
  248. package/dist/components/ui/sonner/toast-demo.svelte.d.ts +6 -0
  249. package/dist/components/ui/textarea/textarea.stories.svelte +22 -0
  250. package/dist/components/ui/textarea/textarea.stories.svelte.d.ts +27 -0
  251. package/dist/components/ui/textarea/textarea.svelte +0 -2
  252. package/dist/components/ui/toggle/toggle.stories.svelte +22 -0
  253. package/dist/components/ui/toggle/toggle.stories.svelte.d.ts +27 -0
  254. package/dist/components/ui/toggle-group/toggle-group.stories.svelte +17 -0
  255. package/dist/components/ui/toggle-group/toggle-group.stories.svelte.d.ts +27 -0
  256. package/dist/components/ui/tooltip/tooltip.stories.svelte +26 -0
  257. package/dist/components/ui/tooltip/tooltip.stories.svelte.d.ts +27 -0
  258. package/dist/core/fields/fieldSchemaToTs.d.ts +1 -0
  259. package/dist/core/fields/fieldSchemaToTs.js +133 -1
  260. package/dist/core/fields/layoutUtils.d.ts +17 -0
  261. package/dist/core/fields/layoutUtils.js +149 -0
  262. package/dist/core/fields/structuredToHtml.d.ts +9 -0
  263. package/dist/core/fields/structuredToHtml.js +161 -0
  264. package/dist/core/server/entries/operations/create.js +2 -1
  265. package/dist/core/server/entries/operations/get.js +10 -7
  266. package/dist/core/server/entries/operations/update.d.ts +3 -0
  267. package/dist/core/server/entries/operations/update.js +30 -2
  268. package/dist/core/server/fields/queryStructuredContent.d.ts +15 -0
  269. package/dist/core/server/fields/queryStructuredContent.js +65 -0
  270. package/dist/core/server/fields/resolveImageFields.js +51 -2
  271. package/dist/core/server/fields/resolveRelationFields.js +2 -2
  272. package/dist/core/server/fields/resolveRichtextLinks.js +80 -13
  273. package/dist/core/server/fields/resolveUrlFields.js +57 -6
  274. package/dist/core/server/fields/slugResolver.d.ts +10 -0
  275. package/dist/core/server/fields/slugResolver.js +34 -0
  276. package/dist/core/server/generator/fields.js +15 -4
  277. package/dist/core/server/generator/generator.js +3 -2
  278. package/dist/db-postgres/index.js +10 -6
  279. package/dist/files-local/index.js +126 -64
  280. package/dist/server/auth.d.ts +5 -0
  281. package/dist/server/auth.js +12 -1
  282. package/dist/sveltekit/components/structured-content.svelte +204 -0
  283. package/dist/sveltekit/components/structured-content.svelte.d.ts +21 -0
  284. package/dist/sveltekit/config.d.ts +13 -3
  285. package/dist/sveltekit/index.d.ts +3 -0
  286. package/dist/sveltekit/index.js +3 -0
  287. package/dist/sveltekit/server/handle.js +1 -0
  288. package/dist/types/config.d.ts +3 -0
  289. package/dist/types/entries.d.ts +3 -0
  290. package/dist/types/fields.d.ts +19 -2
  291. package/dist/types/index.d.ts +2 -0
  292. package/dist/types/index.js +2 -0
  293. package/dist/types/layout.d.ts +54 -0
  294. package/dist/types/layout.js +6 -0
  295. package/dist/types/structured-content.d.ts +63 -0
  296. package/dist/types/structured-content.js +1 -0
  297. package/dist/updates/0.1.5/index.d.ts +2 -0
  298. package/dist/updates/0.1.5/index.js +18 -0
  299. package/dist/updates/0.2.0/index.d.ts +2 -0
  300. package/dist/updates/0.2.0/index.js +11 -0
  301. package/dist/updates/0.2.2/index.d.ts +2 -0
  302. package/dist/updates/0.2.2/index.js +13 -0
  303. package/dist/updates/0.5.0/index.d.ts +2 -0
  304. package/dist/updates/0.5.0/index.js +14 -0
  305. package/dist/updates/0.5.1/index.d.ts +2 -0
  306. package/dist/updates/0.5.1/index.js +17 -0
  307. package/dist/updates/index.js +6 -1
  308. package/package.json +16 -9
  309. package/dist/admin/components/dashboard/updates-banner.svelte +0 -170
  310. package/dist/admin/components/dashboard/updates-banner.svelte.d.ts +0 -3
@@ -0,0 +1,289 @@
1
+ <script lang="ts" module>
2
+ type T = Record<string, unknown>;
3
+ </script>
4
+
5
+ <script lang="ts" generics="T extends Record<string, unknown>">
6
+ import Button from '../../../components/ui/button/button.svelte';
7
+ import Input from '../../../components/ui/input/input.svelte';
8
+ import {
9
+ formFieldProxy,
10
+ type FormFieldProxy,
11
+ type FormPathLeaves,
12
+ type SuperForm
13
+ } from 'sveltekit-superforms';
14
+ import type { ArrayField, UrlFieldData } from '../../../types/fields.js';
15
+ import { onMount } from 'svelte';
16
+ import CirclePlus from '@tabler/icons-svelte/icons/circle-plus';
17
+ import X from '@tabler/icons-svelte/icons/x';
18
+ import { getContentLanguage } from '../../state/content-language.svelte.js';
19
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
20
+
21
+ const contentLanguage = getContentLanguage();
22
+ const interfaceLanguage = useInterfaceLanguage();
23
+
24
+ type Props = {
25
+ field: ArrayField;
26
+ form: SuperForm<T>;
27
+ path: FormPathLeaves<T>;
28
+ };
29
+
30
+ let { field, form, path, ...props }: Props = $props();
31
+
32
+ const { value } = formFieldProxy(form, path) satisfies FormFieldProxy<unknown[] | undefined>;
33
+
34
+ onMount(() => {
35
+ if (!$value || !Array.isArray($value)) {
36
+ $value = [];
37
+ }
38
+ });
39
+
40
+ const atMax = $derived(field.maxItems !== undefined && ($value?.length ?? 0) >= field.maxItems);
41
+
42
+ // --- Text ---
43
+ let textInput = $state('');
44
+
45
+ function addTextItem() {
46
+ if (!textInput.trim() || atMax) return;
47
+ if (field.localized) {
48
+ const item: Record<string, string> = {};
49
+ item[contentLanguage.current] = textInput.trim();
50
+ $value = [...($value ?? []), item];
51
+ } else {
52
+ $value = [...($value ?? []), textInput.trim()];
53
+ }
54
+ textInput = '';
55
+ }
56
+
57
+ function handleTextKeydown(e: KeyboardEvent) {
58
+ if (e.key === 'Enter') {
59
+ e.preventDefault();
60
+ addTextItem();
61
+ }
62
+ }
63
+
64
+ // --- Number ---
65
+ let numberInput = $state('');
66
+
67
+ function addNumberItem() {
68
+ const num = Number(numberInput);
69
+ if (numberInput === '' || isNaN(num) || atMax) return;
70
+ $value = [...($value ?? []), num];
71
+ numberInput = '';
72
+ }
73
+
74
+ function handleNumberKeydown(e: KeyboardEvent) {
75
+ if (e.key === 'Enter') {
76
+ e.preventDefault();
77
+ addNumberItem();
78
+ }
79
+ }
80
+
81
+ // --- URL ---
82
+ function addUrlItem() {
83
+ if (atMax) return;
84
+ const item: UrlFieldData = { url: {}, text: {}, newTab: false };
85
+ $value = [...($value ?? []), item];
86
+ }
87
+
88
+ // --- Common ---
89
+ function removeItem(index: number) {
90
+ if (!$value) return;
91
+ $value = $value.filter((_, i) => i !== index);
92
+ }
93
+
94
+ function getTextDisplay(item: unknown): string {
95
+ if (typeof item === 'string') return item;
96
+ if (typeof item === 'object' && item !== null) {
97
+ const rec = item as Record<string, string>;
98
+ return rec[contentLanguage.current] || Object.values(rec)[0] || '';
99
+ }
100
+ return String(item);
101
+ }
102
+ </script>
103
+
104
+ {#if field.of === 'text'}
105
+ <!-- Tag chips for text items -->
106
+ <div class="space-y-3">
107
+ {#if $value && $value.length > 0}
108
+ <div class="flex flex-wrap gap-2">
109
+ {#each $value as item, index}
110
+ <span
111
+ class="bg-[#EEEAF8] text-[#1A1A2E] inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium"
112
+ >
113
+ {#if field.localized}
114
+ <!-- Localized: show editable input per current lang -->
115
+ <input
116
+ type="text"
117
+ class="bg-transparent border-none outline-none w-auto min-w-[4ch] text-sm"
118
+ style="width: {getTextDisplay(item).length + 1}ch"
119
+ value={getTextDisplay(item)}
120
+ oninput={(e) => {
121
+ const val = e.currentTarget.value;
122
+ if (typeof item === 'object' && item !== null) {
123
+ const rec = { ...(item as Record<string, string>) };
124
+ rec[contentLanguage.current] = val;
125
+ const arr = [...($value ?? [])];
126
+ arr[index] = rec;
127
+ $value = arr;
128
+ }
129
+ }}
130
+ />
131
+ {:else}
132
+ {item}
133
+ {/if}
134
+ <button
135
+ type="button"
136
+ class="text-[#555566] hover:text-[#C44B4B] transition-colors"
137
+ onclick={() => removeItem(index)}
138
+ aria-label="Usuń element"
139
+ >
140
+ <X class="h-3.5 w-3.5" />
141
+ </button>
142
+ </span>
143
+ {/each}
144
+ </div>
145
+ {/if}
146
+
147
+ <div class="flex items-center gap-2">
148
+ <Input
149
+ type="text"
150
+ placeholder="Wpisz i naciśnij Enter..."
151
+ bind:value={textInput}
152
+ onkeydown={handleTextKeydown}
153
+ disabled={atMax}
154
+ class="max-w-xs"
155
+ />
156
+ <Button size="sm" type="button" variant="outline" disabled={atMax || !textInput.trim()} onclick={addTextItem}>
157
+ <CirclePlus class="h-4 w-4" />
158
+ Dodaj
159
+ </Button>
160
+ </div>
161
+
162
+ {#if field.maxItems !== undefined}
163
+ <p class="text-xs {atMax ? 'text-destructive' : 'text-muted-foreground'}">
164
+ {$value?.length ?? 0} / {field.maxItems}
165
+ </p>
166
+ {/if}
167
+ </div>
168
+
169
+ {:else if field.of === 'number'}
170
+ <!-- Tag chips for number items -->
171
+ <div class="space-y-3">
172
+ {#if $value && $value.length > 0}
173
+ <div class="flex flex-wrap gap-2">
174
+ {#each $value as item, index}
175
+ <span
176
+ class="bg-[#EEEAF8] text-[#1A1A2E] inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium tabular-nums"
177
+ >
178
+ {item}
179
+ <button
180
+ type="button"
181
+ class="text-[#555566] hover:text-[#C44B4B] transition-colors"
182
+ onclick={() => removeItem(index)}
183
+ aria-label="Usuń element"
184
+ >
185
+ <X class="h-3.5 w-3.5" />
186
+ </button>
187
+ </span>
188
+ {/each}
189
+ </div>
190
+ {/if}
191
+
192
+ <div class="flex items-center gap-2">
193
+ <Input
194
+ type="number"
195
+ placeholder="Wpisz liczbę..."
196
+ bind:value={numberInput}
197
+ onkeydown={handleNumberKeydown}
198
+ disabled={atMax}
199
+ class="max-w-[160px]"
200
+ />
201
+ <Button size="sm" type="button" variant="outline" disabled={atMax || numberInput === ''} onclick={addNumberItem}>
202
+ <CirclePlus class="h-4 w-4" />
203
+ Dodaj
204
+ </Button>
205
+ </div>
206
+
207
+ {#if field.maxItems !== undefined}
208
+ <p class="text-xs {atMax ? 'text-destructive' : 'text-muted-foreground'}">
209
+ {$value?.length ?? 0} / {field.maxItems}
210
+ </p>
211
+ {/if}
212
+ </div>
213
+
214
+ {:else if field.of === 'url'}
215
+ <!-- Compact list for URL items -->
216
+ <div class="space-y-3">
217
+ {#if $value && $value.length > 0}
218
+ <div class="space-y-2">
219
+ {#each $value as item, index}
220
+ {@const urlItem = item as UrlFieldData}
221
+ <div class="flex items-start gap-2 rounded-xl border border-[#E2DFF0] bg-[#F4F2FA] p-3">
222
+ <div class="flex-1 space-y-2">
223
+ <Input
224
+ type="url"
225
+ placeholder="URL..."
226
+ value={urlItem.url?.[contentLanguage.current] ?? ''}
227
+ oninput={(e) => {
228
+ const val = e.currentTarget.value;
229
+ const updated = { ...urlItem, url: { ...(urlItem.url ?? {}), [contentLanguage.current]: val } };
230
+ const arr = [...($value ?? [])];
231
+ arr[index] = updated;
232
+ $value = arr;
233
+ }}
234
+ />
235
+ <div class="flex items-center gap-2">
236
+ <Input
237
+ type="text"
238
+ placeholder="Tekst linku..."
239
+ class="flex-1"
240
+ value={urlItem.text?.[contentLanguage.current] ?? ''}
241
+ oninput={(e) => {
242
+ const val = e.currentTarget.value;
243
+ const updated = { ...urlItem, text: { ...(urlItem.text ?? {}), [contentLanguage.current]: val } };
244
+ const arr = [...($value ?? [])];
245
+ arr[index] = updated;
246
+ $value = arr;
247
+ }}
248
+ />
249
+ <label class="flex items-center gap-1.5 text-xs text-[#555566] whitespace-nowrap">
250
+ <input
251
+ type="checkbox"
252
+ checked={urlItem.newTab ?? false}
253
+ onchange={(e) => {
254
+ const updated = { ...urlItem, newTab: e.currentTarget.checked };
255
+ const arr = [...($value ?? [])];
256
+ arr[index] = updated;
257
+ $value = arr;
258
+ }}
259
+ class="accent-[#5B4A9E]"
260
+ />
261
+ Nowa karta
262
+ </label>
263
+ </div>
264
+ </div>
265
+ <button
266
+ type="button"
267
+ class="mt-1.5 text-[#555566] hover:text-[#C44B4B] transition-colors"
268
+ onclick={() => removeItem(index)}
269
+ aria-label="Usuń link"
270
+ >
271
+ <X class="h-4 w-4" />
272
+ </button>
273
+ </div>
274
+ {/each}
275
+ </div>
276
+ {/if}
277
+
278
+ <Button size="sm" type="button" variant="outline" disabled={atMax} onclick={addUrlItem}>
279
+ <CirclePlus class="h-4 w-4" />
280
+ Dodaj link
281
+ </Button>
282
+
283
+ {#if field.maxItems !== undefined}
284
+ <p class="text-xs {atMax ? 'text-destructive' : 'text-muted-foreground'}">
285
+ {$value?.length ?? 0} / {field.maxItems}
286
+ </p>
287
+ {/if}
288
+ </div>
289
+ {/if}
@@ -0,0 +1,30 @@
1
+ import { type FormPathLeaves, type SuperForm } from 'sveltekit-superforms';
2
+ import type { ArrayField } from '../../../types/fields.js';
3
+ declare function $$render<T extends Record<string, unknown>>(): {
4
+ props: {
5
+ field: ArrayField;
6
+ form: SuperForm<T>;
7
+ path: FormPathLeaves<T>;
8
+ };
9
+ exports: {};
10
+ bindings: "";
11
+ slots: {};
12
+ events: {};
13
+ };
14
+ declare class __sveltets_Render<T extends Record<string, unknown>> {
15
+ props(): ReturnType<typeof $$render<T>>['props'];
16
+ events(): ReturnType<typeof $$render<T>>['events'];
17
+ slots(): ReturnType<typeof $$render<T>>['slots'];
18
+ bindings(): "";
19
+ exports(): {};
20
+ }
21
+ interface $$IsomorphicComponent {
22
+ new <T extends Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
23
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
24
+ } & ReturnType<__sveltets_Render<T>['exports']>;
25
+ <T extends Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
26
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
27
+ }
28
+ declare const SimpleArrayField: $$IsomorphicComponent;
29
+ type SimpleArrayField<T extends Record<string, unknown>> = InstanceType<typeof SimpleArrayField<T>>;
30
+ export default SimpleArrayField;
@@ -22,13 +22,14 @@
22
22
 
23
23
  let { field, form, path, ...props }: Props = $props();
24
24
 
25
- let pattern = field.pattern;
25
+ let effectivePattern = field.pattern || (field.sourceField ? `{${field.sourceField}}` : undefined);
26
+ let pattern = effectivePattern;
26
27
 
27
28
  const { form: formData } = form;
28
29
 
29
30
  const { value } = formFieldProxy(form, path) satisfies FormFieldProxy<string | undefined>;
30
31
 
31
- let patternKeys = field.pattern ? extractPatternKeys(field.pattern) : [];
32
+ let patternKeys = effectivePattern ? extractPatternKeys(effectivePattern) : [];
32
33
 
33
34
  function extractPatternKeys(pattern: string): string[] {
34
35
  const matches = [...pattern.matchAll(/{([^}]+)}/g)];
@@ -0,0 +1,148 @@
1
+ <script lang="ts">
2
+ import type { Field } from '../../../types/fields.js';
3
+ import Input from '../../../components/ui/input/input.svelte';
4
+ import { Checkbox } from '../../../components/ui/checkbox/index.js';
5
+ import * as Select from '../../../components/ui/select/index.js';
6
+ import Label from '../../../components/ui/label/label.svelte';
7
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
8
+ import { getLocalizedLabel } from '../../utils/collectionLabel.js';
9
+
10
+ type Props = {
11
+ fields: Field[];
12
+ data: Record<string, unknown>;
13
+ onchange: (slug: string, value: unknown) => void;
14
+ };
15
+
16
+ let { fields, data, onchange }: Props = $props();
17
+
18
+ const interfaceLanguage = useInterfaceLanguage();
19
+
20
+ const SUPPORTED_TYPES = new Set([
21
+ 'text',
22
+ 'number',
23
+ 'boolean',
24
+ 'select',
25
+ 'radio',
26
+ 'url'
27
+ ]);
28
+
29
+ function handleInput(slug: string, e: Event) {
30
+ const target = e.target as HTMLInputElement;
31
+ onchange(slug, target.value);
32
+ }
33
+
34
+ function handleNumberInput(slug: string, e: Event) {
35
+ const target = e.target as HTMLInputElement;
36
+ const num = parseFloat(target.value);
37
+ onchange(slug, isNaN(num) ? 0 : num);
38
+ }
39
+ </script>
40
+
41
+ <div class="grid gap-3">
42
+ {#each fields as field}
43
+ {#if SUPPORTED_TYPES.has(field.type)}
44
+ <div class="space-y-1.5">
45
+ {#if field.type !== 'boolean'}
46
+ <Label class="text-xs font-medium">
47
+ {getLocalizedLabel(field.label, interfaceLanguage.current)}
48
+ {#if field.required}<span class="text-destructive">*</span>{/if}
49
+ </Label>
50
+ {/if}
51
+
52
+ {#if field.type === 'text'}
53
+ <Input
54
+ type="text"
55
+ value={String(data[field.slug] ?? '')}
56
+ oninput={(e) => handleInput(field.slug, e)}
57
+ placeholder={field.placeholder ? getLocalizedLabel(field.placeholder, interfaceLanguage.current) : ''}
58
+ class="h-8 text-sm"
59
+ />
60
+ {:else if field.type === 'number'}
61
+ <Input
62
+ type="number"
63
+ value={String(data[field.slug] ?? 0)}
64
+ oninput={(e) => handleNumberInput(field.slug, e)}
65
+ min={field.min}
66
+ max={field.max}
67
+ step={field.step}
68
+ class="h-8 text-sm"
69
+ />
70
+ {:else if field.type === 'boolean'}
71
+ <div class="flex items-center gap-2">
72
+ <Checkbox
73
+ checked={Boolean(data[field.slug])}
74
+ onCheckedChange={(checked) => onchange(field.slug, checked)}
75
+ />
76
+ <Label class="text-xs font-medium">
77
+ {getLocalizedLabel(field.label, interfaceLanguage.current)}
78
+ </Label>
79
+ </div>
80
+ {:else if field.type === 'select' || field.type === 'radio'}
81
+ {@const currentValue = String(data[field.slug] ?? '')}
82
+ {@const currentLabel = field.options.find((o) => o.value === currentValue)}
83
+ <Select.Root
84
+ type="single"
85
+ value={currentValue}
86
+ onValueChange={(v) => onchange(field.slug, v)}
87
+ >
88
+ <Select.Trigger size="sm" class="w-full">
89
+ {#if currentLabel}
90
+ {getLocalizedLabel(currentLabel.label, interfaceLanguage.current)}
91
+ {:else}
92
+ <span class="text-muted-foreground">Wybierz...</span>
93
+ {/if}
94
+ </Select.Trigger>
95
+ <Select.Content>
96
+ {#each field.options as option}
97
+ <Select.Item value={option.value} label={getLocalizedLabel(option.label, interfaceLanguage.current)} />
98
+ {/each}
99
+ </Select.Content>
100
+ </Select.Root>
101
+ {:else if field.type === 'url'}
102
+ {@const urlData = (data[field.slug] as { url?: string; id?: string; text?: string; newTab?: boolean } | undefined) ?? { url: '' }}
103
+ <Input
104
+ type="url"
105
+ value={urlData.url ?? ''}
106
+ oninput={(e) => {
107
+ const target = e.target as HTMLInputElement;
108
+ onchange(field.slug, { ...urlData, url: target.value });
109
+ }}
110
+ placeholder={field.placeholder ? getLocalizedLabel(field.placeholder, interfaceLanguage.current) : 'https://...'}
111
+ class="h-8 text-sm"
112
+ />
113
+ {#if field.text}
114
+ <Input
115
+ type="text"
116
+ value={urlData.text ?? ''}
117
+ oninput={(e) => {
118
+ const target = e.target as HTMLInputElement;
119
+ onchange(field.slug, { ...urlData, text: target.value });
120
+ }}
121
+ placeholder="Tekst linku"
122
+ class="h-8 text-sm mt-1"
123
+ />
124
+ {/if}
125
+ {#if field.newTab}
126
+ <div class="flex items-center gap-2 mt-1">
127
+ <Checkbox
128
+ checked={urlData.newTab ?? false}
129
+ onCheckedChange={(checked) => onchange(field.slug, { ...urlData, newTab: checked })}
130
+ />
131
+ <Label class="text-xs font-medium">Otwórz w nowej karcie</Label>
132
+ </div>
133
+ {/if}
134
+ {/if}
135
+
136
+ {#if field.description}
137
+ <p class="text-muted-foreground text-xs">
138
+ {getLocalizedLabel(field.description, interfaceLanguage.current)}
139
+ </p>
140
+ {/if}
141
+ </div>
142
+ {:else}
143
+ <div class="text-muted-foreground rounded-md border border-dashed p-2 text-center text-xs">
144
+ Pole „{getLocalizedLabel(field.label, interfaceLanguage.current)}" ({field.type}) nie jest obsługiwane w blokach inline
145
+ </div>
146
+ {/if}
147
+ {/each}
148
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { Field } from '../../../types/fields.js';
2
+ type Props = {
3
+ fields: Field[];
4
+ data: Record<string, unknown>;
5
+ onchange: (slug: string, value: unknown) => void;
6
+ };
7
+ declare const StandaloneFieldRenderer: import("svelte").Component<Props, {}, "">;
8
+ type StandaloneFieldRenderer = ReturnType<typeof StandaloneFieldRenderer>;
9
+ export default StandaloneFieldRenderer;