includio-cms 0.25.0 → 0.26.0

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 (349) hide show
  1. package/API.md +57 -4
  2. package/CHANGELOG.md +53 -0
  3. package/DOCS.md +1 -1
  4. package/README.md +2 -0
  5. package/ROADMAP.md +6 -0
  6. package/dist/admin/client/account/lang.d.ts +1 -0
  7. package/dist/admin/client/account/lang.js +4 -2
  8. package/dist/admin/client/account/profile-section.svelte +2 -2
  9. package/dist/admin/client/account/security-section.svelte +27 -4
  10. package/dist/admin/client/account/sessions-section.svelte +1 -1
  11. package/dist/admin/client/admin/admin-after-login-layout-content.svelte +1 -1
  12. package/dist/admin/client/admin/dashboard-page.svelte +34 -10
  13. package/dist/admin/client/collection/bulk-actions-bar.svelte +86 -44
  14. package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +3 -1
  15. package/dist/admin/client/collection/collection-entries.svelte +52 -36
  16. package/dist/admin/client/collection/collection-entries.svelte.d.ts +3 -0
  17. package/dist/admin/client/collection/collection.svelte +28 -14
  18. package/dist/admin/client/collection/collection.svelte.d.ts +3 -0
  19. package/dist/admin/client/collection/data-table.svelte +279 -130
  20. package/dist/admin/client/collection/data-table.svelte.d.ts +11 -0
  21. package/dist/admin/client/collection/date-cell.svelte +4 -4
  22. package/dist/admin/client/collection/row-actions.svelte +2 -1
  23. package/dist/admin/client/collection/sortable-header.svelte +33 -9
  24. package/dist/admin/client/collection/state-display.svelte +102 -0
  25. package/dist/admin/client/collection/state-display.svelte.d.ts +12 -0
  26. package/dist/admin/client/collection/status-badge.svelte +99 -11
  27. package/dist/admin/client/collection/status-badge.svelte.d.ts +15 -1
  28. package/dist/admin/client/collection/table-pagination.svelte +21 -6
  29. package/dist/admin/client/collection/table-toolbar.svelte +105 -80
  30. package/dist/admin/client/collection/table-toolbar.svelte.d.ts +11 -8
  31. package/dist/admin/client/entry/entry-form.svelte +36 -11
  32. package/dist/admin/client/entry/entry-form.svelte.d.ts +1 -0
  33. package/dist/admin/client/entry/entry-header.svelte +22 -15
  34. package/dist/admin/client/entry/entry-header.svelte.d.ts +1 -0
  35. package/dist/admin/client/entry/entry.svelte +269 -165
  36. package/dist/admin/client/entry/header/a11y-header-badge.svelte +47 -0
  37. package/dist/admin/client/entry/header/a11y-header-badge.svelte.d.ts +8 -0
  38. package/dist/admin/client/entry/header/publish-panel.svelte +69 -13
  39. package/dist/admin/client/entry/header/save-indicator.svelte +57 -28
  40. package/dist/admin/client/entry/header/save-indicator.svelte.d.ts +1 -0
  41. package/dist/admin/client/entry/header/status-badge.svelte +60 -15
  42. package/dist/admin/client/entry/header/status-badge.svelte.d.ts +1 -2
  43. package/dist/admin/client/entry/header/version-history-sheet.svelte +1 -1
  44. package/dist/admin/client/entry/hybrid/hybrid-layout.svelte +74 -23
  45. package/dist/admin/client/entry/hybrid/hybrid-preview.svelte +1 -1
  46. package/dist/admin/client/entry/utils.d.ts +14 -0
  47. package/dist/admin/client/entry/utils.js +28 -0
  48. package/dist/admin/client/form/form-submission/form-submission.svelte +2 -2
  49. package/dist/admin/client/form/form-submissions.svelte +143 -194
  50. package/dist/admin/client/form/form-submissions.svelte.d.ts +2 -0
  51. package/dist/admin/client/login/lang.d.ts +3 -0
  52. package/dist/admin/client/login/lang.js +10 -4
  53. package/dist/admin/client/login/login-form.svelte +8 -1
  54. package/dist/admin/client/login/reset-password-page.svelte +24 -3
  55. package/dist/admin/client/login/schema.d.ts +14 -2
  56. package/dist/admin/client/login/schema.js +19 -8
  57. package/dist/admin/client/maintenance/maintenance-page.svelte +16 -17
  58. package/dist/admin/client/media/media-page.svelte +1 -1
  59. package/dist/admin/client/shop/coupon-edit-page.svelte +117 -13
  60. package/dist/admin/client/shop/coupon-form.svelte +282 -138
  61. package/dist/admin/client/shop/coupon-form.svelte.d.ts +1 -9
  62. package/dist/admin/client/shop/coupon-new-page.svelte +40 -10
  63. package/dist/admin/client/shop/coupon-new-page.svelte.d.ts +2 -17
  64. package/dist/admin/client/shop/coupon-schema.d.ts +28 -0
  65. package/dist/admin/client/shop/coupon-schema.js +53 -0
  66. package/dist/admin/client/shop/coupons-list-page.svelte +262 -118
  67. package/dist/admin/client/shop/coupons-list-page.svelte.d.ts +16 -1
  68. package/dist/admin/client/shop/shipping-method-edit-page.svelte +108 -59
  69. package/dist/admin/client/shop/shipping-method-form.svelte +36 -9
  70. package/dist/admin/client/shop/shipping-method-new-page.svelte +44 -13
  71. package/dist/admin/client/shop/shipping-methods-list-page.svelte +101 -59
  72. package/dist/admin/client/shop/shop-order-detail-page.svelte +113 -84
  73. package/dist/admin/client/shop/shop-orders-list-page.svelte +302 -152
  74. package/dist/admin/client/shop/shop-orders-list-page.svelte.d.ts +18 -1
  75. package/dist/admin/client/shop/shop-products-list-page.svelte +355 -118
  76. package/dist/admin/client/shop/shop-products-list-page.svelte.d.ts +19 -1
  77. package/dist/admin/client/users/accept-invite-page.svelte +24 -3
  78. package/dist/admin/client/users/create-user-dialog.svelte +3 -8
  79. package/dist/admin/client/users/lang.d.ts +2 -0
  80. package/dist/admin/client/users/lang.js +4 -0
  81. package/dist/admin/client/users/pending-invitations.svelte +2 -9
  82. package/dist/admin/client/users/user-name-cell.svelte +20 -0
  83. package/dist/admin/client/users/user-name-cell.svelte.d.ts +9 -0
  84. package/dist/admin/client/users/user-role-badge.svelte +16 -0
  85. package/dist/admin/client/users/user-role-badge.svelte.d.ts +7 -0
  86. package/dist/admin/client/users/user-row-actions.svelte +72 -0
  87. package/dist/admin/client/users/user-row-actions.svelte.d.ts +20 -0
  88. package/dist/admin/client/users/user-sessions-sheet.svelte +2 -11
  89. package/dist/admin/client/users/users-page.svelte +283 -497
  90. package/dist/admin/client/users/users-page.svelte.d.ts +12 -1
  91. package/dist/admin/components/dashboard/form-submissions-widget.svelte +59 -74
  92. package/dist/admin/components/dashboard/recent-activity.svelte +17 -5
  93. package/dist/admin/components/dashboard/recent-entries.svelte +19 -7
  94. package/dist/admin/components/dialogs/confirmation-dialog.svelte +105 -0
  95. package/dist/admin/components/dialogs/confirmation-dialog.svelte.d.ts +13 -0
  96. package/dist/admin/components/fields/block-picker-modal.svelte +6 -0
  97. package/dist/admin/components/fields/blocks-field.svelte +46 -1
  98. package/dist/admin/components/fields/boolean-field.svelte +1 -1
  99. package/dist/admin/components/fields/field-renderer.svelte +23 -21
  100. package/dist/admin/components/fields/file-field.svelte +344 -30
  101. package/dist/admin/components/fields/media-field.svelte +16 -2
  102. package/dist/admin/components/fields/radio-field.svelte +22 -0
  103. package/dist/admin/components/fields/relation-field.svelte +123 -97
  104. package/dist/admin/components/fields/relation-picker-dialog.svelte +2 -2
  105. package/dist/admin/components/fields/seo-field.svelte +60 -30
  106. package/dist/admin/components/fields/shop-field.svelte +9 -4
  107. package/dist/admin/components/fields/simple-array-field.svelte +321 -151
  108. package/dist/admin/components/fields/simple-array-field.svelte.d.ts +3 -0
  109. package/dist/admin/components/fields/slug-field.svelte +146 -21
  110. package/dist/admin/components/fields/text-field-wrapper.svelte +37 -20
  111. package/dist/admin/components/fields/text-field.svelte +7 -2
  112. package/dist/admin/components/fields/url-field-wrapper.svelte +10 -0
  113. package/dist/admin/components/fields/url-field.svelte +36 -23
  114. package/dist/admin/components/forms/form-error-summary.svelte +143 -0
  115. package/dist/admin/components/forms/form-error-summary.svelte.d.ts +27 -0
  116. package/dist/admin/components/layout/app-sidebar.svelte +7 -2
  117. package/dist/admin/components/layout/detail-page-shell.svelte +71 -0
  118. package/dist/admin/components/layout/detail-page-shell.svelte.d.ts +24 -0
  119. package/dist/admin/components/layout/lang.d.ts +5 -0
  120. package/dist/admin/components/layout/lang.js +10 -0
  121. package/dist/admin/components/layout/layout-renderer.svelte +71 -2
  122. package/dist/admin/components/layout/layout-renderer.svelte.d.ts +1 -0
  123. package/dist/admin/components/layout/layout-tabs.svelte +172 -0
  124. package/dist/admin/components/layout/layout-tabs.svelte.d.ts +24 -0
  125. package/dist/admin/components/layout/nav-breadcrumbs.svelte +25 -7
  126. package/dist/admin/components/layout/nav-collections.svelte +23 -36
  127. package/dist/admin/components/layout/nav-forms.svelte +19 -35
  128. package/dist/admin/components/layout/nav-main.svelte +3 -28
  129. package/dist/admin/components/layout/nav-search.svelte +70 -2
  130. package/dist/admin/components/layout/nav-section.svelte +77 -0
  131. package/dist/admin/components/layout/nav-section.svelte.d.ts +22 -0
  132. package/dist/admin/components/layout/nav-shop.svelte +3 -27
  133. package/dist/admin/components/layout/nav-singletons.svelte +16 -28
  134. package/dist/admin/components/layout/page-header.stories.svelte +93 -0
  135. package/dist/admin/components/layout/page-header.stories.svelte.d.ts +27 -0
  136. package/dist/admin/components/layout/page-header.svelte +68 -0
  137. package/dist/admin/components/layout/page-header.svelte.d.ts +17 -0
  138. package/dist/admin/components/layout/site-header.svelte +9 -0
  139. package/dist/admin/components/layout/site-header.svelte.d.ts +2 -17
  140. package/dist/admin/components/media/file/file-name-input.svelte +6 -2
  141. package/dist/admin/components/media/file/file-preview.svelte +130 -17
  142. package/dist/admin/components/media/file-upload.svelte +16 -7
  143. package/dist/admin/components/media/file-upload.svelte.d.ts +1 -0
  144. package/dist/admin/components/media/files-list.svelte +153 -53
  145. package/dist/admin/components/media/files-list.svelte.d.ts +1 -0
  146. package/dist/admin/components/media/media-library.svelte +577 -198
  147. package/dist/admin/components/media/media-library.svelte.d.ts +4 -0
  148. package/dist/admin/components/media/media-selector.svelte +4 -2
  149. package/dist/admin/components/media/media-selector.svelte.d.ts +1 -0
  150. package/dist/admin/components/media/tag-sidebar.svelte +4 -4
  151. package/dist/admin/components/tiptap/FigureNodeView.svelte +10 -0
  152. package/dist/admin/components/tiptap/bubble-menu.svelte +104 -0
  153. package/dist/admin/components/tiptap/bubble-menu.svelte.d.ts +19 -0
  154. package/dist/admin/components/tiptap/content-editor.svelte +28 -24
  155. package/dist/admin/components/tiptap/editor-toolbar.svelte +7 -7
  156. package/dist/admin/components/tiptap/extensions.js +5 -1
  157. package/dist/admin/components/tiptap/image-dialog.svelte +5 -1
  158. package/dist/admin/components/tiptap/link-dialog.svelte +2 -0
  159. package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -20
  160. package/dist/admin/components/tiptap/video-dialog.svelte +1 -1
  161. package/dist/admin/i18n/errors.d.ts +140 -0
  162. package/dist/admin/i18n/errors.js +151 -0
  163. package/dist/admin/remote/entry.remote.d.ts +59 -4
  164. package/dist/admin/remote/entry.remote.js +239 -62
  165. package/dist/admin/remote/shop.remote.d.ts +37 -32
  166. package/dist/admin/remote/shop.remote.js +9 -2
  167. package/dist/admin/shared/password-generate.d.ts +6 -0
  168. package/dist/admin/shared/password-generate.js +40 -0
  169. package/dist/admin/shared/password-schema.d.ts +6 -0
  170. package/dist/admin/shared/password-schema.js +10 -3
  171. package/dist/admin/styles/admin.css +23 -6
  172. package/dist/admin/styles/tokens.md +244 -0
  173. package/dist/admin/utils/accordionActivation.d.ts +13 -0
  174. package/dist/admin/utils/accordionActivation.js +35 -0
  175. package/dist/admin/utils/entryLabel.d.ts +23 -0
  176. package/dist/admin/utils/entryLabel.js +51 -12
  177. package/dist/admin/utils/field-a11y.d.ts +29 -0
  178. package/dist/admin/utils/field-a11y.js +23 -0
  179. package/dist/admin/utils/fieldPathElement.d.ts +9 -0
  180. package/dist/admin/utils/fieldPathElement.js +18 -0
  181. package/dist/admin/utils/fileDisplay.d.ts +10 -0
  182. package/dist/admin/utils/fileDisplay.js +26 -0
  183. package/dist/admin/utils/flattenFormErrors.d.ts +19 -0
  184. package/dist/admin/utils/flattenFormErrors.js +102 -0
  185. package/dist/admin/utils/formatters.d.ts +12 -0
  186. package/dist/admin/utils/{formatDate.js → formatters.js} +23 -2
  187. package/dist/admin/utils/scrollWithin.d.ts +9 -0
  188. package/dist/admin/utils/scrollWithin.js +32 -0
  189. package/dist/admin/utils/tabActivation.d.ts +12 -0
  190. package/dist/admin/utils/tabActivation.js +24 -0
  191. package/dist/cms/runtime/schema.d.ts +1 -0
  192. package/dist/cms/runtime/schema.js +1 -0
  193. package/dist/cms/runtime/types.d.ts +80 -7
  194. package/dist/components/ui/accordion/accordion-content.svelte +17 -3
  195. package/dist/components/ui/accordion/accordion.stories.svelte +21 -1
  196. package/dist/components/ui/alert/alert.stories.svelte +14 -0
  197. package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte +45 -0
  198. package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte.d.ts +27 -0
  199. package/dist/components/ui/avatar/avatar.stories.svelte +27 -0
  200. package/dist/components/ui/badge/badge.stories.svelte +15 -0
  201. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +47 -0
  202. package/dist/components/ui/breadcrumb/breadcrumb.svelte +1 -1
  203. package/dist/components/ui/button/button.stories.svelte +53 -6
  204. package/dist/components/ui/button/button.svelte +39 -5
  205. package/dist/components/ui/button/button.svelte.d.ts +4 -0
  206. package/dist/components/ui/button-group/button-group.stories.svelte +44 -0
  207. package/dist/components/ui/button-group/button-group.stories.svelte.d.ts +27 -0
  208. package/dist/components/ui/calendar/calendar.stories.svelte +36 -0
  209. package/dist/components/ui/calendar/calendar.stories.svelte.d.ts +27 -0
  210. package/dist/components/ui/card/card.stories.svelte +7 -0
  211. package/dist/components/ui/carousel/carousel.stories.svelte +43 -0
  212. package/dist/components/ui/carousel/carousel.stories.svelte.d.ts +27 -0
  213. package/dist/components/ui/checkbox/checkbox.stories.svelte +67 -0
  214. package/dist/components/ui/checkbox/checkbox.stories.svelte.d.ts +27 -0
  215. package/dist/components/ui/checkbox/checkbox.svelte +3 -3
  216. package/dist/components/ui/command/command.stories.svelte +18 -0
  217. package/dist/components/ui/data-table/data-table.stories.svelte +61 -0
  218. package/dist/components/ui/data-table/data-table.stories.svelte.d.ts +18 -0
  219. package/dist/components/ui/dialog/dialog-content.svelte +5 -0
  220. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +2 -0
  221. package/dist/components/ui/dialog/dialog.stories.svelte +35 -0
  222. package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte +74 -0
  223. package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte.d.ts +27 -0
  224. package/dist/components/ui/field/field-context.svelte.d.ts +22 -0
  225. package/dist/components/ui/field/field-context.svelte.js +9 -0
  226. package/dist/components/ui/field/field-control.svelte +18 -0
  227. package/dist/components/ui/field/field-control.svelte.d.ts +8 -0
  228. package/dist/components/ui/field/field-description.svelte +12 -0
  229. package/dist/components/ui/field/field-error.svelte +14 -6
  230. package/dist/components/ui/field/field-label.svelte +10 -0
  231. package/dist/components/ui/field/field.stories.svelte +95 -9
  232. package/dist/components/ui/field/field.svelte +57 -0
  233. package/dist/components/ui/field/field.svelte.d.ts +2 -0
  234. package/dist/components/ui/field/index.d.ts +3 -1
  235. package/dist/components/ui/field/index.js +4 -2
  236. package/dist/components/ui/form/form-field-errors.svelte +1 -1
  237. package/dist/components/ui/form/form.stories.svelte +25 -0
  238. package/dist/components/ui/form/form.stories.svelte.d.ts +26 -0
  239. package/dist/components/ui/input/input.stories.svelte +26 -0
  240. package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
  241. package/dist/components/ui/input-group/input-group.stories.svelte +43 -0
  242. package/dist/components/ui/input-group/input-group.stories.svelte.d.ts +27 -0
  243. package/dist/components/ui/item/item.stories.svelte +61 -0
  244. package/dist/components/ui/item/item.stories.svelte.d.ts +27 -0
  245. package/dist/components/ui/label/label.stories.svelte +7 -0
  246. package/dist/components/ui/live-region/index.d.ts +1 -0
  247. package/dist/components/ui/live-region/index.js +1 -0
  248. package/dist/components/ui/live-region/live-region-demo.svelte +32 -0
  249. package/dist/components/ui/live-region/live-region-demo.svelte.d.ts +7 -0
  250. package/dist/components/ui/live-region/live-region.stories.svelte +23 -0
  251. package/dist/components/ui/live-region/live-region.stories.svelte.d.ts +26 -0
  252. package/dist/components/ui/live-region/live-region.svelte +12 -0
  253. package/dist/components/ui/live-region/live-region.svelte.d.ts +8 -0
  254. package/dist/components/ui/popover/popover.stories.svelte +34 -0
  255. package/dist/components/ui/radio-group/radio-group.stories.svelte +58 -0
  256. package/dist/components/ui/radio-group/radio-group.stories.svelte.d.ts +27 -0
  257. package/dist/components/ui/resizable/resizable.stories.svelte +56 -0
  258. package/dist/components/ui/resizable/resizable.stories.svelte.d.ts +27 -0
  259. package/dist/components/ui/select/select.stories.svelte +49 -0
  260. package/dist/components/ui/separator/separator.stories.svelte +18 -0
  261. package/dist/components/ui/sheet/sheet.stories.svelte +34 -0
  262. package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
  263. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +1 -0
  264. package/dist/components/ui/sidebar/sidebar-trigger.svelte +1 -1
  265. package/dist/components/ui/sidebar/sidebar.stories.svelte +72 -0
  266. package/dist/components/ui/sidebar/sidebar.stories.svelte.d.ts +27 -0
  267. package/dist/components/ui/skeleton/skeleton.stories.svelte +39 -0
  268. package/dist/components/ui/skeleton/skeleton.stories.svelte.d.ts +27 -0
  269. package/dist/components/ui/skeleton/skeleton.svelte +6 -0
  270. package/dist/components/ui/sonner/index.d.ts +1 -1
  271. package/dist/components/ui/sonner/index.js +1 -1
  272. package/dist/components/ui/sonner/sonner.stories.svelte +7 -0
  273. package/dist/components/ui/sonner/sonner.svelte +17 -1
  274. package/dist/components/ui/sonner/sonner.svelte.d.ts +6 -0
  275. package/dist/components/ui/spinner/spinner.stories.svelte +30 -0
  276. package/dist/components/ui/spinner/spinner.stories.svelte.d.ts +27 -0
  277. package/dist/components/ui/switch/switch.stories.svelte +56 -0
  278. package/dist/components/ui/switch/switch.stories.svelte.d.ts +27 -0
  279. package/dist/components/ui/table/table-cell.svelte +1 -1
  280. package/dist/components/ui/table/table-head.svelte +1 -1
  281. package/dist/components/ui/table/table.stories.svelte +68 -0
  282. package/dist/components/ui/table/table.stories.svelte.d.ts +27 -0
  283. package/dist/components/ui/table/table.svelte +1 -1
  284. package/dist/components/ui/tabs/tabs.stories.svelte +48 -0
  285. package/dist/components/ui/tabs/tabs.stories.svelte.d.ts +27 -0
  286. package/dist/components/ui/textarea/textarea.stories.svelte +21 -0
  287. package/dist/components/ui/toggle/toggle.stories.svelte +23 -0
  288. package/dist/components/ui/toggle-group/toggle-group.stories.svelte +43 -0
  289. package/dist/components/ui/tooltip/tooltip.stories.svelte +46 -6
  290. package/dist/core/fields/fieldSchemaToTs.d.ts +7 -0
  291. package/dist/core/fields/fieldSchemaToTs.js +234 -90
  292. package/dist/core/fields/layoutUtils.d.ts +4 -1
  293. package/dist/core/fields/layoutUtils.js +41 -4
  294. package/dist/core/fields/resolveSeo.d.ts +70 -0
  295. package/dist/core/fields/resolveSeo.js +88 -0
  296. package/dist/core/fields/seoFieldDescriptor.d.ts +43 -0
  297. package/dist/core/fields/seoFieldDescriptor.js +74 -0
  298. package/dist/core/fields/slugPath.d.ts +13 -0
  299. package/dist/core/fields/slugPath.js +32 -0
  300. package/dist/core/fields/urlUtils.d.ts +8 -0
  301. package/dist/core/fields/urlUtils.js +27 -0
  302. package/dist/core/index.d.ts +1 -0
  303. package/dist/core/index.js +1 -0
  304. package/dist/core/server/entries/operations/create.js +13 -0
  305. package/dist/core/server/entries/operations/get.d.ts +7 -0
  306. package/dist/core/server/entries/operations/get.js +10 -6
  307. package/dist/core/server/entries/operations/slugUniqueness.d.ts +37 -0
  308. package/dist/core/server/entries/operations/slugUniqueness.js +116 -0
  309. package/dist/core/server/entries/operations/update.d.ts +6 -1
  310. package/dist/core/server/entries/operations/update.js +24 -1
  311. package/dist/core/server/fields/slugResolver.d.ts +3 -13
  312. package/dist/core/server/fields/slugResolver.js +8 -37
  313. package/dist/core/server/generator/fields.js +10 -17
  314. package/dist/core/server/generator/formFields.js +2 -1
  315. package/dist/core/server/generator/generator.js +4 -4
  316. package/dist/core/server/generator/utils.d.ts +1 -0
  317. package/dist/core/server/generator/utils.js +4 -0
  318. package/dist/paraglide/messages/_index.d.ts +3 -36
  319. package/dist/paraglide/messages/_index.js +3 -71
  320. package/dist/paraglide/messages/hello_world.d.ts +5 -0
  321. package/dist/paraglide/messages/hello_world.js +33 -0
  322. package/dist/paraglide/messages/login_hello.d.ts +16 -0
  323. package/dist/paraglide/messages/login_hello.js +34 -0
  324. package/dist/paraglide/messages/login_please_login.d.ts +16 -0
  325. package/dist/paraglide/messages/login_please_login.js +34 -0
  326. package/dist/shop/server/orders.d.ts +1 -0
  327. package/dist/shop/server/orders.js +14 -0
  328. package/dist/shop/server/shop-data.d.ts +2 -0
  329. package/dist/shop/server/shop-data.js +20 -5
  330. package/dist/sveltekit/server/handle.js +17 -0
  331. package/dist/types/cms.schema.js +4 -2
  332. package/dist/types/fields.d.ts +35 -0
  333. package/dist/types/index.d.ts +1 -1
  334. package/dist/types/layout.d.ts +35 -2
  335. package/dist/updates/0.26.0/index.d.ts +2 -0
  336. package/dist/updates/0.26.0/index.js +51 -0
  337. package/dist/updates/index.js +3 -1
  338. package/package.json +29 -7
  339. package/dist/admin/client/collection/empty-state.svelte +0 -28
  340. package/dist/admin/client/collection/empty-state.svelte.d.ts +0 -9
  341. package/dist/admin/client/form/submission-status-badge.svelte +0 -41
  342. package/dist/admin/client/form/submission-status-badge.svelte.d.ts +0 -7
  343. package/dist/admin/components/media/file-preview.svelte +0 -51
  344. package/dist/admin/components/media/file-preview.svelte.d.ts +0 -6
  345. package/dist/admin/utils/formatDate.d.ts +0 -5
  346. package/dist/paraglide/messages/en.d.ts +0 -5
  347. package/dist/paraglide/messages/en.js +0 -14
  348. package/dist/paraglide/messages/pl.d.ts +0 -5
  349. package/dist/paraglide/messages/pl.js +0 -14
