@aphexcms/cms-core 8.1.0 → 9.1.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 (290) hide show
  1. package/dist/api/api-keys.d.ts +8 -3
  2. package/dist/api/api-keys.d.ts.map +1 -1
  3. package/dist/api/schemas/assets.js +1 -1
  4. package/dist/api/schemas/documents.d.ts +0 -2
  5. package/dist/api/schemas/documents.d.ts.map +1 -1
  6. package/dist/api/schemas/documents.js +2 -8
  7. package/dist/api/schemas/instance.d.ts +6 -0
  8. package/dist/api/schemas/instance.d.ts.map +1 -0
  9. package/dist/api/schemas/instance.js +7 -0
  10. package/dist/api/schemas/user.js +1 -1
  11. package/dist/auth/auth-hooks.d.ts.map +1 -1
  12. package/dist/auth/auth-hooks.js +9 -3
  13. package/dist/cli/generate-types.d.ts.map +1 -1
  14. package/dist/cli/generate-types.js +198 -11
  15. package/dist/cli/generate-types.js.map +1 -1
  16. package/dist/components/AdminApp.svelte +55 -149
  17. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  18. package/dist/components/admin/DocumentEditor.svelte +282 -253
  19. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  20. package/dist/components/admin/DocumentVersionPanel.svelte +3 -2
  21. package/dist/components/admin/DocumentVersionPanel.svelte.d.ts.map +1 -1
  22. package/dist/components/admin/MediaBrowser.svelte +29 -11
  23. package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -1
  24. package/dist/components/admin/ObjectModal.svelte +62 -75
  25. package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
  26. package/dist/components/admin/SchemaField.svelte +2 -2
  27. package/dist/components/admin/fields/ArrayField.svelte +13 -3
  28. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  29. package/dist/components/admin/fields/FileField.svelte +1 -1
  30. package/dist/components/admin/fields/ImageField.svelte +1 -1
  31. package/dist/components/admin/fields/ReferenceField.svelte +42 -11
  32. package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
  33. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte +116 -0
  34. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts +12 -0
  35. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts.map +1 -0
  36. package/dist/components/admin/fields/richtext/PortableTextInlineView.svelte +111 -0
  37. package/dist/components/admin/fields/richtext/PortableTextInlineView.svelte.d.ts +12 -0
  38. package/dist/components/admin/fields/richtext/PortableTextInlineView.svelte.d.ts.map +1 -0
  39. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte +67 -0
  40. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts +12 -0
  41. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts.map +1 -0
  42. package/dist/components/admin/fields/richtext/RichtextField.svelte +1296 -0
  43. package/dist/components/admin/fields/richtext/RichtextField.svelte.d.ts +15 -0
  44. package/dist/components/admin/fields/richtext/RichtextField.svelte.d.ts.map +1 -0
  45. package/dist/components/admin/fields/richtext/custom-annotation-mark.d.ts +7 -0
  46. package/dist/components/admin/fields/richtext/custom-annotation-mark.d.ts.map +1 -0
  47. package/dist/components/admin/fields/richtext/custom-annotation-mark.js +33 -0
  48. package/dist/components/admin/fields/richtext/portable-text-inline-object.d.ts +11 -0
  49. package/dist/components/admin/fields/richtext/portable-text-inline-object.d.ts.map +1 -0
  50. package/dist/components/admin/fields/richtext/portable-text-inline-object.js +31 -0
  51. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts +11 -0
  52. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -0
  53. package/dist/components/admin/fields/richtext/portable-text-object-node.js +31 -0
  54. package/dist/components/admin/fields/richtext/portable-text-serializer.d.ts +38 -0
  55. package/dist/components/admin/fields/richtext/portable-text-serializer.d.ts.map +1 -0
  56. package/dist/components/admin/fields/richtext/portable-text-serializer.js +297 -0
  57. package/dist/components/admin/fields/richtext/svelte-inline-node-view.d.ts +8 -0
  58. package/dist/components/admin/fields/richtext/svelte-inline-node-view.d.ts.map +1 -0
  59. package/dist/components/admin/fields/richtext/svelte-inline-node-view.js +67 -0
  60. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts +8 -0
  61. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -0
  62. package/dist/components/admin/fields/richtext/svelte-node-view.js +63 -0
  63. package/dist/components/layout/OrganizationSwitcher.svelte +1 -1
  64. package/dist/components/layout/sidebar/NavMain.svelte +9 -1
  65. package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
  66. package/dist/db/interfaces/asset.d.ts +2 -4
  67. package/dist/db/interfaces/asset.d.ts.map +1 -1
  68. package/dist/db/interfaces/document.d.ts +8 -2
  69. package/dist/db/interfaces/document.d.ts.map +1 -1
  70. package/dist/db/interfaces/organization.d.ts +1 -1
  71. package/dist/db/interfaces/organization.d.ts.map +1 -1
  72. package/dist/field-access.d.ts.map +1 -1
  73. package/dist/field-access.js +5 -1
  74. package/dist/graphql/depth-limit.d.ts +8 -0
  75. package/dist/graphql/depth-limit.d.ts.map +1 -0
  76. package/dist/graphql/depth-limit.js +79 -0
  77. package/dist/graphql/index.d.ts.map +1 -1
  78. package/dist/graphql/index.js +12 -1
  79. package/dist/graphql/resolvers.d.ts.map +1 -1
  80. package/dist/graphql/resolvers.js +22 -22
  81. package/dist/graphql/schema.d.ts.map +1 -1
  82. package/dist/graphql/schema.js +7 -3
  83. package/dist/hooks.d.ts +2 -0
  84. package/dist/hooks.d.ts.map +1 -1
  85. package/dist/hooks.js +5 -2
  86. package/dist/lib/api/api-keys.d.ts +8 -3
  87. package/dist/lib/api/api-keys.d.ts.map +1 -1
  88. package/dist/lib/api/api-keys.js.map +1 -1
  89. package/dist/lib/api/schemas/assets.js +1 -1
  90. package/dist/lib/api/schemas/assets.js.map +1 -1
  91. package/dist/lib/api/schemas/documents.d.ts +0 -2
  92. package/dist/lib/api/schemas/documents.d.ts.map +1 -1
  93. package/dist/lib/api/schemas/documents.js +2 -8
  94. package/dist/lib/api/schemas/documents.js.map +1 -1
  95. package/dist/lib/api/schemas/instance.d.ts +6 -0
  96. package/dist/lib/api/schemas/instance.d.ts.map +1 -0
  97. package/dist/lib/api/schemas/instance.js +8 -0
  98. package/dist/lib/api/schemas/instance.js.map +1 -0
  99. package/dist/lib/api/schemas/user.js +1 -1
  100. package/dist/lib/auth/auth-hooks.d.ts.map +1 -1
  101. package/dist/lib/auth/auth-hooks.js +9 -3
  102. package/dist/lib/auth/auth-hooks.js.map +1 -1
  103. package/dist/lib/components/admin/fields/richtext/custom-annotation-mark.d.ts +7 -0
  104. package/dist/lib/components/admin/fields/richtext/custom-annotation-mark.d.ts.map +1 -0
  105. package/dist/lib/components/admin/fields/richtext/custom-annotation-mark.js +34 -0
  106. package/dist/lib/components/admin/fields/richtext/custom-annotation-mark.js.map +1 -0
  107. package/dist/lib/components/admin/fields/richtext/portable-text-inline-object.d.ts +11 -0
  108. package/dist/lib/components/admin/fields/richtext/portable-text-inline-object.d.ts.map +1 -0
  109. package/dist/lib/components/admin/fields/richtext/portable-text-inline-object.js +32 -0
  110. package/dist/lib/components/admin/fields/richtext/portable-text-inline-object.js.map +1 -0
  111. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts +11 -0
  112. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -0
  113. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js +32 -0
  114. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js.map +1 -0
  115. package/dist/lib/components/admin/fields/richtext/portable-text-serializer.d.ts +38 -0
  116. package/dist/lib/components/admin/fields/richtext/portable-text-serializer.d.ts.map +1 -0
  117. package/dist/lib/components/admin/fields/richtext/portable-text-serializer.js +298 -0
  118. package/dist/lib/components/admin/fields/richtext/portable-text-serializer.js.map +1 -0
  119. package/dist/lib/components/admin/fields/richtext/svelte-inline-node-view.d.ts +8 -0
  120. package/dist/lib/components/admin/fields/richtext/svelte-inline-node-view.d.ts.map +1 -0
  121. package/dist/lib/components/admin/fields/richtext/svelte-inline-node-view.js +68 -0
  122. package/dist/lib/components/admin/fields/richtext/svelte-inline-node-view.js.map +1 -0
  123. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts +8 -0
  124. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -0
  125. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js +64 -0
  126. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js.map +1 -0
  127. package/dist/lib/db/interfaces/asset.d.ts +2 -4
  128. package/dist/lib/db/interfaces/asset.d.ts.map +1 -1
  129. package/dist/lib/db/interfaces/document.d.ts +8 -2
  130. package/dist/lib/db/interfaces/document.d.ts.map +1 -1
  131. package/dist/lib/db/interfaces/organization.d.ts +1 -1
  132. package/dist/lib/db/interfaces/organization.d.ts.map +1 -1
  133. package/dist/lib/field-access.d.ts.map +1 -1
  134. package/dist/lib/field-access.js +5 -1
  135. package/dist/lib/field-access.js.map +1 -1
  136. package/dist/lib/graphql/depth-limit.d.ts +8 -0
  137. package/dist/lib/graphql/depth-limit.d.ts.map +1 -0
  138. package/dist/lib/graphql/depth-limit.js +80 -0
  139. package/dist/lib/graphql/depth-limit.js.map +1 -0
  140. package/dist/lib/graphql/index.d.ts.map +1 -1
  141. package/dist/lib/graphql/index.js +12 -1
  142. package/dist/lib/graphql/index.js.map +1 -1
  143. package/dist/lib/graphql/resolvers.d.ts.map +1 -1
  144. package/dist/lib/graphql/resolvers.js +22 -22
  145. package/dist/lib/graphql/resolvers.js.map +1 -1
  146. package/dist/lib/graphql/schema.d.ts.map +1 -1
  147. package/dist/lib/graphql/schema.js +7 -3
  148. package/dist/lib/graphql/schema.js.map +1 -1
  149. package/dist/lib/hooks.d.ts +2 -0
  150. package/dist/lib/hooks.d.ts.map +1 -1
  151. package/dist/lib/hooks.js +5 -2
  152. package/dist/lib/hooks.js.map +1 -1
  153. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  154. package/dist/lib/local-api/collection-api.js +14 -9
  155. package/dist/lib/local-api/collection-api.js.map +1 -1
  156. package/dist/lib/local-api/index.d.ts +5 -1
  157. package/dist/lib/local-api/index.d.ts.map +1 -1
  158. package/dist/lib/local-api/index.js +12 -4
  159. package/dist/lib/local-api/index.js.map +1 -1
  160. package/dist/lib/routes/assets-cdn.d.ts.map +1 -1
  161. package/dist/lib/routes/assets-cdn.js +8 -3
  162. package/dist/lib/routes/assets-cdn.js.map +1 -1
  163. package/dist/lib/schema-utils/validator.d.ts.map +1 -1
  164. package/dist/lib/schema-utils/validator.js +5 -1
  165. package/dist/lib/schema-utils/validator.js.map +1 -1
  166. package/dist/lib/server/api/index.d.ts.map +1 -1
  167. package/dist/lib/server/api/index.js +18 -0
  168. package/dist/lib/server/api/index.js.map +1 -1
  169. package/dist/lib/server/api/routes/assets-bulk.d.ts.map +1 -1
  170. package/dist/lib/server/api/routes/assets-bulk.js +4 -0
  171. package/dist/lib/server/api/routes/assets-bulk.js.map +1 -1
  172. package/dist/lib/server/api/routes/assets-by-id.d.ts.map +1 -1
  173. package/dist/lib/server/api/routes/assets-by-id.js +17 -2
  174. package/dist/lib/server/api/routes/assets-by-id.js.map +1 -1
  175. package/dist/lib/server/api/routes/assets-references.d.ts.map +1 -1
  176. package/dist/lib/server/api/routes/assets-references.js +6 -4
  177. package/dist/lib/server/api/routes/assets-references.js.map +1 -1
  178. package/dist/lib/server/api/routes/assets.d.ts.map +1 -1
  179. package/dist/lib/server/api/routes/assets.js +18 -9
  180. package/dist/lib/server/api/routes/assets.js.map +1 -1
  181. package/dist/lib/server/api/routes/document-versions.d.ts.map +1 -1
  182. package/dist/lib/server/api/routes/document-versions.js +8 -0
  183. package/dist/lib/server/api/routes/document-versions.js.map +1 -1
  184. package/dist/lib/server/api/routes/documents-by-id.d.ts.map +1 -1
  185. package/dist/lib/server/api/routes/documents-by-id.js +3 -3
  186. package/dist/lib/server/api/routes/documents-by-id.js.map +1 -1
  187. package/dist/lib/server/api/routes/documents-publish.d.ts.map +1 -1
  188. package/dist/lib/server/api/routes/documents-publish.js +2 -2
  189. package/dist/lib/server/api/routes/documents-publish.js.map +1 -1
  190. package/dist/lib/server/api/routes/documents-query.d.ts.map +1 -1
  191. package/dist/lib/server/api/routes/documents-query.js +2 -3
  192. package/dist/lib/server/api/routes/documents-query.js.map +1 -1
  193. package/dist/lib/server/api/routes/documents.d.ts.map +1 -1
  194. package/dist/lib/server/api/routes/documents.js +3 -5
  195. package/dist/lib/server/api/routes/documents.js.map +1 -1
  196. package/dist/lib/server/api/routes/organizations-invitations.d.ts.map +1 -1
  197. package/dist/lib/server/api/routes/organizations-invitations.js +1 -1
  198. package/dist/lib/server/api/routes/organizations-invitations.js.map +1 -1
  199. package/dist/lib/server/api/routes/organizations-members.d.ts.map +1 -1
  200. package/dist/lib/server/api/routes/organizations-members.js.map +1 -1
  201. package/dist/lib/server/index.d.ts +1 -0
  202. package/dist/lib/server/index.d.ts.map +1 -1
  203. package/dist/lib/server/index.js +2 -0
  204. package/dist/lib/server/index.js.map +1 -1
  205. package/dist/lib/services/asset-service.d.ts.map +1 -1
  206. package/dist/lib/services/asset-service.js +4 -2
  207. package/dist/lib/services/asset-service.js.map +1 -1
  208. package/dist/lib/services/references-service.d.ts.map +1 -1
  209. package/dist/lib/services/references-service.js.map +1 -1
  210. package/dist/lib/storage/adapters/local-storage-adapter.d.ts +4 -0
  211. package/dist/lib/storage/adapters/local-storage-adapter.d.ts.map +1 -1
  212. package/dist/lib/storage/adapters/local-storage-adapter.js +28 -6
  213. package/dist/lib/storage/adapters/local-storage-adapter.js.map +1 -1
  214. package/dist/lib/types/capabilities.d.ts +1 -0
  215. package/dist/lib/types/capabilities.d.ts.map +1 -1
  216. package/dist/lib/types/capabilities.js +3 -0
  217. package/dist/lib/types/capabilities.js.map +1 -1
  218. package/dist/lib/types/config.d.ts +16 -1
  219. package/dist/lib/types/config.d.ts.map +1 -1
  220. package/dist/lib/types/schemas.d.ts +27 -0
  221. package/dist/lib/types/schemas.d.ts.map +1 -1
  222. package/dist/lib/types/schemas.js +3 -1
  223. package/dist/lib/types/schemas.js.map +1 -1
  224. package/dist/lib/utils/logger.d.ts +8 -6
  225. package/dist/lib/utils/logger.d.ts.map +1 -1
  226. package/dist/lib/utils/logger.js +11 -2
  227. package/dist/lib/utils/logger.js.map +1 -1
  228. package/dist/lib/utils/mime-detect.d.ts.map +1 -1
  229. package/dist/lib/utils/mime-detect.js +21 -6
  230. package/dist/lib/utils/mime-detect.js.map +1 -1
  231. package/dist/lib/vite/index.d.ts.map +1 -1
  232. package/dist/lib/vite/index.js +4 -5
  233. package/dist/lib/vite/index.js.map +1 -1
  234. package/dist/local-api/collection-api.d.ts.map +1 -1
  235. package/dist/local-api/collection-api.js +14 -9
  236. package/dist/local-api/index.d.ts +5 -1
  237. package/dist/local-api/index.d.ts.map +1 -1
  238. package/dist/local-api/index.js +12 -4
  239. package/dist/routes/assets-cdn.d.ts.map +1 -1
  240. package/dist/routes/assets-cdn.js +8 -3
  241. package/dist/schema-utils/validator.d.ts.map +1 -1
  242. package/dist/schema-utils/validator.js +5 -1
  243. package/dist/server/api/index.d.ts.map +1 -1
  244. package/dist/server/api/index.js +18 -0
  245. package/dist/server/api/routes/assets-bulk.d.ts.map +1 -1
  246. package/dist/server/api/routes/assets-bulk.js +4 -0
  247. package/dist/server/api/routes/assets-by-id.d.ts.map +1 -1
  248. package/dist/server/api/routes/assets-by-id.js +17 -2
  249. package/dist/server/api/routes/assets-references.d.ts.map +1 -1
  250. package/dist/server/api/routes/assets-references.js +6 -4
  251. package/dist/server/api/routes/assets.d.ts.map +1 -1
  252. package/dist/server/api/routes/assets.js +18 -9
  253. package/dist/server/api/routes/document-versions.d.ts.map +1 -1
  254. package/dist/server/api/routes/document-versions.js +8 -0
  255. package/dist/server/api/routes/documents-by-id.d.ts.map +1 -1
  256. package/dist/server/api/routes/documents-by-id.js +3 -3
  257. package/dist/server/api/routes/documents-publish.d.ts.map +1 -1
  258. package/dist/server/api/routes/documents-publish.js +2 -2
  259. package/dist/server/api/routes/documents-query.d.ts.map +1 -1
  260. package/dist/server/api/routes/documents-query.js +2 -3
  261. package/dist/server/api/routes/documents.d.ts.map +1 -1
  262. package/dist/server/api/routes/documents.js +3 -5
  263. package/dist/server/api/routes/organizations-invitations.d.ts.map +1 -1
  264. package/dist/server/api/routes/organizations-invitations.js +1 -1
  265. package/dist/server/api/routes/organizations-members.d.ts.map +1 -1
  266. package/dist/server/index.d.ts +1 -0
  267. package/dist/server/index.d.ts.map +1 -1
  268. package/dist/server/index.js +2 -0
  269. package/dist/services/asset-service.d.ts.map +1 -1
  270. package/dist/services/asset-service.js +4 -2
  271. package/dist/services/references-service.d.ts.map +1 -1
  272. package/dist/storage/adapters/local-storage-adapter.d.ts +4 -0
  273. package/dist/storage/adapters/local-storage-adapter.d.ts.map +1 -1
  274. package/dist/storage/adapters/local-storage-adapter.js +28 -6
  275. package/dist/types/capabilities.d.ts +1 -0
  276. package/dist/types/capabilities.d.ts.map +1 -1
  277. package/dist/types/capabilities.js +3 -0
  278. package/dist/types/config.d.ts +16 -1
  279. package/dist/types/config.d.ts.map +1 -1
  280. package/dist/types/schemas.d.ts +27 -0
  281. package/dist/types/schemas.d.ts.map +1 -1
  282. package/dist/types/schemas.js +3 -1
  283. package/dist/utils/logger.d.ts +8 -6
  284. package/dist/utils/logger.d.ts.map +1 -1
  285. package/dist/utils/logger.js +11 -2
  286. package/dist/utils/mime-detect.d.ts.map +1 -1
  287. package/dist/utils/mime-detect.js +21 -6
  288. package/dist/vite/index.d.ts.map +1 -1
  289. package/dist/vite/index.js +4 -5
  290. package/package.json +9 -5
