@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
@@ -0,0 +1,41 @@
1
+ import type { PageSection } from '@prenta/core/page-sections';
2
+ import { type PageAuditResult } from '@prenta/core/seo/page-audit';
3
+ import { type SeoContentRecord } from '../lib/seo-service.js';
4
+ export interface UsePageAuditArgs {
5
+ entityType: 'page' | 'post';
6
+ /** Null for an unsaved document — there is no record to audit against yet. */
7
+ entityId: string | null;
8
+ sections: PageSection[];
9
+ slug: string;
10
+ /**
11
+ * The document's own meta, used when no SEO record exists yet. A page that
12
+ * has never had SEO edited still has a title, a description and sections —
13
+ * it is scoreable, and refusing to score it leaves the header chip blank on
14
+ * exactly the pages that most need the nudge.
15
+ */
16
+ fallback?: {
17
+ title?: string;
18
+ description?: string;
19
+ };
20
+ }
21
+ /**
22
+ * The page's audit, from its saved SEO record — or from the document's own
23
+ * fields when no record exists yet, so every page has a number.
24
+ *
25
+ * This exists so the header chip and the rail's tab dot have a score from first
26
+ * paint. Previously the audit was computed inside the SEO pane, which mounts
27
+ * only when its tab is opened — so before that the chip showed a number from a
28
+ * different scorer with different bands, and the header read 53 beside rings
29
+ * reading 0 and 57.
30
+ *
31
+ * While the SEO pane is open it reports a LIVE audit built from unsaved form
32
+ * state, which supersedes this one. Both go through `buildPageAuditInput`, so
33
+ * they differ only in saved-versus-unsaved metadata — the difference an editor
34
+ * expects to see — and never in how a check is decided.
35
+ */
36
+ export declare function usePageAudit({ entityType, entityId, sections, slug, fallback, }: UsePageAuditArgs): {
37
+ audit: PageAuditResult;
38
+ record: SeoContentRecord | null;
39
+ reload: () => void;
40
+ };
41
+ //# sourceMappingURL=usePageAudit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePageAudit.d.ts","sourceRoot":"","sources":["../../src/hooks/usePageAudit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGpF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,QAAQ,GACT,EAAE,gBAAgB,GAAG;IACpB,KAAK,EAAE,eAAe,CAAA;IACtB,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAiDA"}
@@ -0,0 +1,68 @@
1
+ 'use client';
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { auditPage } from '@prenta/core/seo/page-audit';
4
+ import { fetchSeoContentRecord } from '../lib/seo-service.js';
5
+ import { buildPageAuditInput, metaFromRecord } from '../lib/page-audit-input.js';
6
+ /**
7
+ * The page's audit, from its saved SEO record — or from the document's own
8
+ * fields when no record exists yet, so every page has a number.
9
+ *
10
+ * This exists so the header chip and the rail's tab dot have a score from first
11
+ * paint. Previously the audit was computed inside the SEO pane, which mounts
12
+ * only when its tab is opened — so before that the chip showed a number from a
13
+ * different scorer with different bands, and the header read 53 beside rings
14
+ * reading 0 and 57.
15
+ *
16
+ * While the SEO pane is open it reports a LIVE audit built from unsaved form
17
+ * state, which supersedes this one. Both go through `buildPageAuditInput`, so
18
+ * they differ only in saved-versus-unsaved metadata — the difference an editor
19
+ * expects to see — and never in how a check is decided.
20
+ */
21
+ export function usePageAudit({ entityType, entityId, sections, slug, fallback, }) {
22
+ const [record, setRecord] = useState(null);
23
+ const [nonce, setNonce] = useState(0);
24
+ useEffect(() => {
25
+ if (!entityId) {
26
+ setRecord(null);
27
+ return;
28
+ }
29
+ let alive = true;
30
+ fetchSeoContentRecord(entityType, entityId)
31
+ .then((rec) => {
32
+ if (alive)
33
+ setRecord(rec);
34
+ })
35
+ .catch(() => {
36
+ // A page that has never had SEO saved has no record. That is not an
37
+ // error worth surfacing here — the audit simply reports what it can,
38
+ // and the SEO pane shows its own error state if the user opens it.
39
+ if (alive)
40
+ setRecord(null);
41
+ });
42
+ return () => {
43
+ alive = false;
44
+ };
45
+ }, [entityType, entityId, nonce]);
46
+ /**
47
+ * With a record, audit the saved SEO. Without one, audit the document's own
48
+ * fields and treat the record-only inputs as unset — which is honest: no
49
+ * focus keyword has been chosen, no schema has been bound, and nothing has
50
+ * set noindex. The score is real, and it improves the moment SEO is filled in.
51
+ */
52
+ const meta = record
53
+ ? metaFromRecord(record)
54
+ : {
55
+ metaTitle: fallback?.title ?? '',
56
+ metaDescription: fallback?.description ?? '',
57
+ focusKeyword: '',
58
+ structuredDataType: '',
59
+ noindex: false,
60
+ nosnippet: false,
61
+ llmsInclude: 'AUTO',
62
+ hasOgImage: false,
63
+ };
64
+ const audit = auditPage(buildPageAuditInput({ sections, meta, slug, record }));
65
+ const reload = useCallback(() => setNonce((n) => n + 1), []);
66
+ return { audit, record, reload };
67
+ }
68
+ //# sourceMappingURL=usePageAudit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePageAudit.js","sourceRoot":"","sources":["../../src/hooks/usePageAudit.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAExD,OAAO,EAAE,SAAS,EAAwB,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,qBAAqB,EAAyB,MAAM,uBAAuB,CAAA;AACpF,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAiBhF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,QAAQ,GACS;IAKjB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA0B,IAAI,CAAC,CAAA;IACnE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,SAAS,CAAC,IAAI,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,IAAI,KAAK,GAAG,IAAI,CAAA;QAChB,qBAAqB,CAAC,UAAU,EAAE,QAAQ,CAAC;aACxC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,IAAI,KAAK;gBAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,oEAAoE;YACpE,qEAAqE;YACrE,mEAAmE;YACnE,IAAI,KAAK;gBAAE,SAAS,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC,CAAC,CAAA;QACJ,OAAO,GAAG,EAAE;YACV,KAAK,GAAG,KAAK,CAAA;QACf,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;IAEjC;;;;;OAKG;IACH,MAAM,IAAI,GAAG,MAAM;QACjB,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC;QACxB,CAAC,CAAC;YACE,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE;YAChC,eAAe,EAAE,QAAQ,EAAE,WAAW,IAAI,EAAE;YAC5C,YAAY,EAAE,EAAE;YAChB,kBAAkB,EAAE,EAAE;YACtB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,MAAM;YACnB,UAAU,EAAE,KAAK;SAClB,CAAA;IAEL,MAAM,KAAK,GAAG,SAAS,CAAC,mBAAmB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IAE9E,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAE5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AAClC,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { BreakpointId } from '../lib/breakpoints.js';
2
+ import { type FieldLineCount, type ReflowSeverity } from '../lib/reflow-probe.js';
3
+ export interface ReflowRow extends FieldLineCount {
4
+ /** Lines this field ran to in the published version. */
5
+ was: number;
6
+ /** `lines - was`. Only growth is treated as a problem. */
7
+ diff: number;
8
+ state: ReflowSeverity;
9
+ }
10
+ export interface ReflowGuardResult {
11
+ rows: ReflowRow[];
12
+ /** Breakpoints where the field now wraps to more lines than published. */
13
+ grown: ReflowRow[];
14
+ /** The one worth proofing on, or `null` when nothing grew. */
15
+ worst: BreakpointId | null;
16
+ /** Character delta against the published string; 0 when there is no baseline. */
17
+ delta: number;
18
+ }
19
+ /**
20
+ * Measures how one field wraps at every breakpoint, and how that compares to
21
+ * what is published.
22
+ *
23
+ * ── Why it runs on a delay ────────────────────────────────────────────────
24
+ *
25
+ * A pass clones the canvas and lays it out twelve times (six widths, current
26
+ * and published). That is far too much to do per keystroke, and it is also
27
+ * pointless — mid-word text tells an editor nothing. So it settles first.
28
+ *
29
+ * `null` from the probe means the field is not measurable: the section may be
30
+ * rendered by a consumer's own component that carries no `data-cms-field`
31
+ * markers. The guard then reports nothing rather than a number read off the
32
+ * wrong element — an editor treats a line count as a fact, and a confident
33
+ * wrong one is worse than a blank.
34
+ */
35
+ export declare function useReflowGuard(options: {
36
+ canvas: HTMLElement | null;
37
+ sectionId: string;
38
+ fieldPath: string;
39
+ /** Current field text. Only used to retrigger — the probe reads the DOM. */
40
+ value: string;
41
+ /** Published text, or `undefined` when the field has never been published. */
42
+ baseline: string | undefined;
43
+ /** Skip measuring entirely (field type isn't guarded, panel is collapsed). */
44
+ enabled?: boolean;
45
+ delayMs?: number;
46
+ }): ReflowGuardResult;
47
+ //# sourceMappingURL=useReflowGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReflowGuard.d.ts","sourceRoot":"","sources":["../../src/hooks/useReflowGuard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,SAAU,SAAQ,cAAc;IAC/C,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAA;IACX,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,cAAc,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,EAAE,CAAA;IACjB,0EAA0E;IAC1E,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,8DAA8D;IAC9D,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAC1B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;CACd;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GAAG,iBAAiB,CAoCpB"}
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ import { useEffect, useState } from 'react';
3
+ import { probeFieldReflow, reflowSeverity, worstBreakpoint, } from '../lib/reflow-probe.js';
4
+ const EMPTY = { rows: [], grown: [], worst: null, delta: 0 };
5
+ /**
6
+ * Measures how one field wraps at every breakpoint, and how that compares to
7
+ * what is published.
8
+ *
9
+ * ── Why it runs on a delay ────────────────────────────────────────────────
10
+ *
11
+ * A pass clones the canvas and lays it out twelve times (six widths, current
12
+ * and published). That is far too much to do per keystroke, and it is also
13
+ * pointless — mid-word text tells an editor nothing. So it settles first.
14
+ *
15
+ * `null` from the probe means the field is not measurable: the section may be
16
+ * rendered by a consumer's own component that carries no `data-cms-field`
17
+ * markers. The guard then reports nothing rather than a number read off the
18
+ * wrong element — an editor treats a line count as a fact, and a confident
19
+ * wrong one is worse than a blank.
20
+ */
21
+ export function useReflowGuard(options) {
22
+ const { canvas, sectionId, fieldPath, value, baseline, enabled = true, delayMs = 200 } = options;
23
+ const [result, setResult] = useState(EMPTY);
24
+ useEffect(() => {
25
+ if (!enabled || !canvas) {
26
+ setResult(EMPTY);
27
+ return;
28
+ }
29
+ const timer = setTimeout(() => {
30
+ const probed = probeFieldReflow({ canvas, sectionId, fieldPath, baselineText: baseline });
31
+ if (!probed) {
32
+ setResult(EMPTY);
33
+ return;
34
+ }
35
+ const rows = probed.current.map((row) => {
36
+ const was = probed.baseline.find((b) => b.id === row.id)?.lines ?? row.lines;
37
+ return { ...row, was, diff: row.lines - was, state: reflowSeverity(row.lines, was) };
38
+ });
39
+ setResult({
40
+ rows,
41
+ grown: rows.filter((r) => r.diff > 0),
42
+ worst: worstBreakpoint(probed.current, probed.baseline),
43
+ delta: baseline === undefined ? 0 : value.length - baseline.length,
44
+ });
45
+ }, delayMs);
46
+ return () => clearTimeout(timer);
47
+ // `value` is a dependency because the canvas re-renders as it changes —
48
+ // the probe reads the resulting DOM rather than the string itself.
49
+ }, [canvas, sectionId, fieldPath, value, baseline, enabled, delayMs]);
50
+ return result;
51
+ }
52
+ //# sourceMappingURL=useReflowGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReflowGuard.js","sourceRoot":"","sources":["../../src/hooks/useReflowGuard.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE3C,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,GAGhB,MAAM,wBAAwB,CAAA;AAoB/B,MAAM,KAAK,GAAsB,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;AAE/E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,OAW9B;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,GAAG,EAAE,GAAG,OAAO,CAAA;IAChG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAoB,KAAK,CAAC,CAAA;IAE9D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,SAAS,CAAC,KAAK,CAAC,CAAA;YAChB,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAA;YACzF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,SAAS,CAAC,KAAK,CAAC,CAAA;gBAChB,OAAM;YACR,CAAC;YAED,MAAM,IAAI,GAAgB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACnD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,GAAG,CAAC,KAAK,CAAA;gBAC5E,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAA;YACtF,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC;gBACR,IAAI;gBACJ,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBACrC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC;gBACvD,KAAK,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM;aACnE,CAAC,CAAA;QACJ,CAAC,EAAE,OAAO,CAAC,CAAA;QAEX,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAChC,wEAAwE;QACxE,mEAAmE;IACrE,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAErE,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AdminShell.d.ts","sourceRoot":"","sources":["../../../src/layout/primitives/AdminShell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,SAAS,CAAA;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,SAAS,CAAA;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAA;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,iBAAyB,EACzB,oBAAoB,EACpB,iBAAuB,GACxB,EAAE,eAAe,2CAiEjB"}
1
+ {"version":3,"file":"AdminShell.d.ts","sourceRoot":"","sources":["../../../src/layout/primitives/AdminShell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,SAAS,CAAA;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,SAAS,CAAA;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAA;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,iBAAyB,EACzB,oBAAoB,EACpB,iBAAuB,GACxB,EAAE,eAAe,2CA6EjB"}
@@ -31,7 +31,7 @@ export function AdminShell({ sidebar, header, breadcrumbs, children, mobileSideb
31
31
  }, [desktopBreakpoint]);
32
32
  return (_jsxs("div", { className: "bg-background text-foreground h-screen overflow-hidden", style: isDesktop
33
33
  ? { display: 'grid', gridTemplateColumns: 'auto minmax(0, 1fr)' }
34
- : { display: 'block', position: 'relative' }, children: [!isDesktop && mobileSidebarOpen && (_jsx("div", { "aria-hidden": true, className: "fixed inset-0 z-40 bg-black/30 backdrop-blur-sm", onClick: onMobileSidebarClose })), _jsx("div", { className: "z-50", style: isDesktop
34
+ : { display: 'block', position: 'relative' }, children: [_jsx("a", { className: "prenta-skip-link", href: "#prenta-main", children: "Skip to content" }), !isDesktop && mobileSidebarOpen && (_jsx("div", { "aria-hidden": true, className: "fixed inset-0 z-40 bg-black/30 backdrop-blur-sm", onClick: onMobileSidebarClose })), _jsx("div", { className: "z-50", style: isDesktop
35
35
  ? {
36
36
  gridColumn: '1 / 2',
37
37
  height: '100vh',
@@ -46,6 +46,6 @@ export function AdminShell({ sidebar, header, breadcrumbs, children, mobileSideb
46
46
  transition: 'transform 300ms ease',
47
47
  }, children: sidebar }), _jsxs("div", { className: "flex flex-col overflow-hidden", style: isDesktop
48
48
  ? { gridColumn: '2 / 3', height: '100vh', minWidth: 0 }
49
- : { height: '100vh', minWidth: 0 }, children: [header, breadcrumbs, _jsx("main", { className: "min-h-0 flex-1 overflow-y-auto", children: children })] })] }));
49
+ : { height: '100vh', minWidth: 0 }, children: [header, breadcrumbs, _jsx("main", { id: "prenta-main", className: "min-h-0 flex-1 overflow-y-auto", children: children })] })] }));
50
50
  }
