@drawnagency/primitives 0.1.113 → 0.1.114

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 (483) 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-GPPVYLEI.js → chunk-45FA7Z55.js} +1 -1
  6. package/dist/{chunk-REDDTTGJ.js → chunk-4Y2JQQZL.js} +19 -1
  7. package/dist/chunk-5GFACGSN.js +6 -0
  8. package/dist/chunk-5KSAS4VY.js +275 -0
  9. package/dist/{chunk-Z7W3DQTR.js → chunk-7SAAJVDE.js} +408 -28
  10. package/dist/{chunk-S2L3BPLS.js → chunk-7SX42OP4.js} +1 -1
  11. package/dist/{chunk-GGXZZ77Z.js → chunk-AASEGXNT.js} +18 -1
  12. package/dist/{chunk-WKZ7OENC.js → chunk-BQ5TZZUE.js} +5 -1
  13. package/dist/chunk-DIMDRBFK.js +11 -0
  14. package/dist/{chunk-WUJ3XNFI.js → chunk-GGYY3JQJ.js} +19 -24
  15. package/dist/{chunk-NHN2LSIU.js → chunk-IP2SEBAJ.js} +5 -1
  16. package/dist/{chunk-IINIZBQB.js → chunk-JCDZAFX2.js} +30 -10
  17. package/dist/chunk-JR24U7FJ.js +120 -0
  18. package/dist/{chunk-SW6PCQQD.js → chunk-KQA772WQ.js} +2 -1
  19. package/dist/{chunk-KR2MHTNJ.js → chunk-N3G7DOU3.js} +609 -61
  20. package/dist/chunk-OAGJBCSH.js +67 -0
  21. package/dist/{chunk-6BZ2KNTP.js → chunk-PLANHXS7.js} +191 -61
  22. package/dist/{chunk-VWWY5TL5.js → chunk-PNSCDBU7.js} +38 -56
  23. package/dist/{chunk-AHALSCQH.js → chunk-PTY2RG2K.js} +1 -1
  24. package/dist/{chunk-BDFTMGCL.js → chunk-PZPGJZRG.js} +9 -8
  25. package/dist/{chunk-FRE2CCLV.js → chunk-QHMKIODQ.js} +17 -4
  26. package/dist/{chunk-HBULBDGP.js → chunk-S37DZPHW.js} +1 -1
  27. package/dist/{chunk-4I5OO5UB.js → chunk-TEOAKGZA.js} +0 -1
  28. package/dist/chunk-VUYCRBJK.js +174 -0
  29. package/dist/{chunk-4RNF2DRG.js → chunk-XDEPXTBY.js} +0 -2
  30. package/dist/{chunk-DS4GCYV2.js → chunk-Y5QECJX7.js} +223 -16
  31. package/dist/collab/rebase.d.ts +2 -1
  32. package/dist/collab/rebase.d.ts.map +1 -1
  33. package/dist/collab/rebase.js +20 -5
  34. package/dist/components/brandguide/ColorsEditable.d.ts.map +1 -1
  35. package/dist/components/chat/ChatPanel.d.ts.map +1 -1
  36. package/dist/components/chat/ChatWidget.d.ts.map +1 -1
  37. package/dist/components/docfile/DocFilePane.d.ts.map +1 -1
  38. package/dist/components/editor/ChildBlockWrapper.d.ts.map +1 -1
  39. package/dist/components/editor/ConflictDialog.d.ts.map +1 -1
  40. package/dist/components/editor/DragHandle.d.ts +12 -2
  41. package/dist/components/editor/DragHandle.d.ts.map +1 -1
  42. package/dist/components/editor/DropEdgeIndicator.d.ts +15 -6
  43. package/dist/components/editor/DropEdgeIndicator.d.ts.map +1 -1
  44. package/dist/components/editor/NavGroupRow.d.ts +4 -1
  45. package/dist/components/editor/NavGroupRow.d.ts.map +1 -1
  46. package/dist/components/editor/PagesModal.d.ts.map +1 -1
  47. package/dist/components/editor/SectionWrapper.d.ts +1 -1
  48. package/dist/components/editor/SectionWrapper.d.ts.map +1 -1
  49. package/dist/components/editor/SettingsForm.d.ts.map +1 -1
  50. package/dist/components/editor/TagIndicator.d.ts +15 -0
  51. package/dist/components/editor/TagIndicator.d.ts.map +1 -0
  52. package/dist/components/editor/index.js +148 -77
  53. package/dist/components/primitives/DocumentDropZone.d.ts +1 -1
  54. package/dist/components/primitives/EditableGrid.d.ts.map +1 -1
  55. package/dist/components/primitives/EditableList.d.ts.map +1 -1
  56. package/dist/components/primitives/HeadingSection.d.ts +4 -1
  57. package/dist/components/primitives/HeadingSection.d.ts.map +1 -1
  58. package/dist/components/primitives/ResolvedMedia.d.ts +5 -1
  59. package/dist/components/primitives/ResolvedMedia.d.ts.map +1 -1
  60. package/dist/components/primitives/{defineHeadingSection.d.ts → define-heading-section.d.ts} +1 -1
  61. package/dist/components/primitives/define-heading-section.d.ts.map +1 -0
  62. package/dist/components/primitives/{gridDrop.d.ts → grid-drop.d.ts} +1 -1
  63. package/dist/components/primitives/grid-drop.d.ts.map +1 -0
  64. package/dist/components/primitives/index.d.ts +1 -1
  65. package/dist/components/primitives/index.d.ts.map +1 -1
  66. package/dist/components/primitives/index.js +17 -154
  67. package/dist/components/sections/Button/CTAButton.d.ts.map +1 -1
  68. package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts +2 -6
  69. package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts.map +1 -1
  70. package/dist/components/sections/DoDontMedia/index.d.ts +8 -0
  71. package/dist/components/sections/DoDontMedia/index.d.ts.map +1 -1
  72. package/dist/components/sections/IconList/IconList.d.ts +2 -1
  73. package/dist/components/sections/IconList/IconList.d.ts.map +1 -1
  74. package/dist/components/sections/IconList/IconListSettings.d.ts +2 -1
  75. package/dist/components/sections/IconList/IconListSettings.d.ts.map +1 -1
  76. package/dist/components/sections/IconList/index.d.ts +1 -0
  77. package/dist/components/sections/IconList/index.d.ts.map +1 -1
  78. package/dist/components/sections/Media/MediaBlock.d.ts +2 -1
  79. package/dist/components/sections/Media/MediaBlock.d.ts.map +1 -1
  80. package/dist/components/sections/Media/index.d.ts +8 -0
  81. package/dist/components/sections/Media/index.d.ts.map +1 -1
  82. package/dist/components/sections/Reference/ReferenceList.d.ts +35 -0
  83. package/dist/components/sections/Reference/ReferenceList.d.ts.map +1 -0
  84. package/dist/components/sections/Reference/ReferenceSettings.d.ts +12 -0
  85. package/dist/components/sections/Reference/ReferenceSettings.d.ts.map +1 -0
  86. package/dist/components/sections/Reference/index.d.ts +9 -0
  87. package/dist/components/sections/Reference/index.d.ts.map +1 -0
  88. package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts +38 -0
  89. package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts.map +1 -0
  90. package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts +20 -0
  91. package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts.map +1 -0
  92. package/dist/components/sections/SectionSummary/index.d.ts +33 -0
  93. package/dist/components/sections/SectionSummary/index.d.ts.map +1 -0
  94. package/dist/components/sections/all-sections.d.ts +53 -0
  95. package/dist/components/sections/all-sections.d.ts.map +1 -1
  96. package/dist/components/sections/brand-guide.d.ts +41 -2
  97. package/dist/components/sections/brand-guide.d.ts.map +1 -1
  98. package/dist/components/sections/brand-guide.js +12 -10
  99. package/dist/components/sections/core-sections.d.ts +14 -0
  100. package/dist/components/sections/core-sections.d.ts.map +1 -1
  101. package/dist/components/sections/register-schemas.js +19 -17
  102. package/dist/components/sections/register.js +19 -17
  103. package/dist/components/shared/BrandSwatchesContext.d.ts +9 -0
  104. package/dist/components/shared/BrandSwatchesContext.d.ts.map +1 -0
  105. package/dist/components/shared/Button.d.ts +11 -3
  106. package/dist/components/shared/Button.d.ts.map +1 -1
  107. package/dist/components/shared/Checkbox.d.ts +6 -0
  108. package/dist/components/shared/Checkbox.d.ts.map +1 -1
  109. package/dist/components/shared/ConfirmDialog.d.ts +25 -0
  110. package/dist/components/shared/ConfirmDialog.d.ts.map +1 -0
  111. package/dist/components/shared/ConfirmInline.d.ts +25 -0
  112. package/dist/components/shared/ConfirmInline.d.ts.map +1 -0
  113. package/dist/components/shared/ErrorBoundary.d.ts.map +1 -1
  114. package/dist/components/shared/Fab.d.ts +11 -2
  115. package/dist/components/shared/Fab.d.ts.map +1 -1
  116. package/dist/components/shared/FabStack.d.ts +22 -0
  117. package/dist/components/shared/FabStack.d.ts.map +1 -0
  118. package/dist/components/shared/HistoryChangesModal.d.ts.map +1 -1
  119. package/dist/components/shared/HistoryPopover.d.ts.map +1 -1
  120. package/dist/components/shared/ImageBackgroundField.d.ts +9 -0
  121. package/dist/components/shared/ImageBackgroundField.d.ts.map +1 -0
  122. package/dist/components/shared/{UploadRejectionAlert.d.ts → InlineAlert.d.ts} +4 -2
  123. package/dist/components/shared/InlineAlert.d.ts.map +1 -0
  124. package/dist/components/shared/Input.d.ts +10 -0
  125. package/dist/components/shared/Input.d.ts.map +1 -1
  126. package/dist/components/shared/Navigation.d.ts.map +1 -1
  127. package/dist/components/shared/Notice.d.ts +10 -0
  128. package/dist/components/shared/Notice.d.ts.map +1 -0
  129. package/dist/components/shared/Popover.d.ts.map +1 -1
  130. package/dist/components/shared/ReferenceSourcesContext.d.ts +25 -0
  131. package/dist/components/shared/ReferenceSourcesContext.d.ts.map +1 -0
  132. package/dist/components/shared/Select.d.ts +3 -2
  133. package/dist/components/shared/Select.d.ts.map +1 -1
  134. package/dist/components/shared/SplitButton.d.ts.map +1 -1
  135. package/dist/components/shared/SummaryAnchorsContext.d.ts +10 -0
  136. package/dist/components/shared/SummaryAnchorsContext.d.ts.map +1 -0
  137. package/dist/components/shared/Textarea.d.ts +7 -0
  138. package/dist/components/shared/Textarea.d.ts.map +1 -1
  139. package/dist/components/shared/ToolbarFrame.d.ts +17 -0
  140. package/dist/components/shared/ToolbarFrame.d.ts.map +1 -0
  141. package/dist/components/shared/copy.d.ts +13 -0
  142. package/dist/components/shared/copy.d.ts.map +1 -0
  143. package/dist/components/shared/icons.d.ts +0 -12
  144. package/dist/components/shared/icons.d.ts.map +1 -1
  145. package/dist/components/shell/AudienceDetailsPanel.d.ts +7 -1
  146. package/dist/components/shell/AudienceDetailsPanel.d.ts.map +1 -1
  147. package/dist/components/shell/AudienceRow.d.ts.map +1 -1
  148. package/dist/components/shell/BugReportFAB.d.ts +7 -1
  149. package/dist/components/shell/BugReportFAB.d.ts.map +1 -1
  150. package/dist/components/shell/CredentialList.d.ts.map +1 -1
  151. package/dist/components/shell/DocInspector.d.ts.map +1 -1
  152. package/dist/components/shell/DocumentEditorOverlay.d.ts.map +1 -1
  153. package/dist/components/shell/EditorContext.d.ts +4 -0
  154. package/dist/components/shell/EditorContext.d.ts.map +1 -1
  155. package/dist/components/shell/EditorLoginForm.d.ts.map +1 -1
  156. package/dist/components/shell/EditorModal.d.ts.map +1 -1
  157. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  158. package/dist/components/shell/HistoryToolbar.d.ts.map +1 -1
  159. package/dist/components/shell/MediaFolderTile.d.ts +4 -1
  160. package/dist/components/shell/MediaFolderTile.d.ts.map +1 -1
  161. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
  162. package/dist/components/shell/RestoreModal.d.ts.map +1 -1
  163. package/dist/components/shell/SiteSettingsChatbot.d.ts.map +1 -1
  164. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
  165. package/dist/components/shell/SiteSettingsModal.d.ts +3 -1
  166. package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
  167. package/dist/components/shell/SiteSettingsTags.d.ts +13 -0
  168. package/dist/components/shell/SiteSettingsTags.d.ts.map +1 -0
  169. package/dist/components/shell/SiteSettingsUsers.d.ts.map +1 -1
  170. package/dist/components/shell/ViewerLoginForm.d.ts.map +1 -1
  171. package/dist/components/shell/{blockMoveDispatch.d.ts → block-move-dispatch.d.ts} +1 -1
  172. package/dist/components/shell/block-move-dispatch.d.ts.map +1 -0
  173. package/dist/components/shell/reference-sources.d.ts +22 -0
  174. package/dist/components/shell/reference-sources.d.ts.map +1 -0
  175. package/dist/deck/index.d.ts +2 -2
  176. package/dist/deck/index.d.ts.map +1 -1
  177. package/dist/deck/index.js +1 -3
  178. package/dist/deck-builder/index.js +11 -18
  179. package/dist/document/index.d.ts +2 -2
  180. package/dist/document/index.d.ts.map +1 -1
  181. package/dist/hooks/useBlockDnd.d.ts +11 -0
  182. package/dist/hooks/useBlockDnd.d.ts.map +1 -1
  183. package/dist/hooks/useBuildStatus.d.ts +1 -1
  184. package/dist/hooks/useBuildStatus.d.ts.map +1 -1
  185. package/dist/hooks/useDocumentUploads.d.ts +1 -1
  186. package/dist/hooks/useDocumentUploads.d.ts.map +1 -1
  187. package/dist/hooks/useEditorPersistence.d.ts +5 -1
  188. package/dist/hooks/useEditorPersistence.d.ts.map +1 -1
  189. package/dist/hooks/useEditorPublish.d.ts +2 -2
  190. package/dist/hooks/useEditorPublish.d.ts.map +1 -1
  191. package/dist/hooks/useNotice.d.ts +19 -0
  192. package/dist/hooks/useNotice.d.ts.map +1 -0
  193. package/dist/hooks/useSortableNavRow.d.ts +11 -0
  194. package/dist/hooks/useSortableNavRow.d.ts.map +1 -1
  195. package/dist/hooks/useSortableRow.d.ts +11 -0
  196. package/dist/hooks/useSortableRow.d.ts.map +1 -1
  197. package/dist/hooks/useStackedEscape.d.ts +32 -0
  198. package/dist/hooks/useStackedEscape.d.ts.map +1 -0
  199. package/dist/index.js +67 -49
  200. package/dist/lib/audience-secret.js +2 -2
  201. package/dist/lib/block-dnd.d.ts +5 -0
  202. package/dist/lib/block-dnd.d.ts.map +1 -1
  203. package/dist/lib/block-move.d.ts.map +1 -1
  204. package/dist/lib/brand-swatches.d.ts +12 -0
  205. package/dist/lib/brand-swatches.d.ts.map +1 -0
  206. package/dist/lib/container-ops.d.ts +3 -2
  207. package/dist/lib/container-ops.d.ts.map +1 -1
  208. package/dist/lib/dexie.d.ts.map +1 -1
  209. package/dist/lib/dexie.js +9 -1
  210. package/dist/lib/env.d.ts +4 -0
  211. package/dist/lib/env.d.ts.map +1 -1
  212. package/dist/lib/env.js +5 -3
  213. package/dist/lib/events.d.ts +1 -2
  214. package/dist/lib/events.d.ts.map +1 -1
  215. package/dist/lib/image-background.d.ts +8 -0
  216. package/dist/lib/image-background.d.ts.map +1 -0
  217. package/dist/lib/index-ops.js +3 -3
  218. package/dist/lib/index.d.ts +6 -4
  219. package/dist/lib/index.d.ts.map +1 -1
  220. package/dist/lib/index.js +29 -21
  221. package/dist/lib/loader.d.ts +21 -7
  222. package/dist/lib/loader.d.ts.map +1 -1
  223. package/dist/lib/nav-tree.d.ts +1 -0
  224. package/dist/lib/nav-tree.d.ts.map +1 -1
  225. package/dist/lib/nav.d.ts +38 -0
  226. package/dist/lib/nav.d.ts.map +1 -1
  227. package/dist/lib/platform-broker.d.ts +4 -2
  228. package/dist/lib/platform-broker.d.ts.map +1 -1
  229. package/dist/lib/platform-broker.js +21 -13
  230. package/dist/lib/reference-type.d.ts +2 -0
  231. package/dist/lib/reference-type.d.ts.map +1 -0
  232. package/dist/lib/reference-validation.d.ts +31 -0
  233. package/dist/lib/reference-validation.d.ts.map +1 -0
  234. package/dist/lib/reference-validation.js +39 -0
  235. package/dist/lib/references.d.ts +74 -0
  236. package/dist/lib/references.d.ts.map +1 -0
  237. package/dist/lib/registry.d.ts +35 -0
  238. package/dist/lib/registry.d.ts.map +1 -1
  239. package/dist/lib/{safeRedirect.d.ts → safe-redirect.d.ts} +1 -1
  240. package/dist/lib/safe-redirect.d.ts.map +1 -0
  241. package/dist/lib/tags.d.ts +58 -0
  242. package/dist/lib/tags.d.ts.map +1 -0
  243. package/dist/lib/theme-vars.d.ts +9 -0
  244. package/dist/lib/theme-vars.d.ts.map +1 -1
  245. package/dist/media/index.d.ts +1 -1
  246. package/dist/media/index.d.ts.map +1 -1
  247. package/dist/media/index.js +8 -4
  248. package/dist/media/utils.d.ts +2 -0
  249. package/dist/media/utils.d.ts.map +1 -1
  250. package/dist/media/{videoPoster.d.ts → video-poster.d.ts} +1 -1
  251. package/dist/media/video-poster.d.ts.map +1 -0
  252. package/dist/schemas/audience.js +2 -2
  253. package/dist/schemas/index.d.ts +1 -0
  254. package/dist/schemas/index.d.ts.map +1 -1
  255. package/dist/schemas/index.js +14 -8
  256. package/dist/schemas/shared.d.ts +26 -0
  257. package/dist/schemas/shared.d.ts.map +1 -1
  258. package/dist/schemas/site-config.d.ts +6 -0
  259. package/dist/schemas/site-config.d.ts.map +1 -1
  260. package/dist/schemas/tags.d.ts +27 -0
  261. package/dist/schemas/tags.d.ts.map +1 -0
  262. package/dist/storage/index.js +1 -1
  263. package/dist/types/database.d.ts.map +1 -1
  264. package/package.json +6 -1
  265. package/src/auth/cookies.ts +111 -0
  266. package/src/collab/rebase.ts +26 -2
  267. package/src/components/brandguide/ColorSwatchSettings.tsx +1 -1
  268. package/src/components/brandguide/ColorsEditable.tsx +1 -0
  269. package/src/components/chat/ChatPanel.tsx +2 -3
  270. package/src/components/chat/ChatWidget.tsx +2 -3
  271. package/src/components/docfile/DocFilePane.tsx +4 -12
  272. package/src/components/editor/ChildBlockWrapper.tsx +13 -19
  273. package/src/components/editor/ConflictDialog.tsx +27 -35
  274. package/src/components/editor/DeleteButton.tsx +2 -2
  275. package/src/components/editor/DragHandle.tsx +16 -3
  276. package/src/components/editor/DropEdgeIndicator.tsx +36 -10
  277. package/src/components/editor/InsertButton.tsx +2 -2
  278. package/src/components/editor/NavGroupRow.tsx +43 -14
  279. package/src/components/editor/PagesModal.tsx +99 -26
  280. package/src/components/editor/SectionWrapper.tsx +64 -23
  281. package/src/components/editor/SettingsButton.tsx +2 -2
  282. package/src/components/editor/SettingsForm.tsx +19 -2
  283. package/src/components/editor/StatusIndicator.tsx +4 -4
  284. package/src/components/editor/TagIndicator.tsx +80 -0
  285. package/src/components/primitives/DocumentDropZone.tsx +1 -1
  286. package/src/components/primitives/EditableGrid.tsx +15 -14
  287. package/src/components/primitives/EditableList.tsx +27 -74
  288. package/src/components/primitives/HeadingSection.tsx +5 -2
  289. package/src/components/primitives/ResolvedMedia.tsx +13 -0
  290. package/src/components/primitives/{defineHeadingSection.tsx → define-heading-section.tsx} +1 -0
  291. package/src/components/primitives/index.ts +1 -1
  292. package/src/components/primitives/useEditablePlainText.ts +5 -5
  293. package/src/components/sections/Button/CTAButton.tsx +3 -1
  294. package/src/components/sections/DoDontMedia/DoDontMediaBlock.tsx +4 -4
  295. package/src/components/sections/DoDontMedia/index.tsx +12 -3
  296. package/src/components/sections/IconList/DoDontToggle.tsx +2 -2
  297. package/src/components/sections/IconList/IconList.tsx +70 -37
  298. package/src/components/sections/IconList/IconListSettings.tsx +55 -17
  299. package/src/components/sections/IconList/index.tsx +10 -3
  300. package/src/components/sections/LinkHeading/index.tsx +1 -1
  301. package/src/components/sections/Media/MediaBlock.tsx +13 -2
  302. package/src/components/sections/Media/index.tsx +12 -4
  303. package/src/components/sections/Reference/ReferenceList.tsx +214 -0
  304. package/src/components/sections/Reference/ReferenceSettings.tsx +159 -0
  305. package/src/components/sections/Reference/index.tsx +47 -0
  306. package/src/components/sections/SectionSummary/SectionSummaryBlock.tsx +476 -0
  307. package/src/components/sections/SectionSummary/SectionSummarySettings.tsx +126 -0
  308. package/src/components/sections/SectionSummary/index.tsx +149 -0
  309. package/src/components/sections/SubHeading/index.tsx +1 -1
  310. package/src/components/sections/SubSubHeading/index.tsx +1 -1
  311. package/src/components/sections/brand-guide.ts +4 -3
  312. package/src/components/sections/core-sections.ts +2 -0
  313. package/src/components/shared/BrandSwatchesContext.ts +13 -0
  314. package/src/components/shared/Button.tsx +47 -34
  315. package/src/components/shared/Checkbox.tsx +21 -12
  316. package/src/components/shared/ConfirmDialog.tsx +87 -0
  317. package/src/components/shared/ConfirmInline.tsx +90 -0
  318. package/src/components/shared/ErrorBoundary.tsx +6 -18
  319. package/src/components/shared/Fab.tsx +15 -5
  320. package/src/components/shared/FabStack.tsx +28 -0
  321. package/src/components/shared/HistoryChangesModal.tsx +43 -41
  322. package/src/components/shared/HistoryPopover.tsx +7 -20
  323. package/src/components/shared/ImageBackgroundField.tsx +92 -0
  324. package/src/components/shared/{UploadRejectionAlert.tsx → InlineAlert.tsx} +21 -5
  325. package/src/components/shared/Input.tsx +23 -7
  326. package/src/components/shared/Navigation.tsx +22 -17
  327. package/src/components/shared/Notice.tsx +59 -0
  328. package/src/components/shared/Popover.tsx +7 -11
  329. package/src/components/shared/ReferenceSourcesContext.ts +27 -0
  330. package/src/components/shared/Select.tsx +5 -2
  331. package/src/components/shared/SplitButton.tsx +11 -17
  332. package/src/components/shared/SummaryAnchorsContext.ts +11 -0
  333. package/src/components/shared/Textarea.tsx +17 -2
  334. package/src/components/shared/ToolbarFrame.tsx +28 -0
  335. package/src/components/shared/VideoSourceField.tsx +1 -1
  336. package/src/components/shared/copy.ts +18 -0
  337. package/src/components/shared/icons.tsx +1 -17
  338. package/src/components/shell/AudienceAddForm.tsx +2 -2
  339. package/src/components/shell/AudienceDetailsPanel.tsx +23 -5
  340. package/src/components/shell/AudienceRow.tsx +22 -15
  341. package/src/components/shell/BugReportFAB.tsx +50 -40
  342. package/src/components/shell/CredentialList.tsx +33 -13
  343. package/src/components/shell/DocInspector.tsx +3 -12
  344. package/src/components/shell/DocumentEditorOverlay.tsx +33 -23
  345. package/src/components/shell/EditorContext.tsx +7 -0
  346. package/src/components/shell/EditorLoginForm.tsx +26 -36
  347. package/src/components/shell/EditorModal.tsx +8 -10
  348. package/src/components/shell/EditorShell.tsx +499 -339
  349. package/src/components/shell/HistoryToolbar.tsx +24 -26
  350. package/src/components/shell/MediaFolderTile.tsx +8 -3
  351. package/src/components/shell/MediaLibraryModal.tsx +59 -60
  352. package/src/components/shell/ProcessingIndicator.tsx +2 -2
  353. package/src/components/shell/RestoreModal.tsx +17 -16
  354. package/src/components/shell/SetPasswordForm.tsx +3 -3
  355. package/src/components/shell/SiteSettingsChatbot.tsx +61 -42
  356. package/src/components/shell/SiteSettingsDisplay.tsx +10 -20
  357. package/src/components/shell/SiteSettingsModal.tsx +24 -2
  358. package/src/components/shell/SiteSettingsTags.tsx +143 -0
  359. package/src/components/shell/SiteSettingsUsers.tsx +36 -26
  360. package/src/components/shell/SiteSettingsViewerAccess.tsx +2 -2
  361. package/src/components/shell/ViewerLoginForm.tsx +5 -4
  362. package/src/components/shell/reference-sources.ts +36 -0
  363. package/src/deck/index.ts +2 -2
  364. package/src/document/index.ts +2 -2
  365. package/src/hooks/useBlockDnd.ts +11 -0
  366. package/src/hooks/useBuildStatus.ts +53 -6
  367. package/src/hooks/useDocumentUploads.ts +1 -1
  368. package/src/hooks/useEditorPersistence.ts +141 -35
  369. package/src/hooks/useEditorPublish.ts +18 -27
  370. package/src/hooks/useMediaPipeline.ts +1 -1
  371. package/src/hooks/useNotice.ts +45 -0
  372. package/src/hooks/useSortableNavRow.ts +11 -0
  373. package/src/hooks/useSortableRow.ts +22 -2
  374. package/src/hooks/useStackedEscape.ts +62 -0
  375. package/src/lib/block-dnd.ts +6 -1
  376. package/src/lib/block-move.ts +3 -0
  377. package/src/lib/brand-swatches.ts +32 -0
  378. package/src/lib/container-ops.ts +5 -3
  379. package/src/lib/dexie.ts +15 -1
  380. package/src/lib/env.ts +9 -0
  381. package/src/lib/events.ts +1 -2
  382. package/src/lib/image-background.ts +31 -0
  383. package/src/lib/index.ts +5 -4
  384. package/src/lib/loader.ts +54 -55
  385. package/src/lib/nav-tree.ts +71 -0
  386. package/src/lib/nav.ts +196 -36
  387. package/src/lib/platform-broker.ts +32 -14
  388. package/src/lib/reference-type.ts +3 -0
  389. package/src/lib/reference-validation.ts +69 -0
  390. package/src/lib/references.ts +130 -0
  391. package/src/lib/registry.ts +37 -0
  392. package/src/lib/tags.ts +148 -0
  393. package/src/lib/theme-vars.ts +23 -0
  394. package/src/media/index.ts +1 -1
  395. package/src/media/utils.ts +18 -0
  396. package/src/media/{videoPoster.ts → video-poster.ts} +2 -2
  397. package/src/schemas/index.ts +1 -0
  398. package/src/schemas/shared.ts +24 -1
  399. package/src/schemas/site-config.ts +6 -1
  400. package/src/schemas/tags.ts +33 -0
  401. package/src/storage/types.ts +1 -1
  402. package/src/types/database.ts +2 -0
  403. package/dist/chunk-DNY72JZN.js +0 -86
  404. package/dist/chunk-F2LYQPXV.js +0 -77
  405. package/dist/chunk-JH762VUH.js +0 -128
  406. package/dist/chunk-K7DYZXVU.js +0 -138
  407. package/dist/components/primitives/defineHeadingSection.d.ts.map +0 -1
  408. package/dist/components/primitives/gridDrop.d.ts.map +0 -1
  409. package/dist/components/shared/UploadRejectionAlert.d.ts.map +0 -1
  410. package/dist/components/shell/BuildStatusIndicator.d.ts +0 -7
  411. package/dist/components/shell/BuildStatusIndicator.d.ts.map +0 -1
  412. package/dist/components/shell/blockMoveDispatch.d.ts.map +0 -1
  413. package/dist/hooks/index.d.ts +0 -9
  414. package/dist/hooks/index.d.ts.map +0 -1
  415. package/dist/lib/grid.d.ts +0 -2
  416. package/dist/lib/grid.d.ts.map +0 -1
  417. package/dist/lib/safeRedirect.d.ts.map +0 -1
  418. package/dist/media/videoPoster.d.ts.map +0 -1
  419. package/src/components/brandguide/ColorSwatchSettings.d.ts.map +0 -1
  420. package/src/components/brandguide/Colors.d.ts.map +0 -1
  421. package/src/components/primitives/CustomParagraph.d.ts.map +0 -1
  422. package/src/components/primitives/EditableGrid.d.ts.map +0 -1
  423. package/src/components/primitives/EditablePlainText.d.ts.map +0 -1
  424. package/src/components/primitives/EditableRichText.d.ts.map +0 -1
  425. package/src/components/primitives/HeadingSection.d.ts.map +0 -1
  426. package/src/components/primitives/IconPicker.d.ts.map +0 -1
  427. package/src/components/primitives/LinkPopover.d.ts.map +0 -1
  428. package/src/components/primitives/MediaSettingsForms.d.ts.map +0 -1
  429. package/src/components/primitives/ResolvedMedia.d.ts.map +0 -1
  430. package/src/components/primitives/RichTextToolbar.d.ts.map +0 -1
  431. package/src/components/primitives/tiptap-presets.d.ts.map +0 -1
  432. package/src/components/primitives/useEditableCollection.d.ts.map +0 -1
  433. package/src/components/primitives/useEditablePlainText.d.ts.map +0 -1
  434. package/src/components/primitives/useEditableRichText.d.ts.map +0 -1
  435. package/src/components/sections/Button/CTAButton.d.ts.map +0 -1
  436. package/src/components/sections/Button/index.d.ts.map +0 -1
  437. package/src/components/sections/Colors/index.d.ts.map +0 -1
  438. package/src/components/sections/IconList/IconList.d.ts.map +0 -1
  439. package/src/components/sections/IconList/IconListSettings.d.ts.map +0 -1
  440. package/src/components/sections/IconList/index.d.ts.map +0 -1
  441. package/src/components/sections/LinkHeading/index.d.ts.map +0 -1
  442. package/src/components/sections/Prose/Prose.d.ts.map +0 -1
  443. package/src/components/sections/Prose/index.d.ts.map +0 -1
  444. package/src/components/sections/SubHeading/index.d.ts.map +0 -1
  445. package/src/components/sections/SubSubHeading/index.d.ts.map +0 -1
  446. package/src/components/sections/register-schemas.d.ts.map +0 -1
  447. package/src/components/shared/Button.d.ts.map +0 -1
  448. package/src/components/shared/Checkbox.d.ts.map +0 -1
  449. package/src/components/shared/FormLabel.d.ts.map +0 -1
  450. package/src/components/shared/IconButton.d.ts.map +0 -1
  451. package/src/components/shared/Input.d.ts.map +0 -1
  452. package/src/components/shared/Select.d.ts.map +0 -1
  453. package/src/components/shared/icons.d.ts.map +0 -1
  454. package/src/components/shell/BuildStatusIndicator.tsx +0 -59
  455. package/src/components/shell/MediaLibraryContext.d.ts.map +0 -1
  456. package/src/hooks/index.ts +0 -8
  457. package/src/hooks/useResolvedMedia.d.ts.map +0 -1
  458. package/src/lib/cn.d.ts.map +0 -1
  459. package/src/lib/grid.d.ts.map +0 -1
  460. package/src/lib/grid.ts +0 -7
  461. package/src/lib/icons.d.ts.map +0 -1
  462. package/src/lib/loader.d.ts.map +0 -1
  463. package/src/lib/nav.d.ts.map +0 -1
  464. package/src/lib/registry.d.ts.map +0 -1
  465. package/src/lib/sanitize.d.ts.map +0 -1
  466. package/src/media/github.d.ts.map +0 -1
  467. package/src/media/index.d.ts.map +0 -1
  468. package/src/media/queue.d.ts.map +0 -1
  469. package/src/media/resolve.d.ts.map +0 -1
  470. package/src/media/types.d.ts.map +0 -1
  471. package/src/media/utils.d.ts.map +0 -1
  472. package/src/media/videoPoster.d.ts.map +0 -1
  473. package/src/schemas/auth.d.ts.map +0 -1
  474. package/src/schemas/media-grid-options.d.ts.map +0 -1
  475. package/src/schemas/media.d.ts.map +0 -1
  476. package/src/schemas/sections.d.ts.map +0 -1
  477. package/src/schemas/shared.d.ts.map +0 -1
  478. package/src/schemas/site-config.d.ts.map +0 -1
  479. /package/dist/{chunk-B7VBSE5X.js → chunk-3JDTXOIG.js} +0 -0
  480. /package/dist/{chunk-CXZ5YJG4.js → chunk-L45X7DKX.js} +0 -0
  481. /package/src/components/primitives/{gridDrop.ts → grid-drop.ts} +0 -0
  482. /package/src/components/shell/{blockMoveDispatch.ts → block-move-dispatch.ts} +0 -0
  483. /package/src/lib/{safeRedirect.ts → safe-redirect.ts} +0 -0
