@prenta/admin 0.92.0 → 0.94.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 (425) hide show
  1. package/CHANGELOG.md +663 -0
  2. package/design-system/tokens.css +173 -71
  3. package/design-system/tokens.json +244 -63
  4. package/design-system/tokens.scss +203 -98
  5. package/design-system/tokens.tailwind.cjs +93 -38
  6. package/dist/AdminRoot.d.ts +27 -6
  7. package/dist/AdminRoot.d.ts.map +1 -1
  8. package/dist/AdminRoot.js.map +1 -1
  9. package/dist/__tests__/components/breakpoint-controls.render.test.d.ts +2 -0
  10. package/dist/__tests__/components/breakpoint-controls.render.test.d.ts.map +1 -0
  11. package/dist/__tests__/components/breakpoint-controls.render.test.js +51 -0
  12. package/dist/__tests__/components/breakpoint-controls.render.test.js.map +1 -0
  13. package/dist/__tests__/components/canvas-edit-tip.render.test.d.ts +2 -0
  14. package/dist/__tests__/components/canvas-edit-tip.render.test.d.ts.map +1 -0
  15. package/dist/__tests__/components/canvas-edit-tip.render.test.js +37 -0
  16. package/dist/__tests__/components/canvas-edit-tip.render.test.js.map +1 -0
  17. package/dist/__tests__/components/editor-rail.render.test.d.ts +2 -0
  18. package/dist/__tests__/components/editor-rail.render.test.d.ts.map +1 -0
  19. package/dist/__tests__/components/editor-rail.render.test.js +138 -0
  20. package/dist/__tests__/components/editor-rail.render.test.js.map +1 -0
  21. package/dist/__tests__/components/media-block.render.test.d.ts +2 -0
  22. package/dist/__tests__/components/media-block.render.test.d.ts.map +1 -0
  23. package/dist/__tests__/components/media-block.render.test.js +108 -0
  24. package/dist/__tests__/components/media-block.render.test.js.map +1 -0
  25. package/dist/__tests__/components/page-audit-panel.render.test.d.ts +2 -0
  26. package/dist/__tests__/components/page-audit-panel.render.test.d.ts.map +1 -0
  27. package/dist/__tests__/components/page-audit-panel.render.test.js +59 -0
  28. package/dist/__tests__/components/page-audit-panel.render.test.js.map +1 -0
  29. package/dist/__tests__/components/reflow-meter.render.test.d.ts +2 -0
  30. package/dist/__tests__/components/reflow-meter.render.test.d.ts.map +1 -0
  31. package/dist/__tests__/components/reflow-meter.render.test.js +94 -0
  32. package/dist/__tests__/components/reflow-meter.render.test.js.map +1 -0
  33. package/dist/__tests__/components/seo-char-count.test.js +24 -6
  34. package/dist/__tests__/components/seo-char-count.test.js.map +1 -1
  35. package/dist/__tests__/components/serp-preview.render.test.d.ts +2 -0
  36. package/dist/__tests__/components/serp-preview.render.test.d.ts.map +1 -0
  37. package/dist/__tests__/components/serp-preview.render.test.js +25 -0
  38. package/dist/__tests__/components/serp-preview.render.test.js.map +1 -0
  39. package/dist/__tests__/lib/breakpoints.test.d.ts +2 -0
  40. package/dist/__tests__/lib/breakpoints.test.d.ts.map +1 -0
  41. package/dist/__tests__/lib/breakpoints.test.js +67 -0
  42. package/dist/__tests__/lib/breakpoints.test.js.map +1 -0
  43. package/dist/__tests__/lib/canvas-edit-chrome.test.d.ts +2 -0
  44. package/dist/__tests__/lib/canvas-edit-chrome.test.d.ts.map +1 -0
  45. package/dist/__tests__/lib/canvas-edit-chrome.test.js +44 -0
  46. package/dist/__tests__/lib/canvas-edit-chrome.test.js.map +1 -0
  47. package/dist/__tests__/lib/media-format.test.d.ts +2 -0
  48. package/dist/__tests__/lib/media-format.test.d.ts.map +1 -0
  49. package/dist/__tests__/lib/media-format.test.js +70 -0
  50. package/dist/__tests__/lib/media-format.test.js.map +1 -0
  51. package/dist/__tests__/lib/page-audit-input.test.d.ts +2 -0
  52. package/dist/__tests__/lib/page-audit-input.test.d.ts.map +1 -0
  53. package/dist/__tests__/lib/page-audit-input.test.js +122 -0
  54. package/dist/__tests__/lib/page-audit-input.test.js.map +1 -0
  55. package/dist/__tests__/lib/page-editor-service.test.js +2 -0
  56. package/dist/__tests__/lib/page-editor-service.test.js.map +1 -1
  57. package/dist/__tests__/lib/page-redirect.test.d.ts +2 -0
  58. package/dist/__tests__/lib/page-redirect.test.d.ts.map +1 -0
  59. package/dist/__tests__/lib/page-redirect.test.js +26 -0
  60. package/dist/__tests__/lib/page-redirect.test.js.map +1 -0
  61. package/dist/__tests__/lib/rail-width.test.d.ts +2 -0
  62. package/dist/__tests__/lib/rail-width.test.d.ts.map +1 -0
  63. package/dist/__tests__/lib/rail-width.test.js +69 -0
  64. package/dist/__tests__/lib/rail-width.test.js.map +1 -0
  65. package/dist/__tests__/lib/reflow-baseline.test.d.ts +2 -0
  66. package/dist/__tests__/lib/reflow-baseline.test.d.ts.map +1 -0
  67. package/dist/__tests__/lib/reflow-baseline.test.js +56 -0
  68. package/dist/__tests__/lib/reflow-baseline.test.js.map +1 -0
  69. package/dist/__tests__/lib/reflow-probe.test.d.ts +2 -0
  70. package/dist/__tests__/lib/reflow-probe.test.d.ts.map +1 -0
  71. package/dist/__tests__/lib/reflow-probe.test.js +73 -0
  72. package/dist/__tests__/lib/reflow-probe.test.js.map +1 -0
  73. package/dist/__tests__/lib/version-diff.test.d.ts +2 -0
  74. package/dist/__tests__/lib/version-diff.test.d.ts.map +1 -0
  75. package/dist/__tests__/lib/version-diff.test.js +230 -0
  76. package/dist/__tests__/lib/version-diff.test.js.map +1 -0
  77. package/dist/__tests__/lib/version-history.test.d.ts +2 -0
  78. package/dist/__tests__/lib/version-history.test.d.ts.map +1 -0
  79. package/dist/__tests__/lib/version-history.test.js +125 -0
  80. package/dist/__tests__/lib/version-history.test.js.map +1 -0
  81. package/dist/__tests__/styles/canvas-container-queries.test.d.ts +2 -0
  82. package/dist/__tests__/styles/canvas-container-queries.test.d.ts.map +1 -0
  83. package/dist/__tests__/styles/canvas-container-queries.test.js +87 -0
  84. package/dist/__tests__/styles/canvas-container-queries.test.js.map +1 -0
  85. package/dist/__tests__/styles/packaging.test.d.ts +2 -0
  86. package/dist/__tests__/styles/packaging.test.d.ts.map +1 -0
  87. package/dist/__tests__/styles/packaging.test.js +31 -0
  88. package/dist/__tests__/styles/packaging.test.js.map +1 -0
  89. package/dist/__tests__/styles/responsive-layer.test.d.ts +2 -0
  90. package/dist/__tests__/styles/responsive-layer.test.d.ts.map +1 -0
  91. package/dist/__tests__/styles/responsive-layer.test.js +127 -0
  92. package/dist/__tests__/styles/responsive-layer.test.js.map +1 -0
  93. package/dist/__tests__/styles/tokens-drift.test.d.ts +2 -0
  94. package/dist/__tests__/styles/tokens-drift.test.d.ts.map +1 -0
  95. package/dist/__tests__/styles/tokens-drift.test.js +92 -0
  96. package/dist/__tests__/styles/tokens-drift.test.js.map +1 -0
  97. package/dist/__tests__/views/admin-renderer-compat.test.d.ts +2 -0
  98. package/dist/__tests__/views/admin-renderer-compat.test.d.ts.map +1 -0
  99. package/dist/__tests__/views/admin-renderer-compat.test.js +43 -0
  100. package/dist/__tests__/views/admin-renderer-compat.test.js.map +1 -0
  101. package/dist/__tests__/views/admin-section-renderers.test.js +52 -4
  102. package/dist/__tests__/views/admin-section-renderers.test.js.map +1 -1
  103. package/dist/__tests__/views/canvas-review-mode.render.test.d.ts +2 -0
  104. package/dist/__tests__/views/canvas-review-mode.render.test.d.ts.map +1 -0
  105. package/dist/__tests__/views/canvas-review-mode.render.test.js +70 -0
  106. package/dist/__tests__/views/canvas-review-mode.render.test.js.map +1 -0
  107. package/dist/__tests__/views/editor-top-bar.render.test.js +30 -1
  108. package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
  109. package/dist/__tests__/views/page-tab.render.test.d.ts +2 -0
  110. package/dist/__tests__/views/page-tab.render.test.d.ts.map +1 -0
  111. package/dist/__tests__/views/page-tab.render.test.js +151 -0
  112. package/dist/__tests__/views/page-tab.render.test.js.map +1 -0
  113. package/dist/__tests__/views/section-class-parity.test.d.ts +2 -0
  114. package/dist/__tests__/views/section-class-parity.test.d.ts.map +1 -0
  115. package/dist/__tests__/views/section-class-parity.test.js +81 -0
  116. package/dist/__tests__/views/section-class-parity.test.js.map +1 -0
  117. package/dist/__tests__/views/sections-panel-design-owned.render.test.d.ts +2 -0
  118. package/dist/__tests__/views/sections-panel-design-owned.render.test.d.ts.map +1 -0
  119. package/dist/__tests__/views/sections-panel-design-owned.render.test.js +86 -0
  120. package/dist/__tests__/views/sections-panel-design-owned.render.test.js.map +1 -0
  121. package/dist/__tests__/views/version-history-panel.render.test.d.ts +2 -0
  122. package/dist/__tests__/views/version-history-panel.render.test.d.ts.map +1 -0
  123. package/dist/__tests__/views/version-history-panel.render.test.js +153 -0
  124. package/dist/__tests__/views/version-history-panel.render.test.js.map +1 -0
  125. package/dist/components/BreakpointPicker.d.ts +18 -0
  126. package/dist/components/BreakpointPicker.d.ts.map +1 -0
  127. package/dist/components/BreakpointPicker.js +31 -0
  128. package/dist/components/BreakpointPicker.js.map +1 -0
  129. package/dist/components/CanvasEditTip.d.ts +6 -0
  130. package/dist/components/CanvasEditTip.d.ts.map +1 -0
  131. package/dist/components/CanvasEditTip.js +22 -0
  132. package/dist/components/CanvasEditTip.js.map +1 -0
  133. package/dist/components/EditorRail.d.ts +36 -0
  134. package/dist/components/EditorRail.d.ts.map +1 -0
  135. package/dist/components/EditorRail.js +104 -0
  136. package/dist/components/EditorRail.js.map +1 -0
  137. package/dist/components/EditorRailTabs.d.ts +32 -0
  138. package/dist/components/EditorRailTabs.d.ts.map +1 -0
  139. package/dist/components/EditorRailTabs.js +45 -0
  140. package/dist/components/EditorRailTabs.js.map +1 -0
  141. package/dist/components/MediaBlock.d.ts +49 -0
  142. package/dist/components/MediaBlock.d.ts.map +1 -0
  143. package/dist/components/MediaBlock.js +50 -0
  144. package/dist/components/MediaBlock.js.map +1 -0
  145. package/dist/components/ReflowMeter.d.ts +28 -0
  146. package/dist/components/ReflowMeter.d.ts.map +1 -0
  147. package/dist/components/ReflowMeter.js +42 -0
  148. package/dist/components/ReflowMeter.js.map +1 -0
  149. package/dist/components/ZoomChip.d.ts +17 -0
  150. package/dist/components/ZoomChip.d.ts.map +1 -0
  151. package/dist/components/ZoomChip.js +17 -0
  152. package/dist/components/ZoomChip.js.map +1 -0
  153. package/dist/components/breakpoint-icons.d.ts +3 -0
  154. package/dist/components/breakpoint-icons.d.ts.map +1 -0
  155. package/dist/components/breakpoint-icons.js +16 -0
  156. package/dist/components/breakpoint-icons.js.map +1 -0
  157. package/dist/components/page-tab/AuthorPicker.d.ts +31 -0
  158. package/dist/components/page-tab/AuthorPicker.d.ts.map +1 -0
  159. package/dist/components/page-tab/AuthorPicker.js +95 -0
  160. package/dist/components/page-tab/AuthorPicker.js.map +1 -0
  161. package/dist/components/page-tab/DirectiveSwitch.d.ts +38 -0
  162. package/dist/components/page-tab/DirectiveSwitch.d.ts.map +1 -0
  163. package/dist/components/page-tab/DirectiveSwitch.js +33 -0
  164. package/dist/components/page-tab/DirectiveSwitch.js.map +1 -0
  165. package/dist/components/seo/EditorSeoScoreBadge.d.ts +8 -1
  166. package/dist/components/seo/EditorSeoScoreBadge.d.ts.map +1 -1
  167. package/dist/components/seo/EditorSeoScoreBadge.js +2 -2
  168. package/dist/components/seo/EditorSeoScoreBadge.js.map +1 -1
  169. package/dist/components/seo/PageAuditPanel.d.ts +14 -0
  170. package/dist/components/seo/PageAuditPanel.d.ts.map +1 -0
  171. package/dist/components/seo/PageAuditPanel.js +59 -0
  172. package/dist/components/seo/PageAuditPanel.js.map +1 -0
  173. package/dist/components/seo/SeoCharCount.d.ts +19 -7
  174. package/dist/components/seo/SeoCharCount.d.ts.map +1 -1
  175. package/dist/components/seo/SeoCharCount.js +30 -16
  176. package/dist/components/seo/SeoCharCount.js.map +1 -1
  177. package/dist/components/seo/SeoEditorPane.d.ts +15 -1
  178. package/dist/components/seo/SeoEditorPane.d.ts.map +1 -1
  179. package/dist/components/seo/SeoEditorPane.js +118 -21
  180. package/dist/components/seo/SeoEditorPane.js.map +1 -1
  181. package/dist/components/seo/SerpPreview.d.ts +20 -0
  182. package/dist/components/seo/SerpPreview.d.ts.map +1 -0
  183. package/dist/components/seo/SerpPreview.js +6 -0
  184. package/dist/components/seo/SerpPreview.js.map +1 -0
  185. package/dist/hooks/usePageAudit.d.ts +41 -0
  186. package/dist/hooks/usePageAudit.d.ts.map +1 -0
  187. package/dist/hooks/usePageAudit.js +68 -0
  188. package/dist/hooks/usePageAudit.js.map +1 -0
  189. package/dist/hooks/useReflowGuard.d.ts +47 -0
  190. package/dist/hooks/useReflowGuard.d.ts.map +1 -0
  191. package/dist/hooks/useReflowGuard.js +52 -0
  192. package/dist/hooks/useReflowGuard.js.map +1 -0
  193. package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
  194. package/dist/layout/primitives/AdminShell.js +2 -2
  195. package/dist/layout/primitives/AdminShell.js.map +1 -1
  196. package/dist/lib/breakpoints.d.ts +51 -0
  197. package/dist/lib/breakpoints.d.ts.map +1 -0
  198. package/dist/lib/breakpoints.js +84 -0
  199. package/dist/lib/breakpoints.js.map +1 -0
  200. package/dist/lib/canvas-edit-chrome.d.ts +22 -0
  201. package/dist/lib/canvas-edit-chrome.d.ts.map +1 -0
  202. package/dist/lib/canvas-edit-chrome.js +81 -0
  203. package/dist/lib/canvas-edit-chrome.js.map +1 -0
  204. package/dist/lib/media-format.d.ts +55 -0
  205. package/dist/lib/media-format.d.ts.map +1 -0
  206. package/dist/lib/media-format.js +93 -0
  207. package/dist/lib/media-format.js.map +1 -0
  208. package/dist/lib/page-audit-input.d.ts +45 -0
  209. package/dist/lib/page-audit-input.d.ts.map +1 -0
  210. package/dist/lib/page-audit-input.js +53 -0
  211. package/dist/lib/page-audit-input.js.map +1 -0
  212. package/dist/lib/page-editor-service.d.ts +12 -0
  213. package/dist/lib/page-editor-service.d.ts.map +1 -1
  214. package/dist/lib/page-editor-service.js +6 -0
  215. package/dist/lib/page-editor-service.js.map +1 -1
  216. package/dist/lib/page-redirect.d.ts +39 -0
  217. package/dist/lib/page-redirect.d.ts.map +1 -0
  218. package/dist/lib/page-redirect.js +38 -0
  219. package/dist/lib/page-redirect.js.map +1 -0
  220. package/dist/lib/rail-width.d.ts +23 -0
  221. package/dist/lib/rail-width.d.ts.map +1 -0
  222. package/dist/lib/rail-width.js +59 -0
  223. package/dist/lib/rail-width.js.map +1 -0
  224. package/dist/lib/reflow-baseline.d.ts +45 -0
  225. package/dist/lib/reflow-baseline.d.ts.map +1 -0
  226. package/dist/lib/reflow-baseline.js +38 -0
  227. package/dist/lib/reflow-baseline.js.map +1 -0
  228. package/dist/lib/reflow-probe.d.ts +159 -0
  229. package/dist/lib/reflow-probe.d.ts.map +1 -0
  230. package/dist/lib/reflow-probe.js +228 -0
  231. package/dist/lib/reflow-probe.js.map +1 -0
  232. package/dist/lib/seo-service.d.ts +10 -0
  233. package/dist/lib/seo-service.d.ts.map +1 -1
  234. package/dist/lib/seo-service.js.map +1 -1
  235. package/dist/lib/version-diff.d.ts +50 -0
  236. package/dist/lib/version-diff.d.ts.map +1 -0
  237. package/dist/lib/version-diff.js +294 -0
  238. package/dist/lib/version-diff.js.map +1 -0
  239. package/dist/lib/version-history.d.ts +73 -0
  240. package/dist/lib/version-history.d.ts.map +1 -0
  241. package/dist/lib/version-history.js +126 -0
  242. package/dist/lib/version-history.js.map +1 -0
  243. package/dist/prenta-admin.css +1 -1
  244. package/dist/views/page-editor/CanvasMetaLine.d.ts +19 -0
  245. package/dist/views/page-editor/CanvasMetaLine.d.ts.map +1 -0
  246. package/dist/views/page-editor/CanvasMetaLine.js +23 -0
  247. package/dist/views/page-editor/CanvasMetaLine.js.map +1 -0
  248. package/dist/views/page-editor/EditorCanvas.d.ts +47 -8
  249. package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
  250. package/dist/views/page-editor/EditorCanvas.js +68 -34
  251. package/dist/views/page-editor/EditorCanvas.js.map +1 -1
  252. package/dist/views/page-editor/EditorTopBar.d.ts +21 -2
  253. package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
  254. package/dist/views/page-editor/EditorTopBar.js +13 -20
  255. package/dist/views/page-editor/EditorTopBar.js.map +1 -1
  256. package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
  257. package/dist/views/page-editor/PageSectionEditor.js +383 -78
  258. package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
  259. package/dist/views/page-editor/PageTab.d.ts +36 -0
  260. package/dist/views/page-editor/PageTab.d.ts.map +1 -0
  261. package/dist/views/page-editor/PageTab.js +65 -0
  262. package/dist/views/page-editor/PageTab.js.map +1 -0
  263. package/dist/views/page-editor/ReviewBar.d.ts +21 -0
  264. package/dist/views/page-editor/ReviewBar.d.ts.map +1 -0
  265. package/dist/views/page-editor/ReviewBar.js +22 -0
  266. package/dist/views/page-editor/ReviewBar.js.map +1 -0
  267. package/dist/views/page-editor/SectionInspector.d.ts.map +1 -1
  268. package/dist/views/page-editor/SectionInspector.js +64 -20
  269. package/dist/views/page-editor/SectionInspector.js.map +1 -1
  270. package/dist/views/page-editor/SectionsPanel.d.ts +30 -5
  271. package/dist/views/page-editor/SectionsPanel.d.ts.map +1 -1
  272. package/dist/views/page-editor/SectionsPanel.js +38 -7
  273. package/dist/views/page-editor/SectionsPanel.js.map +1 -1
  274. package/dist/views/page-editor/SitePreviewFrame.d.ts.map +1 -1
  275. package/dist/views/page-editor/SitePreviewFrame.js +3 -0
  276. package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
  277. package/dist/views/page-editor/VersionHistoryPanel.d.ts +29 -0
  278. package/dist/views/page-editor/VersionHistoryPanel.d.ts.map +1 -0
  279. package/dist/views/page-editor/VersionHistoryPanel.js +81 -0
  280. package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -0
  281. package/dist/views/page-editor/reflow-context.d.ts +28 -0
  282. package/dist/views/page-editor/reflow-context.d.ts.map +1 -0
  283. package/dist/views/page-editor/reflow-context.js +14 -0
  284. package/dist/views/page-editor/reflow-context.js.map +1 -0
  285. package/dist/views/page-editor/sections/ByTheNumbersSection.d.ts.map +1 -1
  286. package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
  287. package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
  288. package/dist/views/page-editor/sections/CtaBannerSection.d.ts.map +1 -1
  289. package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
  290. package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
  291. package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -1
  292. package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
  293. package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
  294. package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -1
  295. package/dist/views/page-editor/sections/GallerySection.js +7 -3
  296. package/dist/views/page-editor/sections/GallerySection.js.map +1 -1
  297. package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
  298. package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
  299. package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -1
  300. package/dist/views/page-editor/sections/MissionSection.js +1 -1
  301. package/dist/views/page-editor/sections/MissionSection.js.map +1 -1
  302. package/dist/views/page-editor/sections/PullQuoteSection.d.ts.map +1 -1
  303. package/dist/views/page-editor/sections/PullQuoteSection.js +1 -1
  304. package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -1
  305. package/dist/views/page-editor/sections/RelatedPostsSection.d.ts.map +1 -1
  306. package/dist/views/page-editor/sections/RelatedPostsSection.js +1 -1
  307. package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -1
  308. package/dist/views/page-editor/sections/SectionRenderer.d.ts +13 -1
  309. package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -1
  310. package/dist/views/page-editor/sections/SectionRenderer.js +66 -26
  311. package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
  312. package/dist/views/page-editor/sections/admin-renderers.d.ts +47 -15
  313. package/dist/views/page-editor/sections/admin-renderers.d.ts.map +1 -1
  314. package/dist/views/page-editor/sections/admin-renderers.js +27 -15
  315. package/dist/views/page-editor/sections/admin-renderers.js.map +1 -1
  316. package/dist/views/page-editor/sections/parts.d.ts +0 -1
  317. package/dist/views/page-editor/sections/parts.d.ts.map +1 -1
  318. package/dist/views/page-editor/sections/parts.js +41 -16
  319. package/dist/views/page-editor/sections/parts.js.map +1 -1
  320. package/dist/views/page-editor/viewports.d.ts +7 -14
  321. package/dist/views/page-editor/viewports.d.ts.map +1 -1
  322. package/dist/views/page-editor/viewports.js +7 -12
  323. package/dist/views/page-editor/viewports.js.map +1 -1
  324. package/dist/views/post-editor/PostEditorCanvas.d.ts +2 -1
  325. package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -1
  326. package/dist/views/post-editor/PostEditorCanvas.js +5 -2
  327. package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
  328. package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
  329. package/dist/views/post-editor/PostSectionEditor.js +2 -20
  330. package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
  331. package/dist/views/post-editor/PostTemplateEditor.d.ts.map +1 -1
  332. package/dist/views/post-editor/PostTemplateEditor.js +4 -1
  333. package/dist/views/post-editor/PostTemplateEditor.js.map +1 -1
  334. package/package.json +5 -3
  335. package/src/AdminRoot.tsx +27 -6
  336. package/src/__tests__/components/breakpoint-controls.render.test.tsx +57 -0
  337. package/src/__tests__/components/canvas-edit-tip.render.test.tsx +41 -0
  338. package/src/__tests__/components/editor-rail.render.test.tsx +192 -0
  339. package/src/__tests__/components/media-block.render.test.tsx +126 -0
  340. package/src/__tests__/components/page-audit-panel.render.test.tsx +64 -0
  341. package/src/__tests__/components/reflow-meter.render.test.tsx +144 -0
  342. package/src/__tests__/components/seo-char-count.test.tsx +26 -6
  343. package/src/__tests__/components/serp-preview.render.test.tsx +32 -0
  344. package/src/__tests__/lib/breakpoints.test.ts +84 -0
  345. package/src/__tests__/lib/canvas-edit-chrome.test.ts +56 -0
  346. package/src/__tests__/lib/media-format.test.ts +89 -0
  347. package/src/__tests__/lib/page-audit-input.test.ts +144 -0
  348. package/src/__tests__/lib/page-editor-service.test.ts +2 -0
  349. package/src/__tests__/lib/page-redirect.test.ts +29 -0
  350. package/src/__tests__/lib/rail-width.test.ts +86 -0
  351. package/src/__tests__/lib/reflow-baseline.test.ts +64 -0
  352. package/src/__tests__/lib/reflow-probe.test.ts +95 -0
  353. package/src/__tests__/lib/version-diff.test.ts +278 -0
  354. package/src/__tests__/lib/version-history.test.ts +166 -0
  355. package/src/__tests__/styles/canvas-container-queries.test.ts +103 -0
  356. package/src/__tests__/styles/packaging.test.ts +38 -0
  357. package/src/__tests__/styles/responsive-layer.test.ts +152 -0
  358. package/src/__tests__/styles/tokens-drift.test.ts +110 -0
  359. package/src/__tests__/views/admin-renderer-compat.test.ts +48 -0
  360. package/src/__tests__/views/admin-section-renderers.test.tsx +70 -4
  361. package/src/__tests__/views/canvas-review-mode.render.test.tsx +94 -0
  362. package/src/__tests__/views/editor-top-bar.render.test.tsx +43 -1
  363. package/src/__tests__/views/page-tab.render.test.tsx +226 -0
  364. package/src/__tests__/views/section-class-parity.test.ts +98 -0
  365. package/src/__tests__/views/sections-panel-design-owned.render.test.tsx +104 -0
  366. package/src/__tests__/views/version-history-panel.render.test.tsx +195 -0
  367. package/src/components/BreakpointPicker.tsx +114 -0
  368. package/src/components/CanvasEditTip.tsx +46 -0
  369. package/src/components/EditorRail.tsx +219 -0
  370. package/src/components/EditorRailTabs.tsx +117 -0
  371. package/src/components/MediaBlock.tsx +223 -0
  372. package/src/components/ReflowMeter.tsx +125 -0
  373. package/src/components/ZoomChip.tsx +39 -0
  374. package/src/components/breakpoint-icons.ts +17 -0
  375. package/src/components/page-tab/AuthorPicker.tsx +240 -0
  376. package/src/components/page-tab/DirectiveSwitch.tsx +89 -0
  377. package/src/components/seo/EditorSeoScoreBadge.tsx +9 -1
  378. package/src/components/seo/PageAuditPanel.tsx +192 -0
  379. package/src/components/seo/SeoCharCount.tsx +55 -24
  380. package/src/components/seo/SeoEditorPane.tsx +213 -31
  381. package/src/components/seo/SerpPreview.tsx +41 -0
  382. package/src/hooks/usePageAudit.ts +98 -0
  383. package/src/hooks/useReflowGuard.ts +96 -0
  384. package/src/layout/primitives/AdminShell.tsx +13 -1
  385. package/src/lib/breakpoints.ts +107 -0
  386. package/src/lib/canvas-edit-chrome.ts +82 -0
  387. package/src/lib/media-format.ts +99 -0
  388. package/src/lib/page-audit-input.ts +104 -0
  389. package/src/lib/page-editor-service.ts +18 -0
  390. package/src/lib/page-redirect.ts +60 -0
  391. package/src/lib/rail-width.ts +58 -0
  392. package/src/lib/reflow-baseline.ts +70 -0
  393. package/src/lib/reflow-probe.ts +299 -0
  394. package/src/lib/seo-service.ts +10 -0
  395. package/src/lib/version-diff.ts +376 -0
  396. package/src/lib/version-history.ts +192 -0
  397. package/src/styles/prenta-tokens.css +120 -42
  398. package/src/styles/responsive.css +281 -0
  399. package/src/styles/theme.css +138 -0
  400. package/src/views/page-editor/CanvasMetaLine.tsx +50 -0
  401. package/src/views/page-editor/EditorCanvas.tsx +140 -54
  402. package/src/views/page-editor/EditorTopBar.tsx +55 -51
  403. package/src/views/page-editor/PageSectionEditor.tsx +575 -185
  404. package/src/views/page-editor/PageTab.tsx +433 -0
  405. package/src/views/page-editor/ReviewBar.tsx +76 -0
  406. package/src/views/page-editor/SectionInspector.tsx +84 -42
  407. package/src/views/page-editor/SectionsPanel.tsx +282 -141
  408. package/src/views/page-editor/SitePreviewFrame.tsx +3 -0
  409. package/src/views/page-editor/VersionHistoryPanel.tsx +302 -0
  410. package/src/views/page-editor/reflow-context.ts +43 -0
  411. package/src/views/page-editor/sections/ByTheNumbersSection.tsx +3 -2
  412. package/src/views/page-editor/sections/CtaBannerSection.tsx +3 -1
  413. package/src/views/page-editor/sections/FeatureHighlightSection.tsx +3 -2
  414. package/src/views/page-editor/sections/GallerySection.tsx +7 -3
  415. package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
  416. package/src/views/page-editor/sections/MissionSection.tsx +4 -2
  417. package/src/views/page-editor/sections/PullQuoteSection.tsx +3 -1
  418. package/src/views/page-editor/sections/RelatedPostsSection.tsx +2 -1
  419. package/src/views/page-editor/sections/SectionRenderer.tsx +115 -34
  420. package/src/views/page-editor/sections/admin-renderers.tsx +54 -15
  421. package/src/views/page-editor/sections/parts.tsx +46 -18
  422. package/src/views/page-editor/viewports.ts +13 -26
  423. package/src/views/post-editor/PostEditorCanvas.tsx +18 -11
  424. package/src/views/post-editor/PostSectionEditor.tsx +1 -56
  425. package/src/views/post-editor/PostTemplateEditor.tsx +3 -0
