@drawnagency/primitives 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/README.md +28 -0
  2. package/dist/auth/cookies.d.ts +8 -0
  3. package/dist/auth/cookies.d.ts.map +1 -0
  4. package/dist/auth/cookies.js +44 -0
  5. package/dist/auth/errors.d.ts +8 -0
  6. package/dist/auth/errors.d.ts.map +1 -0
  7. package/dist/auth/errors.js +10 -0
  8. package/dist/auth/index.d.ts +5 -0
  9. package/dist/auth/index.d.ts.map +1 -0
  10. package/dist/auth/index.js +3 -0
  11. package/dist/auth/security.d.ts +13 -0
  12. package/dist/auth/security.d.ts.map +1 -0
  13. package/dist/auth/security.js +48 -0
  14. package/dist/auth/types.d.ts +64 -0
  15. package/dist/auth/types.d.ts.map +1 -0
  16. package/dist/auth/types.js +1 -0
  17. package/dist/components/brandguide/ColorSwatchSettings.d.ts +8 -0
  18. package/dist/components/brandguide/ColorSwatchSettings.d.ts.map +1 -0
  19. package/dist/components/brandguide/ColorSwatchSettings.js +10 -0
  20. package/dist/components/brandguide/Colors.d.ts +15 -0
  21. package/dist/components/brandguide/Colors.d.ts.map +1 -0
  22. package/dist/components/brandguide/Colors.js +79 -0
  23. package/dist/components/brandguide/DoDontList.d.ts +16 -0
  24. package/dist/components/brandguide/DoDontList.d.ts.map +1 -0
  25. package/dist/components/brandguide/DoDontList.js +22 -0
  26. package/dist/components/brandguide/DoDontMediaGrid.d.ts +16 -0
  27. package/dist/components/brandguide/DoDontMediaGrid.d.ts.map +1 -0
  28. package/dist/components/brandguide/DoDontMediaGrid.js +5 -0
  29. package/dist/components/editor/AudiencePicker.d.ts +9 -0
  30. package/dist/components/editor/AudiencePicker.d.ts.map +1 -0
  31. package/dist/components/editor/AudiencePicker.js +24 -0
  32. package/dist/components/editor/DeleteButton.d.ts +6 -0
  33. package/dist/components/editor/DeleteButton.d.ts.map +1 -0
  34. package/dist/components/editor/DeleteButton.js +6 -0
  35. package/dist/components/editor/DragHandle.d.ts +2 -0
  36. package/dist/components/editor/DragHandle.d.ts.map +1 -0
  37. package/dist/components/editor/DragHandle.js +8 -0
  38. package/dist/components/editor/InsertButton.d.ts +7 -0
  39. package/dist/components/editor/InsertButton.d.ts.map +1 -0
  40. package/dist/components/editor/InsertButton.js +7 -0
  41. package/dist/components/editor/SectionWrapper.d.ts +3 -0
  42. package/dist/components/editor/SectionWrapper.d.ts.map +1 -0
  43. package/dist/components/editor/SectionWrapper.js +135 -0
  44. package/dist/components/editor/SettingsButton.d.ts +6 -0
  45. package/dist/components/editor/SettingsButton.d.ts.map +1 -0
  46. package/dist/components/editor/SettingsButton.js +6 -0
  47. package/dist/components/editor/SettingsForm.d.ts +13 -0
  48. package/dist/components/editor/SettingsForm.d.ts.map +1 -0
  49. package/dist/components/editor/SettingsForm.js +64 -0
  50. package/dist/components/editor/StatusBadge.d.ts +7 -0
  51. package/dist/components/editor/StatusBadge.d.ts.map +1 -0
  52. package/dist/components/editor/StatusBadge.js +10 -0
  53. package/dist/components/editor/StatusPicker.d.ts +9 -0
  54. package/dist/components/editor/StatusPicker.d.ts.map +1 -0
  55. package/dist/components/editor/StatusPicker.js +30 -0
  56. package/dist/components/editor/index.d.ts +8 -0
  57. package/dist/components/editor/index.d.ts.map +1 -0
  58. package/dist/components/editor/index.js +7 -0
  59. package/dist/components/primitives/CustomParagraph.d.ts +2 -0
  60. package/dist/components/primitives/CustomParagraph.d.ts.map +1 -0
  61. package/dist/components/primitives/CustomParagraph.js +24 -0
  62. package/dist/components/primitives/EditableGrid.d.ts +19 -0
  63. package/dist/components/primitives/EditableGrid.d.ts.map +1 -0
  64. package/dist/components/primitives/EditableGrid.js +90 -0
  65. package/dist/components/primitives/EditableList.d.ts +15 -0
  66. package/dist/components/primitives/EditableList.d.ts.map +1 -0
  67. package/dist/components/primitives/EditableList.js +54 -0
  68. package/dist/components/primitives/EditablePlainText.d.ts +12 -0
  69. package/dist/components/primitives/EditablePlainText.d.ts.map +1 -0
  70. package/dist/components/primitives/EditablePlainText.js +52 -0
  71. package/dist/components/primitives/EditableRichText.d.ts +11 -0
  72. package/dist/components/primitives/EditableRichText.d.ts.map +1 -0
  73. package/dist/components/primitives/EditableRichText.js +86 -0
  74. package/dist/components/primitives/HeadingSection.d.ts +10 -0
  75. package/dist/components/primitives/HeadingSection.d.ts.map +1 -0
  76. package/dist/components/primitives/HeadingSection.js +7 -0
  77. package/dist/components/primitives/IconPicker.d.ts +9 -0
  78. package/dist/components/primitives/IconPicker.d.ts.map +1 -0
  79. package/dist/components/primitives/IconPicker.js +21 -0
  80. package/dist/components/primitives/LinkPopover.d.ts +8 -0
  81. package/dist/components/primitives/LinkPopover.d.ts.map +1 -0
  82. package/dist/components/primitives/LinkPopover.js +48 -0
  83. package/dist/components/primitives/MediaSettingsForms.d.ts +19 -0
  84. package/dist/components/primitives/MediaSettingsForms.d.ts.map +1 -0
  85. package/dist/components/primitives/MediaSettingsForms.js +42 -0
  86. package/dist/components/primitives/ResolvedMedia.d.ts +8 -0
  87. package/dist/components/primitives/ResolvedMedia.d.ts.map +1 -0
  88. package/dist/components/primitives/ResolvedMedia.js +9 -0
  89. package/dist/components/primitives/RichTextToolbar.d.ts +9 -0
  90. package/dist/components/primitives/RichTextToolbar.d.ts.map +1 -0
  91. package/dist/components/primitives/RichTextToolbar.js +26 -0
  92. package/dist/components/primitives/tiptap-presets.d.ts +4 -0
  93. package/dist/components/primitives/tiptap-presets.d.ts.map +1 -0
  94. package/dist/components/primitives/tiptap-presets.js +44 -0
  95. package/dist/components/primitives/useEditableCollection.d.ts +19 -0
  96. package/dist/components/primitives/useEditableCollection.d.ts.map +1 -0
  97. package/dist/components/primitives/useEditableCollection.js +61 -0
  98. package/dist/components/primitives/useEditablePlainText.d.ts +14 -0
  99. package/dist/components/primitives/useEditablePlainText.d.ts.map +1 -0
  100. package/dist/components/primitives/useEditablePlainText.js +27 -0
  101. package/dist/components/primitives/useEditableRichText.d.ts +16 -0
  102. package/dist/components/primitives/useEditableRichText.d.ts.map +1 -0
  103. package/dist/components/primitives/useEditableRichText.js +52 -0
  104. package/dist/components/sections/Button/CTAButton.d.ts +11 -0
  105. package/dist/components/sections/Button/CTAButton.d.ts.map +1 -0
  106. package/dist/components/sections/Button/CTAButton.js +18 -0
  107. package/dist/components/sections/Button/index.d.ts +11 -0
  108. package/dist/components/sections/Button/index.d.ts.map +1 -0
  109. package/dist/components/sections/Button/index.js +28 -0
  110. package/dist/components/sections/Colors/index.d.ts +22 -0
  111. package/dist/components/sections/Colors/index.d.ts.map +1 -0
  112. package/dist/components/sections/Colors/index.js +34 -0
  113. package/dist/components/sections/DoDontList/index.d.ts +21 -0
  114. package/dist/components/sections/DoDontList/index.d.ts.map +1 -0
  115. package/dist/components/sections/DoDontList/index.js +33 -0
  116. package/dist/components/sections/DoDontMediaGrid/index.d.ts +55 -0
  117. package/dist/components/sections/DoDontMediaGrid/index.d.ts.map +1 -0
  118. package/dist/components/sections/DoDontMediaGrid/index.js +41 -0
  119. package/dist/components/sections/IconList/IconList.d.ts +20 -0
  120. package/dist/components/sections/IconList/IconList.d.ts.map +1 -0
  121. package/dist/components/sections/IconList/IconList.js +131 -0
  122. package/dist/components/sections/IconList/IconListSettings.d.ts +11 -0
  123. package/dist/components/sections/IconList/IconListSettings.d.ts.map +1 -0
  124. package/dist/components/sections/IconList/IconListSettings.js +22 -0
  125. package/dist/components/sections/IconList/index.d.ts +17 -0
  126. package/dist/components/sections/IconList/index.d.ts.map +1 -0
  127. package/dist/components/sections/IconList/index.js +27 -0
  128. package/dist/components/sections/LinkHeading/index.d.ts +8 -0
  129. package/dist/components/sections/LinkHeading/index.d.ts.map +1 -0
  130. package/dist/components/sections/LinkHeading/index.js +15 -0
  131. package/dist/components/sections/MediaGrid/MediaGrid.d.ts +17 -0
  132. package/dist/components/sections/MediaGrid/MediaGrid.d.ts.map +1 -0
  133. package/dist/components/sections/MediaGrid/MediaGrid.js +62 -0
  134. package/dist/components/sections/MediaGrid/index.d.ts +55 -0
  135. package/dist/components/sections/MediaGrid/index.d.ts.map +1 -0
  136. package/dist/components/sections/MediaGrid/index.js +35 -0
  137. package/dist/components/sections/Prose/Prose.d.ts +8 -0
  138. package/dist/components/sections/Prose/Prose.d.ts.map +1 -0
  139. package/dist/components/sections/Prose/Prose.js +11 -0
  140. package/dist/components/sections/Prose/index.d.ts +8 -0
  141. package/dist/components/sections/Prose/index.d.ts.map +1 -0
  142. package/dist/components/sections/Prose/index.js +15 -0
  143. package/dist/components/sections/SectionLayout.d.ts +11 -0
  144. package/dist/components/sections/SectionLayout.d.ts.map +1 -0
  145. package/dist/components/sections/SectionLayout.js +15 -0
  146. package/dist/components/sections/SplitContent/SplitContent.d.ts +11 -0
  147. package/dist/components/sections/SplitContent/SplitContent.d.ts.map +1 -0
  148. package/dist/components/sections/SplitContent/SplitContent.js +31 -0
  149. package/dist/components/sections/SplitContent/SplitContentSettings.d.ts +9 -0
  150. package/dist/components/sections/SplitContent/SplitContentSettings.d.ts.map +1 -0
  151. package/dist/components/sections/SplitContent/SplitContentSettings.js +17 -0
  152. package/dist/components/sections/SplitContent/index.d.ts +13 -0
  153. package/dist/components/sections/SplitContent/index.d.ts.map +1 -0
  154. package/dist/components/sections/SplitContent/index.js +27 -0
  155. package/dist/components/sections/SubHeading/index.d.ts +9 -0
  156. package/dist/components/sections/SubHeading/index.d.ts.map +1 -0
  157. package/dist/components/sections/SubHeading/index.js +18 -0
  158. package/dist/components/sections/SubSubHeading/index.d.ts +9 -0
  159. package/dist/components/sections/SubSubHeading/index.d.ts.map +1 -0
  160. package/dist/components/sections/SubSubHeading/index.js +18 -0
  161. package/dist/components/sections/ViewRenderer.d.ts +8 -0
  162. package/dist/components/sections/ViewRenderer.d.ts.map +1 -0
  163. package/dist/components/sections/ViewRenderer.js +13 -0
  164. package/dist/components/sections/register-schemas.d.ts +2 -0
  165. package/dist/components/sections/register-schemas.d.ts.map +1 -0
  166. package/dist/components/sections/register-schemas.js +15 -0
  167. package/dist/components/sections/register.d.ts +2 -0
  168. package/dist/components/sections/register.d.ts.map +1 -0
  169. package/dist/components/sections/register.js +15 -0
  170. package/dist/components/shared/Button.d.ts +15 -0
  171. package/dist/components/shared/Button.d.ts.map +1 -0
  172. package/dist/components/shared/Button.js +27 -0
  173. package/dist/components/shared/Checkbox.d.ts +14 -0
  174. package/dist/components/shared/Checkbox.d.ts.map +1 -0
  175. package/dist/components/shared/Checkbox.js +10 -0
  176. package/dist/components/shared/ColorPicker.d.ts +9 -0
  177. package/dist/components/shared/ColorPicker.d.ts.map +1 -0
  178. package/dist/components/shared/ColorPicker.js +5 -0
  179. package/dist/components/shared/ErrorBoundary.d.ts +24 -0
  180. package/dist/components/shared/ErrorBoundary.d.ts.map +1 -0
  181. package/dist/components/shared/ErrorBoundary.js +30 -0
  182. package/dist/components/shared/FontPicker.d.ts +8 -0
  183. package/dist/components/shared/FontPicker.d.ts.map +1 -0
  184. package/dist/components/shared/FontPicker.js +190 -0
  185. package/dist/components/shared/FormLabel.d.ts +8 -0
  186. package/dist/components/shared/FormLabel.d.ts.map +1 -0
  187. package/dist/components/shared/FormLabel.js +5 -0
  188. package/dist/components/shared/IconButton.d.ts +12 -0
  189. package/dist/components/shared/IconButton.d.ts.map +1 -0
  190. package/dist/components/shared/IconButton.js +16 -0
  191. package/dist/components/shared/Input.d.ts +8 -0
  192. package/dist/components/shared/Input.d.ts.map +1 -0
  193. package/dist/components/shared/Input.js +8 -0
  194. package/dist/components/shared/Navigation.d.ts +9 -0
  195. package/dist/components/shared/Navigation.d.ts.map +1 -0
  196. package/dist/components/shared/Navigation.js +71 -0
  197. package/dist/components/shared/PasswordInput.d.ts +13 -0
  198. package/dist/components/shared/PasswordInput.d.ts.map +1 -0
  199. package/dist/components/shared/PasswordInput.js +11 -0
  200. package/dist/components/shared/Popover.d.ts +12 -0
  201. package/dist/components/shared/Popover.d.ts.map +1 -0
  202. package/dist/components/shared/Popover.js +33 -0
  203. package/dist/components/shared/PopoverItem.d.ts +7 -0
  204. package/dist/components/shared/PopoverItem.d.ts.map +1 -0
  205. package/dist/components/shared/PopoverItem.js +6 -0
  206. package/dist/components/shared/Select.d.ts +16 -0
  207. package/dist/components/shared/Select.d.ts.map +1 -0
  208. package/dist/components/shared/Select.js +9 -0
  209. package/dist/components/shared/Textarea.d.ts +8 -0
  210. package/dist/components/shared/Textarea.d.ts.map +1 -0
  211. package/dist/components/shared/Textarea.js +8 -0
  212. package/dist/components/shared/Toggle.d.ts +10 -0
  213. package/dist/components/shared/Toggle.d.ts.map +1 -0
  214. package/dist/components/shared/Toggle.js +5 -0
  215. package/dist/components/shared/Tooltip.d.ts +12 -0
  216. package/dist/components/shared/Tooltip.d.ts.map +1 -0
  217. package/dist/components/shared/Tooltip.js +8 -0
  218. package/dist/components/shared/icons.d.ts +17 -0
  219. package/dist/components/shared/icons.d.ts.map +1 -0
  220. package/dist/components/shared/icons.js +23 -0
  221. package/dist/components/shell/AudienceAddForm.d.ts +11 -0
  222. package/dist/components/shell/AudienceAddForm.d.ts.map +1 -0
  223. package/dist/components/shell/AudienceAddForm.js +43 -0
  224. package/dist/components/shell/AudienceRow.d.ts +15 -0
  225. package/dist/components/shell/AudienceRow.d.ts.map +1 -0
  226. package/dist/components/shell/AudienceRow.js +74 -0
  227. package/dist/components/shell/EditorContext.d.ts +14 -0
  228. package/dist/components/shell/EditorContext.d.ts.map +1 -0
  229. package/dist/components/shell/EditorContext.js +24 -0
  230. package/dist/components/shell/EditorLoginForm.d.ts +13 -0
  231. package/dist/components/shell/EditorLoginForm.d.ts.map +1 -0
  232. package/dist/components/shell/EditorLoginForm.js +46 -0
  233. package/dist/components/shell/EditorModal.d.ts +13 -0
  234. package/dist/components/shell/EditorModal.d.ts.map +1 -0
  235. package/dist/components/shell/EditorModal.js +43 -0
  236. package/dist/components/shell/EditorModalContext.d.ts +16 -0
  237. package/dist/components/shell/EditorModalContext.d.ts.map +1 -0
  238. package/dist/components/shell/EditorModalContext.js +20 -0
  239. package/dist/components/shell/EditorShell.d.ts +22 -0
  240. package/dist/components/shell/EditorShell.d.ts.map +1 -0
  241. package/dist/components/shell/EditorShell.js +483 -0
  242. package/dist/components/shell/MediaLibraryContext.d.ts +14 -0
  243. package/dist/components/shell/MediaLibraryContext.d.ts.map +1 -0
  244. package/dist/components/shell/MediaLibraryContext.js +5 -0
  245. package/dist/components/shell/MediaLibraryModal.d.ts +14 -0
  246. package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -0
  247. package/dist/components/shell/MediaLibraryModal.js +145 -0
  248. package/dist/components/shell/ProcessingIndicator.d.ts +7 -0
  249. package/dist/components/shell/ProcessingIndicator.d.ts.map +1 -0
  250. package/dist/components/shell/ProcessingIndicator.js +15 -0
  251. package/dist/components/shell/SectionSkeleton.d.ts +9 -0
  252. package/dist/components/shell/SectionSkeleton.d.ts.map +1 -0
  253. package/dist/components/shell/SectionSkeleton.js +22 -0
  254. package/dist/components/shell/SectionTypePicker.d.ts +14 -0
  255. package/dist/components/shell/SectionTypePicker.d.ts.map +1 -0
  256. package/dist/components/shell/SectionTypePicker.js +15 -0
  257. package/dist/components/shell/SiteSettingsDisplay.d.ts +8 -0
  258. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -0
  259. package/dist/components/shell/SiteSettingsDisplay.js +28 -0
  260. package/dist/components/shell/SiteSettingsModal.d.ts +24 -0
  261. package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -0
  262. package/dist/components/shell/SiteSettingsModal.js +40 -0
  263. package/dist/components/shell/SiteSettingsUsers.d.ts +9 -0
  264. package/dist/components/shell/SiteSettingsUsers.d.ts.map +1 -0
  265. package/dist/components/shell/SiteSettingsUsers.js +87 -0
  266. package/dist/components/shell/SiteSettingsViewerAccess.d.ts +9 -0
  267. package/dist/components/shell/SiteSettingsViewerAccess.d.ts.map +1 -0
  268. package/dist/components/shell/SiteSettingsViewerAccess.js +94 -0
  269. package/dist/components/shell/ViewerLoginForm.d.ts +10 -0
  270. package/dist/components/shell/ViewerLoginForm.d.ts.map +1 -0
  271. package/dist/components/shell/ViewerLoginForm.js +40 -0
  272. package/dist/data/google-fonts.json +7718 -0
  273. package/dist/hooks/index.d.ts +7 -0
  274. package/dist/hooks/index.d.ts.map +1 -0
  275. package/dist/hooks/index.js +6 -0
  276. package/dist/hooks/useActiveHeadings.d.ts +7 -0
  277. package/dist/hooks/useActiveHeadings.d.ts.map +1 -0
  278. package/dist/hooks/useActiveHeadings.js +99 -0
  279. package/dist/hooks/useEditorPersistence.d.ts +13 -0
  280. package/dist/hooks/useEditorPersistence.d.ts.map +1 -0
  281. package/dist/hooks/useEditorPersistence.js +73 -0
  282. package/dist/hooks/useEditorPublish.d.ts +24 -0
  283. package/dist/hooks/useEditorPublish.d.ts.map +1 -0
  284. package/dist/hooks/useEditorPublish.js +145 -0
  285. package/dist/hooks/useFocusTrap.d.ts +3 -0
  286. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  287. package/dist/hooks/useFocusTrap.js +51 -0
  288. package/dist/hooks/useMediaPipeline.d.ts +65 -0
  289. package/dist/hooks/useMediaPipeline.d.ts.map +1 -0
  290. package/dist/hooks/useMediaPipeline.js +253 -0
  291. package/dist/hooks/useResolvedMedia.d.ts +9 -0
  292. package/dist/hooks/useResolvedMedia.d.ts.map +1 -0
  293. package/dist/hooks/useResolvedMedia.js +39 -0
  294. package/dist/index.d.ts +5 -0
  295. package/dist/index.d.ts.map +1 -0
  296. package/dist/index.js +4 -0
  297. package/dist/lib/cn.d.ts +3 -0
  298. package/dist/lib/cn.d.ts.map +1 -0
  299. package/dist/lib/cn.js +5 -0
  300. package/dist/lib/contrast.d.ts +2 -0
  301. package/dist/lib/contrast.d.ts.map +1 -0
  302. package/dist/lib/contrast.js +11 -0
  303. package/dist/lib/dexie.d.ts +41 -0
  304. package/dist/lib/dexie.d.ts.map +1 -0
  305. package/dist/lib/dexie.js +236 -0
  306. package/dist/lib/events.d.ts +12 -0
  307. package/dist/lib/events.d.ts.map +1 -0
  308. package/dist/lib/events.js +15 -0
  309. package/dist/lib/google-fonts.d.ts +2 -0
  310. package/dist/lib/google-fonts.d.ts.map +1 -0
  311. package/dist/lib/google-fonts.js +11 -0
  312. package/dist/lib/grid.d.ts +2 -0
  313. package/dist/lib/grid.d.ts.map +1 -0
  314. package/dist/lib/grid.js +7 -0
  315. package/dist/lib/icons.d.ts +9 -0
  316. package/dist/lib/icons.d.ts.map +1 -0
  317. package/dist/lib/icons.js +27 -0
  318. package/dist/lib/index.d.ts +13 -0
  319. package/dist/lib/index.d.ts.map +1 -0
  320. package/dist/lib/index.js +12 -0
  321. package/dist/lib/loader.d.ts +28 -0
  322. package/dist/lib/loader.d.ts.map +1 -0
  323. package/dist/lib/loader.js +57 -0
  324. package/dist/lib/nav.d.ts +15 -0
  325. package/dist/lib/nav.d.ts.map +1 -0
  326. package/dist/lib/nav.js +58 -0
  327. package/dist/lib/registry.d.ts +110 -0
  328. package/dist/lib/registry.d.ts.map +1 -0
  329. package/dist/lib/registry.js +64 -0
  330. package/dist/lib/safeRedirect.d.ts +7 -0
  331. package/dist/lib/safeRedirect.d.ts.map +1 -0
  332. package/dist/lib/safeRedirect.js +11 -0
  333. package/dist/lib/sanitize.d.ts +2 -0
  334. package/dist/lib/sanitize.d.ts.map +1 -0
  335. package/dist/lib/sanitize.js +6 -0
  336. package/dist/lib/timestamp.d.ts +2 -0
  337. package/dist/lib/timestamp.d.ts.map +1 -0
  338. package/dist/lib/timestamp.js +28 -0
  339. package/dist/media/github.d.ts +3 -0
  340. package/dist/media/github.d.ts.map +1 -0
  341. package/dist/media/github.js +60 -0
  342. package/dist/media/index.d.ts +8 -0
  343. package/dist/media/index.d.ts.map +1 -0
  344. package/dist/media/index.js +9 -0
  345. package/dist/media/queue.d.ts +74 -0
  346. package/dist/media/queue.d.ts.map +1 -0
  347. package/dist/media/queue.js +116 -0
  348. package/dist/media/resolve.d.ts +14 -0
  349. package/dist/media/resolve.d.ts.map +1 -0
  350. package/dist/media/resolve.js +50 -0
  351. package/dist/media/types.d.ts +42 -0
  352. package/dist/media/types.d.ts.map +1 -0
  353. package/dist/media/types.js +1 -0
  354. package/dist/media/utils.d.ts +7 -0
  355. package/dist/media/utils.d.ts.map +1 -0
  356. package/dist/media/utils.js +41 -0
  357. package/dist/media/videoPoster.d.ts +6 -0
  358. package/dist/media/videoPoster.d.ts.map +1 -0
  359. package/dist/media/videoPoster.js +44 -0
  360. package/dist/media/worker.d.ts +36 -0
  361. package/dist/media/worker.d.ts.map +1 -0
  362. package/dist/media/worker.js +73 -0
  363. package/dist/schemas/audience.d.ts +12 -0
  364. package/dist/schemas/audience.d.ts.map +1 -0
  365. package/dist/schemas/audience.js +19 -0
  366. package/dist/schemas/auth.d.ts +36 -0
  367. package/dist/schemas/auth.d.ts.map +1 -0
  368. package/dist/schemas/auth.js +22 -0
  369. package/dist/schemas/index.d.ts +8 -0
  370. package/dist/schemas/index.d.ts.map +1 -0
  371. package/dist/schemas/index.js +7 -0
  372. package/dist/schemas/media-grid-options.d.ts +8 -0
  373. package/dist/schemas/media-grid-options.d.ts.map +1 -0
  374. package/dist/schemas/media-grid-options.js +7 -0
  375. package/dist/schemas/media.d.ts +63 -0
  376. package/dist/schemas/media.d.ts.map +1 -0
  377. package/dist/schemas/media.js +28 -0
  378. package/dist/schemas/sections.d.ts +12 -0
  379. package/dist/schemas/sections.d.ts.map +1 -0
  380. package/dist/schemas/sections.js +12 -0
  381. package/dist/schemas/shared.d.ts +98 -0
  382. package/dist/schemas/shared.d.ts.map +1 -0
  383. package/dist/schemas/shared.js +71 -0
  384. package/dist/schemas/site-config.d.ts +48 -0
  385. package/dist/schemas/site-config.d.ts.map +1 -0
  386. package/dist/schemas/site-config.js +26 -0
  387. package/package.json +57 -0
  388. package/src/auth/cookies.ts +51 -0
  389. package/src/auth/errors.ts +10 -0
  390. package/src/auth/index.ts +15 -0
  391. package/src/auth/security.ts +44 -0
  392. package/src/auth/types.ts +61 -0
  393. package/src/components/brandguide/ColorSwatchSettings.tsx +34 -0
  394. package/src/components/brandguide/Colors.tsx +277 -0
  395. package/src/components/brandguide/DoDontList.tsx +67 -0
  396. package/src/components/brandguide/DoDontMediaGrid.tsx +19 -0
  397. package/src/components/editor/AudiencePicker.tsx +103 -0
  398. package/src/components/editor/DeleteButton.tsx +18 -0
  399. package/src/components/editor/DragHandle.tsx +18 -0
  400. package/src/components/editor/InsertButton.tsx +22 -0
  401. package/src/components/editor/SectionWrapper.tsx +279 -0
  402. package/src/components/editor/SettingsButton.tsx +17 -0
  403. package/src/components/editor/SettingsForm.tsx +159 -0
  404. package/src/components/editor/StatusBadge.tsx +30 -0
  405. package/src/components/editor/StatusPicker.tsx +86 -0
  406. package/src/components/editor/index.ts +7 -0
  407. package/src/components/primitives/CustomParagraph.ts +25 -0
  408. package/src/components/primitives/EditableGrid.tsx +260 -0
  409. package/src/components/primitives/EditableList.tsx +160 -0
  410. package/src/components/primitives/EditablePlainText.tsx +99 -0
  411. package/src/components/primitives/EditableRichText.tsx +132 -0
  412. package/src/components/primitives/HeadingSection.tsx +25 -0
  413. package/src/components/primitives/IconPicker.tsx +60 -0
  414. package/src/components/primitives/LinkPopover.tsx +109 -0
  415. package/src/components/primitives/MediaSettingsForms.tsx +109 -0
  416. package/src/components/primitives/ResolvedMedia.tsx +36 -0
  417. package/src/components/primitives/RichTextToolbar.tsx +149 -0
  418. package/src/components/primitives/tiptap-presets.ts +50 -0
  419. package/src/components/primitives/useEditableCollection.ts +104 -0
  420. package/src/components/primitives/useEditablePlainText.ts +49 -0
  421. package/src/components/primitives/useEditableRichText.ts +74 -0
  422. package/src/components/sections/Button/CTAButton.tsx +50 -0
  423. package/src/components/sections/Button/index.tsx +37 -0
  424. package/src/components/sections/Colors/index.tsx +45 -0
  425. package/src/components/sections/DoDontList/index.tsx +43 -0
  426. package/src/components/sections/DoDontMediaGrid/index.tsx +53 -0
  427. package/src/components/sections/IconList/IconList.tsx +462 -0
  428. package/src/components/sections/IconList/IconListSettings.tsx +81 -0
  429. package/src/components/sections/IconList/index.tsx +36 -0
  430. package/src/components/sections/LinkHeading/index.tsx +24 -0
  431. package/src/components/sections/MediaGrid/MediaGrid.tsx +219 -0
  432. package/src/components/sections/MediaGrid/index.tsx +47 -0
  433. package/src/components/sections/Prose/Prose.tsx +34 -0
  434. package/src/components/sections/Prose/index.tsx +18 -0
  435. package/src/components/sections/SectionLayout.tsx +31 -0
  436. package/src/components/sections/SplitContent/SplitContent.tsx +77 -0
  437. package/src/components/sections/SplitContent/SplitContentSettings.tsx +42 -0
  438. package/src/components/sections/SplitContent/index.tsx +36 -0
  439. package/src/components/sections/SubHeading/index.tsx +27 -0
  440. package/src/components/sections/SubSubHeading/index.tsx +27 -0
  441. package/src/components/sections/ViewRenderer.tsx +29 -0
  442. package/src/components/sections/register-schemas.ts +16 -0
  443. package/src/components/sections/register.ts +16 -0
  444. package/src/components/shared/Button.tsx +77 -0
  445. package/src/components/shared/Checkbox.tsx +73 -0
  446. package/src/components/shared/ColorPicker.tsx +28 -0
  447. package/src/components/shared/ErrorBoundary.tsx +92 -0
  448. package/src/components/shared/FontPicker.tsx +300 -0
  449. package/src/components/shared/FormLabel.tsx +18 -0
  450. package/src/components/shared/IconButton.tsx +45 -0
  451. package/src/components/shared/Input.tsx +34 -0
  452. package/src/components/shared/Navigation.tsx +196 -0
  453. package/src/components/shared/PasswordInput.tsx +64 -0
  454. package/src/components/shared/Popover.tsx +61 -0
  455. package/src/components/shared/PopoverItem.tsx +24 -0
  456. package/src/components/shared/Select.tsx +60 -0
  457. package/src/components/shared/Textarea.tsx +34 -0
  458. package/src/components/shared/Toggle.tsx +35 -0
  459. package/src/components/shared/Tooltip.tsx +28 -0
  460. package/src/components/shared/icons.tsx +28 -0
  461. package/src/components/shell/AudienceAddForm.tsx +94 -0
  462. package/src/components/shell/AudienceRow.tsx +171 -0
  463. package/src/components/shell/EditorContext.tsx +44 -0
  464. package/src/components/shell/EditorLoginForm.tsx +130 -0
  465. package/src/components/shell/EditorModal.tsx +93 -0
  466. package/src/components/shell/EditorModalContext.tsx +40 -0
  467. package/src/components/shell/EditorShell.tsx +910 -0
  468. package/src/components/shell/MediaLibraryContext.tsx +19 -0
  469. package/src/components/shell/MediaLibraryModal.tsx +371 -0
  470. package/src/components/shell/ProcessingIndicator.tsx +84 -0
  471. package/src/components/shell/SectionSkeleton.tsx +54 -0
  472. package/src/components/shell/SectionTypePicker.tsx +47 -0
  473. package/src/components/shell/SiteSettingsDisplay.tsx +78 -0
  474. package/src/components/shell/SiteSettingsModal.tsx +129 -0
  475. package/src/components/shell/SiteSettingsUsers.tsx +190 -0
  476. package/src/components/shell/SiteSettingsViewerAccess.tsx +171 -0
  477. package/src/components/shell/ViewerLoginForm.tsx +95 -0
  478. package/src/data/google-fonts.json +7718 -0
  479. package/src/env.d.ts +3 -0
  480. package/src/hooks/index.ts +6 -0
  481. package/src/hooks/useActiveHeadings.ts +120 -0
  482. package/src/hooks/useEditorPersistence.ts +103 -0
  483. package/src/hooks/useEditorPublish.ts +187 -0
  484. package/src/hooks/useFocusTrap.ts +57 -0
  485. package/src/hooks/useMediaPipeline.ts +309 -0
  486. package/src/hooks/useResolvedMedia.ts +54 -0
  487. package/src/index.ts +4 -0
  488. package/src/lib/cn.ts +6 -0
  489. package/src/lib/contrast.ts +11 -0
  490. package/src/lib/dexie.ts +347 -0
  491. package/src/lib/events.ts +23 -0
  492. package/src/lib/google-fonts.ts +10 -0
  493. package/src/lib/grid.ts +7 -0
  494. package/src/lib/icons.ts +58 -0
  495. package/src/lib/index.ts +35 -0
  496. package/src/lib/loader.ts +81 -0
  497. package/src/lib/nav.ts +64 -0
  498. package/src/lib/registry.ts +202 -0
  499. package/src/lib/safeRedirect.ts +11 -0
  500. package/src/lib/sanitize.ts +6 -0
  501. package/src/lib/timestamp.ts +31 -0
  502. package/src/media/github.ts +72 -0
  503. package/src/media/index.ts +12 -0
  504. package/src/media/queue.ts +166 -0
  505. package/src/media/resolve.ts +63 -0
  506. package/src/media/types.ts +58 -0
  507. package/src/media/utils.ts +48 -0
  508. package/src/media/videoPoster.ts +53 -0
  509. package/src/media/worker.ts +122 -0
  510. package/src/schemas/audience.ts +28 -0
  511. package/src/schemas/auth.ts +31 -0
  512. package/src/schemas/index.ts +7 -0
  513. package/src/schemas/media-grid-options.ts +8 -0
  514. package/src/schemas/media.ts +40 -0
  515. package/src/schemas/sections.ts +24 -0
  516. package/src/schemas/shared.ts +96 -0
  517. package/src/schemas/site-config.ts +38 -0