@@ -18,8 +18,7 @@
18
18
  ) => void;
19
19
  }
20
20
 
21
- let { documentId, onClose, onRestored, onPreviewVersion }: Props = $props();
22
- void onRestored;
21
+ let { documentId, onClose, onPreviewVersion }: Props = $props();
23
22
 
24
23
  let versions = $state<any[]>([]);
25
24
  let loading = $state(true);
@@ -120,6 +119,8 @@
120
119
  </div>
121
120
  {:else}
122
121
  {#each filteredVersions as version, i}
122
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
123
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
123
124
  <div
124
125
  data-version-id={i}
125
126
  class="hover:bg-muted w-full cursor-pointer border-b px-3 py-2.5 text-left transition-colors {previewVersion?.versionNumber ===
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentVersionPanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentVersionPanel.svelte.ts"],"names":[],"mappings":"AASC,UAAU,KAAK;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAClB,OAAO,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,KACJ,IAAI,CAAC;CACV;AAkIF,QAAA,MAAM,oBAAoB;;MAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"DocumentVersionPanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentVersionPanel.svelte.ts"],"names":[],"mappings":"AASC,UAAU,KAAK;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAClB,OAAO,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,KACJ,IAAI,CAAC;CACV;AAmIF,QAAA,MAAM,oBAAoB;;MAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
@@ -106,7 +106,8 @@
106
106
  // Bulk selection state