@@ -1,29 +1,36 @@
1
1
  'use client'
2
2
 
3
3
  /**
4
- * Pluggable canvas renderers for custom section types.
4
+ * Pluggable canvas renderers for the editor canvas and the eye preview.
5
5
  *
6
- * By default the editor canvas renders custom (config-declared) and unmanaged
7
- * section types as structural placeholders. Projects that want a real design
8
- * preview inside the admin can pass renderers to `<AdminRoot
9
- * sectionRenderers={...}>`; the canvas and the eye preview then use them in
10
- * place of the placeholder.
6
+ * RESOLUTION ORDER supplied renderer built-in placeholder.
7
+ *
8
+ * A renderer passed to `<AdminRoot sectionRenderers>` wins for EVERY section
9
+ * type, including the built-ins. Before v0.93 the map was consulted only for
10
+ * types the canvas did not already know, so a consumer passing the public
11
+ * renderer map had their hero, text, feature, stats and cta silently ignored
12
+ * while the canvas rendered the admin's own approximations — different font
13
+ * size, weight and breakpoints — and presented itself as a preview.
14
+ *
15
+ * With nothing supplied, built-in types fall back to those approximations and
16
+ * custom (config-declared) or unmanaged types render as a structural
17
+ * placeholder.
11
18
  *
12
19
  * The renderer signature is a structural mirror of `SectionRenderer` from
13
- * `@prenta/sections-react` (cms-admin depends on cms-core only, so the
14
- * type is duplicated rather than imported). Because the shapes match, a
15
- * consumer can hand `AdminRoot` the exact same components it registers for
16
- * the public site:
20
+ * `@prenta/sections-react` (cms-admin depends on cms-core only, so the type is
21
+ * duplicated rather than imported). `admin-renderer-compat.test.ts` performs
22
+ * the assignment that keeps the two shapes compatible.
17
23
  *
18
24
  * ```tsx
19
- * import { OPAL_RENDERERS } from './sections' // SectionRendererMap
20
- * <AdminRoot sectionRenderers={OPAL_RENDERERS} ... />
25
+ * import { DEFAULT_SECTION_RENDERERS } from '@prenta/sections-react'
26
+ * import { OPAL_RENDERERS } from './sections'
27
+ * <AdminRoot sectionRenderers={{ ...DEFAULT_SECTION_RENDERERS, ...OPAL_RENDERERS }} />
21
28
  * ```
22
29
  *
23
30
  * Renderers run inside the admin bundle, so they must be client-safe (no
24
- * server-only imports). Each one is wrapped in an error boundary — a throwing
25
- * renderer falls back to the structural placeholder instead of taking down
26
- * the editor.
31
+ * server-only imports). Each is wrapped in an error boundary — a throwing
32
+ * renderer falls back to the built-in for that type, or to the placeholder if
33
+ * the type has no built-in, instead of taking down the editor.
27
34
  */