51
51
  //# sourceMappingURL=AdminShell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminShell.js","sourceRoot":"","sources":["../../../src/layout/primitives/AdminShell.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AA0B3C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,iBAAiB,GAAG,KAAK,EACzB,oBAAoB,EACpB,iBAAiB,GAAG,GAAG,GACP;IAChB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QACzC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,iBAAiB,KAAK,CAAC,CAAA;QACnE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,CAAA;QAC9C,OAAO,EAAE,CAAA;QACT,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACtC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACxD,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAEvB,OAAO,CACL,eACE,SAAS,EAAC,wDAAwD,EAClE,KAAK,EACH,SAAS;YACP,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EAAE;YACjE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAG/C,CAAC,SAAS,IAAI,iBAAiB,IAAI,CAClC,mCAEE,SAAS,EAAC,iDAAiD,EAC3D,OAAO,EAAE,oBAAoB,GAC7B,CACH,EAED,cACE,SAAS,EAAC,MAAM,EAChB,KAAK,EACH,SAAS;oBACP,CAAC,CAAC;wBACE,UAAU,EAAE,OAAO;wBACnB,MAAM,EAAE,OAAO;wBACf,QAAQ,EAAE,QAAQ;qBACnB;oBACH,CAAC,CAAC;wBACE,QAAQ,EAAE,OAAO;wBACjB,GAAG,EAAE,CAAC;wBACN,MAAM,EAAE,CAAC;wBACT,IAAI,EAAE,CAAC;wBACP,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,mBAAmB;wBACpE,UAAU,EAAE,sBAAsB;qBACnC,YAGN,OAAO,GACJ,EAEN,eACE,SAAS,EAAC,+BAA+B,EACzC,KAAK,EACH,SAAS;oBACP,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;oBACvD,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,aAGrC,MAAM,EACN,WAAW,EACZ,eAAM,SAAS,EAAC,gCAAgC,YAAE,QAAQ,GAAQ,IAC9D,IACF,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"AdminShell.js","sourceRoot":"","sources":["../../../src/layout/primitives/AdminShell.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AA0B3C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,iBAAiB,GAAG,KAAK,EACzB,oBAAoB,EACpB,iBAAiB,GAAG,GAAG,GACP;IAChB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QACzC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,iBAAiB,KAAK,CAAC,CAAA;QACnE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,CAAA;QAC9C,OAAO,EAAE,CAAA;QACT,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACtC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACxD,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAEvB,OAAO,CACL,eACE,SAAS,EAAC,wDAAwD,EAClE,KAAK,EACH,SAAS;YACP,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EAAE;YACjE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,aAShD,YAAG,SAAS,EAAC,kBAAkB,EAAC,IAAI,EAAC,cAAc,gCAE/C,EAEH,CAAC,SAAS,IAAI,iBAAiB,IAAI,CAClC,mCAEE,SAAS,EAAC,iDAAiD,EAC3D,OAAO,EAAE,oBAAoB,GAC7B,CACH,EAED,cACE,SAAS,EAAC,MAAM,EAChB,KAAK,EACH,SAAS;oBACP,CAAC,CAAC;wBACE,UAAU,EAAE,OAAO;wBACnB,MAAM,EAAE,OAAO;wBACf,QAAQ,EAAE,QAAQ;qBACnB;oBACH,CAAC,CAAC;wBACE,QAAQ,EAAE,OAAO;wBACjB,GAAG,EAAE,CAAC;wBACN,MAAM,EAAE,CAAC;wBACT,IAAI,EAAE,CAAC;wBACP,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,mBAAmB;wBACpE,UAAU,EAAE,sBAAsB;qBACnC,YAGN,OAAO,GACJ,EAEN,eACE,SAAS,EAAC,+BAA+B,EACzC,KAAK,EACH,SAAS;oBACP,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;oBACvD,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,aAGrC,MAAM,EACN,WAAW,EACZ,eAAM,EAAE,EAAC,aAAa,EAAC,SAAS,EAAC,gCAAgC,YAC9D,QAAQ,GACJ,IACH,IACF,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Breakpoint presets for the editor canvas — shared by the page editor, the