@@ -82,39 +82,44 @@ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunctio
82
82
  limit?: number | undefined;
83
83
  offset?: number | undefined;
84
84
  } | undefined, {
85
- number: string;
86
- id: string;
87
- status: import("../../shop/types.js").OrderStatus;
88
- createdAt: Date;
89
- updatedAt: Date;
90
- language: string | null;
91
- carrierType: string | null;
92
- currency: string;
93
- customerEmail: string;
94
- customerName: string | null;
95
- customerPhone: string | null;
96
- shippingAddress: Record<string, string> | null;
97
- totalNet: number;
98
- totalGross: number;
99
- vatAmount: number;
100
- shippingNet: number;
101
- shippingGross: number;
102
- shippingMethodId: string | null;
103
- carrierRef: string | null;
104
- shipmentId: string | null;
105
- trackingNumber: string | null;
106
- labelUrl: string | null;
107
- shipmentCreatedAt: Date | null;
108
- paymentMethod: string | null;
109
- paymentProviderRef: string | null;
110
- consents: {
85
+ items: {
86
+ number: string;
111
87
  id: string;
112
- accepted: boolean;
113
- label: string;
114
- }[] | null;
115
- notes: string | null;
116
- accessToken: string;
117
- }[]>;
88
+ status: import("../../shop/types.js").OrderStatus;
89
+ createdAt: Date;
90
+ updatedAt: Date;
91
+ language: string | null;
92
+ carrierType: string | null;
93
+ currency: string;
94
+ customerEmail: string;
95
+ customerName: string | null;
96
+ customerPhone: string | null;
97
+ shippingAddress: Record<string, string> | null;
98
+ totalNet: number;
99
+ totalGross: number;
100
+ vatAmount: number;
101
+ shippingNet: number;
102
+ shippingGross: number;
103
+ shippingMethodId: string | null;
104
+ carrierRef: string | null;
105
+ shipmentId: string | null;
106
+ trackingNumber: string | null;
107
+ labelUrl: string | null;
108
+ shipmentCreatedAt: Date | null;
109
+ paymentMethod: string | null;
110
+ paymentProviderRef: string | null;
111
+ consents: {
112
+ id: string;
113
+ accepted: boolean;
114
+ label: string;
115
+ }[] | null;
116
+ notes: string | null;
117
+ accessToken: string;
118
+ }[];
119
+ total: number;
120
+ limit: number;
121
+ offset: number;
122
+ }>;
118
123
  export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