@@ -0,0 +1,483 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Fragment, useState, useCallback, useEffect, useRef } from "react";
3
+ import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
4
+ import { SiteConfigSchema } from "../../schemas/site-config";
5
+ import { EditorProvider, useEditorContext } from "./EditorContext";
6
+ import { EditorModalProvider, useEditorModal } from "./EditorModalContext";
7
+ import { EditorModal } from "./EditorModal";
8
+ import { SiteSettingsModal } from "./SiteSettingsModal";
9
+ import { MediaLibraryModal } from "./MediaLibraryModal";
10
+ import { MediaLibraryContext } from "./MediaLibraryContext";
11
+ import { ProcessingIndicator } from "./ProcessingIndicator";
12
+ import { SectionSkeleton } from "./SectionSkeleton";
13
+ import "../sections/register";
14
+ import { getSection, getAllSections } from "../../lib/registry";
15
+ import { SectionWrapper } from "../editor/SectionWrapper";
16
+ import { SectionLayout } from "../sections/SectionLayout";
17
+ import { initEditorStore, checkForLocalChanges, restoreLocalChanges, discardLocalChanges, getCachedContent, cacheContent, persistMediaManifest, getMediaManifest, getPendingMediaItems, getPendingMediaLocalUrls, getPendingMediaDeletions, } from "../../lib/dexie";
18
+ import { useEditorPersistence } from "../../hooks/useEditorPersistence";
19
+ import { useEditorPublish } from "../../hooks/useEditorPublish";
20
+ import { useMediaPipeline } from "../../hooks/useMediaPipeline";
21
+ import { formatTimestamp } from "../../lib/timestamp";
22
+ import { generateNavLinks } from "../../lib/nav";
23
+ import { navChangeEvent, darkModeEvent } from "../../lib/events";
24
+ import { cn } from "../../lib/cn";
25
+ import { Button } from "../shared/Button";
26
+ import { IconButton } from "../shared/IconButton";
27
+ import { SettingsIcon } from "../shared/icons";
28
+ import { ImageIcon } from "lucide-react";
29
+ import { ErrorBoundary } from "../shared/ErrorBoundary";
30
+ export { useMediaLibrary } from "./MediaLibraryContext";
31
+ const typeOptions = getAllSections().map((def) => ({
32
+ type: def.type,
33
+ label: def.label,
34
+ icon: () => null,
35
+ }));
36
+ export default function EditorShell({ headSha, siteId, audiences: initialAudiences, capabilities, currentUser, }) {
37
+ const [shellState, setShellState] = useState({ phase: "loading-content" });
38
+ const [sections, setSections] = useState([]);
39
+ const [siteIndex, setSiteIndex] = useState({ siteId, order: [], sections: {} });
40
+ const [audiences, setAudiences] = useState(initialAudiences);
41
+ const [localChangesExist, setLocalChangesExist] = useState(false);
42
+ const [showDiscardConfirm, setShowDiscardConfirm] = useState(false);
43
+ const [showSiteSettings, setShowSiteSettings] = useState(false);
44
+ const [dirtySectionIds, setDirtySectionIds] = useState(new Set());
45
+ const [siteConfig, setSiteConfig] = useState(null);
46
+ const [mediaManifest, setMediaManifest] = useState({ images: {} });
47
+ const [showMediaLibrary, setShowMediaLibrary] = useState(false);
48
+ const [mediaModalMode, setMediaModalMode] = useState("manage");
49
+ const [mediaSelectCallback, setMediaSelectCallback] = useState(null);
50
+ const siteIndexRef = useRef({ siteId, order: [], sections: {} });
51
+ const fontLinkRef = useRef(null);
52
+ useEffect(() => { siteIndexRef.current = siteIndex; }, [siteIndex]);
53
+ const persistence = useEditorPersistence(siteIndexRef);
54
+ const mediaPipeline = useMediaPipeline({
55
+ siteConfig,
56
+ mediaManifest,
57
+ setMediaManifest,
58
+ sections,
59
+ setSections,
60
+ setLocalChangesExist,
61
+ setDirtySectionIds,
62
+ markSectionDirty: persistence.markSectionDirty,
63
+ });
64
+ const { isPublishing, publishFeedback, handlePublish } = useEditorPublish({
65
+ flushNow: persistence.flushNow,
66
+ cancelPendingFlush: persistence.cancelPendingFlush,
67
+ isConfigDirty: persistence.isConfigDirty,
68
+ clearConfigDirty: persistence.clearConfigDirty,
69
+ siteIndexRef,
70
+ siteConfig,
71
+ sections,
72
+ onSuccess: () => {
73
+ setDirtySectionIds(new Set());
74
+ setLocalChangesExist(false);
75
+ },
76
+ mediaManifest,
77
+ pendingMediaItems: mediaPipeline.pendingMediaItems,
78
+ pendingMediaDeletions: mediaPipeline.pendingDeletions,
79
+ onMediaPublished: (publishedItems, publishedDeletions) => {
80
+ mediaPipeline.setPendingMediaItems([]);
81
+ mediaPipeline.setPendingLocalUrls({});
82
+ mediaPipeline.setPendingDeletions([]);
83
+ setMediaManifest((prev) => {
84
+ const images = { ...prev.images };
85
+ for (const item of publishedItems) {
86
+ images[item.id] = item;
87
+ }
88
+ for (const id of publishedDeletions) {
89
+ delete images[id];
90
+ }
91
+ return { images };
92
+ });
93
+ },
94
+ });
95
+ useEffect(() => {
96
+ if (sections.length === 0)
97
+ return;
98
+ const navLinks = generateNavLinks(sections);
99
+ navChangeEvent.dispatch(navLinks);
100
+ }, [sections]);
101
+ const applySiteConfigPreview = useCallback((config) => {
102
+ const root = document.documentElement;
103
+ root.style.setProperty("--color-primary", config.primaryColor);
104
+ root.style.setProperty("--color-primary-contrast", config.primaryContrast);
105
+ root.style.setProperty("--font-heading", `${config.headingFont}, system-ui, sans-serif`);
106
+ root.style.setProperty("--font-body", `${config.bodyFont}, system-ui, sans-serif`);
107
+ if (config.googleFontsUrl) {
108
+ if (fontLinkRef.current?.href !== config.googleFontsUrl) {
109
+ const link = document.createElement("link");
110
+ link.rel = "stylesheet";
111
+ link.href = config.googleFontsUrl;
112
+ document.head.appendChild(link);
113
+ fontLinkRef.current?.remove();
114
+ fontLinkRef.current = link;
115
+ }
116
+ }
117
+ else {
118
+ fontLinkRef.current?.remove();
119
+ fontLinkRef.current = null;
120
+ }
121
+ if (config.darkMode === "dark") {
122
+ root.classList.add("dark");
123
+ }
124
+ else if (config.darkMode === "light") {
125
+ root.classList.remove("dark");
126
+ }
127
+ else {
128
+ const stored = localStorage.getItem("theme");
129
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
130
+ root.classList.toggle("dark", stored === "dark" || (!stored && prefersDark));
131
+ }
132
+ localStorage.setItem("portal-dark-mode", config.darkMode);
133
+ localStorage.setItem("portal-primary-color", config.primaryColor);
134
+ localStorage.setItem("portal-primary-contrast", config.primaryContrast);
135
+ darkModeEvent.dispatch(config.darkMode);
136
+ }, []);
137
+ // --- Content loading ---
138
+ useEffect(() => {
139
+ let cancelled = false;
140
+ async function loadContent() {
141
+ initEditorStore(siteId);
142
+ let loadedSections;
143
+ let loadedIndex;
144
+ let loadedConfig;
145
+ let loadedManifest = { images: {} };
146
+ const cached = await getCachedContent();
147
+ if (cached && cached.sha === headSha) {
148
+ loadedSections = cached.sections;
149
+ loadedIndex = cached.index;
150
+ loadedConfig = SiteConfigSchema.parse(cached.siteConfig);
151
+ const savedManifest = await getMediaManifest();
152
+ if (savedManifest)
153
+ loadedManifest = savedManifest;
154
+ }
155
+ else {
156
+ const response = await fetch("/api/content");
157
+ if (!response.ok)
158
+ throw new Error(`Failed to load content: ${response.status}`);
159
+ const data = await response.json();
160
+ loadedSections = data.sections;
161
+ loadedIndex = data.index;
162
+ loadedConfig = SiteConfigSchema.parse(data.siteConfig);
163
+ await cacheContent(data.sha, data.sections, data.index, data.siteConfig);
164
+ if (data.mediaManifest) {
165
+ loadedManifest = data.mediaManifest;
166
+ await persistMediaManifest(loadedManifest);
167
+ }
168
+ }
169
+ if (cancelled)
170
+ return;
171
+ setSections(loadedSections);
172
+ setSiteIndex(loadedIndex);
173
+ setSiteConfig(loadedConfig);
174
+ setMediaManifest(loadedManifest);
175
+ siteIndexRef.current = loadedIndex;
176
+ applySiteConfigPreview(loadedConfig);
177
+ // Load pending media from Dexie
178
+ const savedPendingItems = await getPendingMediaItems();
179
+ if (!cancelled && savedPendingItems.length > 0) {
180
+ mediaPipeline.setPendingMediaItems(savedPendingItems);
181
+ const urlMap = {};
182
+ for (const pi of savedPendingItems) {
183
+ const urls = await getPendingMediaLocalUrls(pi.id);
184
+ if (urls) {
185
+ const smallestKey = Object.keys(urls).find((k) => k !== "primary") ?? "primary";
186
+ if (urls[smallestKey])
187
+ urlMap[pi.id] = urls[smallestKey];
188
+ }
189
+ }
190
+ if (!cancelled)
191
+ mediaPipeline.setPendingLocalUrls(urlMap);
192
+ }
193
+ const savedDeletions = await getPendingMediaDeletions();
194
+ if (!cancelled && savedDeletions.length > 0)
195
+ mediaPipeline.setPendingDeletions(savedDeletions);
196
+ const result = await checkForLocalChanges();
197
+ if (cancelled)
198
+ return;
199
+ if (result) {
200
+ setShellState({ phase: "recovery", latestTimestamp: result.latestTimestamp });
201
+ }
202
+ else {
203
+ setShellState({ phase: "ready" });
204
+ }
205
+ }
206
+ loadContent().catch((err) => {
207
+ console.error("Failed to load editor content:", err);
208
+ setShellState({ phase: "error", message: err instanceof Error ? err.message : "Failed to load content" });
209
+ });
210
+ return () => { cancelled = true; };
211
+ }, [headSha, siteId, applySiteConfigPreview]);
212
+ // --- Recovery handlers ---
213
+ const handleRestore = useCallback(async () => {
214
+ const restored = await restoreLocalChanges();
215
+ if (restored.siteIndex) {
216
+ const restoredIndex = restored.siteIndex;
217
+ setSections(() => restoredIndex.order.map((id) => {
218
+ const restoredContent = restored.sections[id];
219
+ const existing = sections.find((s) => s.section.id === id);
220
+ if (restoredContent) {
221
+ return {
222
+ section: { id, ...restoredContent },
223
+ meta: restoredIndex.sections[id] ?? existing?.meta ?? { type: restoredContent.type, status: "draft", access: ["internal"] },
224
+ };
225
+ }
226
+ if (existing) {
227
+ return { ...existing, meta: restoredIndex.sections[id] ?? existing.meta };
228
+ }
229
+ return null;
230
+ }).filter((s) => s !== null));
231
+ setSiteIndex(restoredIndex);
232
+ }
233
+ else {
234
+ setSections((prev) => prev.map((loaded) => {
235
+ const restoredContent = restored.sections[loaded.section.id];
236
+ if (restoredContent) {
237
+ return { ...loaded, section: { id: loaded.section.id, ...restoredContent } };
238
+ }
239
+ return loaded;
240
+ }));
241
+ }
242
+ if (restored.siteConfig) {
243
+ const parsed = SiteConfigSchema.safeParse(restored.siteConfig);
244
+ if (parsed.success) {
245
+ setSiteConfig(parsed.data);
246
+ persistence.persistConfig(parsed.data);
247
+ applySiteConfigPreview(parsed.data);
248
+ }
249
+ }
250
+ setLocalChangesExist(true);
251
+ setDirtySectionIds(new Set(Object.keys(restored.sections)));
252
+ setShellState({ phase: "ready" });
253
+ }, [sections, applySiteConfigPreview, persistence]);
254
+ const handleDiscard = useCallback(async () => {
255
+ await discardLocalChanges();
256
+ setLocalChangesExist(false);
257
+ setDirtySectionIds(new Set());
258
+ mediaPipeline.setPendingMediaItems([]);
259
+ mediaPipeline.setPendingLocalUrls({});
260
+ mediaPipeline.setPendingDeletions([]);
261
+ const cached = await getCachedContent();
262
+ if (cached) {
263
+ setSections(cached.sections);
264
+ setSiteIndex(cached.index);
265
+ siteIndexRef.current = cached.index;
266
+ const parsed = SiteConfigSchema.safeParse(cached.siteConfig);
267
+ if (parsed.success) {
268
+ setSiteConfig(parsed.data);
269
+ applySiteConfigPreview(parsed.data);
270
+ }
271
+ }
272
+ const savedManifest = await getMediaManifest();
273
+ setMediaManifest(savedManifest ?? { images: {} });
274
+ persistence.clearConfigDirty();
275
+ setShellState({ phase: "ready" });
276
+ }, [applySiteConfigPreview, persistence]);
277
+ const handleToolbarDiscard = useCallback(async () => {
278
+ setShowDiscardConfirm(false);
279
+ await handleDiscard();
280
+ }, [handleDiscard]);
281
+ // --- Section CRUD ---
282
+ const onSectionChange = useCallback((sectionId, newContent) => {
283
+ setSections((prev) => prev.map((loaded) => loaded.section.id === sectionId
284
+ ? { ...loaded, section: { id: loaded.section.id, ...newContent } }
285
+ : loaded));
286
+ persistence.markSectionDirty(sectionId, newContent);
287
+ setLocalChangesExist(true);
288
+ setDirtySectionIds((prev) => new Set(prev).add(sectionId));
289
+ }, [persistence]);
290
+ const onAddSection = useCallback((insertIndex, type) => {
291
+ const definition = getSection(type);
292
+ if (!definition)
293
+ return;
294
+ const id = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
295
+ ? crypto.randomUUID()
296
+ : `_id_${Date.now()}_${Math.random().toString(36).slice(2)}`;
297
+ const content = definition.defaults();
298
+ const newSection = {
299
+ section: { id, ...content },
300
+ meta: { type, status: "draft", access: ["internal"] },
301
+ };
302
+ setSections((prev) => {
303
+ const next = [...prev];
304
+ next.splice(insertIndex, 0, newSection);
305
+ return next;
306
+ });
307
+ setSiteIndex((prev) => {
308
+ const newOrder = [...prev.order];
309
+ newOrder.splice(insertIndex, 0, id);
310
+ return {
311
+ ...prev,
312
+ order: newOrder,
313
+ sections: { ...prev.sections, [id]: { type, status: "draft", access: ["internal"] } },
314
+ };
315
+ });
316
+ persistence.markSectionDirty(id, content);
317
+ persistence.markIndexDirty();
318
+ setLocalChangesExist(true);
319
+ setDirtySectionIds((prev) => new Set(prev).add(id));
320
+ }, [persistence]);
321
+ const onDeleteSection = useCallback((sectionId) => {
322
+ setSections((prev) => prev.filter((s) => s.section.id !== sectionId));
323
+ setSiteIndex((prev) => {
324
+ const { [sectionId]: _, ...remainingSections } = prev.sections;
325
+ return {
326
+ ...prev,
327
+ order: prev.order.filter((id) => id !== sectionId),
328
+ sections: remainingSections,
329
+ };
330
+ });
331
+ persistence.markSectionDeleted(sectionId);
332
+ setLocalChangesExist(true);
333
+ setDirtySectionIds((prev) => {
334
+ const next = new Set(prev);
335
+ next.delete(sectionId);
336
+ return next;
337
+ });
338
+ }, [persistence]);
339
+ const onReorderSections = useCallback((fromIndex, toIndex) => {
340
+ setSections((prev) => {
341
+ const next = [...prev];
342
+ const [moved] = next.splice(fromIndex, 1);
343
+ next.splice(toIndex, 0, moved);
344
+ return next;
345
+ });
346
+ setSiteIndex((prev) => {
347
+ const newOrder = [...prev.order];
348
+ const [movedId] = newOrder.splice(fromIndex, 1);
349
+ newOrder.splice(toIndex, 0, movedId);
350
+ return { ...prev, order: newOrder };
351
+ });
352
+ persistence.markIndexDirty();
353
+ setLocalChangesExist(true);
354
+ }, [persistence]);
355
+ const onAccessChange = useCallback((sectionId, access) => {
356
+ setSections((prev) => prev.map((loaded) => loaded.section.id === sectionId
357
+ ? { ...loaded, meta: { ...loaded.meta, access } }
358
+ : loaded));
359
+ setSiteIndex((prev) => ({
360
+ ...prev,
361
+ sections: { ...prev.sections, [sectionId]: { ...prev.sections[sectionId], access } },
362
+ }));
363
+ persistence.markIndexDirty();
364
+ setLocalChangesExist(true);
365
+ }, [persistence]);
366
+ const onStatusChange = useCallback((sectionId, status) => {
367
+ setSections((prev) => prev.map((loaded) => loaded.section.id === sectionId
368
+ ? { ...loaded, meta: { ...loaded.meta, status } }
369
+ : loaded));
370
+ setSiteIndex((prev) => ({
371
+ ...prev,
372
+ sections: { ...prev.sections, [sectionId]: { ...prev.sections[sectionId], status } },
373
+ }));
374
+ persistence.markIndexDirty();
375
+ setLocalChangesExist(true);
376
+ }, [persistence]);
377
+ const handleSiteConfigChange = useCallback((config) => {
378
+ setSiteConfig(config);
379
+ applySiteConfigPreview(config);
380
+ persistence.persistConfig(config);
381
+ setLocalChangesExist(true);
382
+ }, [applySiteConfigPreview, persistence]);
383
+ // --- Render ---
384
+ if (shellState.phase === "loading-content") {
385
+ return _jsx("div", { className: "min-h-screen", "aria-busy": "true", "aria-label": "Loading content" });
386
+ }
387
+ if (shellState.phase === "error") {
388
+ return (_jsx("div", { className: "flex min-h-[50vh] items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-sm text-red-600", children: shellState.message }), _jsx(Button, { variant: "secondary", size: "md", className: "mt-3", onClick: () => window.location.reload(), children: "Retry" })] }) }));
389
+ }
390
+ if (shellState.phase === "recovery") {
391
+ return (_jsxs(EditorModal, { isOpen: true, onClose: () => { }, title: "Unsaved Changes", blocking: true, children: [_jsxs("p", { className: "text-sm text-base-contrast-light", children: ["You have unsaved changes from ", _jsx("strong", { children: formatTimestamp(shellState.latestTimestamp) }), ". Would you like to restore them or start fresh?"] }), _jsxs("div", { className: "mt-4 flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "secondary", size: "md", onClick: handleDiscard, children: "Discard" }), _jsx(Button, { type: "button", variant: "primary", size: "md", onClick: handleRestore, children: "Restore" })] })] }));
392
+ }
393
+ return (_jsx(EditorProvider, { children: _jsx(EditorModalProvider, { children: _jsx(MediaLibraryContext.Provider, { value: {
394
+ ...mediaPipeline.contextValue,
395
+ openSelectModal: (onSelect) => {
396
+ setMediaModalMode("select");
397
+ setMediaSelectCallback(() => onSelect);
398
+ setShowMediaLibrary(true);
399
+ },
400
+ }, children: _jsxs("div", { className: "editor-shell relative", children: [_jsx(EditorToolbar, { localChangesExist: localChangesExist, isPublishing: isPublishing, publishFeedback: publishFeedback, onPublish: handlePublish, onDiscardClick: () => setShowDiscardConfirm(true), onSettingsClick: () => setShowSiteSettings(true), onMediaClick: () => {
401
+ setMediaModalMode("manage");
402
+ setShowMediaLibrary(true);
403
+ }, processingItems: mediaPipeline.processingItems }), _jsx(EditorContent, { sections: sections, audiences: audiences, dirtySectionIds: dirtySectionIds, isPublishing: isPublishing, onSectionChange: onSectionChange, onAddSection: onAddSection, onDeleteSection: onDeleteSection, onReorderSections: onReorderSections, onAccessChange: onAccessChange, onStatusChange: onStatusChange }), _jsx(GlobalModal, {}), _jsx(SiteSettingsModal, { isOpen: showSiteSettings, onClose: () => setShowSiteSettings(false), siteConfig: siteConfig, onSiteConfigChange: handleSiteConfigChange, onAudiencesChange: setAudiences, capabilities: capabilities, currentUser: currentUser }), _jsxs(EditorModal, { isOpen: showDiscardConfirm, onClose: () => setShowDiscardConfirm(false), title: "Discard Changes", children: [_jsx("p", { className: "mb-4 text-sm text-base-contrast-light", children: "Discard all unsaved changes? This will reload with the last published content." }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx(Button, { variant: "secondary", size: "md", onClick: () => setShowDiscardConfirm(false), children: "Cancel" }), _jsx(Button, { variant: "destructive", size: "md", onClick: handleToolbarDiscard, children: "Discard" })] })] }), _jsx(EditorModal, { isOpen: showMediaLibrary, onClose: () => {
404
+ setShowMediaLibrary(false);
405
+ setMediaSelectCallback(null);
406
+ }, title: "Media Library", size: "large", children: _jsx(MediaLibraryModal, { mode: mediaModalMode, items: [
407
+ ...Object.values(mediaManifest.images),
408
+ ...mediaPipeline.pendingMediaItems,
409
+ ].filter((item) => !mediaPipeline.pendingDeletions.includes(item.id)), onSelect: (id) => {
410
+ if (mediaSelectCallback) {
411
+ mediaSelectCallback(id);
412
+ }
413
+ setShowMediaLibrary(false);
414
+ setMediaSelectCallback(null);
415
+ }, onUpload: mediaPipeline.handleMediaUpload, onDelete: mediaPipeline.handleMediaDelete, onAltChange: mediaPipeline.handleMediaAltChange, referenceCountMap: mediaPipeline.referenceCountMap, localUrlMap: mediaPipeline.pendingLocalUrls, maxFileSize: siteConfig?.media.maxFileSize }) })] }) }) }) }));
416
+ }
417
+ function EditorContent({ sections, audiences, dirtySectionIds, isPublishing, onSectionChange, onAddSection, onDeleteSection, onReorderSections, onAccessChange, onStatusChange, }) {
418
+ const { isEditMode } = useEditorContext();
419
+ const { openModal, closeModal } = useEditorModal();
420
+ const [pendingInsertIndex, setPendingInsertIndex] = useState(null);
421
+ const dismissPendingInsert = useCallback(() => setPendingInsertIndex(null), []);
422
+ const editingEnabled = isEditMode && !isPublishing;
423
+ useEffect(() => {
424
+ return monitorForElements({
425
+ onDragStart: ({ source }) => {
426
+ if (source.data.dragType === "section") {
427
+ setPendingInsertIndex(null);
428
+ }
429
+ },
430
+ });
431
+ }, []);
432
+ return (_jsxs("div", { children: [sections.map(({ section, meta }, index) => {
433
+ const definition = getSection(section.type);
434
+ if (!definition) {
435
+ return (_jsxs("div", { className: "border border-amber-400 bg-amber-50 px-4 py-3 text-sm text-amber-800 dark:border-amber-600 dark:bg-amber-900/30 dark:text-amber-300", role: "alert", children: ["Unknown section type: ", _jsx("code", { className: "font-mono font-semibold", children: section.type })] }, section.id));
436
+ }
437
+ const Component = definition.component;
438
+ return (_jsxs(Fragment, { children: [editingEnabled && pendingInsertIndex === index && (_jsx(SectionSkeleton, { types: typeOptions, onSelect: (type) => {
439
+ onAddSection(index, type);
440
+ setPendingInsertIndex(null);
441
+ }, onDismiss: dismissPendingInsert })), _jsx(ErrorBoundary, { label: `${definition.label} (${section.type})`, children: _jsx(SectionLayout, { type: section.type, status: meta.status, dimNonPublished: !isEditMode, children: _jsx(SectionWrapper, { sectionId: section.id, sectionType: section.type, status: meta.status, dirty: dirtySectionIds.has(section.id), index: index, isLast: index === sections.length - 1, definition: definition, options: {
442
+ ...section.content,
443
+ ...("options" in section ? section.options : {}),
444
+ }, audiences: audiences, access: meta.access, onAccessChange: editingEnabled ? (a) => onAccessChange(section.id, a) : undefined, onStatusChange: editingEnabled ? (s) => onStatusChange(section.id, s) : undefined, onSectionChange: editingEnabled ? (settingsResult) => {
445
+ const result = settingsResult;
446
+ if (result && typeof result === "object" && "content" in result && "options" in result) {
447
+ const contentPatch = result.content;
448
+ const optionsPatch = result.options;
449
+ onSectionChange(section.id, {
450
+ ...section,
451
+ content: { ...section.content, ...contentPatch },
452
+ options: { ...("options" in section ? section.options : {}), ...optionsPatch },
453
+ });
454
+ }
455
+ else {
456
+ onSectionChange(section.id, {
457
+ ...section,
458
+ ...result,
459
+ });
460
+ }
461
+ } : undefined, onReorder: editingEnabled ? onReorderSections : undefined, onRequestInsert: editingEnabled ? (i) => setPendingInsertIndex(i) : undefined, onDelete: editingEnabled ? () => {
462
+ openModal("Delete Section", (_jsxs("div", { children: [_jsxs("p", { className: "mb-4 text-sm text-base-contrast-light", children: ["Delete this ", _jsx("strong", { children: definition.label }), " section? This cannot be undone."] }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx(Button, { variant: "secondary", size: "md", onClick: () => closeModal(), children: "Cancel" }), _jsx(Button, { variant: "destructive", size: "md", onClick: () => {
463
+ onDeleteSection(section.id);
464
+ closeModal();
465
+ }, children: "Confirm" })] })] })));
466
+ } : undefined, children: _jsx(Component, { content: section, options: "options" in section ? section.options : undefined, onChange: editingEnabled ? (newContent) => onSectionChange(section.id, newContent) : undefined, isEditMode: isEditMode, openModal: editingEnabled ? openModal : undefined }) }) }) })] }, section.id));
467
+ }), editingEnabled && pendingInsertIndex === sections.length && (_jsx(SectionSkeleton, { types: typeOptions, onSelect: (type) => {
468
+ onAddSection(sections.length, type);
469
+ setPendingInsertIndex(null);
470
+ }, onDismiss: dismissPendingInsert }))] }));
471
+ }
472
+ function GlobalModal() {
473
+ const { modalState, closeModal } = useEditorModal();
474
+ return (_jsx(EditorModal, { isOpen: modalState !== null, onClose: closeModal, title: modalState?.title ?? "", children: modalState?.content }));
475
+ }
476
+ function EditorToolbar({ localChangesExist, isPublishing, publishFeedback, onPublish, onDiscardClick, onSettingsClick, onMediaClick, processingItems, }) {
477
+ const { isEditMode, toggleEditMode } = useEditorContext();
478
+ return (_jsxs(_Fragment, { children: [isEditMode && (_jsxs("div", { className: "fixed top-0 right-0 left-0 z-50 flex items-center justify-between border-b border-base-200 bg-base px-4 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [publishFeedback && (_jsx("span", { className: cn("text-xs font-medium", publishFeedback === "Published" ? "text-green-600" : "text-red-600"), children: publishFeedback })), localChangesExist && (_jsx(Button, { type: "button", variant: "primary", onClick: onPublish, isLoading: isPublishing, loadingLabel: "Publishing...", children: "Publish" })), localChangesExist && (_jsx(Button, { type: "button", variant: "destructive", onClick: onDiscardClick, disabled: isPublishing, children: "Discard Changes" }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ProcessingIndicator, { items: processingItems }), _jsx(IconButton, { icon: _jsx(ImageIcon, { size: 16 }), label: "Media library", size: "md", onClick: onMediaClick, className: "border border-base-200 bg-base-accent" }), _jsx(IconButton, { icon: _jsx(SettingsIcon, { size: 16 }), label: "Site settings", size: "md", onClick: onSettingsClick, className: "border border-base-200 bg-base-accent" }), _jsx(ShowAllChromeToggle, {})] })] })), _jsx("button", { onClick: toggleEditMode, className: "cursor-pointer fixed bottom-4 right-4 z-50 flex h-10 w-10 items-center justify-center rounded-full bg-primary text-primary-contrast shadow-lg hover:opacity-90 transition-opacity", "aria-label": isEditMode ? "Switch to view mode" : "Switch to edit mode", children: isEditMode ? (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: [_jsx("path", { d: "M10 12a2 2 0 100-4 2 2 0 000 4z" }), _jsx("path", { fillRule: "evenodd", d: "M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z", clipRule: "evenodd" })] })) : (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { d: "M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" }) })) })] }));
479
+ }
480
+ function ShowAllChromeToggle() {
481
+ const { showAllChrome, toggleShowAllChrome } = useEditorContext();
482
+ return (_jsx(Button, { variant: "secondary", size: "sm", onClick: toggleShowAllChrome, className: "bg-base-accent", "aria-label": "Toggle editor chrome visibility", children: showAllChrome ? "Hide Controls" : "Show Controls" }));
483
+ }
@@ -0,0 +1,14 @@
1
+ import type { MediaManifest, MediaItem } from "../../media/types";
2
+ import type { SiteConfig } from "../../schemas/site-config";
3
+ export interface MediaLibraryContextValue {
4
+ openSelectModal: (onSelect: (imageId: string) => void) => void;
5
+ uploadFile: (file: File) => void;
6
+ uploadFileWithCallback: (file: File, onComplete: (imageId: string) => void) => string;
7
+ manifest: MediaManifest;
8
+ pendingItems: MediaItem[];
9
+ pendingLocalUrls: Record<string, string>;
10
+ siteConfig: SiteConfig | null;
11
+ }
12
+ export declare const MediaLibraryContext: import("react").Context<MediaLibraryContextValue | null>;
13
+ export declare function useMediaLibrary(): MediaLibraryContextValue | null;
14
+ //# sourceMappingURL=MediaLibraryContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaLibraryContext.d.ts","sourceRoot":"","sources":["../../../src/components/shell/MediaLibraryContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IAC/D,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACjC,sBAAsB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,CAAC;IACtF,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,mBAAmB,0DAAuD,CAAC;AAExF,wBAAgB,eAAe,IAAI,wBAAwB,GAAG,IAAI,CAEjE"}
@@ -0,0 +1,5 @@
1
+ import { createContext, useContext } from "react";
2
+ export const MediaLibraryContext = createContext(null);
3
+ export function useMediaLibrary() {
4
+ return useContext(MediaLibraryContext);
5
+ }
@@ -0,0 +1,14 @@
1
+ import type { MediaItem } from "../../media/types";
2
+ export interface MediaLibraryModalProps {
3
+ mode: "select" | "manage";
4
+ items: MediaItem[];
5
+ onSelect: (id: string) => void;
6
+ onUpload: (files: File[]) => void;
7
+ onDelete: (ids: string[]) => void;
8
+ onAltChange?: (id: string, alt: string) => void;
9
+ referenceCountMap: Record<string, number>;
10
+ localUrlMap?: Record<string, string>;
11
+ maxFileSize?: number;
12
+ }
13
+ export declare function MediaLibraryModal({ mode, items, onSelect, onUpload, onDelete, onAltChange, referenceCountMap, localUrlMap, maxFileSize, }: MediaLibraryModalProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=MediaLibraryModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaLibraryModal.d.ts","sourceRoot":"","sources":["../../../src/components/shell/MediaLibraryModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,mBAAmB,CAAC;AAG9D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA+ED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,WAAgB,EAChB,WAAW,GACZ,EAAE,sBAAsB,2CAuQxB"}