@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.
- package/CHANGELOG.md +663 -0
- package/design-system/tokens.css +173 -71
- package/design-system/tokens.json +244 -63
- package/design-system/tokens.scss +203 -98
- package/design-system/tokens.tailwind.cjs +93 -38
- package/dist/AdminRoot.d.ts +27 -6
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/components/breakpoint-controls.render.test.d.ts +2 -0
- package/dist/__tests__/components/breakpoint-controls.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/breakpoint-controls.render.test.js +51 -0
- package/dist/__tests__/components/breakpoint-controls.render.test.js.map +1 -0
- package/dist/__tests__/components/canvas-edit-tip.render.test.d.ts +2 -0
- package/dist/__tests__/components/canvas-edit-tip.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/canvas-edit-tip.render.test.js +37 -0
- package/dist/__tests__/components/canvas-edit-tip.render.test.js.map +1 -0
- package/dist/__tests__/components/editor-rail.render.test.d.ts +2 -0
- package/dist/__tests__/components/editor-rail.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/editor-rail.render.test.js +138 -0
- package/dist/__tests__/components/editor-rail.render.test.js.map +1 -0
- package/dist/__tests__/components/media-block.render.test.d.ts +2 -0
- package/dist/__tests__/components/media-block.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/media-block.render.test.js +108 -0
- package/dist/__tests__/components/media-block.render.test.js.map +1 -0
- package/dist/__tests__/components/page-audit-panel.render.test.d.ts +2 -0
- package/dist/__tests__/components/page-audit-panel.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/page-audit-panel.render.test.js +59 -0
- package/dist/__tests__/components/page-audit-panel.render.test.js.map +1 -0
- package/dist/__tests__/components/reflow-meter.render.test.d.ts +2 -0
- package/dist/__tests__/components/reflow-meter.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/reflow-meter.render.test.js +94 -0
- package/dist/__tests__/components/reflow-meter.render.test.js.map +1 -0
- package/dist/__tests__/components/seo-char-count.test.js +24 -6
- package/dist/__tests__/components/seo-char-count.test.js.map +1 -1
- package/dist/__tests__/components/serp-preview.render.test.d.ts +2 -0
- package/dist/__tests__/components/serp-preview.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/serp-preview.render.test.js +25 -0
- package/dist/__tests__/components/serp-preview.render.test.js.map +1 -0
- package/dist/__tests__/lib/breakpoints.test.d.ts +2 -0
- package/dist/__tests__/lib/breakpoints.test.d.ts.map +1 -0
- package/dist/__tests__/lib/breakpoints.test.js +67 -0
- package/dist/__tests__/lib/breakpoints.test.js.map +1 -0
- package/dist/__tests__/lib/canvas-edit-chrome.test.d.ts +2 -0
- package/dist/__tests__/lib/canvas-edit-chrome.test.d.ts.map +1 -0
- package/dist/__tests__/lib/canvas-edit-chrome.test.js +44 -0
- package/dist/__tests__/lib/canvas-edit-chrome.test.js.map +1 -0
- package/dist/__tests__/lib/media-format.test.d.ts +2 -0
- package/dist/__tests__/lib/media-format.test.d.ts.map +1 -0
- package/dist/__tests__/lib/media-format.test.js +70 -0
- package/dist/__tests__/lib/media-format.test.js.map +1 -0
- package/dist/__tests__/lib/page-audit-input.test.d.ts +2 -0
- package/dist/__tests__/lib/page-audit-input.test.d.ts.map +1 -0
- package/dist/__tests__/lib/page-audit-input.test.js +122 -0
- package/dist/__tests__/lib/page-audit-input.test.js.map +1 -0
- package/dist/__tests__/lib/page-editor-service.test.js +2 -0
- package/dist/__tests__/lib/page-editor-service.test.js.map +1 -1
- package/dist/__tests__/lib/page-redirect.test.d.ts +2 -0
- package/dist/__tests__/lib/page-redirect.test.d.ts.map +1 -0
- package/dist/__tests__/lib/page-redirect.test.js +26 -0
- package/dist/__tests__/lib/page-redirect.test.js.map +1 -0
- package/dist/__tests__/lib/rail-width.test.d.ts +2 -0
- package/dist/__tests__/lib/rail-width.test.d.ts.map +1 -0
- package/dist/__tests__/lib/rail-width.test.js +69 -0
- package/dist/__tests__/lib/rail-width.test.js.map +1 -0
- package/dist/__tests__/lib/reflow-baseline.test.d.ts +2 -0
- package/dist/__tests__/lib/reflow-baseline.test.d.ts.map +1 -0
- package/dist/__tests__/lib/reflow-baseline.test.js +56 -0
- package/dist/__tests__/lib/reflow-baseline.test.js.map +1 -0
- package/dist/__tests__/lib/reflow-probe.test.d.ts +2 -0
- package/dist/__tests__/lib/reflow-probe.test.d.ts.map +1 -0
- package/dist/__tests__/lib/reflow-probe.test.js +73 -0
- package/dist/__tests__/lib/reflow-probe.test.js.map +1 -0
- package/dist/__tests__/lib/version-diff.test.d.ts +2 -0
- package/dist/__tests__/lib/version-diff.test.d.ts.map +1 -0
- package/dist/__tests__/lib/version-diff.test.js +230 -0
- package/dist/__tests__/lib/version-diff.test.js.map +1 -0
- package/dist/__tests__/lib/version-history.test.d.ts +2 -0
- package/dist/__tests__/lib/version-history.test.d.ts.map +1 -0
- package/dist/__tests__/lib/version-history.test.js +125 -0
- package/dist/__tests__/lib/version-history.test.js.map +1 -0
- package/dist/__tests__/styles/canvas-container-queries.test.d.ts +2 -0
- package/dist/__tests__/styles/canvas-container-queries.test.d.ts.map +1 -0
- package/dist/__tests__/styles/canvas-container-queries.test.js +87 -0
- package/dist/__tests__/styles/canvas-container-queries.test.js.map +1 -0
- package/dist/__tests__/styles/packaging.test.d.ts +2 -0
- package/dist/__tests__/styles/packaging.test.d.ts.map +1 -0
- package/dist/__tests__/styles/packaging.test.js +31 -0
- package/dist/__tests__/styles/packaging.test.js.map +1 -0
- package/dist/__tests__/styles/responsive-layer.test.d.ts +2 -0
- package/dist/__tests__/styles/responsive-layer.test.d.ts.map +1 -0
- package/dist/__tests__/styles/responsive-layer.test.js +127 -0
- package/dist/__tests__/styles/responsive-layer.test.js.map +1 -0
- package/dist/__tests__/styles/tokens-drift.test.d.ts +2 -0
- package/dist/__tests__/styles/tokens-drift.test.d.ts.map +1 -0
- package/dist/__tests__/styles/tokens-drift.test.js +92 -0
- package/dist/__tests__/styles/tokens-drift.test.js.map +1 -0
- package/dist/__tests__/views/admin-renderer-compat.test.d.ts +2 -0
- package/dist/__tests__/views/admin-renderer-compat.test.d.ts.map +1 -0
- package/dist/__tests__/views/admin-renderer-compat.test.js +43 -0
- package/dist/__tests__/views/admin-renderer-compat.test.js.map +1 -0
- package/dist/__tests__/views/admin-section-renderers.test.js +52 -4
- package/dist/__tests__/views/admin-section-renderers.test.js.map +1 -1
- package/dist/__tests__/views/canvas-review-mode.render.test.d.ts +2 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.js +70 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.js.map +1 -0
- package/dist/__tests__/views/editor-top-bar.render.test.js +30 -1
- package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
- package/dist/__tests__/views/page-tab.render.test.d.ts +2 -0
- package/dist/__tests__/views/page-tab.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/page-tab.render.test.js +151 -0
- package/dist/__tests__/views/page-tab.render.test.js.map +1 -0
- package/dist/__tests__/views/section-class-parity.test.d.ts +2 -0
- package/dist/__tests__/views/section-class-parity.test.d.ts.map +1 -0
- package/dist/__tests__/views/section-class-parity.test.js +81 -0
- package/dist/__tests__/views/section-class-parity.test.js.map +1 -0
- package/dist/__tests__/views/sections-panel-design-owned.render.test.d.ts +2 -0
- package/dist/__tests__/views/sections-panel-design-owned.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/sections-panel-design-owned.render.test.js +86 -0
- package/dist/__tests__/views/sections-panel-design-owned.render.test.js.map +1 -0
- package/dist/__tests__/views/version-history-panel.render.test.d.ts +2 -0
- package/dist/__tests__/views/version-history-panel.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/version-history-panel.render.test.js +153 -0
- package/dist/__tests__/views/version-history-panel.render.test.js.map +1 -0
- package/dist/components/BreakpointPicker.d.ts +18 -0
- package/dist/components/BreakpointPicker.d.ts.map +1 -0
- package/dist/components/BreakpointPicker.js +31 -0
- package/dist/components/BreakpointPicker.js.map +1 -0
- package/dist/components/CanvasEditTip.d.ts +6 -0
- package/dist/components/CanvasEditTip.d.ts.map +1 -0
- package/dist/components/CanvasEditTip.js +22 -0
- package/dist/components/CanvasEditTip.js.map +1 -0
- package/dist/components/EditorRail.d.ts +36 -0
- package/dist/components/EditorRail.d.ts.map +1 -0
- package/dist/components/EditorRail.js +104 -0
- package/dist/components/EditorRail.js.map +1 -0
- package/dist/components/EditorRailTabs.d.ts +32 -0
- package/dist/components/EditorRailTabs.d.ts.map +1 -0
- package/dist/components/EditorRailTabs.js +45 -0
- package/dist/components/EditorRailTabs.js.map +1 -0
- package/dist/components/MediaBlock.d.ts +49 -0
- package/dist/components/MediaBlock.d.ts.map +1 -0
- package/dist/components/MediaBlock.js +50 -0
- package/dist/components/MediaBlock.js.map +1 -0
- package/dist/components/ReflowMeter.d.ts +28 -0
- package/dist/components/ReflowMeter.d.ts.map +1 -0
- package/dist/components/ReflowMeter.js +42 -0
- package/dist/components/ReflowMeter.js.map +1 -0
- package/dist/components/ZoomChip.d.ts +17 -0
- package/dist/components/ZoomChip.d.ts.map +1 -0
- package/dist/components/ZoomChip.js +17 -0
- package/dist/components/ZoomChip.js.map +1 -0
- package/dist/components/breakpoint-icons.d.ts +3 -0
- package/dist/components/breakpoint-icons.d.ts.map +1 -0
- package/dist/components/breakpoint-icons.js +16 -0
- package/dist/components/breakpoint-icons.js.map +1 -0
- package/dist/components/page-tab/AuthorPicker.d.ts +31 -0
- package/dist/components/page-tab/AuthorPicker.d.ts.map +1 -0
- package/dist/components/page-tab/AuthorPicker.js +95 -0
- package/dist/components/page-tab/AuthorPicker.js.map +1 -0
- package/dist/components/page-tab/DirectiveSwitch.d.ts +38 -0
- package/dist/components/page-tab/DirectiveSwitch.d.ts.map +1 -0
- package/dist/components/page-tab/DirectiveSwitch.js +33 -0
- package/dist/components/page-tab/DirectiveSwitch.js.map +1 -0
- package/dist/components/seo/EditorSeoScoreBadge.d.ts +8 -1
- package/dist/components/seo/EditorSeoScoreBadge.d.ts.map +1 -1
- package/dist/components/seo/EditorSeoScoreBadge.js +2 -2
- package/dist/components/seo/EditorSeoScoreBadge.js.map +1 -1
- package/dist/components/seo/PageAuditPanel.d.ts +14 -0
- package/dist/components/seo/PageAuditPanel.d.ts.map +1 -0
- package/dist/components/seo/PageAuditPanel.js +59 -0
- package/dist/components/seo/PageAuditPanel.js.map +1 -0
- package/dist/components/seo/SeoCharCount.d.ts +19 -7
- package/dist/components/seo/SeoCharCount.d.ts.map +1 -1
- package/dist/components/seo/SeoCharCount.js +30 -16
- package/dist/components/seo/SeoCharCount.js.map +1 -1
- package/dist/components/seo/SeoEditorPane.d.ts +15 -1
- package/dist/components/seo/SeoEditorPane.d.ts.map +1 -1
- package/dist/components/seo/SeoEditorPane.js +118 -21
- package/dist/components/seo/SeoEditorPane.js.map +1 -1
- package/dist/components/seo/SerpPreview.d.ts +20 -0
- package/dist/components/seo/SerpPreview.d.ts.map +1 -0
- package/dist/components/seo/SerpPreview.js +6 -0
- package/dist/components/seo/SerpPreview.js.map +1 -0
- package/dist/hooks/usePageAudit.d.ts +41 -0
- package/dist/hooks/usePageAudit.d.ts.map +1 -0
- package/dist/hooks/usePageAudit.js +68 -0
- package/dist/hooks/usePageAudit.js.map +1 -0
- package/dist/hooks/useReflowGuard.d.ts +47 -0
- package/dist/hooks/useReflowGuard.d.ts.map +1 -0
- package/dist/hooks/useReflowGuard.js +52 -0
- package/dist/hooks/useReflowGuard.js.map +1 -0
- package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
- package/dist/layout/primitives/AdminShell.js +2 -2
- package/dist/layout/primitives/AdminShell.js.map +1 -1
- package/dist/lib/breakpoints.d.ts +51 -0
- package/dist/lib/breakpoints.d.ts.map +1 -0
- package/dist/lib/breakpoints.js +84 -0
- package/dist/lib/breakpoints.js.map +1 -0
- package/dist/lib/canvas-edit-chrome.d.ts +22 -0
- package/dist/lib/canvas-edit-chrome.d.ts.map +1 -0
- package/dist/lib/canvas-edit-chrome.js +81 -0
- package/dist/lib/canvas-edit-chrome.js.map +1 -0
- package/dist/lib/media-format.d.ts +55 -0
- package/dist/lib/media-format.d.ts.map +1 -0
- package/dist/lib/media-format.js +93 -0
- package/dist/lib/media-format.js.map +1 -0
- package/dist/lib/page-audit-input.d.ts +45 -0
- package/dist/lib/page-audit-input.d.ts.map +1 -0
- package/dist/lib/page-audit-input.js +53 -0
- package/dist/lib/page-audit-input.js.map +1 -0
- package/dist/lib/page-editor-service.d.ts +12 -0
- package/dist/lib/page-editor-service.d.ts.map +1 -1
- package/dist/lib/page-editor-service.js +6 -0
- package/dist/lib/page-editor-service.js.map +1 -1
- package/dist/lib/page-redirect.d.ts +39 -0
- package/dist/lib/page-redirect.d.ts.map +1 -0
- package/dist/lib/page-redirect.js +38 -0
- package/dist/lib/page-redirect.js.map +1 -0
- package/dist/lib/rail-width.d.ts +23 -0
- package/dist/lib/rail-width.d.ts.map +1 -0
- package/dist/lib/rail-width.js +59 -0
- package/dist/lib/rail-width.js.map +1 -0
- package/dist/lib/reflow-baseline.d.ts +45 -0
- package/dist/lib/reflow-baseline.d.ts.map +1 -0
- package/dist/lib/reflow-baseline.js +38 -0
- package/dist/lib/reflow-baseline.js.map +1 -0
- package/dist/lib/reflow-probe.d.ts +159 -0
- package/dist/lib/reflow-probe.d.ts.map +1 -0
- package/dist/lib/reflow-probe.js +228 -0
- package/dist/lib/reflow-probe.js.map +1 -0
- package/dist/lib/seo-service.d.ts +10 -0
- package/dist/lib/seo-service.d.ts.map +1 -1
- package/dist/lib/seo-service.js.map +1 -1
- package/dist/lib/version-diff.d.ts +50 -0
- package/dist/lib/version-diff.d.ts.map +1 -0
- package/dist/lib/version-diff.js +294 -0
- package/dist/lib/version-diff.js.map +1 -0
- package/dist/lib/version-history.d.ts +73 -0
- package/dist/lib/version-history.d.ts.map +1 -0
- package/dist/lib/version-history.js +126 -0
- package/dist/lib/version-history.js.map +1 -0
- package/dist/prenta-admin.css +1 -1
- package/dist/views/page-editor/CanvasMetaLine.d.ts +19 -0
- package/dist/views/page-editor/CanvasMetaLine.d.ts.map +1 -0
- package/dist/views/page-editor/CanvasMetaLine.js +23 -0
- package/dist/views/page-editor/CanvasMetaLine.js.map +1 -0
- package/dist/views/page-editor/EditorCanvas.d.ts +47 -8
- package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
- package/dist/views/page-editor/EditorCanvas.js +68 -34
- package/dist/views/page-editor/EditorCanvas.js.map +1 -1
- package/dist/views/page-editor/EditorTopBar.d.ts +21 -2
- package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
- package/dist/views/page-editor/EditorTopBar.js +13 -20
- package/dist/views/page-editor/EditorTopBar.js.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.js +383 -78
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
- package/dist/views/page-editor/PageTab.d.ts +36 -0
- package/dist/views/page-editor/PageTab.d.ts.map +1 -0
- package/dist/views/page-editor/PageTab.js +65 -0
- package/dist/views/page-editor/PageTab.js.map +1 -0
- package/dist/views/page-editor/ReviewBar.d.ts +21 -0
- package/dist/views/page-editor/ReviewBar.d.ts.map +1 -0
- package/dist/views/page-editor/ReviewBar.js +22 -0
- package/dist/views/page-editor/ReviewBar.js.map +1 -0
- package/dist/views/page-editor/SectionInspector.d.ts.map +1 -1
- package/dist/views/page-editor/SectionInspector.js +64 -20
- package/dist/views/page-editor/SectionInspector.js.map +1 -1
- package/dist/views/page-editor/SectionsPanel.d.ts +30 -5
- package/dist/views/page-editor/SectionsPanel.d.ts.map +1 -1
- package/dist/views/page-editor/SectionsPanel.js +38 -7
- package/dist/views/page-editor/SectionsPanel.js.map +1 -1
- package/dist/views/page-editor/SitePreviewFrame.d.ts.map +1 -1
- package/dist/views/page-editor/SitePreviewFrame.js +3 -0
- package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
- package/dist/views/page-editor/VersionHistoryPanel.d.ts +29 -0
- package/dist/views/page-editor/VersionHistoryPanel.d.ts.map +1 -0
- package/dist/views/page-editor/VersionHistoryPanel.js +81 -0
- package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -0
- package/dist/views/page-editor/reflow-context.d.ts +28 -0
- package/dist/views/page-editor/reflow-context.d.ts.map +1 -0
- package/dist/views/page-editor/reflow-context.js +14 -0
- package/dist/views/page-editor/reflow-context.js.map +1 -0
- package/dist/views/page-editor/sections/ByTheNumbersSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
- package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
- package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/GallerySection.js +7 -3
- package/dist/views/page-editor/sections/GallerySection.js.map +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/MissionSection.js +1 -1
- package/dist/views/page-editor/sections/MissionSection.js.map +1 -1
- package/dist/views/page-editor/sections/PullQuoteSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/PullQuoteSection.js +1 -1
- package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -1
- package/dist/views/page-editor/sections/RelatedPostsSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/RelatedPostsSection.js +1 -1
- package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.d.ts +13 -1
- package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.js +66 -26
- package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
- package/dist/views/page-editor/sections/admin-renderers.d.ts +47 -15
- package/dist/views/page-editor/sections/admin-renderers.d.ts.map +1 -1
- package/dist/views/page-editor/sections/admin-renderers.js +27 -15
- package/dist/views/page-editor/sections/admin-renderers.js.map +1 -1
- package/dist/views/page-editor/sections/parts.d.ts +0 -1
- package/dist/views/page-editor/sections/parts.d.ts.map +1 -1
- package/dist/views/page-editor/sections/parts.js +41 -16
- package/dist/views/page-editor/sections/parts.js.map +1 -1
- package/dist/views/page-editor/viewports.d.ts +7 -14
- package/dist/views/page-editor/viewports.d.ts.map +1 -1
- package/dist/views/page-editor/viewports.js +7 -12
- package/dist/views/page-editor/viewports.js.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.d.ts +2 -1
- package/dist/views/post-editor/PostEditorCanvas.d.ts.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.js +5 -2
- package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.js +2 -20
- package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
- package/dist/views/post-editor/PostTemplateEditor.d.ts.map +1 -1
- package/dist/views/post-editor/PostTemplateEditor.js +4 -1
- package/dist/views/post-editor/PostTemplateEditor.js.map +1 -1
- package/package.json +5 -3
- package/src/AdminRoot.tsx +27 -6
- package/src/__tests__/components/breakpoint-controls.render.test.tsx +57 -0
- package/src/__tests__/components/canvas-edit-tip.render.test.tsx +41 -0
- package/src/__tests__/components/editor-rail.render.test.tsx +192 -0
- package/src/__tests__/components/media-block.render.test.tsx +126 -0
- package/src/__tests__/components/page-audit-panel.render.test.tsx +64 -0
- package/src/__tests__/components/reflow-meter.render.test.tsx +144 -0
- package/src/__tests__/components/seo-char-count.test.tsx +26 -6
- package/src/__tests__/components/serp-preview.render.test.tsx +32 -0
- package/src/__tests__/lib/breakpoints.test.ts +84 -0
- package/src/__tests__/lib/canvas-edit-chrome.test.ts +56 -0
- package/src/__tests__/lib/media-format.test.ts +89 -0
- package/src/__tests__/lib/page-audit-input.test.ts +144 -0
- package/src/__tests__/lib/page-editor-service.test.ts +2 -0
- package/src/__tests__/lib/page-redirect.test.ts +29 -0
- package/src/__tests__/lib/rail-width.test.ts +86 -0
- package/src/__tests__/lib/reflow-baseline.test.ts +64 -0
- package/src/__tests__/lib/reflow-probe.test.ts +95 -0
- package/src/__tests__/lib/version-diff.test.ts +278 -0
- package/src/__tests__/lib/version-history.test.ts +166 -0
- package/src/__tests__/styles/canvas-container-queries.test.ts +103 -0
- package/src/__tests__/styles/packaging.test.ts +38 -0
- package/src/__tests__/styles/responsive-layer.test.ts +152 -0
- package/src/__tests__/styles/tokens-drift.test.ts +110 -0
- package/src/__tests__/views/admin-renderer-compat.test.ts +48 -0
- package/src/__tests__/views/admin-section-renderers.test.tsx +70 -4
- package/src/__tests__/views/canvas-review-mode.render.test.tsx +94 -0
- package/src/__tests__/views/editor-top-bar.render.test.tsx +43 -1
- package/src/__tests__/views/page-tab.render.test.tsx +226 -0
- package/src/__tests__/views/section-class-parity.test.ts +98 -0
- package/src/__tests__/views/sections-panel-design-owned.render.test.tsx +104 -0
- package/src/__tests__/views/version-history-panel.render.test.tsx +195 -0
- package/src/components/BreakpointPicker.tsx +114 -0
- package/src/components/CanvasEditTip.tsx +46 -0
- package/src/components/EditorRail.tsx +219 -0
- package/src/components/EditorRailTabs.tsx +117 -0
- package/src/components/MediaBlock.tsx +223 -0
- package/src/components/ReflowMeter.tsx +125 -0
- package/src/components/ZoomChip.tsx +39 -0
- package/src/components/breakpoint-icons.ts +17 -0
- package/src/components/page-tab/AuthorPicker.tsx +240 -0
- package/src/components/page-tab/DirectiveSwitch.tsx +89 -0
- package/src/components/seo/EditorSeoScoreBadge.tsx +9 -1
- package/src/components/seo/PageAuditPanel.tsx +192 -0
- package/src/components/seo/SeoCharCount.tsx +55 -24
- package/src/components/seo/SeoEditorPane.tsx +213 -31
- package/src/components/seo/SerpPreview.tsx +41 -0
- package/src/hooks/usePageAudit.ts +98 -0
- package/src/hooks/useReflowGuard.ts +96 -0
- package/src/layout/primitives/AdminShell.tsx +13 -1
- package/src/lib/breakpoints.ts +107 -0
- package/src/lib/canvas-edit-chrome.ts +82 -0
- package/src/lib/media-format.ts +99 -0
- package/src/lib/page-audit-input.ts +104 -0
- package/src/lib/page-editor-service.ts +18 -0
- package/src/lib/page-redirect.ts +60 -0
- package/src/lib/rail-width.ts +58 -0
- package/src/lib/reflow-baseline.ts +70 -0
- package/src/lib/reflow-probe.ts +299 -0
- package/src/lib/seo-service.ts +10 -0
- package/src/lib/version-diff.ts +376 -0
- package/src/lib/version-history.ts +192 -0
- package/src/styles/prenta-tokens.css +120 -42
- package/src/styles/responsive.css +281 -0
- package/src/styles/theme.css +138 -0
- package/src/views/page-editor/CanvasMetaLine.tsx +50 -0
- package/src/views/page-editor/EditorCanvas.tsx +140 -54
- package/src/views/page-editor/EditorTopBar.tsx +55 -51
- package/src/views/page-editor/PageSectionEditor.tsx +575 -185
- package/src/views/page-editor/PageTab.tsx +433 -0
- package/src/views/page-editor/ReviewBar.tsx +76 -0
- package/src/views/page-editor/SectionInspector.tsx +84 -42
- package/src/views/page-editor/SectionsPanel.tsx +282 -141
- package/src/views/page-editor/SitePreviewFrame.tsx +3 -0
- package/src/views/page-editor/VersionHistoryPanel.tsx +302 -0
- package/src/views/page-editor/reflow-context.ts +43 -0
- package/src/views/page-editor/sections/ByTheNumbersSection.tsx +3 -2
- package/src/views/page-editor/sections/CtaBannerSection.tsx +3 -1
- package/src/views/page-editor/sections/FeatureHighlightSection.tsx +3 -2
- package/src/views/page-editor/sections/GallerySection.tsx +7 -3
- package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
- package/src/views/page-editor/sections/MissionSection.tsx +4 -2
- package/src/views/page-editor/sections/PullQuoteSection.tsx +3 -1
- package/src/views/page-editor/sections/RelatedPostsSection.tsx +2 -1
- package/src/views/page-editor/sections/SectionRenderer.tsx +115 -34
- package/src/views/page-editor/sections/admin-renderers.tsx +54 -15
- package/src/views/page-editor/sections/parts.tsx +46 -18
- package/src/views/page-editor/viewports.ts +13 -26
- package/src/views/post-editor/PostEditorCanvas.tsx +18 -11
- package/src/views/post-editor/PostSectionEditor.tsx +1 -56
- 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,
|
|
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,
|
|
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"}
|