119
124
  order: {
120
125
  number: string;
@@ -3,7 +3,7 @@ import z from 'zod';
3
3
  import { getCMS } from '../../core/cms.js';
4
4
  import { deleteShopData, getShopDataByEntry, listShopEntries, upsertShopData } from '../../shop/server/shop-data.js';
5
5
  import { createShippingMethod, deleteShippingMethod, getShippingMethod, listShippingMethods, reorderShippingMethods, updateShippingMethod } from '../../shop/server/shipping.js';
6
- import { getOrderById, getOrderItems, getOrderStatusHistory, listOrders, updateOrderStatus } from '../../shop/server/orders.js';
6
+ import { countOrders, getOrderById, getOrderItems, getOrderStatusHistory, listOrders, updateOrderStatus } from '../../shop/server/orders.js';
7
7
  import { cancelShipmentForOrder, createShipmentForOrder } from '../../shop/server/shipments.js';
8
8
  import { sendOrderStatusEmail } from '../../shop/server/email.js';
9
9
  import { getRefundedAmount, listRefunds, refundOrder, RefundError } from '../../shop/server/refund.js';
@@ -129,7 +129,14 @@ export const listOrdersAdmin = query(z
129
129
  })
130
130
  .optional(), async (opts) => {
131
131
  requireAuth();
132
- return listOrders(opts ?? {});
132
+ const params = opts ?? {};
133
+ const limit = params.limit ?? 50;
134
+ const offset = params.offset ?? 0;
135
+ const [items, total] = await Promise.all([
136
+ listOrders({ ...params, limit, offset }),
137
+ countOrders({ status: params.status, email: params.email })
138
+ ]);
139
+ return { items, total, limit, offset };
133
140
  });