@@ -0,0 +1,214 @@
1
+ import { useContext, useMemo } from "react";
2
+ import { ArrowUpRight } from "lucide-react";
3
+ import { cn } from "../../../lib/cn";
4
+ import { getSection } from "../../../lib/registry";
5
+ import { audiencePasses, pageDisplayTitle } from "../../../lib/pages";
6
+ import {
7
+ referenceItems, type ReferenceContent, type ReferenceExclusion, type ReferenceItem,
8
+ } from "../../../lib/references";
9
+ import { ReferenceSourcesContext, type ReferenceSources } from "../../shared/ReferenceSourcesContext";
10
+ import { SummaryAnchorsContext } from "../../shared/SummaryAnchorsContext";
11
+ import { useOptionalEditorContext } from "../../shell/EditorContext";
12
+ import { Button } from "../../shared/Button";
13
+
14
+ type ViewBranch = "saved" | "live";
15
+
16
+ /** Everything the canvas does with an item the published site drops, by why
17
+ * it drops it. `renders`: whether there is a copy to draw at all (a dangling
18
+ * pick has no source; a nested Reference is never expanded). `inPreview`:
19
+ * whether the preview still shows it, mirroring how it treats native sections. */
20
+ const EXCLUSIONS: Record<ReferenceExclusion, {
21
+ reason: (item: ReferenceItem) => string;
22
+ renders: boolean;
23
+ inPreview: (item: ReferenceItem, viewBranch: ViewBranch) => boolean;
24
+ }> = {
25
+ missing: {
26
+ reason: (i) => `Not found — deleted, unreadable, or not a top-level section (${i.sectionId})`,
27
+ renders: false,
28
+ inPreview: () => false,
29
+ },
30
+ reference: { reason: () => "Another Reference — never shown", renders: false, inPreview: () => false },
31
+ "archived-page": { reason: () => "On an archived page", renders: true, inPreview: () => false },
32
+ "not-live": {
33
+ reason: (i) => (i.source?.meta.status === "archived" ? "Archived section" : "Draft — publish it to show it here"),
34
+ renders: true,
35
+ // The Unpublished preview dims drafts and hides archived sections.
36
+ inPreview: (i, viewBranch) => viewBranch === "saved" && i.source?.meta.status === "draft",
37
+ },
38
+ };
39
+
40
+ const shownInPreview = (item: ReferenceItem, viewBranch: ViewBranch) =>
41
+ item.excluded === null || EXCLUSIONS[item.excluded].inPreview(item, viewBranch);
42
+
43
+ /**
44
+ * Whether a Reference draws anything in preview. The viewer renders no wrapper
45
+ * for an empty Reference, so EditorContent skips its wrapper in preview too.
46
+ * Audience-independent: an audience preview dims copies, it never removes them.
47
+ */
48
+ export function referenceShowsInPreview(
49
+ sources: ReferenceSources, referenceId: string, content: ReferenceContent, viewBranch: ViewBranch,
50
+ ): boolean {
51
+ return referenceItems({ referenceId, content, index: sources.index, allSections: sources.sections, audiences: [] })
52
+ .some((item) => shownInPreview(item, viewBranch));
53
+ }
54
+
55
+ const NO_SUMMARY_ANCHORS = {};
56
+
57
+ /**
58
+ * A Reference on the editor canvas, laid out exactly as the viewer lays out
59
+ * the sections it expands to — copy after copy, each 2.25rem below the last
60
+ * (a `.section-wrapper`'s top padding; the Reference's own wrapper supplies the
61
+ * first copy's) — so toggling between editing and preview never moves
62
+ * anything. Everything editor-only (where a copy comes from, why the site
63
+ * drops it, which of the page's audiences can't see it, Edit source) is an
64
+ * overlay that takes no space.
65
+ *
66
+ * Which copies show follows how the canvas treats native sections: edit mode
67
+ * lists every item, greyed with the reason when the published site drops it
68
+ * (a dangling pick or a nested Reference as an empty greyed row);
69
+ * the Unpublished preview hides archived ones and dims drafts; the Published
70
+ * preview shows exactly what the viewer resolves (EditorShell hands it the
71
+ * `main` branch's content then). An audience preview dims what that audience
72
+ * can't see. The audience warnings are relative to who can see this Reference
73
+ * — the page's audiences narrowed by the Reference's own access; when that
74
+ * leaves no one, the whole Reference says so.
75
+ */
76
+ export function ReferenceList({ referenceId, content, isEditMode }: {
77
+ referenceId: string;
78
+ content: ReferenceContent;
79
+ isEditMode: boolean;
80
+ }) {
81
+ const sources = useContext(ReferenceSourcesContext);
82
+ const editor = useOptionalEditorContext();
83
+ const viewBranch = editor?.viewBranch ?? "saved";
84
+ const previewAudience = editor?.previewAudience ?? null;
85
+
86
+ const model = useMemo(() => {
87
+ if (!sources) return null;
88
+ const { index, sections, audiences } = sources;
89
+ const page = index.pages.find((p) => p.order.includes(referenceId));
90
+ const access = index.sections[referenceId]?.access ?? [];
91
+ const viewers = audiences.filter((a) => audiencePasses(page?.access ?? [], a.name) && audiencePasses(access, a.name));
92
+ const items = referenceItems({
93
+ referenceId, content, index, allSections: sections, audiences: viewers.map((a) => a.name),
94
+ });
95
+ return {
96
+ items,
97
+ // Copies carry the page-wide anchors the editor nav links to, so no
98
+ // heading here duplicates its source's DOM id or another Reference's.
99
+ copyById: sources.copies[referenceId] ?? {},
100
+ displayName: new Map(viewers.map((a) => [a.name, a.displayName])),
101
+ viewerCount: viewers.length,
102
+ // The site has audiences, yet none passes both the page's access and the
103
+ // Reference's own: no one can ever see a copy here. (Empty access is
104
+ // "everyone", so an unrestricted page or Reference never lands here.)
105
+ noViewers: audiences.length > 0 && viewers.length === 0,
106
+ // Absent `tags` is "not loaded": tagged sections can't be listed yet.
107
+ tagsUnloaded: index.tags === undefined && content.tagIds.length > 0,
108
+ };
109
+ }, [sources, referenceId, content]);
110
+
111
+ if (!sources || !model) {
112
+ return isEditMode ? <Placeholder>Reference: shown as live copies on the published site.</Placeholder> : null;
113
+ }
114
+
115
+ // Edit mode lists every item, greyed with its reason when the site drops it;
116
+ // preview shows what the canvas shows for native sections.
117
+ const shown = isEditMode ? model.items : model.items.filter((item) => shownInPreview(item, viewBranch));
118
+
119
+ const notes = [
120
+ model.tagsUnloaded && "Tags haven't loaded, so tagged sections aren't listed yet.",
121
+ model.noViewers && "No audience can see this Reference on this page",
122
+ ].filter((n): n is string => !!n);
123
+
124
+ if (shown.length === 0) {
125
+ // EditorContent skips an empty Reference's wrapper in preview
126
+ // (referenceShowsInPreview); this covers rendering without it.
127
+ if (!isEditMode) return null;
128
+ if (notes.length === 0) return <Placeholder>Reference: no tags or sections chosen yet.</Placeholder>;
129
+ return <Placeholder>{["Reference: nothing to show.", ...notes].join(" ")}</Placeholder>;
130
+ }
131
+
132
+ return (
133
+ // The page's summary anchors are keyed by section id, so a copy of a
134
+ // summary also on this page would take its native anchor; emptying the
135
+ // context leaves every copy on the anchor stamped for it.
136
+ <SummaryAnchorsContext.Provider value={NO_SUMMARY_ANCHORS}>
137
+ {shown.map((item, n) => {
138
+ const { source } = item;
139
+ const exclusion = item.excluded ? EXCLUSIONS[item.excluded] : null;
140
+ const drawn = source && (!exclusion || exclusion.renders) ? source : null;
141
+ const definition = source ? getSection(source.section.type) : undefined;
142
+ const copy = drawn ? model.copyById[item.sectionId] ?? drawn.section : null;
143
+ const Component = definition?.component;
144
+ const reason = exclusion?.reason(item) ?? null;
145
+ const hiddenForAll = model.noViewers || (model.viewerCount > 0 && item.hiddenFrom.length === model.viewerCount);
146
+ const previewHidden = previewAudience !== null && !!source &&
147
+ (!audiencePasses(item.page?.access ?? [], previewAudience) || !audiencePasses(source.meta.access, previewAudience));
148
+ const typeLabel = definition?.label ?? source?.section.type ?? "Section";
149
+ const label = (source && definition?.getLabel?.(source.section)) || typeLabel;
150
+
151
+ return (
152
+ <div key={item.sectionId} className={cn(n > 0 && "pt-9")}>
153
+ <div
154
+ data-reference-item={item.sectionId}
155
+ className={cn(
156
+ // `group` mirrors the viewer's per-section wrapper for the copy's
157
+ // own hover styles; `group/copy` scopes Edit source to this copy,
158
+ // since the Reference's wrapper is a `group` too.
159
+ "group group/copy relative",
160
+ isEditMode && "rounded-outer hover:outline hover:outline-1 hover:outline-dashed hover:outline-primary/40",
161
+ previewHidden ? "opacity-15 transition-opacity duration-200 hover:opacity-100"
162
+ : (isEditMode ? reason || hiddenForAll : item.excluded) && "opacity-50",
163
+ )}
164
+ >
165
+ {/* inert while editing: a copy is read-only — edits happen on its source. */}
166
+ <div inert={isEditMode}>
167
+ {!copy && <div className="min-h-20 rounded-md border-2 border-dashed" />}
168
+ {copy && Component && (
169
+ <Component
170
+ content={copy}
171
+ options={"options" in copy ? (copy.options as Record<string, unknown>) : undefined}
172
+ isEditMode={false}
173
+ />
174
+ )}
175
+ </div>
176
+ {isEditMode && (
177
+ <div className="absolute right-2 top-2 z-20 flex max-w-[calc(100%-1rem)] flex-wrap items-center justify-end gap-1">
178
+ {n === 0 && notes.map((note) => <Badge key={note}>{note}</Badge>)}
179
+ {reason && <Badge>{reason}</Badge>}
180
+ {!reason && hiddenForAll && !model.noViewers && <Badge>Hidden for all of this page's audiences</Badge>}
181
+ {!reason && !hiddenForAll && item.hiddenFrom.length > 0 && (
182
+ <Badge>{`Hidden from ${item.hiddenFrom.map((a) => model.displayName.get(a) ?? a).join(", ")}`}</Badge>
183
+ )}
184
+ {source && <span className="flex items-center gap-2 rounded-full border border-base-200 bg-base px-2 py-0.5 text-xs opacity-0 shadow-sm transition-opacity focus-within:opacity-100 group-hover/copy:opacity-100">
185
+ <span className="max-w-56 truncate text-base-contrast-light">
186
+ {item.page ? `${pageDisplayTitle(item.page.title)} · ` : ""}{label}
187
+ </span>
188
+ <Button variant="ghost" className="inline-flex items-center gap-0.5" onClick={() => sources.jumpToSection(item.sectionId)}>
189
+ Edit source <ArrowUpRight size={12} aria-hidden="true" />
190
+ </Button>
191
+ </span>}
192
+ </div>
193
+ )}
194
+ </div>
195
+ </div>
196
+ );
197
+ })}
198
+ </SummaryAnchorsContext.Provider>
199
+ );
200
+ }
201
+
202
+ function Badge({ children }: { children: string }) {
203
+ return (
204
+ <span className="rounded-full border border-warning bg-warning-bg px-2 py-0.5 text-xs text-warning shadow-sm">{children}</span>
205
+ );
206
+ }
207
+
208
+ function Placeholder({ children }: { children: string }) {
209
+ return (
210
+ <div className="flex min-h-20 items-center justify-center rounded-md border-2 border-dashed px-4 text-center text-xs text-base-contrast-light/50">
211
+ {children}
212
+ </div>
213
+ );
214
+ }
@@ -0,0 +1,159 @@
1
+ import { useContext, useState } from "react";
2
+ import { cn } from "../../../lib/cn";
3
+ import { getSection } from "../../../lib/registry";
4
+ import { pageDisplayTitle } from "../../../lib/pages";
5
+ import { pagesInNavOrder } from "../../../lib/nav-tree";
6
+ import { siteTags, tagDisplayLabel } from "../../../lib/tags";
7
+ import { pluralize } from "../../../lib/text";
8
+ import { toThumbViews, type ThumbView } from "../../../lib/thumb-views";
9
+ import { REFERENCE_TYPE } from "../../../lib/reference-type";
10
+ import type { ReferenceContent } from "../../../lib/references";
11
+ import { ReferenceSourcesContext } from "../../shared/ReferenceSourcesContext";
12
+ import { SectionSummaryRow } from "../../shared/SectionSummaryRow";
13
+ import { Checkbox, CheckboxBox } from "../../shared/Checkbox";
14
+ import { Tabs } from "../../shared/Tabs";
15
+
16
+ const panel = "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-px";
17
+
18
+ /**
19
+ * Tags and Sections, combined as a union. Ids the registry or index no longer
20
+ * knows are listed too, so an editor can see them and clear them — the viewer
21
+ * drops them silently.
22
+ */
23
+ export function ReferenceSettings({
24
+ tagIds = [],
25
+ sectionIds = [],
26
+ onChange,
27
+ }: Partial<ReferenceContent> & { onChange: (result: { content: ReferenceContent }) => void }) {
28
+ const sources = useContext(ReferenceSourcesContext);
29
+ const [v, setV] = useState<ReferenceContent>({ tagIds, sectionIds });
30
+
31
+ const update = (next: ReferenceContent) => {
32
+ setV(next);
33
+ onChange({ content: next });
34
+ };
35
+ const toggle = (list: string[], id: string, on: boolean) => (on ? [...list, id] : list.filter((x) => x !== id));
36
+
37
+ if (!sources) return null;
38
+ const { index, sections, mediaManifest } = sources;
39
+
40
+ // Absent `tags` is "not loaded", not "none": every stored tag would read as
41
+ // deleted, and clearing one would drop a real tag. Hold the tab read-only.
42
+ const tagsLoaded = index.tags !== undefined;
43
+ const tags = siteTags(index);
44
+ const deletedTagIds = tagsLoaded ? v.tagIds.filter((id) => !tags.some((t) => t.id === id)) : [];
45
+
46
+ const byId = new Map(sections.map((s) => [s.section.id, s]));
47
+ const pageGroups = pagesInNavOrder(index)
48
+ .map((page) => ({
49
+ page,
50
+ rows: page.order.flatMap((id) => {
51
+ const s = byId.get(id);
52
+ // References can't be picked; one already picked (by an agent) is
53
+ // listed so it can be cleared.
54
+ return s && (s.section.type !== REFERENCE_TYPE || v.sectionIds.includes(id)) ? [s] : [];
55
+ }),
56
+ }))
57
+ .filter((g) => g.rows.length > 0);
58
+ const onAPage = new Set(pageGroups.flatMap((g) => g.rows.map((s) => s.section.id)));
59
+ const deletedSectionIds = v.sectionIds.filter((id) => !onAPage.has(id));
60
+
61
+ const tagsTab = (
62
+ <div className={panel}>
63
+ {!tagsLoaded && (
64
+ <p className="text-sm text-base-contrast-light">Tags haven't loaded, so they can't be changed right now.</p>
65
+ )}
66
+ {tagsLoaded && tags.length === 0 && deletedTagIds.length === 0 && (
67
+ <p className="text-sm text-base-contrast-light">
68
+ No tags yet. Add them from a section's Tags pill or under Site settings → Tags.
69
+ </p>
70
+ )}
71
+ {tags.map((t) => (
72
+ <Checkbox
73
+ key={t.id}
74
+ label={tagDisplayLabel(t.label)}
75
+ description={pluralize(t.sectionIds.length, "section")}
76
+ checked={v.tagIds.includes(t.id)}
77
+ onChange={(on) => update({ ...v, tagIds: toggle(v.tagIds, t.id, on) })}
78
+ />
79
+ ))}
80
+ {deletedTagIds.map((id) => (
81
+ <Checkbox
82
+ key={id}
83
+ label="Deleted tag"
84
+ description="Shows nothing. Untick to remove it."
85
+ checked
86
+ onChange={() => update({ ...v, tagIds: toggle(v.tagIds, id, false) })}
87
+ />
88
+ ))}
89
+ </div>
90
+ );
91
+
92
+ const sectionRow = (id: string, label: string, typeLabel: string, thumbs: ThumbView[], status?: string) => {
93
+ const checked = v.sectionIds.includes(id);
94
+ return (
95
+ <button
96
+ key={id}
97
+ type="button"
98
+ role="checkbox"
99
+ aria-checked={checked}
100
+ aria-label={`${typeLabel}: ${label}`}
101
+ onClick={() => update({ ...v, sectionIds: toggle(v.sectionIds, id, !checked) })}
102
+ className="flex w-full cursor-pointer text-left"
103
+ >
104
+ <SectionSummaryRow
105
+ label={label}
106
+ typeLabel={typeLabel}
107
+ thumbnails={thumbs}
108
+ className={cn(checked && "border-primary")}
109
+ trailing={
110
+ <>
111
+ {status && status !== "live" && <span className="text-xs capitalize text-base-contrast-light">{status}</span>}
112
+ <CheckboxBox checked={checked} />
113
+ </>
114
+ }
115
+ />
116
+ </button>
117
+ );
118
+ };
119
+
120
+ const sectionsTab = (
121
+ <div className={panel}>
122
+ {pageGroups.map(({ page, rows }) => (
123
+ <section key={page.id} className="flex flex-col gap-2">
124
+ <h3 className="text-xs font-medium uppercase tracking-wide text-base-contrast-light">
125
+ {pageDisplayTitle(page.title)}
126
+ {page.status === "archived" && " (archived)"}
127
+ </h3>
128
+ {rows.map((s) => {
129
+ const def = getSection(s.section.type);
130
+ const typeLabel = def?.label ?? s.section.type;
131
+ return sectionRow(
132
+ s.section.id,
133
+ def?.getLabel?.(s.section) ?? typeLabel,
134
+ typeLabel,
135
+ toThumbViews(def?.getThumbnails?.(s.section) ?? [], mediaManifest),
136
+ s.meta.status,
137
+ );
138
+ })}
139
+ </section>
140
+ ))}
141
+ {deletedSectionIds.length > 0 && (
142
+ <section className="flex flex-col gap-2">
143
+ <h3 className="text-xs font-medium uppercase tracking-wide text-base-contrast-light">Not found</h3>
144
+ {deletedSectionIds.map((id) => sectionRow(id, "Section not found", "Deleted or can't be read", []))}
145
+ </section>
146
+ )}
147
+ </div>
148
+ );
149
+
150
+ return (
151
+ <Tabs
152
+ fullBleedTabBar
153
+ tabs={[
154
+ { id: "tags", label: `Tags${v.tagIds.length ? ` (${v.tagIds.length})` : ""}`, content: tagsTab },
155
+ { id: "sections", label: `Sections${v.sectionIds.length ? ` (${v.sectionIds.length})` : ""}`, content: sectionsTab },
156
+ ]}
157
+ />
158
+ );
159
+ }
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { Copy } from "lucide-react";
3
+ import { defineSection } from "../../../lib/registry";
4
+ import { REFERENCE_TYPE } from "../../../lib/reference-type";
5
+ import { ReferenceList } from "./ReferenceList";
6
+ import { ReferenceSettings } from "./ReferenceSettings";
7
+
8
+ const schema = z.object({
9
+ type: z.literal(REFERENCE_TYPE),
10
+ content: z.object({
11
+ tagIds: z
12
+ .array(z.string())
13
+ .default([])
14
+ .describe("Ids of tags from the site's tag registry (tags.json); every section carrying one of them is shown."),
15
+ sectionIds: z
16
+ .array(z.string())
17
+ .default([])
18
+ .describe("Ids of individually picked sections to show, from any page. Combined with the tagged sections as a union."),
19
+ }),
20
+ });
21
+
22
+ export default defineSection({
23
+ type: REFERENCE_TYPE,
24
+ label: "Reference",
25
+ icon: <Copy size={18} />,
26
+ schema,
27
+ authoringNote:
28
+ "Shows read-only, live copies of other sections: every section carrying one of tagIds, plus every id in " +
29
+ "sectionIds (overlaps listed once). Resolved at render time from the published site, so edits to a source " +
30
+ "show up wherever it is referenced — never copy content to reuse it. Items are listed in site order (pages " +
31
+ "in nav order, then position on the page), whatever order the ids are stored in. Only live sections on live " +
32
+ "pages appear (hidden pages count, archived pages do not); a viewer sees an item only if they could see it " +
33
+ "on its own page, so a Reference never widens who sees what. References in the source set are skipped, " +
34
+ "itself included; containers come whole. Headings inside the copies join this page's nav, anchored " +
35
+ "<heading>-<this Reference's id>. Unknown ids and deleted tags drop silently on the viewer, but the MCP " +
36
+ "connector rejects them on save — create a tag (save_sections `tags`) before naming it. Top level only — not inside a container.",
37
+ // Viewer paths never render this component: buildViewerPage replaces a
38
+ // Reference with the sections it resolves to. The editor canvas renders the
39
+ // same copies here, in edit mode and preview alike.
40
+ component: ({ content, isEditMode }) => {
41
+ const id = (content as { id?: string }).id ?? "";
42
+ return <ReferenceList referenceId={id} content={content.content} isEditMode={isEditMode} />;
43
+ },
44
+ settingsForm: ReferenceSettings,
45
+ defaults: () => ({ type: REFERENCE_TYPE, content: { tagIds: [], sectionIds: [] } }),
46
+ getLabel: () => "Reference",
47
+ });