@drawnagency/primitives 0.1.113 → 0.1.115

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 (534) hide show
  1. package/README.md +1 -1
  2. package/dist/auth/cookies.d.ts +39 -0
  3. package/dist/auth/cookies.d.ts.map +1 -1
  4. package/dist/auth/index.js +3 -3
  5. package/dist/chunk-4WQ36ZP7.js +83 -0
  6. package/dist/{chunk-REDDTTGJ.js → chunk-4Y2JQQZL.js} +19 -1
  7. package/dist/chunk-5GFACGSN.js +6 -0
  8. package/dist/{chunk-AHALSCQH.js → chunk-67P34WNW.js} +76 -131
  9. package/dist/{chunk-S2L3BPLS.js → chunk-7SX42OP4.js} +1 -1
  10. package/dist/{chunk-GGXZZ77Z.js → chunk-AASEGXNT.js} +18 -1
  11. package/dist/chunk-APIJPTFG.js +64 -0
  12. package/dist/{chunk-WKZ7OENC.js → chunk-BQ5TZZUE.js} +5 -1
  13. package/dist/chunk-CDBURDPX.js +90 -0
  14. package/dist/chunk-DFKTF3CH.js +0 -0
  15. package/dist/chunk-DIMDRBFK.js +11 -0
  16. package/dist/chunk-DJABADOO.js +131 -0
  17. package/dist/{chunk-NHN2LSIU.js → chunk-DJOGPSRU.js} +31 -68
  18. package/dist/{chunk-KR2MHTNJ.js → chunk-FHTKSELX.js} +610 -62
  19. package/dist/{chunk-WUJ3XNFI.js → chunk-GGYY3JQJ.js} +19 -24
  20. package/dist/chunk-GNF6KFQ7.js +18 -0
  21. package/dist/{chunk-FRE2CCLV.js → chunk-HHNPSKPT.js} +5 -79
  22. package/dist/{chunk-IINIZBQB.js → chunk-JCDZAFX2.js} +30 -10
  23. package/dist/chunk-JR24U7FJ.js +120 -0
  24. package/dist/{chunk-BDFTMGCL.js → chunk-JXATNKLV.js} +11 -10
  25. package/dist/{chunk-SW6PCQQD.js → chunk-KQA772WQ.js} +2 -1
  26. package/dist/{chunk-6BZ2KNTP.js → chunk-NX7TFHA4.js} +195 -65
  27. package/dist/{chunk-VWWY5TL5.js → chunk-O37AV27P.js} +14 -75
  28. package/dist/chunk-RIITGTV3.js +275 -0
  29. package/dist/{chunk-HBULBDGP.js → chunk-S37DZPHW.js} +1 -1
  30. package/dist/chunk-S7QRHUWO.js +8 -0
  31. package/dist/{chunk-Z7W3DQTR.js → chunk-T26HAKW3.js} +424 -42
  32. package/dist/{chunk-4I5OO5UB.js → chunk-TEOAKGZA.js} +0 -1
  33. package/dist/{chunk-GPPVYLEI.js → chunk-UUUSJDIG.js} +1 -1
  34. package/dist/chunk-VY3IFGE3.js +70 -0
  35. package/dist/chunk-WYOFQHKI.js +176 -0
  36. package/dist/{chunk-4RNF2DRG.js → chunk-XDEPXTBY.js} +0 -2
  37. package/dist/{chunk-DS4GCYV2.js → chunk-YV3YSZEB.js} +223 -16
  38. package/dist/collab/rebase.d.ts +2 -1
  39. package/dist/collab/rebase.d.ts.map +1 -1
  40. package/dist/collab/rebase.js +24 -9
  41. package/dist/components/brandguide/ColorsEditable.d.ts.map +1 -1
  42. package/dist/components/chat/ChatPanel.d.ts.map +1 -1
  43. package/dist/components/chat/ChatWidget.d.ts.map +1 -1
  44. package/dist/components/docfile/DocFilePane.d.ts.map +1 -1
  45. package/dist/components/editor/ChildBlockWrapper.d.ts.map +1 -1
  46. package/dist/components/editor/ConflictDialog.d.ts.map +1 -1
  47. package/dist/components/editor/DragHandle.d.ts +12 -2
  48. package/dist/components/editor/DragHandle.d.ts.map +1 -1
  49. package/dist/components/editor/DropEdgeIndicator.d.ts +15 -6
  50. package/dist/components/editor/DropEdgeIndicator.d.ts.map +1 -1
  51. package/dist/components/editor/NavGroupRow.d.ts +4 -1
  52. package/dist/components/editor/NavGroupRow.d.ts.map +1 -1
  53. package/dist/components/editor/PagesModal.d.ts.map +1 -1
  54. package/dist/components/editor/SectionWrapper.d.ts +1 -1
  55. package/dist/components/editor/SectionWrapper.d.ts.map +1 -1
  56. package/dist/components/editor/SettingsForm.d.ts.map +1 -1
  57. package/dist/components/editor/TagIndicator.d.ts +15 -0
  58. package/dist/components/editor/TagIndicator.d.ts.map +1 -0
  59. package/dist/components/editor/index.js +150 -79
  60. package/dist/components/primitives/DocumentDropZone.d.ts +1 -1
  61. package/dist/components/primitives/EditableGrid.d.ts.map +1 -1
  62. package/dist/components/primitives/EditableList.d.ts.map +1 -1
  63. package/dist/components/primitives/HeadingSection.d.ts +4 -1
  64. package/dist/components/primitives/HeadingSection.d.ts.map +1 -1
  65. package/dist/components/primitives/ResolvedMedia.d.ts +5 -1
  66. package/dist/components/primitives/ResolvedMedia.d.ts.map +1 -1
  67. package/dist/components/primitives/{defineHeadingSection.d.ts → define-heading-section.d.ts} +1 -1
  68. package/dist/components/primitives/define-heading-section.d.ts.map +1 -0
  69. package/dist/components/primitives/{gridDrop.d.ts → grid-drop.d.ts} +1 -1
  70. package/dist/components/primitives/grid-drop.d.ts.map +1 -0
  71. package/dist/components/primitives/index.d.ts +1 -1
  72. package/dist/components/primitives/index.d.ts.map +1 -1
  73. package/dist/components/primitives/index.js +22 -154
  74. package/dist/components/sections/Button/CTAButton.d.ts.map +1 -1
  75. package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts +2 -6
  76. package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts.map +1 -1
  77. package/dist/components/sections/DoDontMedia/index.d.ts +8 -0
  78. package/dist/components/sections/DoDontMedia/index.d.ts.map +1 -1
  79. package/dist/components/sections/IconList/IconList.d.ts +2 -1
  80. package/dist/components/sections/IconList/IconList.d.ts.map +1 -1
  81. package/dist/components/sections/IconList/IconListSettings.d.ts +2 -1
  82. package/dist/components/sections/IconList/IconListSettings.d.ts.map +1 -1
  83. package/dist/components/sections/IconList/index.d.ts +1 -0
  84. package/dist/components/sections/IconList/index.d.ts.map +1 -1
  85. package/dist/components/sections/Media/MediaBlock.d.ts +2 -1
  86. package/dist/components/sections/Media/MediaBlock.d.ts.map +1 -1
  87. package/dist/components/sections/Media/index.d.ts +8 -0
  88. package/dist/components/sections/Media/index.d.ts.map +1 -1
  89. package/dist/components/sections/Reference/ReferenceList.d.ts +35 -0
  90. package/dist/components/sections/Reference/ReferenceList.d.ts.map +1 -0
  91. package/dist/components/sections/Reference/ReferenceSettings.d.ts +12 -0
  92. package/dist/components/sections/Reference/ReferenceSettings.d.ts.map +1 -0
  93. package/dist/components/sections/Reference/index.d.ts +9 -0
  94. package/dist/components/sections/Reference/index.d.ts.map +1 -0
  95. package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts +38 -0
  96. package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts.map +1 -0
  97. package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts +20 -0
  98. package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts.map +1 -0
  99. package/dist/components/sections/SectionSummary/index.d.ts +33 -0
  100. package/dist/components/sections/SectionSummary/index.d.ts.map +1 -0
  101. package/dist/components/sections/all-sections.d.ts +53 -0
  102. package/dist/components/sections/all-sections.d.ts.map +1 -1
  103. package/dist/components/sections/brand-guide.d.ts +41 -2
  104. package/dist/components/sections/brand-guide.d.ts.map +1 -1
  105. package/dist/components/sections/brand-guide.js +17 -10
  106. package/dist/components/sections/core-sections.d.ts +14 -0
  107. package/dist/components/sections/core-sections.d.ts.map +1 -1
  108. package/dist/components/sections/register-schemas.js +25 -18
  109. package/dist/components/sections/register.js +25 -18
  110. package/dist/components/shared/BrandSwatchesContext.d.ts +9 -0
  111. package/dist/components/shared/BrandSwatchesContext.d.ts.map +1 -0
  112. package/dist/components/shared/Button.d.ts +11 -3
  113. package/dist/components/shared/Button.d.ts.map +1 -1
  114. package/dist/components/shared/Checkbox.d.ts +6 -0
  115. package/dist/components/shared/Checkbox.d.ts.map +1 -1
  116. package/dist/components/shared/ConfirmDialog.d.ts +25 -0
  117. package/dist/components/shared/ConfirmDialog.d.ts.map +1 -0
  118. package/dist/components/shared/ConfirmInline.d.ts +25 -0
  119. package/dist/components/shared/ConfirmInline.d.ts.map +1 -0
  120. package/dist/components/shared/ErrorBoundary.d.ts.map +1 -1
  121. package/dist/components/shared/Fab.d.ts +11 -2
  122. package/dist/components/shared/Fab.d.ts.map +1 -1
  123. package/dist/components/shared/FabStack.d.ts +22 -0
  124. package/dist/components/shared/FabStack.d.ts.map +1 -0
  125. package/dist/components/shared/HistoryChangesModal.d.ts.map +1 -1
  126. package/dist/components/shared/HistoryPopover.d.ts.map +1 -1
  127. package/dist/components/shared/ImageBackgroundField.d.ts +9 -0
  128. package/dist/components/shared/ImageBackgroundField.d.ts.map +1 -0
  129. package/dist/components/shared/{UploadRejectionAlert.d.ts → InlineAlert.d.ts} +4 -2
  130. package/dist/components/shared/InlineAlert.d.ts.map +1 -0
  131. package/dist/components/shared/Input.d.ts +10 -0
  132. package/dist/components/shared/Input.d.ts.map +1 -1
  133. package/dist/components/shared/Navigation.d.ts.map +1 -1
  134. package/dist/components/shared/Notice.d.ts +10 -0
  135. package/dist/components/shared/Notice.d.ts.map +1 -0
  136. package/dist/components/shared/Popover.d.ts.map +1 -1
  137. package/dist/components/shared/ReferenceSourcesContext.d.ts +25 -0
  138. package/dist/components/shared/ReferenceSourcesContext.d.ts.map +1 -0
  139. package/dist/components/shared/Select.d.ts +3 -2
  140. package/dist/components/shared/Select.d.ts.map +1 -1
  141. package/dist/components/shared/SplitButton.d.ts.map +1 -1
  142. package/dist/components/shared/SummaryAnchorsContext.d.ts +10 -0
  143. package/dist/components/shared/SummaryAnchorsContext.d.ts.map +1 -0
  144. package/dist/components/shared/Textarea.d.ts +7 -0
  145. package/dist/components/shared/Textarea.d.ts.map +1 -1
  146. package/dist/components/shared/ToolbarFrame.d.ts +17 -0
  147. package/dist/components/shared/ToolbarFrame.d.ts.map +1 -0
  148. package/dist/components/shared/copy.d.ts +13 -0
  149. package/dist/components/shared/copy.d.ts.map +1 -0
  150. package/dist/components/shared/icons.d.ts +0 -12
  151. package/dist/components/shared/icons.d.ts.map +1 -1
  152. package/dist/components/shell/AudienceDetailsPanel.d.ts +7 -1
  153. package/dist/components/shell/AudienceDetailsPanel.d.ts.map +1 -1
  154. package/dist/components/shell/AudienceRow.d.ts.map +1 -1
  155. package/dist/components/shell/BugReportFAB.d.ts +7 -1
  156. package/dist/components/shell/BugReportFAB.d.ts.map +1 -1
  157. package/dist/components/shell/CredentialList.d.ts.map +1 -1
  158. package/dist/components/shell/DocInspector.d.ts.map +1 -1
  159. package/dist/components/shell/DocumentEditorOverlay.d.ts.map +1 -1
  160. package/dist/components/shell/EditorContext.d.ts +4 -0
  161. package/dist/components/shell/EditorContext.d.ts.map +1 -1
  162. package/dist/components/shell/EditorLoginForm.d.ts.map +1 -1
  163. package/dist/components/shell/EditorModal.d.ts.map +1 -1
  164. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  165. package/dist/components/shell/HistoryToolbar.d.ts.map +1 -1
  166. package/dist/components/shell/MediaFolderTile.d.ts +4 -1
  167. package/dist/components/shell/MediaFolderTile.d.ts.map +1 -1
  168. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
  169. package/dist/components/shell/RestoreModal.d.ts.map +1 -1
  170. package/dist/components/shell/SiteSettingsChatbot.d.ts.map +1 -1
  171. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
  172. package/dist/components/shell/SiteSettingsModal.d.ts +3 -1
  173. package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
  174. package/dist/components/shell/SiteSettingsTags.d.ts +13 -0
  175. package/dist/components/shell/SiteSettingsTags.d.ts.map +1 -0
  176. package/dist/components/shell/SiteSettingsUsers.d.ts.map +1 -1
  177. package/dist/components/shell/ViewerLoginForm.d.ts.map +1 -1
  178. package/dist/components/shell/{blockMoveDispatch.d.ts → block-move-dispatch.d.ts} +1 -1
  179. package/dist/components/shell/block-move-dispatch.d.ts.map +1 -0
  180. package/dist/components/shell/reference-sources.d.ts +22 -0
  181. package/dist/components/shell/reference-sources.d.ts.map +1 -0
  182. package/dist/deck/index.d.ts +2 -2
  183. package/dist/deck/index.d.ts.map +1 -1
  184. package/dist/deck/index.js +1 -3
  185. package/dist/deck-builder/index.js +10 -17
  186. package/dist/document/index.d.ts +2 -2
  187. package/dist/document/index.d.ts.map +1 -1
  188. package/dist/hooks/useBlockDnd.d.ts +11 -0
  189. package/dist/hooks/useBlockDnd.d.ts.map +1 -1
  190. package/dist/hooks/useBuildStatus.d.ts +1 -1
  191. package/dist/hooks/useBuildStatus.d.ts.map +1 -1
  192. package/dist/hooks/useDocumentUploads.d.ts +1 -1
  193. package/dist/hooks/useDocumentUploads.d.ts.map +1 -1
  194. package/dist/hooks/useEditorPersistence.d.ts +5 -1
  195. package/dist/hooks/useEditorPersistence.d.ts.map +1 -1
  196. package/dist/hooks/useEditorPublish.d.ts +6 -3
  197. package/dist/hooks/useEditorPublish.d.ts.map +1 -1
  198. package/dist/hooks/useMediaPipeline.d.ts.map +1 -1
  199. package/dist/hooks/useNotice.d.ts +19 -0
  200. package/dist/hooks/useNotice.d.ts.map +1 -0
  201. package/dist/hooks/useSortableNavRow.d.ts +11 -0
  202. package/dist/hooks/useSortableNavRow.d.ts.map +1 -1
  203. package/dist/hooks/useSortableRow.d.ts +11 -0
  204. package/dist/hooks/useSortableRow.d.ts.map +1 -1
  205. package/dist/hooks/useStackedEscape.d.ts +32 -0
  206. package/dist/hooks/useStackedEscape.d.ts.map +1 -0
  207. package/dist/index.js +95 -48
  208. package/dist/lib/audience-secret.js +2 -2
  209. package/dist/lib/block-dnd.d.ts +5 -0
  210. package/dist/lib/block-dnd.d.ts.map +1 -1
  211. package/dist/lib/block-move.d.ts.map +1 -1
  212. package/dist/lib/brand-swatches.d.ts +12 -0
  213. package/dist/lib/brand-swatches.d.ts.map +1 -0
  214. package/dist/lib/container-ops.d.ts +3 -2
  215. package/dist/lib/container-ops.d.ts.map +1 -1
  216. package/dist/lib/dexie.d.ts +7 -1
  217. package/dist/lib/dexie.d.ts.map +1 -1
  218. package/dist/lib/dexie.js +12 -3
  219. package/dist/lib/env.d.ts +4 -0
  220. package/dist/lib/env.d.ts.map +1 -1
  221. package/dist/lib/env.js +5 -3
  222. package/dist/lib/events.d.ts +1 -2
  223. package/dist/lib/events.d.ts.map +1 -1
  224. package/dist/lib/image-background.d.ts +8 -0
  225. package/dist/lib/image-background.d.ts.map +1 -0
  226. package/dist/lib/image-variant-plan.d.ts +42 -0
  227. package/dist/lib/image-variant-plan.d.ts.map +1 -0
  228. package/dist/lib/image-variant-plan.js +53 -0
  229. package/dist/lib/index-ops.d.ts.map +1 -1
  230. package/dist/lib/index-ops.js +21 -17
  231. package/dist/lib/index.d.ts +7 -4
  232. package/dist/lib/index.d.ts.map +1 -1
  233. package/dist/lib/index.js +55 -26
  234. package/dist/lib/loader.d.ts +25 -12
  235. package/dist/lib/loader.d.ts.map +1 -1
  236. package/dist/lib/media-ops.d.ts +73 -0
  237. package/dist/lib/media-ops.d.ts.map +1 -0
  238. package/dist/lib/media-ops.js +60 -0
  239. package/dist/lib/nav-tree.d.ts +7 -0
  240. package/dist/lib/nav-tree.d.ts.map +1 -1
  241. package/dist/lib/nav.d.ts +38 -0
  242. package/dist/lib/nav.d.ts.map +1 -1
  243. package/dist/lib/pages.d.ts +2 -1
  244. package/dist/lib/pages.d.ts.map +1 -1
  245. package/dist/lib/platform-broker.d.ts +4 -2
  246. package/dist/lib/platform-broker.d.ts.map +1 -1
  247. package/dist/lib/platform-broker.js +21 -13
  248. package/dist/lib/reference-type.d.ts +2 -0
  249. package/dist/lib/reference-type.d.ts.map +1 -0
  250. package/dist/lib/reference-validation.d.ts +31 -0
  251. package/dist/lib/reference-validation.d.ts.map +1 -0
  252. package/dist/lib/reference-validation.js +39 -0
  253. package/dist/lib/references.d.ts +74 -0
  254. package/dist/lib/references.d.ts.map +1 -0
  255. package/dist/lib/registry.d.ts +35 -0
  256. package/dist/lib/registry.d.ts.map +1 -1
  257. package/dist/lib/{safeRedirect.d.ts → safe-redirect.d.ts} +1 -1
  258. package/dist/lib/safe-redirect.d.ts.map +1 -0
  259. package/dist/lib/sidecar-diagnostics.d.ts +20 -0
  260. package/dist/lib/sidecar-diagnostics.d.ts.map +1 -0
  261. package/dist/lib/sidecars.d.ts +118 -0
  262. package/dist/lib/sidecars.d.ts.map +1 -0
  263. package/dist/lib/sidecars.js +23 -0
  264. package/dist/lib/slug.d.ts +2 -0
  265. package/dist/lib/slug.d.ts.map +1 -0
  266. package/dist/lib/storage-tier.d.ts +17 -0
  267. package/dist/lib/storage-tier.d.ts.map +1 -0
  268. package/dist/lib/storage-tier.js +29 -0
  269. package/dist/lib/tags.d.ts +64 -0
  270. package/dist/lib/tags.d.ts.map +1 -0
  271. package/dist/lib/theme-vars.d.ts +9 -0
  272. package/dist/lib/theme-vars.d.ts.map +1 -1
  273. package/dist/media/index.d.ts +1 -1
  274. package/dist/media/index.d.ts.map +1 -1
  275. package/dist/media/index.js +18 -14
  276. package/dist/media/queue.d.ts +2 -0
  277. package/dist/media/queue.d.ts.map +1 -1
  278. package/dist/media/utils.d.ts +2 -0
  279. package/dist/media/utils.d.ts.map +1 -1
  280. package/dist/media/{videoPoster.d.ts → video-poster.d.ts} +1 -1
  281. package/dist/media/video-poster.d.ts.map +1 -0
  282. package/dist/media/worker.d.ts +1 -35
  283. package/dist/media/worker.d.ts.map +1 -1
  284. package/dist/schemas/audience.js +2 -2
  285. package/dist/schemas/index.d.ts +1 -0
  286. package/dist/schemas/index.d.ts.map +1 -1
  287. package/dist/schemas/index.js +25 -13
  288. package/dist/schemas/media.d.ts +4 -0
  289. package/dist/schemas/media.d.ts.map +1 -1
  290. package/dist/schemas/shared.d.ts +26 -0
  291. package/dist/schemas/shared.d.ts.map +1 -1
  292. package/dist/schemas/site-config.d.ts +6 -0
  293. package/dist/schemas/site-config.d.ts.map +1 -1
  294. package/dist/schemas/tags.d.ts +27 -0
  295. package/dist/schemas/tags.d.ts.map +1 -0
  296. package/dist/storage/index.js +2 -1
  297. package/dist/storage/memory.d.ts +21 -0
  298. package/dist/storage/memory.d.ts.map +1 -0
  299. package/dist/storage/memory.js +129 -0
  300. package/dist/storage/types.d.ts +9 -0
  301. package/dist/storage/types.d.ts.map +1 -1
  302. package/dist/types/database.d.ts.map +1 -1
  303. package/package.json +26 -1
  304. package/src/auth/cookies.ts +111 -0
  305. package/src/collab/rebase.ts +29 -9
  306. package/src/components/brandguide/ColorSwatchSettings.tsx +1 -1
  307. package/src/components/brandguide/ColorsEditable.tsx +1 -0
  308. package/src/components/chat/ChatPanel.tsx +2 -3
  309. package/src/components/chat/ChatWidget.tsx +2 -3
  310. package/src/components/docfile/DocFilePane.tsx +4 -12
  311. package/src/components/editor/ChildBlockWrapper.tsx +13 -19
  312. package/src/components/editor/ConflictDialog.tsx +27 -35
  313. package/src/components/editor/DeleteButton.tsx +2 -2
  314. package/src/components/editor/DragHandle.tsx +16 -3
  315. package/src/components/editor/DropEdgeIndicator.tsx +36 -10
  316. package/src/components/editor/InsertButton.tsx +2 -2
  317. package/src/components/editor/NavGroupRow.tsx +43 -14
  318. package/src/components/editor/PagesModal.tsx +99 -26
  319. package/src/components/editor/SectionWrapper.tsx +64 -23
  320. package/src/components/editor/SettingsButton.tsx +2 -2
  321. package/src/components/editor/SettingsForm.tsx +19 -2
  322. package/src/components/editor/StatusIndicator.tsx +4 -4
  323. package/src/components/editor/TagIndicator.tsx +80 -0
  324. package/src/components/primitives/DocumentDropZone.tsx +1 -1
  325. package/src/components/primitives/EditableGrid.tsx +15 -14
  326. package/src/components/primitives/EditableList.tsx +27 -74
  327. package/src/components/primitives/HeadingSection.tsx +5 -2
  328. package/src/components/primitives/ResolvedMedia.tsx +13 -0
  329. package/src/components/primitives/{defineHeadingSection.tsx → define-heading-section.tsx} +1 -0
  330. package/src/components/primitives/index.ts +1 -1
  331. package/src/components/primitives/useEditablePlainText.ts +5 -5
  332. package/src/components/sections/Button/CTAButton.tsx +3 -1
  333. package/src/components/sections/DoDontMedia/DoDontMediaBlock.tsx +4 -4
  334. package/src/components/sections/DoDontMedia/index.tsx +12 -3
  335. package/src/components/sections/IconList/DoDontToggle.tsx +2 -2
  336. package/src/components/sections/IconList/IconList.tsx +70 -37
  337. package/src/components/sections/IconList/IconListSettings.tsx +55 -17
  338. package/src/components/sections/IconList/index.tsx +10 -3
  339. package/src/components/sections/LinkHeading/index.tsx +1 -1
  340. package/src/components/sections/Media/MediaBlock.tsx +13 -2
  341. package/src/components/sections/Media/index.tsx +12 -4
  342. package/src/components/sections/Reference/ReferenceList.tsx +214 -0
  343. package/src/components/sections/Reference/ReferenceSettings.tsx +159 -0
  344. package/src/components/sections/Reference/index.tsx +47 -0
  345. package/src/components/sections/SectionSummary/SectionSummaryBlock.tsx +476 -0
  346. package/src/components/sections/SectionSummary/SectionSummarySettings.tsx +126 -0
  347. package/src/components/sections/SectionSummary/index.tsx +149 -0
  348. package/src/components/sections/SubHeading/index.tsx +1 -1
  349. package/src/components/sections/SubSubHeading/index.tsx +1 -1
  350. package/src/components/sections/brand-guide.ts +4 -3
  351. package/src/components/sections/core-sections.ts +2 -0
  352. package/src/components/shared/BrandSwatchesContext.ts +13 -0
  353. package/src/components/shared/Button.tsx +47 -34
  354. package/src/components/shared/Checkbox.tsx +21 -12
  355. package/src/components/shared/ConfirmDialog.tsx +87 -0
  356. package/src/components/shared/ConfirmInline.tsx +90 -0
  357. package/src/components/shared/ErrorBoundary.tsx +6 -18
  358. package/src/components/shared/Fab.tsx +15 -5
  359. package/src/components/shared/FabStack.tsx +28 -0
  360. package/src/components/shared/HistoryChangesModal.tsx +43 -41
  361. package/src/components/shared/HistoryPopover.tsx +7 -20
  362. package/src/components/shared/ImageBackgroundField.tsx +92 -0
  363. package/src/components/shared/{UploadRejectionAlert.tsx → InlineAlert.tsx} +21 -5
  364. package/src/components/shared/Input.tsx +23 -7
  365. package/src/components/shared/Navigation.tsx +22 -17
  366. package/src/components/shared/Notice.tsx +59 -0
  367. package/src/components/shared/Popover.tsx +7 -11
  368. package/src/components/shared/ReferenceSourcesContext.ts +27 -0
  369. package/src/components/shared/Select.tsx +5 -2
  370. package/src/components/shared/SplitButton.tsx +11 -17
  371. package/src/components/shared/SummaryAnchorsContext.ts +11 -0
  372. package/src/components/shared/Textarea.tsx +17 -2
  373. package/src/components/shared/ToolbarFrame.tsx +28 -0
  374. package/src/components/shared/VideoSourceField.tsx +1 -1
  375. package/src/components/shared/copy.ts +18 -0
  376. package/src/components/shared/icons.tsx +1 -17
  377. package/src/components/shell/AudienceAddForm.tsx +2 -2
  378. package/src/components/shell/AudienceDetailsPanel.tsx +23 -5
  379. package/src/components/shell/AudienceRow.tsx +22 -15
  380. package/src/components/shell/BugReportFAB.tsx +50 -40
  381. package/src/components/shell/CredentialList.tsx +33 -13
  382. package/src/components/shell/DocInspector.tsx +3 -12
  383. package/src/components/shell/DocumentEditorOverlay.tsx +33 -23
  384. package/src/components/shell/EditorContext.tsx +7 -0
  385. package/src/components/shell/EditorLoginForm.tsx +26 -36
  386. package/src/components/shell/EditorModal.tsx +8 -10
  387. package/src/components/shell/EditorShell.tsx +501 -338
  388. package/src/components/shell/HistoryToolbar.tsx +24 -26
  389. package/src/components/shell/MediaFolderTile.tsx +8 -3
  390. package/src/components/shell/MediaLibraryModal.tsx +59 -60
  391. package/src/components/shell/ProcessingIndicator.tsx +2 -2
  392. package/src/components/shell/RestoreModal.tsx +17 -16
  393. package/src/components/shell/SetPasswordForm.tsx +3 -3
  394. package/src/components/shell/SiteSettingsChatbot.tsx +61 -42
  395. package/src/components/shell/SiteSettingsDisplay.tsx +10 -20
  396. package/src/components/shell/SiteSettingsModal.tsx +24 -2
  397. package/src/components/shell/SiteSettingsTags.tsx +143 -0
  398. package/src/components/shell/SiteSettingsUsers.tsx +36 -26
  399. package/src/components/shell/SiteSettingsViewerAccess.tsx +2 -2
  400. package/src/components/shell/ViewerLoginForm.tsx +5 -4
  401. package/src/components/shell/reference-sources.ts +36 -0
  402. package/src/deck/index.ts +2 -2
  403. package/src/document/index.ts +2 -2
  404. package/src/hooks/useBlockDnd.ts +11 -0
  405. package/src/hooks/useBuildStatus.ts +53 -6
  406. package/src/hooks/useDocumentUploads.ts +1 -1
  407. package/src/hooks/useEditorPersistence.ts +141 -35
  408. package/src/hooks/useEditorPublish.ts +27 -31
  409. package/src/hooks/useMediaPipeline.ts +30 -24
  410. package/src/hooks/useNotice.ts +45 -0
  411. package/src/hooks/useSortableNavRow.ts +11 -0
  412. package/src/hooks/useSortableRow.ts +22 -2
  413. package/src/hooks/useStackedEscape.ts +62 -0
  414. package/src/lib/block-dnd.ts +6 -1
  415. package/src/lib/block-move.ts +3 -0
  416. package/src/lib/brand-swatches.ts +32 -0
  417. package/src/lib/container-ops.ts +5 -3
  418. package/src/lib/dexie.ts +24 -2
  419. package/src/lib/env.ts +9 -0
  420. package/src/lib/events.ts +1 -2
  421. package/src/lib/image-background.ts +31 -0
  422. package/src/lib/image-variant-plan.ts +92 -0
  423. package/src/lib/index-ops.ts +9 -18
  424. package/src/lib/index.ts +20 -4
  425. package/src/lib/loader.ts +28 -88
  426. package/src/lib/media-ops.ts +112 -0
  427. package/src/lib/nav-tree.ts +104 -4
  428. package/src/lib/nav.ts +196 -36
  429. package/src/lib/pages.ts +2 -3
  430. package/src/lib/platform-broker.ts +32 -14
  431. package/src/lib/reference-type.ts +3 -0
  432. package/src/lib/reference-validation.ts +69 -0
  433. package/src/lib/references.ts +130 -0
  434. package/src/lib/registry.ts +37 -0
  435. package/src/lib/sidecar-diagnostics.ts +29 -0
  436. package/src/lib/sidecars.ts +221 -0
  437. package/src/lib/slug.ts +6 -0
  438. package/src/lib/storage-tier.ts +38 -0
  439. package/src/lib/tags.ts +165 -0
  440. package/src/lib/theme-vars.ts +23 -0
  441. package/src/media/index.ts +1 -1
  442. package/src/media/queue.ts +3 -0
  443. package/src/media/utils.ts +19 -1
  444. package/src/media/{videoPoster.ts → video-poster.ts} +2 -2
  445. package/src/media/worker.ts +17 -8
  446. package/src/schemas/index.ts +1 -0
  447. package/src/schemas/media.ts +7 -2
  448. package/src/schemas/shared.ts +24 -1
  449. package/src/schemas/site-config.ts +6 -1
  450. package/src/schemas/tags.ts +33 -0
  451. package/src/storage/memory.ts +178 -0
  452. package/src/storage/types.ts +16 -3
  453. package/src/types/database.ts +2 -0
  454. package/dist/chunk-DNY72JZN.js +0 -86
  455. package/dist/chunk-F2LYQPXV.js +0 -77
  456. package/dist/chunk-JH762VUH.js +0 -128
  457. package/dist/chunk-K7DYZXVU.js +0 -138
  458. package/dist/components/primitives/defineHeadingSection.d.ts.map +0 -1
  459. package/dist/components/primitives/gridDrop.d.ts.map +0 -1
  460. package/dist/components/shared/UploadRejectionAlert.d.ts.map +0 -1
  461. package/dist/components/shell/BuildStatusIndicator.d.ts +0 -7
  462. package/dist/components/shell/BuildStatusIndicator.d.ts.map +0 -1
  463. package/dist/components/shell/blockMoveDispatch.d.ts.map +0 -1
  464. package/dist/hooks/index.d.ts +0 -9
  465. package/dist/hooks/index.d.ts.map +0 -1
  466. package/dist/lib/grid.d.ts +0 -2
  467. package/dist/lib/grid.d.ts.map +0 -1
  468. package/dist/lib/safeRedirect.d.ts.map +0 -1
  469. package/dist/media/videoPoster.d.ts.map +0 -1
  470. package/src/components/brandguide/ColorSwatchSettings.d.ts.map +0 -1
  471. package/src/components/brandguide/Colors.d.ts.map +0 -1
  472. package/src/components/primitives/CustomParagraph.d.ts.map +0 -1
  473. package/src/components/primitives/EditableGrid.d.ts.map +0 -1
  474. package/src/components/primitives/EditablePlainText.d.ts.map +0 -1
  475. package/src/components/primitives/EditableRichText.d.ts.map +0 -1
  476. package/src/components/primitives/HeadingSection.d.ts.map +0 -1
  477. package/src/components/primitives/IconPicker.d.ts.map +0 -1
  478. package/src/components/primitives/LinkPopover.d.ts.map +0 -1
  479. package/src/components/primitives/MediaSettingsForms.d.ts.map +0 -1
  480. package/src/components/primitives/ResolvedMedia.d.ts.map +0 -1
  481. package/src/components/primitives/RichTextToolbar.d.ts.map +0 -1
  482. package/src/components/primitives/tiptap-presets.d.ts.map +0 -1
  483. package/src/components/primitives/useEditableCollection.d.ts.map +0 -1
  484. package/src/components/primitives/useEditablePlainText.d.ts.map +0 -1
  485. package/src/components/primitives/useEditableRichText.d.ts.map +0 -1
  486. package/src/components/sections/Button/CTAButton.d.ts.map +0 -1
  487. package/src/components/sections/Button/index.d.ts.map +0 -1
  488. package/src/components/sections/Colors/index.d.ts.map +0 -1
  489. package/src/components/sections/IconList/IconList.d.ts.map +0 -1
  490. package/src/components/sections/IconList/IconListSettings.d.ts.map +0 -1
  491. package/src/components/sections/IconList/index.d.ts.map +0 -1
  492. package/src/components/sections/LinkHeading/index.d.ts.map +0 -1
  493. package/src/components/sections/Prose/Prose.d.ts.map +0 -1
  494. package/src/components/sections/Prose/index.d.ts.map +0 -1
  495. package/src/components/sections/SubHeading/index.d.ts.map +0 -1
  496. package/src/components/sections/SubSubHeading/index.d.ts.map +0 -1
  497. package/src/components/sections/register-schemas.d.ts.map +0 -1
  498. package/src/components/shared/Button.d.ts.map +0 -1
  499. package/src/components/shared/Checkbox.d.ts.map +0 -1
  500. package/src/components/shared/FormLabel.d.ts.map +0 -1
  501. package/src/components/shared/IconButton.d.ts.map +0 -1
  502. package/src/components/shared/Input.d.ts.map +0 -1
  503. package/src/components/shared/Select.d.ts.map +0 -1
  504. package/src/components/shared/icons.d.ts.map +0 -1
  505. package/src/components/shell/BuildStatusIndicator.tsx +0 -59
  506. package/src/components/shell/MediaLibraryContext.d.ts.map +0 -1
  507. package/src/hooks/index.ts +0 -8
  508. package/src/hooks/useResolvedMedia.d.ts.map +0 -1
  509. package/src/lib/cn.d.ts.map +0 -1
  510. package/src/lib/grid.d.ts.map +0 -1
  511. package/src/lib/grid.ts +0 -7
  512. package/src/lib/icons.d.ts.map +0 -1
  513. package/src/lib/loader.d.ts.map +0 -1
  514. package/src/lib/nav.d.ts.map +0 -1
  515. package/src/lib/registry.d.ts.map +0 -1
  516. package/src/lib/sanitize.d.ts.map +0 -1
  517. package/src/media/github.d.ts.map +0 -1
  518. package/src/media/index.d.ts.map +0 -1
  519. package/src/media/queue.d.ts.map +0 -1
  520. package/src/media/resolve.d.ts.map +0 -1
  521. package/src/media/types.d.ts.map +0 -1
  522. package/src/media/utils.d.ts.map +0 -1
  523. package/src/media/videoPoster.d.ts.map +0 -1
  524. package/src/schemas/auth.d.ts.map +0 -1
  525. package/src/schemas/media-grid-options.d.ts.map +0 -1
  526. package/src/schemas/media.d.ts.map +0 -1
  527. package/src/schemas/sections.d.ts.map +0 -1
  528. package/src/schemas/shared.d.ts.map +0 -1
  529. package/src/schemas/site-config.d.ts.map +0 -1
  530. /package/dist/{chunk-B7VBSE5X.js → chunk-3JDTXOIG.js} +0 -0
  531. /package/dist/{chunk-CXZ5YJG4.js → chunk-L45X7DKX.js} +0 -0
  532. /package/src/components/primitives/{gridDrop.ts → grid-drop.ts} +0 -0
  533. /package/src/components/shell/{blockMoveDispatch.ts → block-move-dispatch.ts} +0 -0
  534. /package/src/lib/{safeRedirect.ts → safe-redirect.ts} +0 -0