107
107
  let selectMode = $state(false);
108
108
  let selectedIds = $state<Set<string>>(
109
- selectable && multiSelect && existingAssetIds ? new Set(existingAssetIds) : new Set()
109
+ (() =>
110
+ selectable && multiSelect && existingAssetIds ? new Set(existingAssetIds) : new Set())()
110
111
  );
111
112
  let isBulkDeleting = $state(false);
112
113
 
@@ -166,7 +167,7 @@
166
167
  // Fetch reference counts for this page
167
168
  fetchReferenceCounts(result.data.map((a) => a.id));
168
169
  }
169
- } catch (err) {
170
+ } catch {
170
171
  toast.error('Failed to fetch assets');
171
172
  } finally {
172
173
  loading = false;
@@ -186,7 +187,7 @@
186
187
  if (result.success && result.data) {
187
188
  referenceCounts = { ...referenceCounts, ...result.data };
188
189
  }
189
- } catch (err) {
190
+ } catch {
190
191
  toast.error('Failed to fetch reference counts');
191
192
  }
192
193
  }
@@ -200,7 +201,7 @@
200
201
  selectedAssetRefs = result.data.references;
201
202
  selectedRefCount = result.data.total;
202
203
  }
203
- } catch (err) {
204
+ } catch {
204
205
  toast.error('Failed to fetch asset references');
205
206
  selectedAssetRefs = [];
206
207
  selectedRefCount = 0;
@@ -284,7 +285,7 @@
284
285
  if (result.success && result.data) {
285
286
  referenceCounts = { ...referenceCounts, ...result.data };
286
287
  }
287
- } catch (err) {
288
+ } catch {
288
289
  toast.error('Failed to check references');
289
290
  }