28
35
  import { createContext, useContext, type ReactNode } from 'react'
29
36
 
@@ -50,6 +57,16 @@ export interface AdminSectionPostContext {
50
57
  relatedPosts?: Array<{ title: string; url?: string; excerpt?: string }>
51
58
  }
52
59
 
60
+ /**
61
+ * Structural mirror of `LcpController`. The canvas has no Largest-Contentful-
62
+ * Paint budget to protect, but sections-react renderers call `claim()` during
63
+ * render, so the shape must exist or a real renderer throws on its first image.
64
+ */
65
+ export interface AdminLcpController {
66
+ claim(): boolean
67
+ readonly claimed: boolean
68
+ }
69
+
53
70
  /** Props passed to an admin section renderer (mirrors `SectionRendererProps`). */
54
71
  export interface AdminSectionRendererProps {
55
72
  section: {
@@ -65,6 +82,23 @@ export interface AdminSectionRendererProps {
65
82
  sanitizeHtml: (html: string) => string
66
83
  baseUrl: string
67
84
  renderImage: (props: AdminRenderImageProps) => ReactNode
85
+ /** Mirrors `ResolvedRenderOptions.lcp`. */
86
+ lcp: AdminLcpController
87
+ /**
88
+ * Mirrors `ResolvedRenderOptions.prefetchedForms`. Always empty in the
89
+ * canvas: the admin does not prefetch form schemas, so a form section
90
+ * falls back to its client island exactly as an un-prefetched page does.
91
+ *
92
+ * Typed `any` rather than `unknown` deliberately. Renderers are function
93
+ * types, so `strictFunctionTypes` compares their parameters
94
+ * contravariantly — a `Record<string, unknown>` here would make
95
+ * `SectionRendererMap` from @prenta/sections-react UNASSIGNABLE to this
96
+ * map, defeating the entire point of the mirror. The value is never read
97
+ * in the canvas, so the looser type costs nothing.
98
+ * See `admin-renderer-compat.test.ts`.
99
+ */
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ prefetchedForms: Record<string, any>
68
102
  }
69
103
  }
70
104
 
@@ -83,6 +117,11 @@ export type AdminSectionRendererMap = Record<string, AdminSectionRenderer>
83
117
  export const ADMIN_RENDER_OPTIONS: AdminSectionRendererProps['options'] = {
84
118
  sanitizeHtml: (html) => html,
85
119
  baseUrl: '',
120
+ // Never grants the priority slot. On a public page exactly one image may
121
+ // load eagerly; in the canvas nothing competes for bandwidth and every
122
+ // image should lazy-load, so `claim()` always declines.
123
+ lcp: { claim: () => false, claimed: true },
124
+ prefetchedForms: {},
86
125
  renderImage: ({ src, alt, className, priority, width, height }) => (
87
126
  <img
88
127
  src={src}
@@ -9,6 +9,11 @@
9
9
  * page; the surrounding editor UI still uses the admin design tokens.
10
10
  */
11
11
  import type { SectionSettings } from '../section-types.js'
12
+ import {
13
+ backgroundPreset,
14
+ isDarkBackground as coreIsDarkBackground,
15
+ type BackgroundPreset,
16
+ } from '@prenta/core/page-sections'
12
17
 
13
18
  /**
14
19
  * Live post data passed to the post-oriented section renderers
@@ -46,33 +51,54 @@ export function paddingClass(settings: SectionSettings): string {
46
51
  case 'md':
47
52
  return 'py-12'
48
53
  case 'xl':
49
- return 'py-20 sm:py-28'
54
+ return 'py-20 @pv-md:py-28 @pv-2xl:py-36'
50
55
  case 'lg':
51
56
  default:
52
- return 'py-16 sm:py-20'
57
+ return 'py-16 @pv-md:py-20 @pv-2xl:py-28'
53
58
  }
54
59
  }
55
60
 
56
61
  /** Returns true when the section background is the dark/purple treatment. */
57
62
  export function isDarkBackground(settings: SectionSettings): boolean {
58
- return (
59
- (settings.backgroundType === 'solid' || settings.backgroundType === 'gradient') &&
60
- settings.backgroundColor === 'purple'
61
- )
63
+ return coreIsDarkBackground(settings)
64
+ }
65
+
66
+ /**
67
+ * The canvas's section backgrounds — deliberately the SITE's palette, not the
68
+ * admin's theme tokens.
69
+ *
70
+ * ── Why not theme tokens ──────────────────────────────────────────────────
71
+ *
72
+ * They were, and it made the canvas lie. `bg-card` and `bg-brand` follow the
73
+ * admin's light/dark theme, so an editor working in dark mode saw a hero in
74
+ * `#9D71F0` and body sections on a dark surface — while the live page renders
75
+ * `violet-600` on white, whatever theme the editor happens to prefer. The
76
+ * canvas exists to show the page as visitors get it; tracking the chrome's
77
+ * theme is the one thing it must not do.
78
+ *
79
+ * In light mode this changes almost nothing: `--brand` resolves to `#7C3AED`,
80
+ * which is `violet-600`. The whole difference was in dark mode, which is
81
+ * exactly where it was least likely to be noticed.
82
+ *
83
+ * ── Why the strings are duplicated from sections-react ────────────────────
84
+ *
85
+ * They have to be. Tailwind generates utilities by scanning source text, and
86
+ * the admin's stylesheet scans only the admin's `src/` tree. Importing the
87
+ * literals from sections-react (or from core) would leave them generated by
88
+ * nobody, and every canvas section would render with no background — silently,
89
+ * with correct markup. `backgroundPreset` in core owns the DECISION so the two
90
+ * cannot diverge, the `Record` below is exhaustive over it, and
91
+ * `section-class-parity.test.ts` asserts the strings still match the site's.
92
+ */
93
+ const PRESET_CLASSES: Record<BackgroundPreset, string> = {
94
+ 'gradient-purple': 'bg-gradient-to-br from-violet-600 to-violet-700 text-white',
95
+ 'solid-purple': 'bg-violet-600 text-white',
96
+ 'solid-muted': 'bg-zinc-50 text-zinc-900',
97
+ plain: 'bg-white text-zinc-900',
62
98
  }
63
99
 
64
- /** Background utility classes derived from settings. */
65
100
  export function backgroundClass(settings: SectionSettings): string {
66
- if (settings.backgroundType === 'gradient' && settings.backgroundColor === 'purple') {
67
- return 'bg-gradient-to-br from-violet-600 to-violet-700 text-white'
68
- }
69
- if (settings.backgroundType === 'solid' && settings.backgroundColor === 'purple') {
70
- return 'bg-brand text-white'
71
- }
72
- if (settings.backgroundType === 'solid' && settings.backgroundColor === 'muted') {
73
- return 'bg-muted text-foreground'
74
- }
75
- return 'bg-card text-foreground'
101
+ return PRESET_CLASSES[backgroundPreset(settings)]
76
102
  }
77
103
 
78
104
  /**
@@ -90,8 +116,10 @@ export function PreviewButton({
90
116
  tone?: 'primary' | 'onDark' | 'ghost'
91
117
  }) {
92
118
  if (!label) return null
119
+ // Handoff: buttons go full width below 460. `w-full` on an inline-flex
120
+ // element still fills its line box, so the narrow case needs no extra wrapper.
93
121
  const base =
94
- 'inline-flex items-center justify-center rounded-lg px-5 py-2.5 text-sm font-medium transition-colors'
122
+ '@pv-sm:w-auto inline-flex w-full items-center justify-center rounded-lg px-5 py-2.5 text-sm font-medium transition-colors'
95
123
  const toneClass =
96
124
  tone === 'onDark'
97
125
  ? 'bg-card text-brand hover:bg-brand/10'
@@ -1,26 +1,13 @@
1
- /** Preview viewport presets for the page editor canvas. */
2
- export type ViewportId = '4k' | '1080p' | 'laptop' | 'tablet' | 'mobile'
3
-
4
- export interface Viewport {
5
- id: ViewportId
6
- label: string
7
- /** lucide-react icon name */
8
- icon: string
9
- /** logical CSS width of the preview surface, in px */
10
- width: number
11
- }
12
-
13
- export const VIEWPORTS: Viewport[] = [
14
- { id: '4k', label: '4K', icon: 'monitor', width: 1920 },
15
- { id: '1080p', label: '1080p', icon: 'monitor', width: 1440 },
16
- { id: 'laptop', label: 'Laptop', icon: 'laptop', width: 1280 },
17
- { id: 'tablet', label: 'Tablet', icon: 'tablet', width: 768 },
18
- { id: 'mobile', label: 'Mobile', icon: 'smartphone', width: 390 },
19
- ]
20
-
21
- /** Default working width — near 1:1 in a typical editor pane; device toggles scale-to-fit. */
22
- export const DEFAULT_VIEWPORT: ViewportId = '1080p'
23
-
24
- export function getViewport(id: ViewportId): Viewport {
25
- return VIEWPORTS.find((v) => v.id === id) ?? VIEWPORTS[1]!
26
- }
1
+ /**
2
+ * @deprecated Moved to `src/lib/breakpoints.ts` when the post editor adopted
3
+ * the same canvas — presets are shared editor infrastructure, not a page-editor
4
+ * detail. This module re-exports under the old names so nothing breaks
5
+ * mid-migration; import from `../../lib/breakpoints.js` in new code.
6
+ */
7
+ export {
8
+ BREAKPOINTS as VIEWPORTS,
9
+ DEFAULT_BREAKPOINT as DEFAULT_VIEWPORT,
10
+ getBreakpoint as getViewport,
11
+ type Breakpoint as Viewport,
12
+ type BreakpointId as ViewportId,
13
+ } from '../../lib/breakpoints.js'
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
4
4
  import { FileText, Plus } from 'lucide-react'
5
+ import { CanvasEditTip } from '../../components/CanvasEditTip.js'
5
6
  import type { PageSection, PostHeaderConfig } from '../../lib/post-editor-service.js'
6
7
  import { SectionRenderer, type PostRenderContext } from '../page-editor/sections/index.js'
7
8
  import { StructureNotice } from '../page-editor/StructureNotice.js'
@@ -15,7 +16,8 @@ interface PostEditorCanvasProps {
15
16
  selectedId: string | null
16
17
  viewport: ViewportId
17
18
  onSelect: (id: string) => void
18
- onAddSection: () => void
19
+ /** Add-section CTA on the empty canvas. Omitted by design-owned editors. */
20
+ onAddSection?: () => void
19
21
  /** Section types rendered as placeholders — shows the "Structure view" notice. */
20
22
  structuralTypes?: string[]
21
23
  /** Site preview toggle is available — show WYSIWYG nudge on the canvas. */
@@ -77,6 +79,7 @@ export function PostEditorCanvas({
77
79
 
78
80
  return (
79
81
  <div ref={containerRef} className="bg-muted h-full overflow-auto p-6">
82
+ {sections.length > 0 && <CanvasEditTip />}
80
83
  <StructureNotice
81
84
  structuralTypes={structuralTypes}
82
85
  sitePreviewAvailable={sitePreviewAvailable}
@@ -112,7 +115,7 @@ export function PostEditorCanvas({
112
115
  )
113
116
  }
114
117
 
115
- function EmptyBody({ onAddSection }: { onAddSection: () => void }) {
118
+ function EmptyBody({ onAddSection }: { onAddSection?: () => void }) {
116
119
  // This block sits inside the fixed-white preview surface, so the neutral
117
120
  // greys intentionally match the website-preview palette used by PostHeader
118
121
  // and the section renderers (not the admin theme tokens, which flip in dark
@@ -125,16 +128,20 @@ function EmptyBody({ onAddSection }: { onAddSection: () => void }) {
125
128
  <FileText className="text-muted-foreground h-5 w-5" aria-hidden />
126
129
  </span>
127
130
  <p className="text-muted-foreground text-sm">
128
- The header is set by the template. Add body sections to build out this post.
131
+ {onAddSection
132
+ ? 'The header is set by the template. Add body sections to build out this post. Hover sections for a light outline, click to select, and edit in the inspector — or use Site preview to click text and images in place.'
133
+ : 'This post’s template renders no body sections. Layout is design-owned — sections come from the template in code. Pick a different template in Post settings, or edit the template itself.'}
129
134
  </p>
130
- <button
131
- type="button"
132
- onClick={onAddSection}
133
- className="bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors"
134
- >
135
- <Plus className="h-4 w-4" aria-hidden />
136
- Add Section
137
- </button>
135
+ {onAddSection && (
136
+ <button
137
+ type="button"
138
+ onClick={onAddSection}
139
+ className="bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors"
140
+ >
141
+ <Plus className="h-4 w-4" aria-hidden />
142
+ Add Section
143
+ </button>
144
+ )}
138
145
  </div>
139
146
  )
140
147
  }
@@ -10,17 +10,11 @@ import { EditorSeoAside } from '../../components/EditorSeoAside.js'
10
10
  import { ErrorBoundary } from '../../components/ErrorBoundary.js'
11
11
  import { VersionHistory } from '../../components/VersionHistory.js'
12
12
  import {
13
- addSection,
14
- createSection,
15
- duplicateSection,
16
13
  emptyPostFromTemplate,
17
14
  fetchPostForEditor,
18
15
  fetchTemplateForEditor,
19
16
  missingPostFields,
20
- moveSection,
21
17
  publishPost,
22
- removeSection,
23
- reorderSections,
24
18
  savePostDraft,
25
19
  toggleSectionVisibility,
26
20
  updateSectionContent,
@@ -40,7 +34,7 @@ import {
40
34
  createPreviewToken,
41
35
  } from '../../lib/preview-link.js'
42
36
  import { usePublicSiteUrl } from '../../hooks/usePublicSiteUrl.js'
43
- import type { SectionSettings, SectionTypeId } from '../page-editor/section-types.js'
37
+ import type { SectionSettings } from '../page-editor/section-types.js'
44
38
  import {
45
39
  hasCanvasRenderer,
46
40
  useAdminSectionRenderers,
@@ -52,7 +46,6 @@ import { SitePreviewFrame } from '../page-editor/SitePreviewFrame.js'
52
46
  import { useSitePreview } from '../page-editor/useSitePreview.js'
53
47
  import { SectionsPanel } from '../page-editor/SectionsPanel.js'
54
48
  import { SectionInspector } from '../page-editor/SectionInspector.js'
55
- import { AddSectionModal } from '../page-editor/AddSectionModal.js'
56
49
  import { ValidationSummary } from '../page-editor/ValidationSummary.js'
57
50
  import { resolveDefaultSitePreview } from '../../lib/editor-preview.js'
58
51
  import { computeLiveSeoScore } from '../../lib/editor-seo-content.js'
@@ -137,11 +130,9 @@ export function PostSectionEditor({
137
130
  const [saveState, setSaveState] = useState<SaveState>('idle')
138
131
  const [publishing, setPublishing] = useState(false)
139
132
 
140
- const [addOpen, setAddOpen] = useState(false)
141
133
  const [fieldsOpen, setFieldsOpen] = useState(false)
142
134
  const [seoOpen, setSeoOpen] = useState(false)
143
135
  const [historyOpen, setHistoryOpen] = useState(false)
144
- const [deleteTargetId, setDeleteTargetId] = useState<string | null>(null)
145
136
  const [confirmPublish, setConfirmPublish] = useState(false)
146
137
  const [scheduleOpen, setScheduleOpen] = useState(false)
147
138
  const [leaveTarget, setLeaveTarget] = useState<string | null>(null)
@@ -268,34 +259,10 @@ export function PostSectionEditor({
268
259
  [],
269
260
  )
270
261
 
271
- const handleAdd = useCallback(
272
- (type: SectionTypeId) => {
273
- const section = createSection(type)
274
- mutateSections((s) => addSection(s, section))
275
- setSelectedId(section.id)
276
- setAddOpen(false)
277
- },
278
- [mutateSections],
279
- )
280
-
281
- const handleReorder = useCallback(
282
- (orderedIds: string[]) => mutateSections((s) => reorderSections(s, orderedIds)),
283
- [mutateSections],
284
- )
285
262
  const handleToggleVisibility = useCallback(
286
263
  (id: string) => mutateSections((s) => toggleSectionVisibility(s, id)),
287
264
  [mutateSections],
288
265
  )
289
- const handleDuplicate = useCallback(
290
- (id: string) => mutateSections((s) => duplicateSection(s, id)),
291
- [mutateSections],
292
- )
293
- const confirmDelete = useCallback(() => {
294
- if (!deleteTargetId) return
295
- mutateSections((s) => removeSection(s, deleteTargetId))
296
- setSelectedId((cur) => (cur === deleteTargetId ? null : cur))
297
- setDeleteTargetId(null)
298
- }, [deleteTargetId, mutateSections])
299
266
 
300
267
  const handleContentChange = useCallback(
301
268
  (patch: Record<string, unknown>) => {
@@ -709,11 +676,7 @@ export function PostSectionEditor({
709
676
  selectedId={selectedId}
710
677
  canEdit={canEdit}
711
678
  onSelect={handleSelectSection}
712
- onReorder={handleReorder}
713
679
  onToggleVisibility={handleToggleVisibility}
714
- onDuplicate={handleDuplicate}
715
- onRequestDelete={(id) => setDeleteTargetId(id)}
716
- onAdd={() => setAddOpen(true)}
717
680
  />
718
681
 
719
682
  <div className="flex-1 overflow-hidden">
@@ -738,7 +701,6 @@ export function PostSectionEditor({
738
701
  selectedId={selectedId}
739
702
  viewport={viewport}
740
703
  onSelect={handleSelectSection}
741
- onAddSection={() => setAddOpen(true)}
742
704
  structuralTypes={structuralTypes}
743
705
  sitePreviewAvailable={sitePreviewAvailable && !sitePreview.active}
744
706
  />
@@ -778,13 +740,6 @@ export function PostSectionEditor({
778
740
  </div>
779
741
  </div>
780
742
 
781
- <AddSectionModal
782
- open={addOpen}
783
- scope="post"
784
- onClose={() => setAddOpen(false)}
785
- onAdd={handleAdd}
786
- />
787
-
788
743
  {post.id && (
789
744
  <VersionHistory
790
745
  collectionSlug={postType}
@@ -804,16 +759,6 @@ export function PostSectionEditor({
804
759
  onSave={handleFields}
805
760
  />
806
761
 
807
- <ConfirmDialog
808
- open={deleteTargetId !== null}
809
- onClose={() => setDeleteTargetId(null)}
810
- onConfirm={confirmDelete}
811
- title="Delete section?"
812
- description="This removes the section from the post. You can undo by leaving without saving."
813
- confirmLabel="Delete"
814
- destructive
815
- />
816
-
817
762
  <ConfirmDialog
818
763
  open={confirmPublish}
819
764
  onClose={() => setConfirmPublish(false)}
@@ -247,6 +247,9 @@ export function PostTemplateEditor({
247
247
  sections={template.sections}
248
248
  selectedId={selectedSectionId}
249
249
  canEdit={canEdit}
250
+ // The template editor is where structure is authored — it is the
251
+ // one surface that opts into add / reorder / duplicate / delete.
252
+ structural
250
253
  onSelect={(id) => setSelected({ kind: 'section', id })}
251
254
  onReorder={(ids) => mutateSections((s) => reorderSections(s, ids))}
252
255
  onToggleVisibility={(id) => mutateSections((s) => toggleSectionVisibility(s, id))}