3
+ * post editor, and the site-preview frame.
4
+ *
5
+ * Each entry's `width` is the **real CSS width** the canvas renders at. The
6
+ * canvas is then scaled down with a transform to fit the available column, so
7
+ * the page reflows against its own width via container queries rather than
8
+ * being squeezed by a max-width clamp. A clamp does not reflow: it produces a
9
+ * narrow desktop layout, not the mobile layout.
10
+ *
11
+ * `4k` is 2560, not 3840. 2560 is the CSS width a 4K/Retina display reports
12
+ * once device-pixel-ratio is applied; 3840 is the physical pixel count and no
13
+ * stylesheet ever sees it. It is also the only preset above the canvas's
14
+ * `min-width: 2000px` container step, so it is the only one that exercises
15
+ * that branch.
16
+ */
17
+ export type BreakpointId = '4k' | 'wide' | 'laptop' | 'tabletL' | 'tabletP' | 'mobile';
18
+ export type BreakpointGroup = 'DESKTOP' | 'TABLET' | 'MOBILE';
19
+ export interface Breakpoint {
20
+ id: BreakpointId;
21
+ /** Full name, shown in the picker menu. */
22
+ name: string;
23
+ /** Two-letter form for the collapsed trigger. */
24
+ abbr: string;
25
+ /** lucide-react icon name */
26
+ icon: string;
27
+ /** Real CSS width of the preview surface, in px. */
28
+ width: number;
29
+ group: BreakpointGroup;
30
+ }
31
+ export declare const BREAKPOINTS: readonly Breakpoint[];
32
+ /** Menu order. Groups render as labelled sections in the breakpoint picker. */
33
+ export declare const BREAKPOINT_GROUPS: readonly BreakpointGroup[];
34
+ export declare const DEFAULT_BREAKPOINT: BreakpointId;
35
+ export declare function getBreakpoint(id: BreakpointId): Breakpoint;
36
+ export declare function breakpointsInGroup(group: BreakpointGroup): Breakpoint[];
37
+ export declare function coerceBreakpointId(value: unknown): BreakpointId;
38
+ export type Zoom = 'fit' | 1;
39
+ /**
40
+ * Scale factor for the canvas transform.
41
+ *
42
+ * `available` must come from a zero-height sentinel measured inside the canvas
43
+ * panel — NOT from `panel.clientWidth - padding`. The two disagree whenever the
44
+ * host scales the preview or a scrollbar appears, and the padding arithmetic is
45
+ * the kind that silently rots when the gutter changes.
46
+ *
47
+ * Never scales above 1: a 390px mobile canvas blown up to fill a 1200px column
48
+ * would show text at 3× the size the visitor sees.
49
+ */
50
+ export declare function fitScale(available: number, width: number, zoom?: Zoom): number;
51
+ //# sourceMappingURL=breakpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.d.ts","sourceRoot":"","sources":["../../src/lib/breakpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEtF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE7D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,YAAY,CAAA;IAChB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,CAAA;CACvB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,UAAU,EAqB5C,CAAA;AAED,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAAoC,CAAA;AAE5F,eAAO,MAAM,kBAAkB,EAAE,YAAqB,CAAA;AAItD,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,UAAU,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,EAAE,CAEvE;AAaD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAI/D;AAED,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA;AAE5B;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,IAAY,GAAG,MAAM,CAIrF"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Breakpoint presets for the editor canvas — shared by the page editor, the
3
+ * post editor, and the site-preview frame.
4
+ *
5
+ * Each entry's `width` is the **real CSS width** the canvas renders at. The
6
+ * canvas is then scaled down with a transform to fit the available column, so
7
+ * the page reflows against its own width via container queries rather than
8
+ * being squeezed by a max-width clamp. A clamp does not reflow: it produces a
9
+ * narrow desktop layout, not the mobile layout.
10
+ *
11
+ * `4k` is 2560, not 3840. 2560 is the CSS width a 4K/Retina display reports
12
+ * once device-pixel-ratio is applied; 3840 is the physical pixel count and no
13
+ * stylesheet ever sees it. It is also the only preset above the canvas's
14
+ * `min-width: 2000px` container step, so it is the only one that exercises
15
+ * that branch.
16
+ */
17
+ export const BREAKPOINTS = [
18
+ { id: '4k', name: '4K / Retina', abbr: '4K', icon: 'monitor', width: 2560, group: 'DESKTOP' },
19
+ { id: 'wide', name: 'Wide Screen', abbr: 'WS', icon: 'monitor', width: 1920, group: 'DESKTOP' },
20
+ { id: 'laptop', name: 'Laptop', abbr: 'LT', icon: 'laptop', width: 1440, group: 'DESKTOP' },
21
+ {
22
+ id: 'tabletL',
23
+ name: 'Tablet Landscape',
24
+ abbr: 'TL',
25
+ icon: 'tablet',
26
+ width: 1024,
27
+ group: 'TABLET',
28
+ },
29
+ {
30
+ id: 'tabletP',
31
+ name: 'Tablet Portrait',
32
+ abbr: 'TP',
33
+ icon: 'tablet',
34
+ width: 768,
35
+ group: 'TABLET',
36
+ },
37
+ { id: 'mobile', name: 'Mobile', abbr: 'M', icon: 'smartphone', width: 390, group: 'MOBILE' },
38
+ ];
39
+ /** Menu order. Groups render as labelled sections in the breakpoint picker. */
40
+ export const BREAKPOINT_GROUPS = ['DESKTOP', 'TABLET', 'MOBILE'];
41
+ export const DEFAULT_BREAKPOINT = 'wide';
42
+ const BY_ID = new Map(BREAKPOINTS.map((b) => [b.id, b]));
43
+ export function getBreakpoint(id) {
44
+ return BY_ID.get(id) ?? BY_ID.get(DEFAULT_BREAKPOINT);
45
+ }
46
+ export function breakpointsInGroup(group) {
47
+ return BREAKPOINTS.filter((b) => b.group === group);
48
+ }
49
+ /**
50
+ * Narrows arbitrary input (persisted state, a URL param, a stale prop) to a
51
+ * known id. The v0.92 preset ids — `1080p` and `tablet` — map onto their
52
+ * closest current equivalents so an editor open across the upgrade doesn't
53
+ * land on the default.
54
+ */
55
+ const LEGACY_IDS = {
56
+ '1080p': 'laptop', // was 1440 — same width, renamed
57
+ tablet: 'tabletP', // was 768 — same width, split into landscape/portrait
58
+ };
59
+ export function coerceBreakpointId(value) {
60
+ if (typeof value !== 'string')
61
+ return DEFAULT_BREAKPOINT;
62
+ if (BY_ID.has(value))
63
+ return value;
64
+ return LEGACY_IDS[value] ?? DEFAULT_BREAKPOINT;
65
+ }
66
+ /**
67
+ * Scale factor for the canvas transform.
68
+ *
69
+ * `available` must come from a zero-height sentinel measured inside the canvas
70
+ * panel — NOT from `panel.clientWidth - padding`. The two disagree whenever the
71
+ * host scales the preview or a scrollbar appears, and the padding arithmetic is
72
+ * the kind that silently rots when the gutter changes.
73
+ *
74
+ * Never scales above 1: a 390px mobile canvas blown up to fill a 1200px column
75
+ * would show text at 3× the size the visitor sees.
76
+ */
77
+ export function fitScale(available, width, zoom = 'fit') {
78
+ if (zoom !== 'fit')
79
+ return 1;
80
+ if (!Number.isFinite(available) || available <= 0 || width <= 0)
81
+ return 1;
82
+ return Math.min(1, available / width);
83
+ }
84
+ //# sourceMappingURL=breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.js","sourceRoot":"","sources":["../../src/lib/breakpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAmBH,MAAM,CAAC,MAAM,WAAW,GAA0B;IAChD,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IAC7F,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IAC/F,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;IAC3F;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,QAAQ;KAChB;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,QAAQ;KAChB;IACD,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;CAC7F,CAAA;AAED,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAE5F,MAAM,CAAC,MAAM,kBAAkB,GAAiB,MAAM,CAAA;AAEtD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAExD,MAAM,UAAU,aAAa,CAAC,EAAgB;IAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAE,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAiC;IAC/C,OAAO,EAAE,QAAQ,EAAE,iCAAiC;IACpD,MAAM,EAAE,SAAS,EAAE,sDAAsD;CAC1E,CAAA;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAA;IACxD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAqB,CAAC;QAAE,OAAO,KAAqB,CAAA;IAClE,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAA;AAChD,CAAC;AAID;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAiB,EAAE,KAAa,EAAE,OAAa,KAAK;IAC3E,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAA;IACzE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAA;AACvC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared edit affordances for the page/post canvas and Site preview iframe.
3
+ *
4
+ * Structure canvas: section hover is styled in `theme.css` under `.prenta-canvas`.
5
+ * Site preview: the same field chrome is injected into the iframe document when
6
+ * same-origin (CMS-host preview) so consumers get hover borders without shipping CSS.
7
+ */
8
+ /** localStorage key for the dismissible canvas tip. */
9
+ export declare const CANVAS_EDIT_TIP_STORAGE_KEY = "prenta.canvasEditTip.dismissed";
10
+ /**
11
+ * CSS injected into the Site preview iframe while editing is enabled.
12
+ * Uses system colors so it works without admin theme tokens in the iframe.
13
+ */
14
+ export declare const PREVIEW_EDITABLE_FIELD_CHROME_CSS: string;
15
+ /**
16
+ * Inject (or refresh) editable-field hover chrome into a same-origin preview
17
+ * iframe. No-ops on cross-origin frames (browser blocks contentDocument).
18
+ */
19
+ export declare function injectPreviewEditChrome(iframe: HTMLIFrameElement | null): boolean;
20
+ export declare function isCanvasEditTipDismissed(): boolean;
21
+ export declare function dismissCanvasEditTip(): void;
22
+ //# sourceMappingURL=canvas-edit-chrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-edit-chrome.d.ts","sourceRoot":"","sources":["../../src/lib/canvas-edit-chrome.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,uDAAuD;AACvD,eAAO,MAAM,2BAA2B,mCAAmC,CAAA;AAE3E;;;GAGG;AACH,eAAO,MAAM,iCAAiC,QA0BtC,CAAA;AAIR;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAgBjF;AAED,wBAAgB,wBAAwB,IAAI,OAAO,CAMlD;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Shared edit affordances for the page/post canvas and Site preview iframe.
3
+ *
4
+ * Structure canvas: section hover is styled in `theme.css` under `.prenta-canvas`.
5
+ * Site preview: the same field chrome is injected into the iframe document when
6
+ * same-origin (CMS-host preview) so consumers get hover borders without shipping CSS.
7
+ */
8
+ /** localStorage key for the dismissible canvas tip. */
9
+ export const CANVAS_EDIT_TIP_STORAGE_KEY = 'prenta.canvasEditTip.dismissed';
10
+ /**
11
+ * CSS injected into the Site preview iframe while editing is enabled.
12
+ * Uses system colors so it works without admin theme tokens in the iframe.
13
+ */
14
+ export const PREVIEW_EDITABLE_FIELD_CHROME_CSS = `
15
+ /* Prenta Site preview — editable field hover chrome (injected by @prenta/admin) */
16
+ [data-cms-field] {
17
+ outline: 1px solid transparent;
18
+ outline-offset: 2px;
19
+ border-radius: 2px;
20
+ transition: outline-color 120ms ease;
21
+ cursor: text;
22
+ }
23
+ [data-cms-field]:hover,
24
+ [data-cms-field]:focus,
25
+ [data-cms-field]:focus-within {
26
+ outline-color: color-mix(in oklab, CanvasText 24%, transparent);
27
+ }
28
+ [data-cms-field][data-cms-field-kind="media"] {
29
+ cursor: pointer;
30
+ }
31
+ [data-cms-field][data-cms-field-kind="media"]:hover,
32
+ [data-cms-field][data-cms-field-kind="media"]:focus {
33
+ outline-color: color-mix(in oklab, CanvasText 32%, transparent);
34
+ }
35
+ @media (prefers-reduced-motion: reduce) {
36
+ [data-cms-field] {
37
+ transition: none;
38
+ }
39
+ }
40
+ `.trim();
41
+ const STYLE_ATTR = 'data-prenta-edit-chrome';
42
+ /**
43
+ * Inject (or refresh) editable-field hover chrome into a same-origin preview
44
+ * iframe. No-ops on cross-origin frames (browser blocks contentDocument).
45
+ */
46
+ export function injectPreviewEditChrome(iframe) {
47
+ try {
48
+ const doc = iframe?.contentDocument;
49
+ if (!doc?.head)
50
+ return false;
51
+ let style = doc.head.querySelector(`style[${STYLE_ATTR}]`);
52
+ if (!style) {
53
+ style = doc.createElement('style');
54
+ style.setAttribute(STYLE_ATTR, '1');
55
+ doc.head.appendChild(style);
56
+ }
57
+ style.textContent = PREVIEW_EDITABLE_FIELD_CHROME_CSS;
58
+ doc.documentElement.setAttribute('data-prenta-preview-editing', 'true');
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ export function isCanvasEditTipDismissed() {
66
+ try {
67
+ return localStorage.getItem(CANVAS_EDIT_TIP_STORAGE_KEY) === '1';
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ export function dismissCanvasEditTip() {
74
+ try {
75
+ localStorage.setItem(CANVAS_EDIT_TIP_STORAGE_KEY, '1');
76
+ }
77
+ catch {
78
+ /* private mode — tip will reappear next session */
79
+ }
80
+ }
81
+ //# sourceMappingURL=canvas-edit-chrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-edit-chrome.js","sourceRoot":"","sources":["../../src/lib/canvas-edit-chrome.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,uDAAuD;AACvD,MAAM,CAAC,MAAM,2BAA2B,GAAG,gCAAgC,CAAA;AAE3E;;;GAGG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BhD,CAAC,IAAI,EAAE,CAAA;AAER,MAAM,UAAU,GAAG,yBAAyB,CAAA;AAE5C;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAgC;IACtE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,eAAe,CAAA;QACnC,IAAI,CAAC,GAAG,EAAE,IAAI;YAAE,OAAO,KAAK,CAAA;QAC5B,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,aAAa,CAAmB,SAAS,UAAU,GAAG,CAAC,CAAA;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YAClC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;YACnC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,iCAAiC,CAAA;QACrD,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;QACvE,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,2BAA2B,CAAC,KAAK,GAAG,CAAA;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAA;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;AACH,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Presentation helpers for the media block.
3
+ *
4
+ * Pure, because these are the parts with real logic — the rest of the block is
5
+ * layout. Ported from the design prototype so the labels an editor reads match
6
+ * the ones the design specifies.
7
+ */
8
+ /** The crop the template renders an image at. Drives the frame's aspect ratio. */
9
+ export type MediaCrop = 'section' | 'social';
10
+ /**
11
+ * Aspect ratio per crop, as a CSS `aspect-ratio` value.
12
+ *
13
+ * The frame shows the crop the TEMPLATE renders, not the asset's own ratio.
14
+ * Showing the asset's ratio would tell an editor their portrait photo is fine
15
+ * and then crop its subject out on the page.
16
+ */
17
+ export declare const CROP_RATIO: Record<MediaCrop, string>;
18
+ /**
19
+ * Human ratio for an asset's intrinsic dimensions.
20
+ *
21
+ * Snaps to a named ratio when within 0.05, else reports the number. The
22
+ * tolerance matters: a 2400×1600 photo is 1.5 exactly, but a 2401×1600 scan is
23
+ * 1.5006 and an editor should still read "3:2" rather than "1.50:1".
24
+ *
25
+ * Returns null when dimensions are unknown — the library does not always have
26
+ * them, and inventing "1.00:1" would be worse than saying nothing.
27
+ */
28
+ export declare function ratioLabel(width?: number, height?: number): string | null;
29
+ /**
30
+ * Short format badge — the file extension, uppercased.
31
+ *
32
+ * Falls back to the MIME subtype so a URL with no extension (a signed CDN link,
33
+ * an upload route) still shows something meaningful rather than a blank chip.
34
+ */
35
+ export declare function formatBadge(filenameOrUrl: string, mimeType?: string): string;
36
+ /**
37
+ * Filename for display, from a filename or a URL.
38
+ *
39
+ * Query strings are dropped — a signed URL's token is noise in a 200px-wide
40
+ * toolbar, and it is never what an editor is trying to read.
41
+ */
42
+ export declare function displayName(filenameOrUrl: string): string;
43
+ /**
44
+ * A stable background tint for an asset.
45
+ *
46
+ * The design fills the frame with a wash derived from the asset's dominant
47
+ * colour. The media library stores no such value, so it is derived from the
48
+ * name instead: the same asset is always the same colour, which is the property
49
+ * that actually matters for recognising a thumbnail, and it costs no storage
50
+ * and no extra request.
51
+ *
52
+ * Returned as a 135° gradient to the design's `color-mix(tint 45%, #fff)`.
53
+ */
54
+ export declare function assetWash(seed: string): string;
55
+ //# sourceMappingURL=media-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-format.d.ts","sourceRoot":"","sources":["../../src/lib/media-format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAGhD,CAAA;AAaD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9C"}