290
291
 
@@ -316,7 +317,7 @@
316
317
  selectedIds = new Set();
317
318
  await fetchAssets();
318
319
  }
319
- } catch (err) {
320
+ } catch {
320
321
  toast.error('Failed to delete assets');
321
322
  } finally {
322
323
  isBulkDeleting = false;
@@ -424,7 +425,7 @@
424
425
  assetList = assetList.map((a) => (a.id === selectedAsset!.id ? result.data! : a));
425
426
  selectedAsset = result.data;
426
427
  }
427
- } catch (err) {
428
+ } catch {
428
429
  toast.error('Failed to save metadata');
429
430
  } finally {
430
431
  isSaving = false;
@@ -433,6 +434,14 @@
433
434
 
434
435
  // Delete asset
435
436
  async function deleteAsset(asset: Asset) {
437
+ try {
438
+ const result = await assets.getReferenceCounts([asset.id]);
439
+ if (result.success && result.data) {
440
+ referenceCounts = { ...referenceCounts, ...result.data };
441
+ }
442
+ } catch {
443
+ // Fall through to cached count
444
+ }
436
445
  const refCount = referenceCounts[asset.id] || 0;
437
446
  if (refCount > 0) {
438
447
  toast.error(
@@ -455,7 +464,7 @@
455
464
  }
456
465
  await fetchAssets();
457
466
  }
458
- } catch (err) {
467
+ } catch {
459
468
  toast.error('Failed to delete asset');
460
469
  }
461
470
  }