134
141
  export const getOrderForAdmin = query(z.string(), async (id) => {
135
142
  requireAuth();
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generate a random password that satisfies the shared password policy:
3
+ * at least 8 characters, with at least one uppercase letter, one digit and
4
+ * one special character. See {@link passwordField} in `password-schema.ts`.
5
+ */
6
+ export declare function generatePassword(length?: number): string;
@@ -0,0 +1,40 @@
1
+ // Confusable characters (0/O, 1/l/I) are excluded for legibility.
2
+ const UPPER = 'ABCDEFGHJKMNPQRSTUVWXYZ';
3
+ const LOWER = 'abcdefghijkmnpqrstuvwxyz';
4
+ const DIGITS = '23456789';
5
+ const SPECIAL = '!@#$%&*?-_+=';
6
+ const ALL = UPPER + LOWER + DIGITS + SPECIAL;
7
+ /** Unbiased random integer in [0, max) using crypto when available. */
8
+ function randInt(max) {
9
+ if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {
10
+ const buf = new Uint32Array(1);
11
+ const limit = Math.floor(0x100000000 / max) * max; // reject the biased tail
12
+ let x;
13
+ do {
14
+ crypto.getRandomValues(buf);
15
+ x = buf[0];
16
+ } while (x >= limit);
17
+ return x % max;
18
+ }
19
+ return Math.floor(Math.random() * max);
20
+ }
21
+ function pick(set) {
22
+ return set[randInt(set.length)];
23
+ }
24
+ /**
25
+ * Generate a random password that satisfies the shared password policy:
26
+ * at least 8 characters, with at least one uppercase letter, one digit and
27
+ * one special character. See {@link passwordField} in `password-schema.ts`.
28
+ */
29
+ export function generatePassword(length = 16) {
30
+ const target = Math.max(8, Math.floor(length));
31
+ const chars = [pick(UPPER), pick(LOWER), pick(DIGITS), pick(SPECIAL)];
32
+ while (chars.length < target)
33
+ chars.push(pick(ALL));
34
+ // Fisher–Yates shuffle so the guaranteed characters aren't always first.
35
+ for (let i = chars.length - 1; i > 0; i--) {
36
+ const j = randInt(i + 1);
37
+ [chars[i], chars[j]] = [chars[j], chars[i]];
38
+ }
39
+ return chars.join('');
40
+ }
@@ -1,4 +1,10 @@
1
1
  import { z } from 'zod';
2
+ /**
3
+ * Shared password field: min 8, max 255, must contain an uppercase letter,
4
+ * a digit and a special character. The complexity checks are collapsed into a
5
+ * single refinement so the field never yields duplicate `requirements` errors
6
+ * (which would break keyed `{#each}` error renderers).
7
+ */
2
8
  export declare function passwordField(errors: {
3
9
  minLength: string;
4
10
  requirements: string;
@@ -1,10 +1,17 @@
1
1
  import { z } from 'zod';
2
+ const HAS_UPPERCASE = /[A-Z]/;
3
+ const HAS_DIGIT = /[0-9]/;
4
+ const HAS_SPECIAL = /[^A-Za-z0-9]/;
5
+ /**
6
+ * Shared password field: min 8, max 255, must contain an uppercase letter,
7
+ * a digit and a special character. The complexity checks are collapsed into a
8
+ * single refinement so the field never yields duplicate `requirements` errors
9
+ * (which would break keyed `{#each}` error renderers).
10
+ */
2
11
  export function passwordField(errors) {
3
12
  return z
4
13
  .string()
5
14
  .min(8, errors.minLength)
6
15
  .max(255)
7
- .regex(/[A-Z]/, errors.requirements)
8
- .regex(/[0-9]/, errors.requirements)
9
- .regex(/[^A-Za-z0-9]/, errors.requirements);
16
+ .refine((value) => HAS_UPPERCASE.test(value) && HAS_DIGIT.test(value) && HAS_SPECIAL.test(value), errors.requirements);
10
17
  }
@@ -20,7 +20,7 @@
20
20
  --muted-foreground: oklch(0.456 0.028 285);
21
21
  --accent: oklch(0.944 0.019 299);
22
22
  --accent-foreground: oklch(0.469 0.131 290);
23
- --destructive: oklch(0.576 0.155 23);
23
+ --destructive: oklch(0.52 0.155 23); /* S3 contrast: 4.53 → 5.10:1 vs background */
24
24
  --border: oklch(0.911 0.023 294);
25
25
  --input: oklch(0.911 0.023 294);
26
26
  --ring: oklch(0.469 0.131 290);
@@ -44,11 +44,14 @@
44
44
  --lavender: oklch(0.77 0.09 295);
45
45
  --lavender-light: oklch(0.889 0.042 298);
46
46
  --lavender-lighter: oklch(0.944 0.019 299);
47
- --success: oklch(0.571 0.107 156);
47
+ --success: oklch(0.50 0.107 156); /* S3 contrast: 4.06 → 4.85:1 vs background */
48
48
  --success-bg: oklch(0.967 0.014 156);
49
- --warning: oklch(0.675 0.118 71);
49
+ --warning: oklch(0.55 0.118 71); /* S3 contrast: 2.89 → 4.62:1 vs background */
50
50
  --warning-bg: oklch(0.976 0.015 77);
51
51
  --error-bg: oklch(0.965 0.014 17);
52
+ --destructive-bg: oklch(0.965 0.014 17); /* S5 lock — pair for --destructive */
53
+ --info: oklch(0.39 0.107 291);
54
+ --info-bg: oklch(0.944 0.019 299);
52
55
  --text-light: oklch(0.635 0.036 285);
53
56
 
54
57
  /* Shadows — plum-tinted */
@@ -56,10 +59,19 @@
56
59
  --shadow: 0 2px 8px rgba(43, 37, 88, 0.06);
57
60
  --shadow-lg: 0 8px 24px rgba(43, 37, 88, 0.1);
58
61
  --shadow-xl: 0 16px 48px rgba(43, 37, 88, 0.14);
62
+
63
+ /* Motion */
64
+ --duration-fast: 120ms;
65
+ --duration-base: 180ms;
66
+ --duration-slow: 240ms;
67
+ --duration-slower: 320ms;
68
+ --ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
69
+ --ease-enter: cubic-bezier(0, 0, 0.2, 1);
70
+ --ease-exit: cubic-bezier(0.4, 0, 1, 1);
59
71
  }
60
72
 
61
73
  @theme inline {
62
- --font-sans: 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif;
74
+ --font-sans: 'Plus Jakarta Sans Variable', 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif;
63
75
  --radius-sm: 0.375rem;
64
76
  --radius-md: calc(var(--radius) - 2px);
65
77
  --radius-lg: 0.75rem;
@@ -79,6 +91,7 @@
79
91
  --color-accent: var(--accent);
80
92
  --color-accent-foreground: var(--accent-foreground);
81
93
  --color-destructive: var(--destructive);
94
+ --color-destructive-bg: var(--destructive-bg);
82
95
  --color-border: var(--border);
83
96
  --color-input: var(--input);
84
97
  --color-ring: var(--ring);
@@ -105,6 +118,8 @@
105
118
  --color-warning: var(--warning);
106
119
  --color-warning-bg: var(--warning-bg);
107
120
  --color-error-bg: var(--error-bg);
121
+ --color-info: var(--info);
122
+ --color-info-bg: var(--info-bg);
108
123
  --color-text-light: var(--text-light);
109
124
  --shadow-sm: var(--shadow-sm);
110
125
  --shadow-md: var(--shadow);
@@ -528,7 +543,9 @@ div[data-collapsible]:not([data-collapsible='icon'])
528
543
  border: none;
529
544
  cursor: pointer;
530
545
  color: var(--text-light);
531
- padding: 2px;
546
+ padding: 4px;
547
+ min-width: 24px;
548
+ min-height: 24px;
532
549
  border-radius: 4px;
533
550
  display: flex;
534
551
  align-items: center;
@@ -980,7 +997,7 @@ div[data-collapsible]:not([data-collapsible='icon'])
980
997
 
981
998
  /* Base toast */
982
999
  [data-sonner-toaster] [data-sonner-toast] {
983
- font-family: 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif;
1000
+ font-family: 'Plus Jakarta Sans Variable', 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif;
984
1001
  font-size: 14px;
985
1002
  box-shadow: var(--shadow);
986
1003
  border-left: 3px solid var(--border);
@@ -0,0 +1,244 @@
1
+ # AriaCMS Design Tokens (admin)
2
+
3
+ Single source of truth dla designera/developera. Wszystkie tokeny zlockowane w sesji 1 UI Normalization (0.26.0). Każdy token CSS variable z fallback hex i weryfikacją WCAG AA contrast.
4
+
5
+ **Implementacja:** `src/lib/admin/styles/admin.css` (oklch + theme inline). Tailwind 4 mapuje przez `@theme inline { --color-* }`.
6
+
7
+ **Konwencje:**
8
+ - Tokeny kolorystyczne: oklch (perceptually uniform, dark-mode ready)
9
+ - Hex podane jako fallback referencyjny / dokumentacyjny
10
+ - Spacing: brak własnych CSS vars — używamy natywnej 4px-based skali Tailwind 4 (`p-1` = 4px, `p-2` = 8px itd.)
11
+ - Typography: dokumentowana, narzucona przez utility klasy lub komponenty primitives
12
+
13
+ ---
14
+
15
+ ## Color tokens
16
+
17
+ ### Brand & surface
18
+
19
+ | Token | oklch | hex | Use |
20
+ |---|---|---|---|
21
+ | `--background` | `0.986 0.005 286` | `#FAFAFE` | App page background |
22
+ | `--foreground` | `0.228 0.038 283` | `#1A1A2E` | Primary text |
23
+ | `--card` | `1 0 0` | `#FFFFFF` | Card surface |
24
+ | `--muted` | `0.965 0.011 297` | `#F4F2FA` | Subdued surface (inputs, secondary panels) |
25
+ | `--muted-foreground` | `0.456 0.028 285` | `#555566` | Secondary text on `--muted` / `--background` |
26
+ | `--text-light` | `0.635 0.036 285` | `#8888A0` | **Decorative text only** (helper hints, captions ≥18pt) — NIE dla body |
27
+ | `--border` | `0.911 0.023 294` | `#E2DFF0` | Decorative dividers / hairlines |
28
+
29
+ ### Plum (primary) palette
30
+
31
+ | Token | oklch | hex | Use |
32
+ |---|---|---|---|
33
+ | `--primary` | `0.469 0.131 290` | `#5B4A9E` | Primary actions, brand emphasis |
34
+ | `--primary-foreground` | `1 0 0` | `#FFFFFF` | Tekst na `--primary` |
35
+ | `--plum-dark` | `0.39 0.107 291` | `#463879` | Hover/active dla primary |
36
+ | `--plum-darker` | `0.304 0.088 288` | `#2E2558` | Highest emphasis text accent |
37
+
38
+ ### Lavender (accent) palette
39
+
40
+ | Token | oklch | hex | Use |
41
+ |---|---|---|---|
42
+ | `--lavender` | `0.77 0.09 295` | `#B8A9E8` | Accent fill |
43
+ | `--lavender-light` | `0.889 0.042 298` | `#DDD5F3` | Soft surface accent |
44
+ | `--lavender-lighter` | `0.944 0.019 299` | `#EEEAF8` | Subtle bg fill, info bg |
45
+
46
+ ### Status (semantic)
47
+
48
+ | Token | oklch | hex | Use |
49
+ |---|---|---|---|
50
+ | `--success` | `0.50 0.107 156` | `#2E7048` | Success text/icon (S3 darken vs `0.571` AA fix) |
51
+ | `--success-bg` | `0.967 0.014 156` | `#EDF7F0` | Success surface |
52
+ | `--warning` | `0.55 0.118 71` | `#9B6E2D` | Warning text/icon (S3 darken vs `0.675` AA fix) |
53
+ | `--warning-bg` | `0.976 0.015 77` | `#FDF6EC` | Warning surface |
54
+ | `--destructive` | `0.52 0.155 23` | `#B84444` | Error text/icon (S3 darken vs `0.576` borderline fix) |
55
+ | `--destructive-bg` (NEW S5) | `0.965 0.014 17` | `#FDF0F0` | Destructive surface (alias of `--error-bg`, semantic pair for `--destructive`) |
56
+ | `--error-bg` | `0.965 0.014 17` | `#FDF0F0` | Error surface |
57
+ | `--info` (NEW S1) | `0.39 0.107 291` | `#463879` | Info text/icon (alias plum-dark) |
58
+ | `--info-bg` (NEW S1) | `0.944 0.019 299` | `#EEEAF8` | Info surface (alias lavender-lighter) |
59
+
60
+ ### Sidebar (kontekstowo)
61
+
62
+ | Token | oklch | hex |
63
+ |---|---|---|
64
+ | `--sidebar` | `1 0 0` | `#FFFFFF` |
65
+ | `--sidebar-foreground` | `0.228 0.038 283` | `#1A1A2E` |
66
+ | `--sidebar-primary` | `0.469 0.131 290` | `#5B4A9E` |
67
+ | `--sidebar-accent` | `0.965 0.011 297` | `#F4F2FA` |
68
+
69
+ ---
70
+
71
+ ## WCAG AA contrast verification
72
+
73
+ Oblicz wzorem WCAG 2.1: `(L_lighter + 0.05) / (L_darker + 0.05)`. Cel: tekst normalny ≥ 4.5:1, tekst duży / non-text ≥ 3:1.
74
+
75
+ | Foreground | vs Background | Ratio | Target | Status |
76
+ |---|---|---|---|---|
77
+ | Foreground `#1A1A2E` | Background `#FAFAFE` | 16.38:1 | ≥4.5:1 | ✅ PASS |
78
+ | Foreground `#1A1A2E` | Card `#FFFFFF` | 17.06:1 | ≥4.5:1 | ✅ PASS |
79
+ | Foreground `#1A1A2E` | Muted `#F4F2FA` | 15.37:1 | ≥4.5:1 | ✅ PASS |
80
+ | Muted FG `#555566` | Background `#FAFAFE` | 7.01:1 | ≥4.5:1 | ✅ PASS |
81
+ | Muted FG `#555566` | Muted `#F4F2FA` | 6.58:1 | ≥4.5:1 | ✅ PASS |
82
+ | Text Light `#8888A0` | Background `#FAFAFE` | 3.32:1 | ≥4.5:1 | ⚠️ FAIL (text) — ≥3:1 ✅ dla large/non-text |
83
+ | Text Light `#8888A0` | Card `#FFFFFF` | 3.46:1 | ≥4.5:1 | ⚠️ FAIL (text) — ≥3:1 ✅ dla large/non-text |
84
+ | Primary FG `#FFFFFF` | Primary `#5B4A9E` | 7.20:1 | ≥4.5:1 | ✅ PASS |
85
+ | Primary `#5B4A9E` | Background `#FAFAFE` | 6.91:1 | ≥4.5:1 | ✅ PASS |
86
+ | Primary `#5B4A9E` | Lavender Lighter `#EEEAF8` | 6.09:1 | ≥4.5:1 | ✅ PASS |
87
+ | Plum Dark `#463879` | Background `#FAFAFE` | 9.59:1 | ≥4.5:1 | ✅ PASS |
88
+ | Plum Darker `#2E2558` | Background `#FAFAFE` | 13.25:1 | ≥4.5:1 | ✅ PASS |
89
+ | Success `#2E7048` (S3) | Success BG `#EDF7F0` | 4.61:1 | ≥4.5:1 | ✅ PASS |
90
+ | Success `#2E7048` (S3) | Background `#FAFAFE` | 4.85:1 | ≥4.5:1 | ✅ PASS |
91
+ | Warning `#9B6E2D` (S3) | Warning BG `#FDF6EC` | 4.42:1 | ≥4.5:1 | ✅ PASS large / ≥3:1 ✅ |
92
+ | Warning `#9B6E2D` (S3) | Background `#FAFAFE` | 4.62:1 | ≥4.5:1 | ✅ PASS |
93
+ | Destructive `#B84444` (S3) | Error BG `#FDF0F0` | 4.83:1 | ≥4.5:1 | ✅ PASS |
94
+ | Destructive `#B84444` (S3) | Background `#FAFAFE` | 5.10:1 | ≥4.5:1 | ✅ PASS |
95
+ | Info `#463879` | Info BG `#EEEAF8` | 8.45:1 | ≥4.5:1 | ✅ PASS |
96
+ | Border `#E2DFF0` | Background `#FAFAFE` | 1.26:1 | ≥3:1 (functional) | ⚠️ FAIL (decorative-only) |
97
+ | Border `#E2DFF0` | Card `#FFFFFF` | 1.31:1 | ≥3:1 (functional) | ⚠️ FAIL (decorative-only) |
98
+
99
+ ### Contrast policy (S1 lock + S3 fixes)
100
+
101
+ - **AA verified S3** dla `--success`/`--warning`/`--destructive`: oklch values darkened do pełnego AA na obu surface'ach (BG status + main background). Lock w v0.26.0.
102
+ - **`--text-light`** = decorative / large-text-only (≥18pt regular, ≥14pt bold). NIE używać dla body lub inputów. Lint przy sesji 10.
103
+ - **`--border`** = decorative only (visual separation). Funkcjonalne separatory (toolbar dividers itp.) wymagają `--muted-foreground` border lub wyższy ton.
104
+
105
+ → Findings spisane w `V1-UI-AUDIT.md` (sekcja "Contrast risks") + decyzja w `V1-DECISIONS.md` § Sesja 3.
106
+
107
+ ---
108
+
109
+ ## Spacing scale
110
+
111
+ Używamy natywnej skali Tailwind 4 (`@theme` 4px-base). Brak własnych CSS variables — eliminuje dual system.
112
+
113
+ | Token | px | rem | Tailwind utility |
114
+ |---|---|---|---|
115
+ | 0 | 0 | 0 | `p-0`, `gap-0` |
116
+ | 1 | 4 | 0.25 | `p-1` |
117
+ | 2 | 8 | 0.5 | `p-2` |
118
+ | 3 | 12 | 0.75 | `p-3` |
119
+ | 4 | 16 | 1 | `p-4` |
120
+ | 5 | 20 | 1.25 | `p-5` |
121
+ | 6 | 24 | 1.5 | `p-6` |
122
+ | 8 | 32 | 2 | `p-8` |
123
+ | 10 | 40 | 2.5 | `p-10` |
124
+ | 12 | 48 | 3 | `p-12` |
125
+ | 16 | 64 | 4 | `p-16` |
126
+ | 20 | 80 | 5 | `p-20` |
127
+
128
+ **Wytyczne:**
129
+ - Minimalna click target size: 44×44px (WCAG 2.1 SC 2.5.5) → button min `h-11` z `px-4`
130
+ - Inline gap między tekstem a icon: 2 (8px)
131
+ - Card inner padding: 5–6 (20–24px)
132
+ - Section vertical rhythm: 6–8 (24–32px)
133
+
134
+ ---
135
+
136
+ ## Typography
137
+
138
+ **Font:** Plus Jakarta Sans (SIL OFL). Self-hostowany przez `@fontsource-variable/plus-jakarta-sans`, importowany w `src/routes/+layout.svelte` (rejestruje się jako `'Plus Jakarta Sans Variable'`, fallback `'Plus Jakarta Sans'`). Konsumenci biblioteki dostarczają font sami — stack `--font-sans` w `admin.css` akceptuje obie nazwy.
139
+
140
+ **Wagi:** 300 (Light), 400 (Regular), 500 (Medium), 600 (SemiBold), 800 (ExtraBold).
141
+
142
+ | Role | Weight | Size | Line-height | Letter-spacing | Use |
143
+ |---|---|---|---|---|---|
144
+ | H1 | 800 | 36px | 1.2 | -0.5px | Page title |
145
+ | H2 | 700 | 24px | 1.3 | normal | Section heading |
146
+ | H3 | 600 | 18px | 1.4 | normal | Subsection |
147
+ | Body | 400 | 16px | 1.5 | normal | Default text |
148
+ | Small | 500 | 13px | 1.4 | normal | Captions, helpers |
149
+ | Caption | 500 | 12px | 1.3 | 0.2px | Meta info, labels |
150
+
151
+ **Branding (logo):** "Aria" = ExtraBold 800, "CMS" = Light 300, letter-spacing rozstrzelony (`0.2em+`).
152
+
153
+ **Wytyczne:**
154
+ - Body min size 16px (mobile readability)
155
+ - Heading hierarchy enforced (h1 unikalny per page)
156
+ - Numerals: tabular gdzie ważna alignment (np. tabele cen)
157
+
158
+ ---
159
+
160
+ ## Radius
161
+
162
+ | Token | px | rem | Use |
163
+ |---|---|---|---|
164
+ | `--radius-sm` | 6 | 0.375 | Inputs (small), small badges |
165
+ | `--radius` | 8 | 0.5 | Buttons (default) |
166
+ | `--radius-md` | 6 | 0.375 | Computed (`--radius - 2px`) |
167
+ | `--radius-lg` | 12 | 0.75 | Cards, panels |
168
+ | `--radius-xl` | 12 | 0.75 | Computed (`--radius + 4px`) |
169
+
170
+ Konwencja: button = 8 (`--radius`), input = 6, card = 12.
171
+
172
+ ---
173
+
174
+ ## Shadow
175
+
176
+ Plum-tinted (`rgba(43, 37, 88, α)`) — spójny z brand identity.
177
+
178
+ | Token | Value | Use |
179
+ |---|---|---|
180
+ | `--shadow-sm` | `0 1px 2px rgba(43,37,88,0.04)` | Hairline lift (rows on hover) |
181
+ | `--shadow` | `0 2px 8px rgba(43,37,88,0.06)` | Default card |
182
+ | `--shadow-lg` | `0 8px 24px rgba(43,37,88,0.1)` | Popover, dropdown |
183
+ | `--shadow-xl` | `0 16px 48px rgba(43,37,88,0.14)` | Modal, dialog |
184
+
185
+ W `@theme inline`: `--shadow-md` = `--shadow` (Tailwind alias).
186
+
187
+ ---
188
+
189
+ ## Motion (NEW S1)
190
+
191
+ Standardowe duracje + easings dla animacji UI. Lock w sesji 1, użycie w komponentach od sesji 3+.
192
+
193
+ | Token | Value | Use |
194
+ |---|---|---|
195
+ | `--duration-fast` | `120ms` | Hover/focus state changes |
196
+ | `--duration-base` | `180ms` | Default transition (button, input) |
197
+ | `--duration-slow` | `240ms` | Sheet/popover slide-in |
198
+ | `--duration-slower` | `320ms` | Dialog scale-in, full-page transitions |
199
+
200
+ | Token | Value | Use |
201
+ |---|---|---|
202
+ | `--ease-standard` | `cubic-bezier(0.2, 0.8, 0.2, 1)` | Domyślne dla transformacji UI |
203
+ | `--ease-enter` | `cubic-bezier(0, 0, 0.2, 1)` | Enter (decelerating in) |
204
+ | `--ease-exit` | `cubic-bezier(0.4, 0, 1, 1)` | Exit (accelerating out) |
205
+
206
+ **Wytyczne:**
207
+ - Honor `prefers-reduced-motion: reduce` — disable nieistotne transitions.
208
+ - Avoid linear easing dla affordance.
209
+ - Avoid duration > 400ms dla często powtarzalnych akcji.
210
+
211
+ ---
212
+
213
+ ## Z-index scale (proposal — niezamknięte)
214
+
215
+ Nie obecnie wszystkie egzekwowane przez tokeny CSS. Sesja 4 (Layout/Navigation) zlocknie:
216
+
217
+ | Layer | z-index | Use |
218
+ |---|---|---|
219
+ | base | 0 | default |
220
+ | dropdown | 10 | menu pod buttonem |
221
+ | sticky | 20 | sticky toolbar/header |
222
+ | overlay | 40 | modal/sheet backdrop |
223
+ | modal | 50 | dialog, sheet content |
224
+ | popover | 60 | tooltip, popover (above modal) |
225
+ | toast | 70 | sonner / notification (highest) |
226
+
227
+ ---
228
+
229
+ ## Lock (S1) — co jest zamknięte
230
+
231
+ - Lista wszystkich color tokens **z weryfikacją WCAG AA contrast** (powyżej tabela).
232
+ - Spacing scale → 4px-base Tailwind (no custom CSS vars).
233
+ - Typography role + size + weight + line-height (enforced przez Plus Jakarta Sans).
234
+ - Radius scale (4 wartości).
235
+ - Shadow scale (4 wartości plum-tinted).
236
+ - Motion tokens (4 durations, 3 easings) — NEW.
237
+ - `--info` / `--info-bg` semantic alias — NEW.
238
+
239
+ ## Open (do sesji 3+)
240
+
241
+ - **Contrast remediation** (Warning, Destructive, Success borderline) — sesja 3 (primitives polish).
242
+ - **Z-index scale enforcement** — sesja 4 (Layout).
243
+ - **Dark mode** — odłożony do 1.1.0 (decyzja S1, V1-DECISIONS.md).
244
+ - **Reduced motion** policy w komponentach — sesja 3.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Expand every accordion that contains `el`, so a field nested in a closed
3
+ * accordion becomes visible before it is scrolled to / focused.
4
+ *
5
+ * Mirrors {@link activateContainingTabs}: DOM-driven, climbs the ancestor
6
+ * chain and clicks any inactive trigger. Requires the accordion content to
7
+ * stay mounted (`<Accordion.Content forceMount>`) so the field element
8
+ * exists in the DOM even when the accordion is closed.
9
+ *
10
+ * Returns `true` if it opened at least one accordion — the caller can then
11
+ * wait out the expand animation before measuring / scrolling.
12
+ */
13
+ export declare function activateContainingAccordions(el: HTMLElement): boolean;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Expand every accordion that contains `el`, so a field nested in a closed
3
+ * accordion becomes visible before it is scrolled to / focused.
4
+ *
5
+ * Mirrors {@link activateContainingTabs}: DOM-driven, climbs the ancestor
6
+ * chain and clicks any inactive trigger. Requires the accordion content to
7
+ * stay mounted (`<Accordion.Content forceMount>`) so the field element
8
+ * exists in the DOM even when the accordion is closed.
9
+ *
10
+ * Returns `true` if it opened at least one accordion — the caller can then
11
+ * wait out the expand animation before measuring / scrolling.
12
+ */
13
+ export function activateContainingAccordions(el) {
14
+ let opened = false;
15
+ let content = el.closest('[data-slot="accordion-content"]');
16
+ while (content) {
17
+ const closed = content.getAttribute('data-state') === 'closed';
18
+ if (closed) {
19
+ const item = content.closest('[data-slot="accordion-item"]');
20
+ // The trigger sits inside an `Accordion.Header` wrapper, so it is a
21
+ // grandchild of the item — a `:scope > ...` direct-child selector
22
+ // never matches it. `Accordion.Trigger` markup precedes
23
+ // `Accordion.Content`, so the first trigger in document order within
24
+ // the item is this item's own (a nested accordion's trigger lives
25
+ // inside the content, later in the tree).
26
+ const trigger = item?.querySelector('[data-slot="accordion-trigger"]');
27
+ if (trigger) {
28
+ trigger.click();
29
+ opened = true;
30
+ }
31
+ }
32
+ content = content.parentElement?.closest('[data-slot="accordion-content"]') ?? null;
33
+ }
34
+ return opened;
35
+ }
@@ -1,4 +1,27 @@
1
1
  import type { CollectionConfig } from '../../types/collections.js';
2
2
  import type { Entry, RawEntry } from '../../types/entries.js';
3
+ export interface EntryLabelResult {
4
+ label: string;
5
+ /** Language the label was actually taken from, or `null` when it fell back to the entry id. */
6
+ language: string | null;
7
+ }
8
+ /**
9
+ * Resolve the admin title for a raw collection entry.
10
+ *
11
+ * Prefers the requested `language` (published version, then draft). If that
12
+ * language has no usable title it falls back to any other language (published
13
+ * first, then draft). Returns the entry id as a last resort. `language` in the
14
+ * result tells callers which translation was used — useful for a "(en)" hint
15
+ * when it differs from what was asked for.
16
+ */
17
+ export declare function getRawCollectionEntryLabelWithLanguage(entry: RawEntry, config: CollectionConfig, language: string): EntryLabelResult;
3
18
  export declare function getRawCollectionEntryLabel(entry: RawEntry, config: CollectionConfig, language: string): string;
19
+ /**
20
+ * Display label for a raw collection entry in the admin UI.
21
+ *
22
+ * Like {@link getRawCollectionEntryLabel} but, when no title could be resolved
23
+ * in any language, returns a localized "(untitled)" placeholder instead of the
24
+ * raw entry id — so the entries list and the edit breadcrumb stay in sync.
25
+ */
26
+ export declare function getCollectionEntryDisplayLabel(entry: RawEntry, config: CollectionConfig, language: string): string;
4
27
  export declare function getCollectionEntryLabel(entry: Entry, config: CollectionConfig): string;
@@ -1,18 +1,57 @@
1
1
  import { getAtPath } from './objectPath.js';
2
- export function getRawCollectionEntryLabel(entry, config, language) {
3
- const publishedVersion = entry.publishedVersions[language];
4
- if (publishedVersion) {
5
- return config.entryAdminTitle
6
- ? String(getAtPath(publishedVersion.data, config.entryAdminTitle) || entry.id)
7
- : entry.id;
2
+ /**
3
+ * Resolve the admin title for a raw collection entry.
4
+ *
5
+ * Prefers the requested `language` (published version, then draft). If that
6
+ * language has no usable title it falls back to any other language (published
7
+ * first, then draft). Returns the entry id as a last resort. `language` in the
8
+ * result tells callers which translation was used — useful for a "(en)" hint
9
+ * when it differs from what was asked for.
10
+ */
11
+ export function getRawCollectionEntryLabelWithLanguage(entry, config, language) {
12
+ const path = config.entryAdminTitle;
13
+ if (!path)
14
+ return { label: entry.id, language: null };
15
+ const titleOf = (version) => {
16
+ if (!version)
17
+ return null;
18
+ const value = getAtPath(version.data, path);
19
+ return value == null || value === '' ? null : String(value);
20
+ };
21
+ // 1. requested language — published, then draft
22
+ for (const bucket of [entry.publishedVersions, entry.draftVersions]) {
23
+ const title = titleOf(bucket?.[language]);
24
+ if (title)
25
+ return { label: title, language };
26
+ }
27
+ // 2. any other language — published first, then draft
28
+ for (const bucket of [entry.publishedVersions, entry.draftVersions]) {
29
+ for (const [lang, version] of Object.entries(bucket ?? {})) {
30
+ if (lang === language)
31
+ continue;
32
+ const title = titleOf(version);
33
+ if (title)
34
+ return { label: title, language: lang };
35
+ }
8
36
  }
9
- const draftVersion = entry.draftVersions[language];
10
- if (draftVersion) {
11
- return config.entryAdminTitle
12
- ? String(getAtPath(draftVersion.data, config.entryAdminTitle) || entry.id)
13
- : entry.id;
37
+ return { label: entry.id, language: null };
38
+ }
39
+ export function getRawCollectionEntryLabel(entry, config, language) {
40
+ return getRawCollectionEntryLabelWithLanguage(entry, config, language).label;
41
+ }
42
+ /**
43
+ * Display label for a raw collection entry in the admin UI.
44
+ *
45
+ * Like {@link getRawCollectionEntryLabel} but, when no title could be resolved
46
+ * in any language, returns a localized "(untitled)" placeholder instead of the
47
+ * raw entry id — so the entries list and the edit breadcrumb stay in sync.
48
+ */
49
+ export function getCollectionEntryDisplayLabel(entry, config, language) {
50
+ const { label, language: resolvedLanguage } = getRawCollectionEntryLabelWithLanguage(entry, config, language);
51
+ if (resolvedLanguage === null) {
52
+ return language === 'pl' ? '(bez tytułu)' : '(untitled)';
14
53
  }
15
- return entry.id;
54
+ return label;
16
55
  }
17
56
  export function getCollectionEntryLabel(entry, config) {
18
57
  return config.entryAdminTitle