@@ -1,8 +1,11 @@
1
- import { useRef, useEffect, useState, type ReactNode } from "react";
2
- import { DragHandle, DeleteIcon } from "../shared/icons";
1
+ import { useId, type ReactNode } from "react";
2
+ import { DragHandle } from "../shared/icons";
3
+ import { Trash2 } from "lucide-react";
3
4
  import { IconButton } from "../shared/IconButton";
5
+ import { DropEdgeIndicator } from "../editor/DropEdgeIndicator";
4
6
  import { cn } from "../../lib/cn";
5
7
  import { useEditableCollection } from "./useEditableCollection";
8
+ import { useSortableRow } from "../../hooks/useSortableRow";
6
9
 
7
10
  interface EditableListProps<T> {
8
11
  items: T[];
@@ -26,11 +29,11 @@ export function EditableList<T>({
26
29
  onChange,
27
30
  createItem,
28
31
  });
29
-
30
- const [dragState, setDragState] = useState<{
31
- sourceId: string | null;
32
- targetId: string | null;
33
- }>({ sourceId: null, targetId: null });
32
+ // One shared dragType per EditableList instance — a bare "list-row" let a
33
+ // row dragged out of one list reorder a DIFFERENT list it was hovered over,
34
+ // since useSortableRow's DnD matching keys off dragType alone.
35
+ const listId = useId();
36
+ const dragType = `list-row-${listId}`;
34
37
 
35
38
  if (!isEditMode) {
36
39
  return (
@@ -51,10 +54,9 @@ export function EditableList<T>({
51
54
  key={wrapped.id}
52
55
  id={wrapped.id}
53
56
  index={index}
57
+ dragType={dragType}
54
58
  onReorder={onReorder}
55
59
  onRemove={onRemove}
56
- dragState={dragState}
57
- setDragState={setDragState}
58
60
  >
59
61
  {renderItem(wrapped.data, { isEditMode: true, index })}
60
62
  </ListRow>
@@ -72,85 +74,36 @@ export function EditableList<T>({
72
74
  function ListRow({
73
75
  id,
74
76
  index,
77
+ dragType,
75
78
  onReorder,
76
79
  onRemove,
77
- dragState,
78
- setDragState,
79
80
  children,
80
81
  }: {
81
82
  id: string;
82
83
  index: number;
84
+ dragType: string;
83
85
  onReorder: (from: number, to: number) => void;
84
86
  onRemove: (id: string) => void;
85
- dragState: { sourceId: string | null; targetId: string | null };
86
- setDragState: React.Dispatch<React.SetStateAction<{ sourceId: string | null; targetId: string | null }>>;
87
87
  children: ReactNode;
88
88
  }) {
89
- const rowRef = useRef<HTMLDivElement>(null);
90
- const handleRef = useRef<HTMLButtonElement>(null);
91
-
92
- // onReorder's identity chains back to the editor shell's inline onChange, so it
93
- // changes on every editor render. Listing it in the deps below re-registered the
94
- // draggable — re-awaiting the dynamic import — on every one of those, and a
95
- // re-registration landing mid-drag cancels the drag. Read it through a ref, as
96
- // IconList's monitor and EditableGrid already do.
97
- const onReorderRef = useRef(onReorder);
98
- onReorderRef.current = onReorder;
99
-
100
- useEffect(() => {
101
- const row = rowRef.current;
102
- const handle = handleRef.current;
103
- if (!row || !handle) return;
104
-
105
- let cleanup: (() => void) | undefined;
106
- let cancelled = false;
107
-
108
- import("@atlaskit/pragmatic-drag-and-drop/element/adapter").then(({ draggable, dropTargetForElements }) => {
109
- if (cancelled) return;
110
-
111
- const cleanupDraggable = draggable({
112
- element: handle,
113
- getInitialData: () => ({ dragType: "list-row", id, index }),
114
- onDragStart: () => setDragState({ sourceId: id, targetId: null }),
115
- onDrop: () => setDragState({ sourceId: null, targetId: null }),
116
- });
117
-
118
- const cleanupDropTarget = dropTargetForElements({
119
- element: row,
120
- canDrop: ({ source }) => source.data.dragType === "list-row",
121
- getData: () => ({ id, index }),
122
- onDragEnter: () => setDragState((prev) => ({ ...prev, targetId: id })),
123
- onDragLeave: () => setDragState((prev) => prev.targetId === id ? { ...prev, targetId: null } : prev),
124
- onDrop: ({ source }) => {
125
- const fromIndex = source.data.index as number;
126
- if (fromIndex !== index) {
127
- onReorderRef.current(fromIndex, index);
128
- }
129
- },
130
- });
131
-
132
- cleanup = () => {
133
- cleanupDraggable();
134
- cleanupDropTarget();
135
- };
136
- });
137
-
138
- return () => {
139
- cancelled = true;
140
- cleanup?.();
141
- };
142
- }, [id, index, setDragState]);
143
-
144
- const isDropTarget = dragState.targetId === id && dragState.sourceId !== id;
89
+ // The row itself is the draggable (handle stays the visual grab affordance
90
+ // and drag-initiation target); drop-feedback is the closest-edge line, and a
91
+ // drop lands before/after by pointer half — useSortableRow reads onReorder
92
+ // through a ref internally, so a fresh arrow every render (as EditorShell's
93
+ // callers pass) doesn't re-register the drag mid-gesture.
94
+ const { rowRef, handleRef, isDragging, closestEdge } = useSortableRow<HTMLDivElement, HTMLButtonElement>({
95
+ index,
96
+ dragType,
97
+ onReorder,
98
+ });
145
99
 
146
100
  return (
147
101
  <div
148
102
  ref={rowRef}
149
- className={cn(
150
- "group/row relative flex items-center gap-2",
151
- isDropTarget && "border-t-2 border-primary",
152
- )}
103
+ className={cn("group/row relative flex items-center gap-2", isDragging && "opacity-50")}
153
104
  >
105
+ <DropEdgeIndicator edge={closestEdge} />
106
+
154
107
  {/* Drag handle — left edge, visible on hover or no-hover devices */}
155
108
  <IconButton
156
109
  ref={handleRef}
@@ -167,7 +120,7 @@ function ListRow({
167
120
 
168
121
  {/* Delete button — right edge, visible on hover or no-hover devices */}
169
122
  <IconButton
170
- icon={<DeleteIcon size={14} />}
123
+ icon={<Trash2 size={14} />}
171
124
  label="Delete item"
172
125
  size="sm"
173
126
  intent="destructive"
@@ -7,10 +7,13 @@ interface Props {
7
7
  tag: "h2" | "h3" | "h4";
8
8
  placeholder: string;
9
9
  className?: string;
10
+ /** Overrides the heading-derived id — the `<heading>-<reference id>` anchor stamped on a copy a
11
+ * Reference pulled in (withNavAnchors). */
12
+ anchor?: string;
10
13
  onChange?: (heading: string) => void;
11
14
  }
12
15
 
13
- export function HeadingSection({ heading, tag, placeholder, className, onChange }: Props) {
16
+ export function HeadingSection({ heading, tag, placeholder, className, anchor, onChange }: Props) {
14
17
  return (
15
18
  <EditablePlainText
16
19
  tag={tag}
@@ -18,7 +21,7 @@ export function HeadingSection({ heading, tag, placeholder, className, onChange
18
21
  onChange={onChange ?? (() => {})}
19
22
  isEditMode={!!onChange}
20
23
  placeholder={placeholder}
21
- id={toSectionId(heading)}
24
+ id={anchor ?? toSectionId(heading)}
22
25
  className={cn("scroll-mt-20", className)}
23
26
  />
24
27
  );
@@ -2,6 +2,7 @@ import { useState } from "react";
2
2
  import { cn } from "../../lib/cn";
3
3
  import { ImageIcon } from "lucide-react";
4
4
  import { useResolvedMedia } from "../../hooks/useResolvedMedia";
5
+ import type { ImageBackdrop } from "../../lib/image-background";
5
6
 
6
7
  interface ResolvedMediaProps {
7
8
  imageId: string | undefined;
@@ -13,6 +14,9 @@ interface ResolvedMediaProps {
13
14
  className?: string;
14
15
  imgClassName?: string;
15
16
  invertFrom?: string;
17
+ /** Painted above the loading placeholder and below the media, so it holds in
18
+ * the zero-JS viewer (where the placeholder never fades) and after load. */
19
+ backdrop?: ImageBackdrop;
16
20
  }
17
21
 
18
22
  export function ResolvedMedia({
@@ -25,6 +29,7 @@ export function ResolvedMedia({
25
29
  className,
26
30
  imgClassName,
27
31
  invertFrom,
32
+ backdrop,
28
33
  }: ResolvedMediaProps) {
29
34
  const resolved = useResolvedMedia(imageId);
30
35
  // A successful live resolution is always fresher than baked props (the ref
@@ -64,6 +69,14 @@ export function ResolvedMedia({
64
69
  loaded ? "opacity-0" : "opacity-100",
65
70
  )}
66
71
  />
72
+ {backdrop && (
73
+ <div
74
+ aria-hidden="true"
75
+ data-testid="media-backdrop"
76
+ className={cn("pointer-events-none absolute inset-0", backdrop.className)}
77
+ style={backdrop.style}
78
+ />
79
+ )}
67
80
  {kind === "video" ? (
68
81
  <video
69
82
  src={src}
@@ -56,6 +56,7 @@ export function defineHeadingSection<T extends string>(config: HeadingSectionCon
56
56
  heading={content.content.heading}
57
57
  tag={config.tag}
58
58
  placeholder={config.placeholder}
59
+ anchor={(content as { navAnchor?: string }).navAnchor}
59
60
  onChange={onChange ? (heading: string) => onChange({ ...content, content: { ...content.content, heading } }) : undefined}
60
61
  />
61
62
  ),
@@ -7,7 +7,7 @@ export { EditableGrid } from "./EditableGrid";
7
7
  export { ImageDropZone } from "./ImageDropZone";
8
8
  export { ResolvedMedia } from "./ResolvedMedia";
9
9
  export { LinkPopover } from "./LinkPopover";
10
- export { defineHeadingSection } from "./defineHeadingSection";
10
+ export { defineHeadingSection } from "./define-heading-section";
11
11
  export { MediaBlock } from "../sections/Media/MediaBlock";
12
12
  // Link selector (external URL / internal page + section) plus the pages context
13
13
  // that feeds its dropdowns, so custom sections can reuse the same link picker the
@@ -37,11 +37,11 @@ export function useEditablePlainText({
37
37
  }, [onChange]);
38
38
 
39
39
  // Commit on every input, not only on blur — the same contract
40
- // useEditableRichText adopted, and for the same reason: pressing ⌘S (or any
41
- // keyboard save/publish, or an autosave flush) without leaving the field
42
- // flushes persistence before blur ever fires, so a blur-only commit silently
43
- // drops the in-progress edit. Deliberately NOT debounced: any debounce window
44
- // is the same bug, just narrower.
40
+ // useEditableRichText adopted, and for the same reason: clicking Save (or an
41
+ // autosave flush) while the field is still focused flushes persistence before
42
+ // blur ever fires, so a blur-only commit silently drops the in-progress edit.
43
+ // Deliberately NOT debounced: any debounce window is the same bug, just
44
+ // narrower.
45
45
  const handleInput = useCallback((text: string) => {
46
46
  setValue(text);
47
47
  if (text !== lastPropValue.current) {
@@ -45,5 +45,7 @@ export default function Button({ text, link, download, onChange }: Props) {
45
45
  );
46
46
  }
47
47
 
48
- return <button className={cn("cursor-pointer", base, variant)}>{text}</button>;
48
+ // No link configured: not an interactive control, so render inert markup
49
+ // rather than a focusable button that does nothing on activation.
50
+ return <span className={cn(base, variant)}>{text}</span>;
49
51
  }
@@ -1,11 +1,11 @@
1
1
  import { Check, X } from "lucide-react";
2
2
  import type { SingleMediaReference } from "../../../schemas/shared";
3
3
  import type { LinkValue } from "../../../schemas/link";
4
- import { MediaBlock } from "../Media/MediaBlock";
4
+ import { MediaBlock, type MediaBlockProps } from "../Media/MediaBlock";
5
5
 
6
6
  export interface DoDontMediaBlockProps {
7
7
  refValue: SingleMediaReference;
8
- options: { square?: boolean; showCaption?: boolean; border?: boolean; objectFit?: "cover" | "contain" };
8
+ options: MediaBlockProps["options"];
9
9
  link?: LinkValue;
10
10
  dodont: "do" | "dont";
11
11
  isEditMode: boolean;
@@ -20,8 +20,8 @@ export function DoDontMediaBlock({ refValue, options, link, dodont, isEditMode,
20
20
  <div>
21
21
  <div className="flex h-10 items-center justify-center pb-1">
22
22
  {dodont === "do"
23
- ? <Check size={28} className="text-green-600" />
24
- : <X size={28} className="text-red-600" />}
23
+ ? <Check size={28} className="text-success" />
24
+ : <X size={28} className="text-danger" />}
25
25
  </div>
26
26
  <MediaBlock
27
27
  refValue={refValue}
@@ -1,9 +1,10 @@
1
1
  import { defineSection } from "../../../lib/registry";
2
2
  import { z } from "zod";
3
3
  import { Image as ImageIcon } from "lucide-react";
4
- import { SingleMediaReferenceSchema } from "../../../schemas/shared";
4
+ import { SingleMediaReferenceSchema, ImageBackgroundSchema } from "../../../schemas/shared";
5
5
  import { LinkValueSchema, DEFAULT_LINK } from "../../../schemas/link";
6
6
  import { DoDontMediaBlock } from "./DoDontMediaBlock";
7
+ import type { MediaBlockProps } from "../Media/MediaBlock";
7
8
 
8
9
  const schema = z.object({
9
10
  type: z.literal("dodont_media"),
@@ -27,6 +28,9 @@ const schema = z.object({
27
28
  .enum(["cover", "contain"])
28
29
  .describe("How the image fills its box: 'contain' (fit whole image) or 'cover' (fill and crop).")
29
30
  .optional(),
31
+ background: ImageBackgroundSchema.describe(
32
+ "Optional backdrop filling the image box, for images that need contrast (e.g. a white transparent logo). 'theme' picks the site's light or dark surface separately for light and dark mode; 'custom' uses one hex for both. Images only — ignored for video. Omit for none.",
33
+ ).optional(),
30
34
  })
31
35
  .default({}),
32
36
  });
@@ -42,7 +46,7 @@ export default defineSection({
42
46
  component: ({ content, options, onChange }) => (
43
47
  <DoDontMediaBlock
44
48
  refValue={content.content.ref}
45
- options={(options ?? {}) as { square?: boolean; showCaption?: boolean; border?: boolean; objectFit?: "cover" | "contain" }}
49
+ options={(options ?? {}) as MediaBlockProps["options"]}
46
50
  link={content.content.link}
47
51
  dodont={content.content.dodont}
48
52
  isEditMode={!!onChange}
@@ -74,6 +78,11 @@ export default defineSection({
74
78
  { label: "Cover", value: "cover" },
75
79
  ],
76
80
  },
81
+ background: {
82
+ type: "image-background",
83
+ label: "Image background",
84
+ hidden: (values) => (values.ref as { type?: string } | undefined)?.type === "video",
85
+ },
77
86
  link: { type: "link", label: "Link", default: DEFAULT_LINK, target: "content" },
78
87
  dodont: {
79
88
  type: "select",
@@ -88,7 +97,7 @@ export default defineSection({
88
97
  },
89
98
  inheritableSettings: ["square", "showCaption", "border", "objectFit"],
90
99
  settingsTabs: [
91
- { label: "Display", fields: ["square", "showCaption", "border", "objectFit"] },
100
+ { label: "Display", fields: ["square", "showCaption", "border", "objectFit", "background"] },
92
101
  { label: "Link", fields: ["link"] },
93
102
  { label: "Do / Don't", fields: ["dodont"] },
94
103
  ],
@@ -49,7 +49,7 @@ export function DoDontToggle({ value, onSelect, onClose }: DoDontToggleProps) {
49
49
  aria-label="Do"
50
50
  className={cn(
51
51
  "cursor-pointer flex flex-col items-center justify-center gap-1 rounded py-2 transition-colors",
52
- "text-green-600 hover:bg-base-accent",
52
+ "text-success hover:bg-base-accent",
53
53
  value === "do" && "ring-2 ring-primary bg-base-accent",
54
54
  )}
55
55
  onClick={() => onSelect("do")}
@@ -62,7 +62,7 @@ export function DoDontToggle({ value, onSelect, onClose }: DoDontToggleProps) {
62
62
  aria-label="Don't"
63
63
  className={cn(
64
64
  "cursor-pointer flex flex-col items-center justify-center gap-1 rounded py-2 transition-colors",
65
- "text-red-600 hover:bg-base-accent",
65
+ "text-danger hover:bg-base-accent",
66
66
  value === "dont" && "ring-2 ring-primary bg-base-accent",
67
67
  )}
68
68
  onClick={() => onSelect("dont")}
@@ -4,8 +4,9 @@ import { cn } from "../../../lib/cn";
4
4
  import { getIcon } from "../../../lib/icons";
5
5
  import { useEditableCollection } from "../../primitives/useEditableCollection";
6
6
  import { EditablePlainText } from "../../primitives/EditablePlainText";
7
- import { DragHandle, DeleteIcon, AddIcon } from "../../shared/icons";
8
- import { Check, CopyPlus, Pencil, X } from "lucide-react";
7
+ import { DragHandle } from "../../shared/icons";
8
+ import { DropEdgeIndicator } from "../../editor/DropEdgeIndicator";
9
+ import { Check, CopyPlus, Pencil, Plus, Trash2, X } from "lucide-react";
9
10
  import { IconButton } from "../../shared/IconButton";
10
11
  import { IconPicker } from "../../primitives/IconPicker";
11
12
  import { DoDontToggle } from "./DoDontToggle";
@@ -17,6 +18,7 @@ interface Props {
17
18
  showLabel?: boolean;
18
19
  stackText?: boolean;
19
20
  dodont?: "do" | "dont";
21
+ marker?: "icon" | "number";
20
22
  labelClassName?: string;
21
23
  textClassName?: string;
22
24
  iconClassName?: string;
@@ -30,6 +32,7 @@ export default function IconList({
30
32
  showLabel = true,
31
33
  stackText = false,
32
34
  dodont,
35
+ marker,
33
36
  labelClassName = "font-bold text-base-contrast",
34
37
  textClassName = "text-base-contrast-light",
35
38
  iconClassName = "text-primary",
@@ -37,17 +40,20 @@ export default function IconList({
37
40
  onItemsChange,
38
41
  }: Props) {
39
42
  const isEditMode = !!onChange || !!onItemsChange;
43
+ // Numbering is for standard icon lists: a whole-list Do/Don't keeps its
44
+ // checks/x's even if a number marker was stored before it was switched on.
45
+ const numbered = marker === "number" && !dodont;
40
46
 
41
47
  const emitItems = useCallback(
42
48
  (newItems: IconListItem[]) => {
43
49
  onChange?.({
44
50
  type: "icon_list",
45
51
  content: { items: newItems },
46
- options: { icon, showLabel, stackText, dodont },
52
+ options: { icon, showLabel, stackText, dodont, marker },
47
53
  });
48
54
  onItemsChange?.(newItems);
49
55
  },
50
- [onChange, onItemsChange, icon, showLabel, stackText, dodont],
56
+ [onChange, onItemsChange, icon, showLabel, stackText, dodont, marker],
51
57
  );
52
58
 
53
59
  if (!isEditMode) {
@@ -58,6 +64,7 @@ export default function IconList({
58
64
  showLabel={showLabel}
59
65
  stackText={stackText}
60
66
  dodont={dodont}
67
+ numbered={numbered}
61
68
  labelClassName={labelClassName}
62
69
  textClassName={textClassName}
63
70
  iconClassName={iconClassName}
@@ -72,6 +79,7 @@ export default function IconList({
72
79
  showLabel={showLabel}
73
80
  stackText={stackText}
74
81
  dodont={dodont}
82
+ numbered={numbered}
75
83
  labelClassName={labelClassName}
76
84
  textClassName={textClassName}
77
85
  iconClassName={iconClassName}
@@ -105,14 +113,26 @@ function resolveIconColor(
105
113
  iconClassName: string,
106
114
  sectionDodont: "do" | "dont" | undefined,
107
115
  ) {
108
- if (item.dodont === "do") return "text-green-600";
109
- if (item.dodont === "dont") return "text-red-600";
116
+ if (item.dodont === "do") return "text-success";
117
+ if (item.dodont === "dont") return "text-danger";
110
118
  if (item.icon) return iconClassName;
111
- if (sectionDodont === "do") return "text-green-600";
112
- if (sectionDodont === "dont") return "text-red-600";
119
+ if (sectionDodont === "do") return "text-success";
120
+ if (sectionDodont === "dont") return "text-danger";
113
121
  return iconClassName;
114
122
  }
115
123
 
124
+ // Bold numeral in the same 18px box as the lucide glyph, so a numbered list
125
+ // lines up exactly with an icon list; it takes the cell's color like an icon.
126
+ // Font size is spelled text-[1rem]: `text-base` is the --color-base background
127
+ // color here, not a size, and would paint the numeral invisible.
128
+ function NumberMarker({ n }: { n: number }) {
129
+ return (
130
+ <span className="flex h-[18px] min-w-[18px] items-center justify-center text-[1rem] leading-none font-bold tabular-nums">
131
+ {n}
132
+ </span>
133
+ );
134
+ }
135
+
116
136
  // ---------------------------------------------------------------------------
117
137
  // View mode
118
138
  // ---------------------------------------------------------------------------
@@ -123,6 +143,7 @@ function ViewIconList({
123
143
  showLabel,
124
144
  stackText,
125
145
  dodont,
146
+ numbered,
126
147
  labelClassName,
127
148
  textClassName,
128
149
  iconClassName,
@@ -132,11 +153,12 @@ function ViewIconList({
132
153
  showLabel: boolean;
133
154
  stackText: boolean;
134
155
  dodont: "do" | "dont" | undefined;
156
+ numbered: boolean;
135
157
  labelClassName: string;
136
158
  textClassName: string;
137
159
  iconClassName: string;
138
160
  }) {
139
- const hasAnyIcon = items.some((item) => resolveIcon(item, defaultIcon, dodont));
161
+ const hasAnyIcon = numbered || items.some((item) => resolveIcon(item, defaultIcon, dodont));
140
162
 
141
163
  return (
142
164
  <div className="grid gap-4 pb-4">
@@ -156,7 +178,7 @@ function ViewIconList({
156
178
  data-testid="icon-list-icon"
157
179
  className={cn("flex items-start pt-0.5", iconColor)}
158
180
  >
159
- {iconEntry && <iconEntry.icon size={18} />}
181
+ {numbered ? <NumberMarker n={i + 1} /> : iconEntry ? <iconEntry.icon size={18} /> : null}
160
182
  </div>
161
183
  )}
162
184
  <div
@@ -185,6 +207,7 @@ function EditIconList({
185
207
  showLabel,
186
208
  stackText,
187
209
  dodont,
210
+ numbered,
188
211
  labelClassName,
189
212
  textClassName,
190
213
  iconClassName,
@@ -195,6 +218,7 @@ function EditIconList({
195
218
  showLabel: boolean;
196
219
  stackText: boolean;
197
220
  dodont: "do" | "dont" | undefined;
221
+ numbered: boolean;
198
222
  labelClassName: string;
199
223
  textClassName: string;
200
224
  iconClassName: string;
@@ -287,7 +311,7 @@ function EditIconList({
287
311
  );
288
312
 
289
313
  // In edit mode the icon column always renders — even items with no icon need
290
- // the always-present picker trigger (icon + Do/Don't tagging) in the icon cell.
314
+ // the always-present picker trigger in the icon cell (or, numbered, the numeral).
291
315
  const hasAnyIcon = true;
292
316
 
293
317
  return (
@@ -304,6 +328,7 @@ function EditIconList({
304
328
  showLabel={showLabel}
305
329
  stackText={stackText}
306
330
  dodont={dodont}
331
+ numbered={numbered}
307
332
  labelClassName={labelClassName}
308
333
  textClassName={textClassName}
309
334
  iconClassName={iconClassName}
@@ -324,7 +349,7 @@ function EditIconList({
324
349
 
325
350
  {/* Add button — centered below list, visible on list hover */}
326
351
  <IconButton
327
- icon={<AddIcon size={16} />}
352
+ icon={<Plus size={16} />}
328
353
  label="Add item"
329
354
  size="lg"
330
355
  intent="primary"
@@ -345,6 +370,7 @@ function EditableRow({
345
370
  showLabel,
346
371
  stackText,
347
372
  dodont,
373
+ numbered,
348
374
  labelClassName,
349
375
  textClassName,
350
376
  iconClassName,
@@ -363,6 +389,7 @@ function EditableRow({
363
389
  showLabel: boolean;
364
390
  stackText: boolean;
365
391
  dodont: "do" | "dont" | undefined;
392
+ numbered: boolean;
366
393
  labelClassName: string;
367
394
  textClassName: string;
368
395
  iconClassName: string;
@@ -446,40 +473,45 @@ function EditableRow({
446
473
  className={cn(
447
474
  "group/row relative grid gap-x-3",
448
475
  hasAnyIcon ? "grid-cols-[24px_1fr]" : "grid-cols-1",
449
- isDropTarget && "border-t-2 border-primary",
450
476
  )}
451
477
  onFocusCapture={onEditableActivity}
452
478
  onInput={onEditableActivity}
453
479
  onMouseMove={() => setEditingSuppressed(false)}
454
480
  >
481
+ <DropEdgeIndicator edge={isDropTarget ? "top" : null} />
455
482
 
456
483
  {/* Icon cell — matches ViewIconList layout: 24px column, flex items-start
457
484
  pt-0.5. A single always-present trigger shows the current effective glyph
458
485
  (resolveIcon returns the forced check/x for tagged rows or a whole-list
459
486
  default) and opens the IconPicker (a pure icon grid). Per-item do/dont
460
- tagging lives in the separate DoDontToggle in the row's hover toolbar. */}
487
+ tagging lives in the separate DoDontToggle in the row's hover toolbar.
488
+ A numbered list shows the static numeral instead — there is no icon to pick. */}
461
489
  {hasAnyIcon && (
462
490
  <div
463
491
  data-testid="icon-list-icon"
464
492
  className={cn("relative flex items-start pt-0.5", iconColor)}
465
- onMouseEnter={() => setIconHover(true)}
466
- onMouseLeave={() => setIconHover(false)}
493
+ onMouseEnter={numbered ? undefined : () => setIconHover(true)}
494
+ onMouseLeave={numbered ? undefined : () => setIconHover(false)}
467
495
  >
468
- <button
469
- className="cursor-pointer transition-opacity hover:opacity-70"
470
- aria-label="Change icon"
471
- onClick={() => { setPickerOpen((prev) => !prev); setDodontOpen(false); }}
472
- >
473
- {iconHover && !pickerOpen ? (
474
- <Pencil size={18} className="text-base-contrast-light" />
475
- ) : iconEntry ? (
476
- <iconEntry.icon size={18} />
477
- ) : (
478
- <span className="flex h-[18px] w-[18px] items-center justify-center rounded-sm border border-dashed border-base-contrast-light/40" />
479
- )}
480
- </button>
496
+ {numbered ? (
497
+ <NumberMarker n={index + 1} />
498
+ ) : (
499
+ <button
500
+ className="cursor-pointer transition-opacity hover:opacity-70"
501
+ aria-label="Change icon"
502
+ onClick={() => { setPickerOpen((prev) => !prev); setDodontOpen(false); }}
503
+ >
504
+ {iconHover && !pickerOpen ? (
505
+ <Pencil size={18} className="text-base-contrast-light" />
506
+ ) : iconEntry ? (
507
+ <iconEntry.icon size={18} />
508
+ ) : (
509
+ <span className="flex h-[18px] w-[18px] items-center justify-center rounded-sm border border-dashed border-base-contrast-light/40" />
510
+ )}
511
+ </button>
512
+ )}
481
513
 
482
- {pickerOpen && (
514
+ {pickerOpen && !numbered && (
483
515
  <div className="absolute top-full left-0 z-50 mt-1">
484
516
  <IconPicker
485
517
  selected={effectiveIconId}
@@ -537,8 +569,8 @@ function EditableRow({
537
569
  onClick={() => { setDodontOpen((p) => !p); setPickerOpen(false); }}
538
570
  className="cursor-pointer rounded bg-base/80 p-1 shadow-sm text-base-contrast-light hover:text-primary"
539
571
  >
540
- {item.dodont === "do" ? <Check size={14} className="text-green-600" />
541
- : item.dodont === "dont" ? <X size={14} className="text-red-600" />
572
+ {item.dodont === "do" ? <Check size={14} className="text-success" />
573
+ : item.dodont === "dont" ? <X size={14} className="text-danger" />
542
574
  : <Pencil size={14} />}
543
575
  </button>
544
576
  {dodontOpen && (
@@ -567,7 +599,7 @@ function EditableRow({
567
599
  <CopyPlus size={14} />
568
600
  </button>
569
601
  <IconButton
570
- icon={<DeleteIcon size={14} />}
602
+ icon={<Trash2 size={14} />}
571
603
  label="Delete item"
572
604
  size="sm"
573
605
  intent="destructive"
@@ -626,9 +658,10 @@ function TrailingDropZone({
626
658
  const isDropTarget = dragState.targetId === trailingId;
627
659
 
628
660
  return (
629
- <div
630
- ref={ref}
631
- className={cn("absolute bottom-0 left-0 right-0 h-4", isDropTarget && "border-t-2 border-primary")}
632
- />
661
+ <div ref={ref} className="absolute bottom-0 left-0 right-0 h-4">
662
+ <div className="relative h-full">
663
+ <DropEdgeIndicator edge={isDropTarget ? "top" : null} />
664
+ </div>
665
+ </div>
633
666
  );
634
667
  }