@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
|
@@ -1,71 +1,116 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
|
4
|
-
import { LayoutTemplate
|
|
4
|
+
import { LayoutTemplate } from 'lucide-react'
|
|
5
|
+
import { CanvasEditTip } from '../../components/CanvasEditTip.js'
|
|
6
|
+
import { CanvasMetaLine } from './CanvasMetaLine.js'
|
|
7
|
+
import { fitScale, getBreakpoint, type BreakpointId, type Zoom } from '../../lib/breakpoints.js'
|
|
5
8
|
import type { PageSection } from '../../lib/page-editor-service.js'
|
|
6
9
|
import { SectionRenderer } from './sections/index.js'
|
|
7
10
|
import { StructureNotice } from './StructureNotice.js'
|
|
8
|
-
import { getViewport, type ViewportId } from './viewports.js'
|
|
9
11
|
|
|
10
12
|
interface EditorCanvasProps {
|
|
11
13
|
sections: PageSection[]
|
|
12
14
|
selectedId: string | null
|
|
13
|
-
|
|
15
|
+
breakpoint: BreakpointId
|
|
16
|
+
zoom?: Zoom
|
|
14
17
|
onSelect: (id: string) => void
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Reports the measured scale so the header's zoom chip can show a real
|
|
20
|
+
* percentage. Only the canvas knows the available width, so the number has
|
|
21
|
+
* to travel up rather than being recomputed by the header.
|
|
22
|
+
*/
|
|
23
|
+
onScaleChange?: (scale: number) => void
|
|
24
|
+
/**
|
|
25
|
+
* Reports the canvas surface element, so the reflow guard can clone it. The
|
|
26
|
+
* guard needs the real element rather than a `document.querySelector`, which
|
|
27
|
+
* would also match the site-preview frame's canvas when that is mounted.
|
|
28
|
+
*/
|
|
29
|
+
onCanvasElement?: (el: HTMLElement | null) => void
|
|
16
30
|
/** Section types rendered as placeholders — shows the "Structure view" notice. */
|
|
17
31
|
structuralTypes?: string[]
|
|
18
32
|
sitePreviewAvailable?: boolean
|
|
33
|
+
/**
|
|
34
|
+
* Read-only render of a past version. Suppresses selection and the editing
|
|
35
|
+
* affordances, and turns on the changed-section outlines.
|
|
36
|
+
*/
|
|
37
|
+
reviewing?: boolean
|
|
38
|
+
/** Sections that differ from the version before the one being reviewed. */
|
|
39
|
+
changedSectionIds?: ReadonlySet<string>
|
|
40
|
+
/**
|
|
41
|
+
* Rendered in place of the editing tip / structure notice while reviewing.
|
|
42
|
+
* Passed in rather than built here because the review bar's actions belong
|
|
43
|
+
* to the editor's history state, which the canvas knows nothing about.
|
|
44
|
+
*/
|
|
45
|
+
reviewBar?: React.ReactNode
|
|
19
46
|
}
|
|
20
47
|
|
|
21
48
|
/**
|
|
22
|
-
* The preview canvas.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* a
|
|
49
|
+
* The preview canvas.
|
|
50
|
+
*
|
|
51
|
+
* The canvas renders at the breakpoint's **real CSS width** and is scaled down
|
|
52
|
+
* with a transform. Combined with `container-type: inline-size`, that makes the
|
|
53
|
+
* page reflow against its own width — the same container queries that style the
|
|
54
|
+
* live page decide the layout. A max-width clamp cannot do this: it yields a
|
|
55
|
+
* narrow desktop layout rather than the mobile one.
|
|
56
|
+
*
|
|
57
|
+
* Two measurement rules, both learned the hard way:
|
|
58
|
+
*
|
|
59
|
+
* 1. Available width comes from a **zero-height sentinel** rendered as the
|
|
60
|
+
* panel's first child, not from `panel.clientWidth - padding`. The two
|
|
61
|
+
* disagree once a scrollbar appears or the host scales the preview, and
|
|
62
|
+
* the padding arithmetic silently rots whenever the gutter changes.
|
|
63
|
+
* 2. Both measurements are re-taken on **every render**, not only from the
|
|
64
|
+
* ResizeObserver. Page height changes with every text edit, image swap and
|
|
65
|
+
* show/hide — none of which resize the observed elements. The observer
|
|
66
|
+
* exists for later window resizes; its first callback is not a substitute.
|
|
26
67
|
*/
|
|
27
68
|
export function EditorCanvas({
|
|
28
69
|
sections,
|
|
29
70
|
selectedId,
|
|
30
|
-
|
|
71
|
+
breakpoint,
|
|
72
|
+
zoom = 'fit',
|
|
31
73
|
onSelect,
|
|
32
|
-
|
|
74
|
+
onScaleChange,
|
|
75
|
+
onCanvasElement,
|
|
33
76
|
structuralTypes = [],
|
|
34
77
|
sitePreviewAvailable = false,
|
|
78
|
+
reviewing = false,
|
|
79
|
+
changedSectionIds,
|
|
80
|
+
reviewBar,
|
|
35
81
|
}: EditorCanvasProps) {
|
|
36
|
-
const
|
|
37
|
-
const
|
|
82
|
+
const bp = getBreakpoint(breakpoint)
|
|
83
|
+
const sentinelRef = useRef<HTMLDivElement>(null)
|
|
38
84
|
const surfaceRef = useRef<HTMLDivElement>(null)
|
|
39
85
|
const sectionRefs = useRef<Map<string, HTMLElement>>(new Map())
|
|
40
|
-
|
|
41
|
-
const [
|
|
86
|
+
|
|
87
|
+
const [available, setAvailable] = useState(0)
|
|
88
|
+
const [pageHeight, setPageHeight] = useState(0)
|
|
42
89
|
|
|
43
90
|
const registerRef = useCallback((id: string, el: HTMLElement | null) => {
|
|
44
91
|
if (el) sectionRefs.current.set(id, el)
|
|
45
92
|
else sectionRefs.current.delete(id)
|
|
46
93
|
}, [])
|
|
47
94
|
|
|
48
|
-
//
|
|
95
|
+
// No dependency array: page height changes on edits that resize nothing the
|
|
96
|
+
// observer watches. Both setters bail when the value is unchanged, so this
|
|
97
|
+
// settles after one extra pass instead of looping.
|
|
49
98
|
useLayoutEffect(() => {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const next = Math.min(1, available / vp.width)
|
|
57
|
-
setScale(next > 0 ? next : 1)
|
|
58
|
-
if (surfaceRef.current) {
|
|
59
|
-
setSurfaceHeight(surfaceRef.current.offsetHeight * (next > 0 ? next : 1))
|
|
60
|
-
}
|
|
99
|
+
const measure = () => {
|
|
100
|
+
const sentinelWidth = sentinelRef.current?.offsetWidth ?? 0
|
|
101
|
+
if (sentinelWidth > 0) setAvailable((prev) => (prev === sentinelWidth ? prev : sentinelWidth))
|
|
102
|
+
|
|
103
|
+
const height = surfaceRef.current?.offsetHeight ?? 0
|
|
104
|
+
if (height > 0) setPageHeight((prev) => (prev === height ? prev : height))
|
|
61
105
|
}
|
|
62
106
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
ro
|
|
107
|
+
measure()
|
|
108
|
+
|
|
109
|
+
const ro = new ResizeObserver(measure)
|
|
110
|
+
if (sentinelRef.current) ro.observe(sentinelRef.current)
|
|
66
111
|
if (surfaceRef.current) ro.observe(surfaceRef.current)
|
|
67
112
|
return () => ro.disconnect()
|
|
68
|
-
}
|
|
113
|
+
})
|
|
69
114
|
|
|
70
115
|
// Scroll the selected section into view within the canvas.
|
|
71
116
|
useEffect(() => {
|
|
@@ -74,28 +119,70 @@ export function EditorCanvas({
|
|
|
74
119
|
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
|
75
120
|
}, [selectedId])
|
|
76
121
|
|
|
122
|
+
const scale = fitScale(available, bp.width, zoom)
|
|
123
|
+
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
onScaleChange?.(scale)
|
|
126
|
+
}, [scale, onScaleChange])
|
|
127
|
+
|
|
77
128
|
return (
|
|
78
|
-
<div
|
|
129
|
+
<div className="prenta-canvas-scroll bg-muted h-full overflow-auto px-6 pt-4.5 pb-10 text-center">
|
|
130
|
+
{/*
|
|
131
|
+
* Zero-height sentinel. Its offsetWidth IS the usable width — it is
|
|
132
|
+
* subject to exactly the same padding, scrollbar and host scaling as the
|
|
133
|
+
* canvas, so there is no arithmetic to get wrong. Must stay the first
|
|
134
|
+
* child and must stay zero-height.
|
|
135
|
+
*/}
|
|
136
|
+
<div ref={sentinelRef} aria-hidden className="h-0" />
|
|
137
|
+
|
|
79
138
|
{sections.length === 0 ? (
|
|
80
|
-
<EmptyCanvas
|
|
139
|
+
<EmptyCanvas />
|
|
81
140
|
) : (
|
|
82
141
|
<>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
142
|
+
{/* The review bar REPLACES the editing chrome rather than joining it:
|
|
143
|
+
a tip about clicking sections to edit them is actively wrong while
|
|
144
|
+
the canvas is showing a version you cannot edit. */}
|
|
145
|
+
{reviewing ? (
|
|
146
|
+
reviewBar
|
|
147
|
+
) : (
|
|
148
|
+
<>
|
|
149
|
+
<CanvasEditTip />
|
|
150
|
+
<StructureNotice
|
|
151
|
+
structuralTypes={structuralTypes}
|
|
152
|
+
sitePreviewAvailable={sitePreviewAvailable}
|
|
153
|
+
/>
|
|
154
|
+
</>
|
|
155
|
+
)}
|
|
156
|
+
<CanvasMetaLine breakpoint={bp} pageHeight={pageHeight} scale={scale} />
|
|
157
|
+
|
|
158
|
+
{/*
|
|
159
|
+
* Fit box: reserves the scaled footprint so the surrounding scroll
|
|
160
|
+
* area sizes correctly against a transformed child. Deliberately has
|
|
161
|
+
* NO width/height transition — a transition frozen mid-flight (a
|
|
162
|
+
* preview that is not visible never finishes one) reports a bogus
|
|
163
|
+
* height and corrupts the next measurement.
|
|
164
|
+
*/}
|
|
87
165
|
<div
|
|
88
|
-
className="mx-auto"
|
|
89
|
-
style={{
|
|
166
|
+
className="prenta-canvas-fit mx-auto block"
|
|
167
|
+
style={{
|
|
168
|
+
width: Math.round(bp.width * scale),
|
|
169
|
+
height: pageHeight ? Math.round(pageHeight * scale) : undefined,
|
|
170
|
+
}}
|
|
90
171
|
>
|
|
91
172
|
{/* `prenta-canvas` is the public hook for consumer brand CSS:
|
|
92
173
|
site styles that should render in this preview scope to
|
|
93
174
|
`.prenta-admin .prenta-canvas` instead of the admin root. */}
|
|
94
175
|
<div
|
|
95
|
-
ref={
|
|
96
|
-
|
|
176
|
+
ref={(el) => {
|
|
177
|
+
surfaceRef.current = el
|
|
178
|
+
onCanvasElement?.(el)
|
|
179
|
+
}}
|
|
180
|
+
// `prenta-canvas` carries `container-type: inline-size` (theme.css)
|
|
181
|
+
// — that is what makes the `@pv-*` steps in the section renderers
|
|
182
|
+
// resolve against the simulated width instead of the viewport.
|
|
183
|
+
className="prenta-canvas border-border bg-card origin-top-left overflow-hidden rounded-lg text-left shadow-[0_2px_20px_rgba(0,0,0,0.12)] motion-safe:transition-[width,transform] motion-safe:duration-(--mo-slow) motion-safe:ease-(--ease)"
|
|
97
184
|
style={{
|
|
98
|
-
width:
|
|
185
|
+
width: bp.width,
|
|
99
186
|
transform: `scale(${scale})`,
|
|
100
187
|
transformOrigin: 'top left',
|
|
101
188
|
}}
|
|
@@ -105,6 +192,8 @@ export function EditorCanvas({
|
|
|
105
192
|
key={section.id}
|
|
106
193
|
section={section}
|
|
107
194
|
editable
|
|
195
|
+
reviewing={reviewing}
|
|
196
|
+
changed={changedSectionIds?.has(section.id) ?? false}
|
|
108
197
|
selected={section.id === selectedId}
|
|
109
198
|
onSelect={onSelect}
|
|
110
199
|
registerRef={registerRef}
|
|
@@ -118,25 +207,22 @@ export function EditorCanvas({
|
|
|
118
207
|
)
|
|
119
208
|
}
|
|
120
209
|
|
|
121
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Design-owned pages always ship the template's sections, so an empty canvas
|
|
212
|
+
* means the template resolved to nothing — a configuration problem, not an
|
|
213
|
+
* invitation to add a section. There is deliberately no "Add section" button.
|
|
214
|
+
*/
|
|
215
|
+
function EmptyCanvas() {
|
|
122
216
|
return (
|
|
123
217
|
<div className="mx-auto flex h-full max-w-md flex-col items-center justify-center text-center">
|
|
124
218
|
<div className="bg-card border-border mb-4 flex h-14 w-14 items-center justify-center rounded-full border">
|
|
125
219
|
<LayoutTemplate className="text-muted-foreground h-6 w-6" aria-hidden />
|
|
126
220
|
</div>
|
|
127
|
-
<h2 className="text-foreground text-lg font-medium">This
|
|
128
|
-
<p className="text-muted-foreground mt-1
|
|
129
|
-
|
|
130
|
-
|
|
221
|
+
<h2 className="text-foreground text-lg font-medium">This template renders no sections</h2>
|
|
222
|
+
<p className="text-muted-foreground mt-1 text-sm">
|
|
223
|
+
Layout is design-owned — sections come from the page's template in code. Check that the page
|
|
224
|
+
has a template assigned, or pick a different one in Page settings.
|
|
131
225
|
</p>
|
|
132
|
-
<button
|
|
133
|
-
type="button"
|
|
134
|
-
onClick={onAddSection}
|
|
135
|
-
className="bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors"
|
|
136
|
-
>
|
|
137
|
-
<Plus className="h-4 w-4" aria-hidden />
|
|
138
|
-
Add Section
|
|
139
|
-
</button>
|
|
140
226
|
</div>
|
|
141
227
|
)
|
|
142
228
|
}
|
|
@@ -7,18 +7,16 @@ import {
|
|
|
7
7
|
Eye,
|
|
8
8
|
Globe,
|
|
9
9
|
History,
|
|
10
|
-
Laptop,
|
|
11
10
|
Loader2,
|
|
12
|
-
type LucideIcon,
|
|
13
|
-
Monitor,
|
|
14
11
|
Settings2,
|
|
15
|
-
Smartphone,
|
|
16
|
-
Tablet,
|
|
17
12
|
TriangleAlert,
|
|
18
13
|
} from 'lucide-react'
|
|
19
14
|
import { EditorSeoScoreBadge } from '../../components/seo/EditorSeoScoreBadge.js'
|
|
15
|
+
import { BreakpointPicker } from '../../components/BreakpointPicker.js'
|
|
16
|
+
import { ZoomChip } from '../../components/ZoomChip.js'
|
|
20
17
|
import type { PageStatus } from '../../lib/page-editor-service.js'
|
|
21
|
-
import {
|
|
18
|
+
import type { Zoom } from '../../lib/breakpoints.js'
|
|
19
|
+
import { type ViewportId } from './viewports.js'
|
|
22
20
|
|
|
23
21
|
export type SaveState = 'idle' | 'saving' | 'saved' | 'error'
|
|
24
22
|
|
|
@@ -35,6 +33,11 @@ interface EditorTopBarProps {
|
|
|
35
33
|
/** Shown on hover/focus when publish is blocked by validation (not role). */
|
|
36
34
|
publishDisabledReason?: string
|
|
37
35
|
viewport: ViewportId
|
|
36
|
+
/** Canvas zoom mode; omit to hide the zoom chip (e.g. the site-preview iframe). */
|
|
37
|
+
zoom?: Zoom
|
|
38
|
+
/** Scale the canvas actually measured, 0–1 — displayed by the zoom chip. */
|
|
39
|
+
canvasScale?: number
|
|
40
|
+
onZoom?: (zoom: Zoom) => void
|
|
38
41
|
/** Breadcrumb root label + back-button text (e.g. "Pages" or "Posts"). */
|
|
39
42
|
backLabel?: string
|
|
40
43
|
onViewport: (v: ViewportId) => void
|
|
@@ -47,10 +50,16 @@ interface EditorTopBarProps {
|
|
|
47
50
|
*/
|
|
48
51
|
onViewOnSite?: () => void
|
|
49
52
|
/**
|
|
50
|
-
*
|
|
53
|
+
* Toggle the version history panel. When omitted the History button is
|
|
51
54
|
* hidden — e.g. for unsaved documents that have no versions yet.
|
|
52
55
|
*/
|
|
53
56
|
onHistory?: () => void
|
|
57
|
+
/**
|
|
58
|
+
* Whether history is showing. History takes over the rail rather than
|
|
59
|
+
* opening a dialog, so the button needs a pressed state — without one there
|
|
60
|
+
* is nothing in the chrome saying which mode the editor is in.
|
|
61
|
+
*/
|
|
62
|
+
historyOpen?: boolean
|
|
54
63
|
/** Whether the inline site preview (iframe of the public site) is showing. */
|
|
55
64
|
sitePreview?: boolean
|
|
56
65
|
/**
|
|
@@ -63,7 +72,14 @@ interface EditorTopBarProps {
|
|
|
63
72
|
onOpenSeo?: () => void
|
|
64
73
|
seoOpen?: boolean
|
|
65
74
|
/** Live 0–100 SEO score shown left of the SEO label. */
|
|
75
|
+
/**
|
|
76
|
+
* 0-100 for the header chip. `undefined` means not known yet — the chip
|
|
77
|
+
* renders without a number rather than defaulting to 0, which would read as
|
|
78
|
+
* a catastrophic score for a page nobody has audited.
|
|
79
|
+
*/
|
|
66
80
|
seoScore?: number
|
|
81
|
+
/** Band for `seoScore`; omit to derive from the content-analysis scale. */
|
|
82
|
+
seoScoreBand?: 'good' | 'fair' | 'poor'
|
|
67
83
|
onSaveDraft: () => void
|
|
68
84
|
onPublish: () => void
|
|
69
85
|
/** Open the schedule-publish dialog. Omitted when the document is unsaved. */
|
|
@@ -81,13 +97,6 @@ interface EditorTopBarProps {
|
|
|
81
97
|
structuralTypes?: string[]
|
|
82
98
|
}
|
|
83
99
|
|
|
84
|
-
const VIEWPORT_ICONS: Record<string, LucideIcon> = {
|
|
85
|
-
monitor: Monitor,
|
|
86
|
-
laptop: Laptop,
|
|
87
|
-
tablet: Tablet,
|
|
88
|
-
smartphone: Smartphone,
|
|
89
|
-
}
|
|
90
|
-
|
|
91
100
|
const STATUS_TEXT: Record<PageStatus, { label: string; className: string }> = {
|
|
92
101
|
DRAFT: { label: 'Draft', className: 'text-warning dark:text-amber-400' },
|
|
93
102
|
PUBLISHED: { label: 'Published', className: 'text-emerald-600 dark:text-emerald-400' },
|
|
@@ -106,18 +115,23 @@ export function EditorTopBar({
|
|
|
106
115
|
publishReady = true,
|
|
107
116
|
publishDisabledReason,
|
|
108
117
|
viewport,
|
|
118
|
+
zoom,
|
|
119
|
+
canvasScale,
|
|
120
|
+
onZoom,
|
|
109
121
|
backLabel = 'Pages',
|
|
110
122
|
onViewport,
|
|
111
123
|
onBack,
|
|
112
124
|
onPreview,
|
|
113
125
|
onViewOnSite,
|
|
114
126
|
onHistory,
|
|
127
|
+
historyOpen = false,
|
|
115
128
|
sitePreview = false,
|
|
116
129
|
onToggleSitePreview,
|
|
117
130
|
onOpenSettings,
|
|
118
131
|
onOpenSeo,
|
|
119
132
|
seoOpen = false,
|
|
120
|
-
seoScore
|
|
133
|
+
seoScore,
|
|
134
|
+
seoScoreBand,
|
|
121
135
|
onSaveDraft,
|
|
122
136
|
onPublish,
|
|
123
137
|
onSchedule,
|
|
@@ -170,7 +184,7 @@ export function EditorTopBar({
|
|
|
170
184
|
: 'Schedule a future publish date'
|
|
171
185
|
|
|
172
186
|
return (
|
|
173
|
-
<header className="bg-card border-border flex h-14 shrink-0 items-center justify-between gap-4 border-b px-4">
|
|
187
|
+
<header className="prenta-editor-header bg-card border-border flex h-14 shrink-0 items-center justify-between gap-4 border-b px-4">
|
|
174
188
|
{/* Breadcrumb + status */}
|
|
175
189
|
<div className="flex min-w-0 items-center gap-2">
|
|
176
190
|
<nav aria-label="Breadcrumb" className="flex min-w-0 items-center gap-1.5 text-sm">
|
|
@@ -209,32 +223,11 @@ export function EditorTopBar({
|
|
|
209
223
|
|
|
210
224
|
{/* Right controls */}
|
|
211
225
|
<div className="flex items-center gap-2">
|
|
212
|
-
<div
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
{VIEWPORTS.map((v) => {
|
|
218
|
-
const Icon = VIEWPORT_ICONS[v.icon] ?? Monitor
|
|
219
|
-
const active = v.id === viewport
|
|
220
|
-
return (
|
|
221
|
-
<button
|
|
222
|
-
key={v.id}
|
|
223
|
-
type="button"
|
|
224
|
-
onClick={() => onViewport(v.id)}
|
|
225
|
-
aria-pressed={active}
|
|
226
|
-
title={`${v.label} (${v.width}px)`}
|
|
227
|
-
className={`flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium transition-colors ${
|
|
228
|
-
active
|
|
229
|
-
? 'bg-primary text-primary-foreground'
|
|
230
|
-
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
|
|
231
|
-
}`}
|
|
232
|
-
>
|
|
233
|
-
<Icon className="h-3.5 w-3.5" aria-hidden />
|
|
234
|
-
<span className="hidden lg:inline">{v.label}</span>
|
|
235
|
-
</button>
|
|
236
|
-
)
|
|
237
|
-
})}
|
|
226
|
+
<div className="hidden items-center gap-1.5 md:flex">
|
|
227
|
+
<BreakpointPicker value={viewport} onChange={onViewport} />
|
|
228
|
+
{zoom !== undefined && onZoom && (
|
|
229
|
+
<ZoomChip zoom={zoom} scale={canvasScale ?? 1} onChange={onZoom} />
|
|
230
|
+
)}
|
|
238
231
|
</div>
|
|
239
232
|
|
|
240
233
|
<button
|
|
@@ -242,7 +235,7 @@ export function EditorTopBar({
|
|
|
242
235
|
onClick={onOpenSettings}
|
|
243
236
|
aria-label="Page settings"
|
|
244
237
|
title="Page settings"
|
|
245
|
-
className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
238
|
+
className="prenta-touch-target text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
246
239
|
>
|
|
247
240
|
<Settings2 className="h-4 w-4" aria-hidden />
|
|
248
241
|
</button>
|
|
@@ -252,15 +245,21 @@ export function EditorTopBar({
|
|
|
252
245
|
type="button"
|
|
253
246
|
onClick={onOpenSeo}
|
|
254
247
|
aria-pressed={seoOpen}
|
|
255
|
-
aria-label={`SEO, score ${seoScore} out of 100`}
|
|
256
|
-
title={
|
|
248
|
+
aria-label={seoScore === undefined ? 'SEO' : `SEO, score ${seoScore} out of 100`}
|
|
249
|
+
title={
|
|
250
|
+
seoScore === undefined
|
|
251
|
+
? 'SEO — meta tags, social preview, schema, and analysis.'
|
|
252
|
+
: `SEO — score ${seoScore}/100. Meta tags, social preview, schema, and analysis.`
|
|
253
|
+
}
|
|
257
254
|
className={`inline-flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm font-medium transition-colors ${
|
|
258
255
|
seoOpen
|
|
259
256
|
? 'bg-primary text-primary-foreground'
|
|
260
257
|
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
|
|
261
258
|
}`}
|
|
262
259
|
>
|
|
263
|
-
|
|
260
|
+
{seoScore !== undefined && (
|
|
261
|
+
<EditorSeoScoreBadge score={seoScore} band={seoScoreBand} inverted={seoOpen} />
|
|
262
|
+
)}
|
|
264
263
|
<span className="hidden sm:inline">SEO</span>
|
|
265
264
|
</button>
|
|
266
265
|
)}
|
|
@@ -269,9 +268,14 @@ export function EditorTopBar({
|
|
|
269
268
|
<button
|
|
270
269
|
type="button"
|
|
271
270
|
onClick={onHistory}
|
|
271
|
+
aria-pressed={historyOpen}
|
|
272
272
|
aria-label="Version history"
|
|
273
|
-
title=
|
|
274
|
-
className=
|
|
273
|
+
title={historyOpen ? 'Close version history' : 'Version history'}
|
|
274
|
+
className={`prenta-touch-target rounded-lg p-2 transition-colors ${
|
|
275
|
+
historyOpen
|
|
276
|
+
? 'bg-primary text-primary-foreground'
|
|
277
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
|
|
278
|
+
}`}
|
|
275
279
|
>
|
|
276
280
|
<History className="h-4 w-4" aria-hidden />
|
|
277
281
|
</button>
|
|
@@ -282,7 +286,7 @@ export function EditorTopBar({
|
|
|
282
286
|
onClick={onPreview}
|
|
283
287
|
aria-label={previewLabel}
|
|
284
288
|
title={previewLabel}
|
|
285
|
-
className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
289
|
+
className="prenta-touch-target text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
286
290
|
>
|
|
287
291
|
<Eye className="h-4 w-4" aria-hidden />
|
|
288
292
|
</button>
|
|
@@ -298,7 +302,7 @@ export function EditorTopBar({
|
|
|
298
302
|
? 'Back to editor canvas'
|
|
299
303
|
: 'Inline site preview — render the draft through your public site, in place'
|
|
300
304
|
}
|
|
301
|
-
className={`rounded-lg p-2 transition-colors ${
|
|
305
|
+
className={`prenta-touch-target rounded-lg p-2 transition-colors ${
|
|
302
306
|
sitePreview
|
|
303
307
|
? 'bg-primary text-primary-foreground'
|
|
304
308
|
: 'text-muted-foreground hover:text-foreground hover:bg-accent'
|
|
@@ -329,7 +333,7 @@ export function EditorTopBar({
|
|
|
329
333
|
onClick={onViewOnSite}
|
|
330
334
|
aria-label={isLive ? 'View live page' : 'View draft on site'}
|
|
331
335
|
title={isLive ? 'View live page' : 'View draft on site'}
|
|
332
|
-
className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
336
|
+
className="prenta-touch-target text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
|
|
333
337
|
>
|
|
334
338
|
<ExternalLink className="h-4 w-4" aria-hidden />
|
|
335
339
|
</button>
|