@@ -826,12 +835,21 @@
826
835
  </div>
827
836
  {/if}
828
837
  {#if selectable}
829
- <!-- Info button to view details without selecting -->
830
- <button
838
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
839
+ <div
840
+ role="button"
841
+ tabindex="0"
831
842
  onclick={(e) => {
832
843
  e.stopPropagation();
833
844
  openAssetDetail(asset);
834
845
  }}
846
+ onkeydown={(e) => {
847
+ if (e.key === 'Enter' || e.key === ' ') {
848
+ e.preventDefault();
849
+ e.stopPropagation();
850
+ openAssetDetail(asset);
851
+ }
852
+ }}
835
853
  class="bg-background/80 absolute top-1.5 right-1.5 rounded p-1 opacity-0 transition-opacity group-hover:opacity-100"
836
854
  title="View details"
837
855
  >
@@ -848,7 +866,7 @@
848
866
  d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
849
867
  />
850
868
  </svg>
851
- </button>
869
+ </div>
852
870
  {:else if isSelectMode}
853
871
  <!-- Checkbox overlay for bulk mode -->
854
872
  <div class="absolute top-1.5 left-1.5">
@@ -1 +1 @@
1
- {"version":3,"file":"MediaBrowser.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/MediaBrowser.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAS9C,UAAU,KAAK;IACd,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IAC7C,oCAAoC;IACpC,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AAgqCF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"MediaBrowser.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/MediaBrowser.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAS9C,UAAU,KAAK;IACd,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IAC7C,oCAAoC;IACpC,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AA+qCF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -53,10 +53,6 @@
53
53
  const backdropZ = $derived(50 + Math.max(myDepth - 1, 0) * 10);
54
54
  const panelZ = $derived(backdropZ + 1);
55
55
 
56
- // Handle backdrop click — only close if this is the topmost modal, so a
57
- // click that visually lands on a parent's backdrop (because the inner
58
- // backdrop doesn't extend that far) doesn't accidentally close the
59
- // parent.
60
56
  function isTopmost(): boolean {
61
57
  return myDepth === modalStack;
62
58
  }
@@ -75,89 +71,80 @@
75
71
  </script>
76
72
 
77
73
  {#if open}
78
- <!-- NOTE: scoped to the editor area via `absolute inset-0` (DocumentEditor
79
- is the nearest positioned ancestor). The trade-off: a nested modal's
80
- backdrop only covers its parent panel, so clicks in the truly
81
- "outside" region land on the grandparent backdrop. The modalStack
82
- check above neutralises that case (only the topmost modal reacts).
83
- We may later move this to a viewport-level portal so nested
84
- backdrops cover the full screen, but for now keeping it inside the
85
- editor is the design we want. -->
86
74
  <div
87
- class="bg-background/80 absolute inset-0"
75
+ class="bg-background/80 absolute inset-0 flex items-center justify-center p-4 lg:p-6"
88
76
  style="z-index: {backdropZ}"
89
77
  onclick={handleBackdropClick}
90
78
  onkeydown={handleKeydown}
91
79
  role="button"
92
80
  tabindex="-1"
93
- ></div>
94
-
95
- <!-- Panel: centered dialog. max-h is relative to the editor container
96
- so tall schemas scroll inside the panel instead of being clipped;
97
- min-h-0 on the body (below) is what actually lets the inner
98
- overflow-auto take effect inside this flex column. -->
99
- <div
100
- class="border-border bg-background absolute top-1/2 left-1/2 flex max-h-[calc(100%-4rem)] w-[calc(100%-2rem)] max-w-3xl -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border shadow-lg"
101
- style="z-index: {panelZ}"
102
81
  >
82
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
103
83
  <div
104
- class="border-border bg-background flex shrink-0 items-center justify-between gap-3 border-b px-4 py-2"
84
+ class="border-border bg-background max-h-full w-full max-w-3xl overflow-auto rounded-lg border shadow-lg"
85
+ style="z-index: {panelZ}"
86
+ onclick={(e) => e.stopPropagation()}
87
+ onkeydown={(e) => e.stopPropagation()}
105
88
  >
106
- <span class="text-sm font-medium">Edit {schema.title}</span>
107
- <div class="flex items-center gap-2">
108
- {#if saveState}
109
- {#if saveState.saving}
110
- <span
111
- class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
112
- >
113
- <span class="bg-muted-foreground/60 h-1.5 w-1.5 animate-pulse rounded-full"></span>
114
- Saving
115
- </span>
116
- {:else if saveState.hasUnsavedChanges}
117
- <span
118
- class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
119
- >
120
- <span class="bg-muted-foreground/60 h-1.5 w-1.5 rounded-full"></span>
121
- Unsaved
122
- </span>
123
- {:else if saveState.savedAgoText}
124
- <span
125
- class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
126
- >
127
- <span class="bg-muted-foreground/60 h-1.5 w-1.5 rounded-full"></span>
128
- Auto-saved
129
- </span>
89
+ <div
90
+ class="border-border bg-background sticky top-0 z-10 flex items-center justify-between gap-3 border-b px-4 py-2"
91
+ >
92
+ <span class="text-sm font-medium">Edit {schema.title}</span>
93
+ <div class="flex items-center gap-2">
94
+ {#if saveState}
95
+ {#if saveState.saving}
96
+ <span
97
+ class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
98
+ >
99
+ <span class="bg-muted-foreground/60 h-1.5 w-1.5 animate-pulse rounded-full"></span>
100
+ Saving
101
+ </span>
102
+ {:else if saveState.hasUnsavedChanges}
103
+ <span
104
+ class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
105
+ >
106
+ <span class="bg-muted-foreground/60 h-1.5 w-1.5 rounded-full"></span>
107
+ Unsaved
108
+ </span>
109
+ {:else if saveState.savedAgoText}
110
+ <span
111
+ class="text-muted-foreground inline-flex items-center gap-1.5 text-[10px] font-medium tracking-wider whitespace-nowrap uppercase"
112
+ >
113
+ <span class="bg-muted-foreground/60 h-1.5 w-1.5 rounded-full"></span>
114
+ Auto-saved
115
+ </span>
116
+ {/if}
130
117
  {/if}
131
- {/if}
132
- <Button variant="ghost" size="icon" class="h-7 w-7" onclick={onClose}>
133
- <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
134
- <path
135
- stroke-linecap="round"
136
- stroke-linejoin="round"
137
- stroke-width="2"
138
- d="M6 18L18 6M6 6l12 12"
139
- />
140
- </svg>
141
- </Button>
118
+ <Button variant="ghost" size="icon" class="h-7 w-7" onclick={onClose}>
119
+ <svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
120
+ <path
121
+ stroke-linecap="round"
122
+ stroke-linejoin="round"
123
+ stroke-width="2"
124
+ d="M6 18L18 6M6 6l12 12"
125
+ />
126
+ </svg>
127
+ </Button>
128
+ </div>
142
129
  </div>
143
- </div>
144
130
 
145
- <div class="bg-background min-h-0 flex-1 space-y-3 overflow-auto p-4">
146
- {#if schema.fields}
147
- {#each schema.fields as field, index (index)}
148
- <SchemaField
149
- {field}
150
- value={(value ?? {})[field.name]}
151
- documentData={value ?? {}}
152
- onUpdate={(newValue) => {
153
- onUpdate({ ...value, [field.name]: newValue });
154
- }}
155
- {onOpenReference}
156
- {readonly}
157
- {organizationId}
158
- />
159
- {/each}
160
- {/if}
131
+ <div class="bg-background space-y-3 p-4">
132
+ {#if schema.fields}
133
+ {#each schema.fields as field, index (index)}
134
+ <SchemaField
135
+ {field}
136
+ value={(value ?? {})[field.name]}
137
+ documentData={value ?? {}}
138
+ onUpdate={(newValue) => {
139
+ onUpdate({ ...value, [field.name]: newValue });
140
+ }}
141
+ {onOpenReference}
142
+ {readonly}
143
+ {organizationId}
144
+ />
145
+ {/each}
146
+ {/if}
147
+ </div>
161
148
  </div>
162
149
  </div>
163
150
  {/if}
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectModal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/ObjectModal.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKxD,UAAU,KAAK;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA6GF,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ObjectModal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/ObjectModal.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKxD,UAAU,KAAK;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAwGF,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -61,7 +61,7 @@
61
61
  }: Props = $props();
62
62
 
63
63
  // Build full field path
64
- const fieldPath = parentPath ? `${parentPath}.${field.name}` : field.name;
64
+ const fieldPath = $derived(parentPath ? `${parentPath}.${field.name}` : field.name);
65
65
 
66
66
  // Validation state for the wrapper (displays errors and status)
67
67
  let validationErrors = $state<ValidationError[]>([]);
@@ -239,7 +239,7 @@
239
239
  {/each}
240
240
  </div>
241
241
 
242
- <!-- Array Field -->
242
+ <!-- Array Field (includes block content editor when of contains {type: 'block'}) -->
243
243
  {:else if field.type === 'array' && field.of}
244
244
  <ArrayField {field} {value} {onUpdate} {onOpenReference} {readonly} {organizationId} />
245
245
 
@@ -33,6 +33,7 @@
33
33
  import { documents } from '../../../api/documents';
34
34
  import { SvelteMap } from 'svelte/reactivity';
35
35
  import { getDocumentVersion } from '../../../document-refresh.svelte';
36
+ import RichtextField from './richtext/RichtextField.svelte';
36
37
 
37
38
  interface Props {
38
39
  field: ArrayFieldType;
@@ -73,6 +74,7 @@
73
74
  return getSchemaByName(schemas, typeName);
74
75
  }
75
76
 
77
+ const isBlockArray = $derived(field.of.some((ref) => ref.type === 'block'));
76
78
  const isGridLayout = $derived(field.options?.layout === 'grid');
77
79
  const isReferenceArray = $derived(
78
80
  field.of && field.of.length > 0 && field.of[0]?.type === 'reference'
@@ -320,7 +322,7 @@
320
322
  _key: generateKey(),
321
323
  asset: { _type: 'reference', _ref: result.data!.id }
322
324
  };
323
- } catch (error) {
325
+ } catch {
324
326
  toast.error(`Failed to upload ${file.name}`);
325
327
  return null;
326
328
  }
@@ -494,7 +496,9 @@
494
496
  }
495
497
  </script>
496
498
 
497
- {#if isReferenceArray && referenceFieldShape}
499
+ {#if isBlockArray}
500
+ <RichtextField {field} {value} {onUpdate} {readonly} {onOpenReference} {organizationId} />
501
+ {:else if isReferenceArray && referenceFieldShape}
498
502
  <!-- Reference array — each row reuses ReferenceField. Drag handle on the
499
503
  left, ReferenceField fills the row, an X button on empty rows lets the
500
504
  user discard a never-picked row (populated rows use ReferenceField's
@@ -599,6 +603,8 @@
599
603
  class="border-border/50 bg-background group relative aspect-square overflow-hidden rounded-md border"
600
604
  class:opacity-50={sortable.isDragging}
601
605
  >
606
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
607
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
602
608
  <div
603
609
  class="h-full w-full cursor-pointer"
604
610
  onclick={() => handleOpenImageModal(index)}
@@ -695,6 +701,8 @@
695
701
  </button>
696
702
  {/if}
697
703
 
704
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
705
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
698
706
  <div
699
707
  class="min-w-0 flex-1 cursor-pointer text-left"
700
708
  onclick={() => handleOpenImageModal(index)}
@@ -925,7 +933,9 @@
925
933
  class="flex flex-1 cursor-pointer items-center gap-2 self-stretch truncate px-1 py-2 text-left text-sm"
926
934
  onclick={() => handleEditItem(index)}
927
935
  >
928
- <span class="text-muted-foreground flex h-5 w-5 shrink-0 items-center justify-center">
936
+ <span
937
+ class="text-muted-foreground flex h-5 w-5 shrink-0 items-center justify-center"
938
+ >
929
939
  {#if getItemIcon(item)}
930
940
  {@const Icon = getItemIcon(item)}
931
941
  <Icon class="h-4 w-4" />
@@ -1 +1 @@
1
- {"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAc,MAAM,wBAAwB,CAAC;AA8BtF,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAq5BF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAc,MAAM,wBAAwB,CAAC;AA+BtF,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA65BF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -189,7 +189,7 @@
189
189
  toast.error('Failed to fetch asset details');
190
190
  assetData = null;
191
191
  }
192
- } catch (error) {
192
+ } catch {
193
193
  toast.error('Failed to load file asset');
194
194
  assetData = null;
195
195
  } finally {
@@ -188,7 +188,7 @@
188
188
  toast.error('Failed to fetch asset details');
189
189
  assetData = null;
190
190
  }
191
- } catch (error) {
191
+ } catch {
192
192
  toast.error('Failed to load image asset');
193
193
  assetData = null;
194
194
  } finally {
@@ -42,14 +42,16 @@
42
42
  const refId = $derived(value?._ref ?? null);
43
43
 
44
44
  // Cast to reference field type
45
- const referenceField = field as ReferenceFieldType;
46
- const targetType = referenceField.to?.[0]?.type;
45
+ const referenceField = $derived(field as ReferenceFieldType);
46
+ const targetType = $derived(referenceField.to?.[0]?.type);
47
47
 
48
48
  const schemas = getSchemaContext();
49
49
  const targetSchema = $derived(targetType ? getSchemaByName(schemas, targetType) : null);
50
50
  const TargetIcon = $derived(targetSchema?.icon ?? null);
51
51
 
52
52
  // State
53
+ let inputWrapperEl = $state<HTMLElement>();
54
+ let dropdownPos = $state({ top: 0, left: 0, width: 0 });
53
55
  let open = $state(false);
54
56
  let searchResults = $state<any[]>([]);
55
57
  let selectedDocument = $state<any>(null);
@@ -78,7 +80,7 @@
78
80
  if (doc.success) {
79
81
  selectedDocument = doc.data;
80
82
  }
81
- } catch (err) {
83
+ } catch {
82
84
  toast.error('Failed to load referenced document');
83
85
  selectedDocument = null;
84
86
  }
@@ -145,6 +147,18 @@
145
147
  });
146
148
  });
147
149
 
150
+ function updateDropdownPos() {
151
+ if (!inputWrapperEl) return;
152
+ const rect = inputWrapperEl.getBoundingClientRect();
153
+ dropdownPos = { top: rect.bottom + 4, left: rect.left, width: rect.width };
154
+ }
155
+
156
+ $effect(() => {
157
+ if (open && inputWrapperEl) {
158
+ updateDropdownPos();
159
+ }
160
+ });
161
+
148
162
  function closeAndFocusTrigger() {
149
163
  open = false;
150
164
  }
@@ -196,7 +210,7 @@
196
210
  onUpdate({ _type: 'reference', _ref: result.data.id });
197
211
  closeAndFocusTrigger();
198
212
  }
199
- } catch (err) {
213
+ } catch {
200
214
  toast.error('Failed to create document');
201
215
  } finally {
202
216
  creating = false;
@@ -291,22 +305,33 @@
291
305
  {:else}
292
306
  <!-- Inline empty state: search input + chevron + Create button. The input
293
307
  is the primary focus target — the results dropdown is a sibling div
294
- positioned absolutely under the input wrapper, with click-outside
295
- closing it. No popover wrapping the input, so no double-click. -->
308
+ positioned with fixed so it escapes overflow containers (e.g. modals),
309
+ with click-outside closing it. No popover wrapping the input, so no
310
+ double-click. -->
296
311
  <div class="flex items-center gap-1">
297
- <div class="relative min-w-0 flex-1" use:clickOutside={() => (open = false)}>
312
+ <div
313
+ bind:this={inputWrapperEl}
314
+ class="relative min-w-0 flex-1"
315
+ use:clickOutside={() => (open = false)}
316
+ >
298
317
  <div
299
318
  class="border-input bg-background focus-within:ring-ring flex h-9 items-center rounded-md border focus-within:ring-1"
300
319
  >
301
320
  <Input
302
321
  bind:value={query}
303
322
  placeholder="Type to search..."
304
- onfocus={() => (open = true)}
323
+ onfocus={() => {
324
+ updateDropdownPos();
325
+ open = true;
326
+ }}
305
327
  class="h-8 border-0 bg-transparent shadow-none focus-visible:ring-0"
306
328
  />
307
329
  <button
308
330
  type="button"
309
- onclick={() => (open = !open)}
331
+ onclick={() => {
332
+ updateDropdownPos();
333
+ open = !open;
334
+ }}
310
335
  class="text-muted-foreground hover:text-foreground flex h-8 w-8 shrink-0 items-center justify-center"
311
336
  aria-label="Toggle results"
312
337
  >
@@ -315,7 +340,11 @@
315
340
  </div>
316
341
  {#if open}
317
342
  <div
318
- class="bg-popover text-popover-foreground absolute top-full left-0 z-[9999] mt-1 w-[400px] max-w-[min(400px,calc(100vw-2rem))] rounded-md border p-0 shadow-md"
343
+ class="bg-popover text-popover-foreground fixed z-[9999] rounded-md border p-0 shadow-md"
344
+ style="top: {dropdownPos.top}px; left: {dropdownPos.left}px; width: {Math.min(
345
+ 400,
346
+ dropdownPos.width
347
+ )}px;"
319
348
  >
320
349
  <Command.Root shouldFilter={false}>
321
350
  <Command.List class="max-h-[300px] overflow-y-auto">
@@ -351,7 +380,9 @@
351
380
  </span>
352
381
  </div>
353
382
  {#if doc._meta?.status === 'published'}
354
- <span class="h-1.5 w-1.5 shrink-0 rounded-full bg-green-500" title="Published"
383
+ <span
384
+ class="h-1.5 w-1.5 shrink-0 rounded-full bg-green-500"
385
+ title="Published"
355
386
  ></span>
356
387
  {:else if doc._meta?.status === 'unpublished'}
357
388
  <span
@@ -1 +1 @@
1
- {"version":3,"file":"ReferenceField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ReferenceField.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,wBAAwB,CAAC;AAUzF,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAqUF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"ReferenceField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ReferenceField.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,wBAAwB,CAAC;AAUzF,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AA4VF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,116 @@
1
+ <script lang="ts">
2
+ import { Trash2, Image as ImageIcon } from '@lucide/svelte';
3
+ import { assets } from '../../../../api/assets';
4
+
5
+ interface Props {
6
+ type: string;
7
+ nodeKey: string;
8
+ data: Record<string, unknown>;
9
+ selected?: boolean;
10
+ onEdit: () => void;
11
+ onDelete: () => void;
12
+ }
13
+
14
+ let { data, selected = false, onEdit, onDelete }: Props = $props();
15
+
16
+ const assetRef = $derived((data?.asset as any)?._ref as string | undefined);
17
+ const assetPromise = $derived(assetRef ? assets.getById(assetRef) : null);
18
+ </script>
19
+
20
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
21
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
22
+ <div class="image-block-view group" class:selected onclick={onEdit}>
23
+ {#if assetPromise}
24
+ {#await assetPromise}
25
+ <div class="image-block-placeholder">
26
+ <div
27
+ class="border-primary h-5 w-5 animate-spin rounded-full border-2 border-t-transparent"
28
+ ></div>
29
+ </div>
30
+ {:then result}
31
+ {#if result.success && result.data?.url}
32
+ <img src={result.data.url} alt={result.data.alt || ''} class="image-block-img" />
33
+ {:else}
34
+ <div class="image-block-placeholder">
35
+ <ImageIcon class="text-muted-foreground h-8 w-8" />
36
+ <span class="text-muted-foreground text-xs">Image not found</span>
37
+ </div>
38
+ {/if}
39
+ {:catch}
40
+ <div class="image-block-placeholder">
41
+ <ImageIcon class="text-muted-foreground h-8 w-8" />
42
+ <span class="text-muted-foreground text-xs">Failed to load</span>
43
+ </div>
44
+ {/await}
45
+ {:else}
46
+ <div class="image-block-placeholder">
47
+ <ImageIcon class="text-muted-foreground h-8 w-8" />
48
+ <span class="text-muted-foreground text-xs">No image</span>
49
+ </div>
50
+ {/if}
51
+
52
+ <div class="image-block-actions">
53
+ <button
54
+ type="button"
55
+ class="text-muted-foreground hover:text-destructive rounded p-1 transition-colors"
56
+ onclick={(e) => {
57
+ e.stopPropagation();
58
+ onDelete();
59
+ }}
60
+ title="Remove"
61
+ >
62
+ <Trash2 class="h-3.5 w-3.5" />
63
+ </button>
64
+ </div>
65
+ </div>
66
+
67
+ <style>
68
+ .image-block-view {
69
+ position: relative;
70
+ width: 100%;
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: center;
74
+ border: 1px solid var(--border);
75
+ border-radius: var(--radius);
76
+ background: var(--muted);
77
+ margin: 0.5em 0;
78
+ overflow: hidden;
79
+ cursor: pointer;
80
+ transition: border-color 0.15s;
81
+ }
82
+
83
+ .image-block-view.selected {
84
+ border-color: var(--primary);
85
+ box-shadow: 0 0 0 1px var(--primary);
86
+ }
87
+
88
+ .image-block-img {
89
+ display: block;
90
+ max-width: 100%;
91
+ max-height: 400px;
92
+ object-fit: contain;
93
+ }
94
+
95
+ .image-block-placeholder {
96
+ display: flex;
97
+ flex-direction: column;
98
+ align-items: center;
99
+ justify-content: center;
100
+ gap: 0.25rem;
101
+ width: 100%;
102
+ height: 120px;
103
+ }
104
+
105
+ .image-block-actions {
106
+ position: absolute;
107
+ top: 0.5rem;
108
+ right: 0.5rem;
109
+ opacity: 0;
110
+ transition: opacity 0.15s;
111
+ }
112
+
113
+ .image-block-view:hover .image-block-actions {
114
+ opacity: 1;
115
+ }
116
+ </style>