@drawnagency/primitives 0.1.113 → 0.1.115
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/README.md +1 -1
- package/dist/auth/cookies.d.ts +39 -0
- package/dist/auth/cookies.d.ts.map +1 -1
- package/dist/auth/index.js +3 -3
- package/dist/chunk-4WQ36ZP7.js +83 -0
- package/dist/{chunk-REDDTTGJ.js → chunk-4Y2JQQZL.js} +19 -1
- package/dist/chunk-5GFACGSN.js +6 -0
- package/dist/{chunk-AHALSCQH.js → chunk-67P34WNW.js} +76 -131
- package/dist/{chunk-S2L3BPLS.js → chunk-7SX42OP4.js} +1 -1
- package/dist/{chunk-GGXZZ77Z.js → chunk-AASEGXNT.js} +18 -1
- package/dist/chunk-APIJPTFG.js +64 -0
- package/dist/{chunk-WKZ7OENC.js → chunk-BQ5TZZUE.js} +5 -1
- package/dist/chunk-CDBURDPX.js +90 -0
- package/dist/chunk-DFKTF3CH.js +0 -0
- package/dist/chunk-DIMDRBFK.js +11 -0
- package/dist/chunk-DJABADOO.js +131 -0
- package/dist/{chunk-NHN2LSIU.js → chunk-DJOGPSRU.js} +31 -68
- package/dist/{chunk-KR2MHTNJ.js → chunk-FHTKSELX.js} +610 -62
- package/dist/{chunk-WUJ3XNFI.js → chunk-GGYY3JQJ.js} +19 -24
- package/dist/chunk-GNF6KFQ7.js +18 -0
- package/dist/{chunk-FRE2CCLV.js → chunk-HHNPSKPT.js} +5 -79
- package/dist/{chunk-IINIZBQB.js → chunk-JCDZAFX2.js} +30 -10
- package/dist/chunk-JR24U7FJ.js +120 -0
- package/dist/{chunk-BDFTMGCL.js → chunk-JXATNKLV.js} +11 -10
- package/dist/{chunk-SW6PCQQD.js → chunk-KQA772WQ.js} +2 -1
- package/dist/{chunk-6BZ2KNTP.js → chunk-NX7TFHA4.js} +195 -65
- package/dist/{chunk-VWWY5TL5.js → chunk-O37AV27P.js} +14 -75
- package/dist/chunk-RIITGTV3.js +275 -0
- package/dist/{chunk-HBULBDGP.js → chunk-S37DZPHW.js} +1 -1
- package/dist/chunk-S7QRHUWO.js +8 -0
- package/dist/{chunk-Z7W3DQTR.js → chunk-T26HAKW3.js} +424 -42
- package/dist/{chunk-4I5OO5UB.js → chunk-TEOAKGZA.js} +0 -1
- package/dist/{chunk-GPPVYLEI.js → chunk-UUUSJDIG.js} +1 -1
- package/dist/chunk-VY3IFGE3.js +70 -0
- package/dist/chunk-WYOFQHKI.js +176 -0
- package/dist/{chunk-4RNF2DRG.js → chunk-XDEPXTBY.js} +0 -2
- package/dist/{chunk-DS4GCYV2.js → chunk-YV3YSZEB.js} +223 -16
- package/dist/collab/rebase.d.ts +2 -1
- package/dist/collab/rebase.d.ts.map +1 -1
- package/dist/collab/rebase.js +24 -9
- package/dist/components/brandguide/ColorsEditable.d.ts.map +1 -1
- package/dist/components/chat/ChatPanel.d.ts.map +1 -1
- package/dist/components/chat/ChatWidget.d.ts.map +1 -1
- package/dist/components/docfile/DocFilePane.d.ts.map +1 -1
- package/dist/components/editor/ChildBlockWrapper.d.ts.map +1 -1
- package/dist/components/editor/ConflictDialog.d.ts.map +1 -1
- package/dist/components/editor/DragHandle.d.ts +12 -2
- package/dist/components/editor/DragHandle.d.ts.map +1 -1
- package/dist/components/editor/DropEdgeIndicator.d.ts +15 -6
- package/dist/components/editor/DropEdgeIndicator.d.ts.map +1 -1
- package/dist/components/editor/NavGroupRow.d.ts +4 -1
- package/dist/components/editor/NavGroupRow.d.ts.map +1 -1
- package/dist/components/editor/PagesModal.d.ts.map +1 -1
- package/dist/components/editor/SectionWrapper.d.ts +1 -1
- package/dist/components/editor/SectionWrapper.d.ts.map +1 -1
- package/dist/components/editor/SettingsForm.d.ts.map +1 -1
- package/dist/components/editor/TagIndicator.d.ts +15 -0
- package/dist/components/editor/TagIndicator.d.ts.map +1 -0
- package/dist/components/editor/index.js +150 -79
- package/dist/components/primitives/DocumentDropZone.d.ts +1 -1
- package/dist/components/primitives/EditableGrid.d.ts.map +1 -1
- package/dist/components/primitives/EditableList.d.ts.map +1 -1
- package/dist/components/primitives/HeadingSection.d.ts +4 -1
- package/dist/components/primitives/HeadingSection.d.ts.map +1 -1
- package/dist/components/primitives/ResolvedMedia.d.ts +5 -1
- package/dist/components/primitives/ResolvedMedia.d.ts.map +1 -1
- package/dist/components/primitives/{defineHeadingSection.d.ts → define-heading-section.d.ts} +1 -1
- package/dist/components/primitives/define-heading-section.d.ts.map +1 -0
- package/dist/components/primitives/{gridDrop.d.ts → grid-drop.d.ts} +1 -1
- package/dist/components/primitives/grid-drop.d.ts.map +1 -0
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/components/primitives/index.d.ts.map +1 -1
- package/dist/components/primitives/index.js +22 -154
- package/dist/components/sections/Button/CTAButton.d.ts.map +1 -1
- package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts +2 -6
- package/dist/components/sections/DoDontMedia/DoDontMediaBlock.d.ts.map +1 -1
- package/dist/components/sections/DoDontMedia/index.d.ts +8 -0
- package/dist/components/sections/DoDontMedia/index.d.ts.map +1 -1
- package/dist/components/sections/IconList/IconList.d.ts +2 -1
- package/dist/components/sections/IconList/IconList.d.ts.map +1 -1
- package/dist/components/sections/IconList/IconListSettings.d.ts +2 -1
- package/dist/components/sections/IconList/IconListSettings.d.ts.map +1 -1
- package/dist/components/sections/IconList/index.d.ts +1 -0
- package/dist/components/sections/IconList/index.d.ts.map +1 -1
- package/dist/components/sections/Media/MediaBlock.d.ts +2 -1
- package/dist/components/sections/Media/MediaBlock.d.ts.map +1 -1
- package/dist/components/sections/Media/index.d.ts +8 -0
- package/dist/components/sections/Media/index.d.ts.map +1 -1
- package/dist/components/sections/Reference/ReferenceList.d.ts +35 -0
- package/dist/components/sections/Reference/ReferenceList.d.ts.map +1 -0
- package/dist/components/sections/Reference/ReferenceSettings.d.ts +12 -0
- package/dist/components/sections/Reference/ReferenceSettings.d.ts.map +1 -0
- package/dist/components/sections/Reference/index.d.ts +9 -0
- package/dist/components/sections/Reference/index.d.ts.map +1 -0
- package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts +38 -0
- package/dist/components/sections/SectionSummary/SectionSummaryBlock.d.ts.map +1 -0
- package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts +20 -0
- package/dist/components/sections/SectionSummary/SectionSummarySettings.d.ts.map +1 -0
- package/dist/components/sections/SectionSummary/index.d.ts +33 -0
- package/dist/components/sections/SectionSummary/index.d.ts.map +1 -0
- package/dist/components/sections/all-sections.d.ts +53 -0
- package/dist/components/sections/all-sections.d.ts.map +1 -1
- package/dist/components/sections/brand-guide.d.ts +41 -2
- package/dist/components/sections/brand-guide.d.ts.map +1 -1
- package/dist/components/sections/brand-guide.js +17 -10
- package/dist/components/sections/core-sections.d.ts +14 -0
- package/dist/components/sections/core-sections.d.ts.map +1 -1
- package/dist/components/sections/register-schemas.js +25 -18
- package/dist/components/sections/register.js +25 -18
- package/dist/components/shared/BrandSwatchesContext.d.ts +9 -0
- package/dist/components/shared/BrandSwatchesContext.d.ts.map +1 -0
- package/dist/components/shared/Button.d.ts +11 -3
- package/dist/components/shared/Button.d.ts.map +1 -1
- package/dist/components/shared/Checkbox.d.ts +6 -0
- package/dist/components/shared/Checkbox.d.ts.map +1 -1
- package/dist/components/shared/ConfirmDialog.d.ts +25 -0
- package/dist/components/shared/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/shared/ConfirmInline.d.ts +25 -0
- package/dist/components/shared/ConfirmInline.d.ts.map +1 -0
- package/dist/components/shared/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/shared/Fab.d.ts +11 -2
- package/dist/components/shared/Fab.d.ts.map +1 -1
- package/dist/components/shared/FabStack.d.ts +22 -0
- package/dist/components/shared/FabStack.d.ts.map +1 -0
- package/dist/components/shared/HistoryChangesModal.d.ts.map +1 -1
- package/dist/components/shared/HistoryPopover.d.ts.map +1 -1
- package/dist/components/shared/ImageBackgroundField.d.ts +9 -0
- package/dist/components/shared/ImageBackgroundField.d.ts.map +1 -0
- package/dist/components/shared/{UploadRejectionAlert.d.ts → InlineAlert.d.ts} +4 -2
- package/dist/components/shared/InlineAlert.d.ts.map +1 -0
- package/dist/components/shared/Input.d.ts +10 -0
- package/dist/components/shared/Input.d.ts.map +1 -1
- package/dist/components/shared/Navigation.d.ts.map +1 -1
- package/dist/components/shared/Notice.d.ts +10 -0
- package/dist/components/shared/Notice.d.ts.map +1 -0
- package/dist/components/shared/Popover.d.ts.map +1 -1
- package/dist/components/shared/ReferenceSourcesContext.d.ts +25 -0
- package/dist/components/shared/ReferenceSourcesContext.d.ts.map +1 -0
- package/dist/components/shared/Select.d.ts +3 -2
- package/dist/components/shared/Select.d.ts.map +1 -1
- package/dist/components/shared/SplitButton.d.ts.map +1 -1
- package/dist/components/shared/SummaryAnchorsContext.d.ts +10 -0
- package/dist/components/shared/SummaryAnchorsContext.d.ts.map +1 -0
- package/dist/components/shared/Textarea.d.ts +7 -0
- package/dist/components/shared/Textarea.d.ts.map +1 -1
- package/dist/components/shared/ToolbarFrame.d.ts +17 -0
- package/dist/components/shared/ToolbarFrame.d.ts.map +1 -0
- package/dist/components/shared/copy.d.ts +13 -0
- package/dist/components/shared/copy.d.ts.map +1 -0
- package/dist/components/shared/icons.d.ts +0 -12
- package/dist/components/shared/icons.d.ts.map +1 -1
- package/dist/components/shell/AudienceDetailsPanel.d.ts +7 -1
- package/dist/components/shell/AudienceDetailsPanel.d.ts.map +1 -1
- package/dist/components/shell/AudienceRow.d.ts.map +1 -1
- package/dist/components/shell/BugReportFAB.d.ts +7 -1
- package/dist/components/shell/BugReportFAB.d.ts.map +1 -1
- package/dist/components/shell/CredentialList.d.ts.map +1 -1
- package/dist/components/shell/DocInspector.d.ts.map +1 -1
- package/dist/components/shell/DocumentEditorOverlay.d.ts.map +1 -1
- package/dist/components/shell/EditorContext.d.ts +4 -0
- package/dist/components/shell/EditorContext.d.ts.map +1 -1
- package/dist/components/shell/EditorLoginForm.d.ts.map +1 -1
- package/dist/components/shell/EditorModal.d.ts.map +1 -1
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/components/shell/HistoryToolbar.d.ts.map +1 -1
- package/dist/components/shell/MediaFolderTile.d.ts +4 -1
- package/dist/components/shell/MediaFolderTile.d.ts.map +1 -1
- package/dist/components/shell/MediaLibraryModal.d.ts.map +1 -1
- package/dist/components/shell/RestoreModal.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsChatbot.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsModal.d.ts +3 -1
- package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsTags.d.ts +13 -0
- package/dist/components/shell/SiteSettingsTags.d.ts.map +1 -0
- package/dist/components/shell/SiteSettingsUsers.d.ts.map +1 -1
- package/dist/components/shell/ViewerLoginForm.d.ts.map +1 -1
- package/dist/components/shell/{blockMoveDispatch.d.ts → block-move-dispatch.d.ts} +1 -1
- package/dist/components/shell/block-move-dispatch.d.ts.map +1 -0
- package/dist/components/shell/reference-sources.d.ts +22 -0
- package/dist/components/shell/reference-sources.d.ts.map +1 -0
- package/dist/deck/index.d.ts +2 -2
- package/dist/deck/index.d.ts.map +1 -1
- package/dist/deck/index.js +1 -3
- package/dist/deck-builder/index.js +10 -17
- package/dist/document/index.d.ts +2 -2
- package/dist/document/index.d.ts.map +1 -1
- package/dist/hooks/useBlockDnd.d.ts +11 -0
- package/dist/hooks/useBlockDnd.d.ts.map +1 -1
- package/dist/hooks/useBuildStatus.d.ts +1 -1
- package/dist/hooks/useBuildStatus.d.ts.map +1 -1
- package/dist/hooks/useDocumentUploads.d.ts +1 -1
- package/dist/hooks/useDocumentUploads.d.ts.map +1 -1
- package/dist/hooks/useEditorPersistence.d.ts +5 -1
- package/dist/hooks/useEditorPersistence.d.ts.map +1 -1
- package/dist/hooks/useEditorPublish.d.ts +6 -3
- package/dist/hooks/useEditorPublish.d.ts.map +1 -1
- package/dist/hooks/useMediaPipeline.d.ts.map +1 -1
- package/dist/hooks/useNotice.d.ts +19 -0
- package/dist/hooks/useNotice.d.ts.map +1 -0
- package/dist/hooks/useSortableNavRow.d.ts +11 -0
- package/dist/hooks/useSortableNavRow.d.ts.map +1 -1
- package/dist/hooks/useSortableRow.d.ts +11 -0
- package/dist/hooks/useSortableRow.d.ts.map +1 -1
- package/dist/hooks/useStackedEscape.d.ts +32 -0
- package/dist/hooks/useStackedEscape.d.ts.map +1 -0
- package/dist/index.js +95 -48
- package/dist/lib/audience-secret.js +2 -2
- package/dist/lib/block-dnd.d.ts +5 -0
- package/dist/lib/block-dnd.d.ts.map +1 -1
- package/dist/lib/block-move.d.ts.map +1 -1
- package/dist/lib/brand-swatches.d.ts +12 -0
- package/dist/lib/brand-swatches.d.ts.map +1 -0
- package/dist/lib/container-ops.d.ts +3 -2
- package/dist/lib/container-ops.d.ts.map +1 -1
- package/dist/lib/dexie.d.ts +7 -1
- package/dist/lib/dexie.d.ts.map +1 -1
- package/dist/lib/dexie.js +12 -3
- package/dist/lib/env.d.ts +4 -0
- package/dist/lib/env.d.ts.map +1 -1
- package/dist/lib/env.js +5 -3
- package/dist/lib/events.d.ts +1 -2
- package/dist/lib/events.d.ts.map +1 -1
- package/dist/lib/image-background.d.ts +8 -0
- package/dist/lib/image-background.d.ts.map +1 -0
- package/dist/lib/image-variant-plan.d.ts +42 -0
- package/dist/lib/image-variant-plan.d.ts.map +1 -0
- package/dist/lib/image-variant-plan.js +53 -0
- package/dist/lib/index-ops.d.ts.map +1 -1
- package/dist/lib/index-ops.js +21 -17
- package/dist/lib/index.d.ts +7 -4
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +55 -26
- package/dist/lib/loader.d.ts +25 -12
- package/dist/lib/loader.d.ts.map +1 -1
- package/dist/lib/media-ops.d.ts +73 -0
- package/dist/lib/media-ops.d.ts.map +1 -0
- package/dist/lib/media-ops.js +60 -0
- package/dist/lib/nav-tree.d.ts +7 -0
- package/dist/lib/nav-tree.d.ts.map +1 -1
- package/dist/lib/nav.d.ts +38 -0
- package/dist/lib/nav.d.ts.map +1 -1
- package/dist/lib/pages.d.ts +2 -1
- package/dist/lib/pages.d.ts.map +1 -1
- package/dist/lib/platform-broker.d.ts +4 -2
- package/dist/lib/platform-broker.d.ts.map +1 -1
- package/dist/lib/platform-broker.js +21 -13
- package/dist/lib/reference-type.d.ts +2 -0
- package/dist/lib/reference-type.d.ts.map +1 -0
- package/dist/lib/reference-validation.d.ts +31 -0
- package/dist/lib/reference-validation.d.ts.map +1 -0
- package/dist/lib/reference-validation.js +39 -0
- package/dist/lib/references.d.ts +74 -0
- package/dist/lib/references.d.ts.map +1 -0
- package/dist/lib/registry.d.ts +35 -0
- package/dist/lib/registry.d.ts.map +1 -1
- package/dist/lib/{safeRedirect.d.ts → safe-redirect.d.ts} +1 -1
- package/dist/lib/safe-redirect.d.ts.map +1 -0
- package/dist/lib/sidecar-diagnostics.d.ts +20 -0
- package/dist/lib/sidecar-diagnostics.d.ts.map +1 -0
- package/dist/lib/sidecars.d.ts +118 -0
- package/dist/lib/sidecars.d.ts.map +1 -0
- package/dist/lib/sidecars.js +23 -0
- package/dist/lib/slug.d.ts +2 -0
- package/dist/lib/slug.d.ts.map +1 -0
- package/dist/lib/storage-tier.d.ts +17 -0
- package/dist/lib/storage-tier.d.ts.map +1 -0
- package/dist/lib/storage-tier.js +29 -0
- package/dist/lib/tags.d.ts +64 -0
- package/dist/lib/tags.d.ts.map +1 -0
- package/dist/lib/theme-vars.d.ts +9 -0
- package/dist/lib/theme-vars.d.ts.map +1 -1
- package/dist/media/index.d.ts +1 -1
- package/dist/media/index.d.ts.map +1 -1
- package/dist/media/index.js +18 -14
- package/dist/media/queue.d.ts +2 -0
- package/dist/media/queue.d.ts.map +1 -1
- package/dist/media/utils.d.ts +2 -0
- package/dist/media/utils.d.ts.map +1 -1
- package/dist/media/{videoPoster.d.ts → video-poster.d.ts} +1 -1
- package/dist/media/video-poster.d.ts.map +1 -0
- package/dist/media/worker.d.ts +1 -35
- package/dist/media/worker.d.ts.map +1 -1
- package/dist/schemas/audience.js +2 -2
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +25 -13
- package/dist/schemas/media.d.ts +4 -0
- package/dist/schemas/media.d.ts.map +1 -1
- package/dist/schemas/shared.d.ts +26 -0
- package/dist/schemas/shared.d.ts.map +1 -1
- package/dist/schemas/site-config.d.ts +6 -0
- package/dist/schemas/site-config.d.ts.map +1 -1
- package/dist/schemas/tags.d.ts +27 -0
- package/dist/schemas/tags.d.ts.map +1 -0
- package/dist/storage/index.js +2 -1
- package/dist/storage/memory.d.ts +21 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +129 -0
- package/dist/storage/types.d.ts +9 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/types/database.d.ts.map +1 -1
- package/package.json +26 -1
- package/src/auth/cookies.ts +111 -0
- package/src/collab/rebase.ts +29 -9
- package/src/components/brandguide/ColorSwatchSettings.tsx +1 -1
- package/src/components/brandguide/ColorsEditable.tsx +1 -0
- package/src/components/chat/ChatPanel.tsx +2 -3
- package/src/components/chat/ChatWidget.tsx +2 -3
- package/src/components/docfile/DocFilePane.tsx +4 -12
- package/src/components/editor/ChildBlockWrapper.tsx +13 -19
- package/src/components/editor/ConflictDialog.tsx +27 -35
- package/src/components/editor/DeleteButton.tsx +2 -2
- package/src/components/editor/DragHandle.tsx +16 -3
- package/src/components/editor/DropEdgeIndicator.tsx +36 -10
- package/src/components/editor/InsertButton.tsx +2 -2
- package/src/components/editor/NavGroupRow.tsx +43 -14
- package/src/components/editor/PagesModal.tsx +99 -26
- package/src/components/editor/SectionWrapper.tsx +64 -23
- package/src/components/editor/SettingsButton.tsx +2 -2
- package/src/components/editor/SettingsForm.tsx +19 -2
- package/src/components/editor/StatusIndicator.tsx +4 -4
- package/src/components/editor/TagIndicator.tsx +80 -0
- package/src/components/primitives/DocumentDropZone.tsx +1 -1
- package/src/components/primitives/EditableGrid.tsx +15 -14
- package/src/components/primitives/EditableList.tsx +27 -74
- package/src/components/primitives/HeadingSection.tsx +5 -2
- package/src/components/primitives/ResolvedMedia.tsx +13 -0
- package/src/components/primitives/{defineHeadingSection.tsx → define-heading-section.tsx} +1 -0
- package/src/components/primitives/index.ts +1 -1
- package/src/components/primitives/useEditablePlainText.ts +5 -5
- package/src/components/sections/Button/CTAButton.tsx +3 -1
- package/src/components/sections/DoDontMedia/DoDontMediaBlock.tsx +4 -4
- package/src/components/sections/DoDontMedia/index.tsx +12 -3
- package/src/components/sections/IconList/DoDontToggle.tsx +2 -2
- package/src/components/sections/IconList/IconList.tsx +70 -37
- package/src/components/sections/IconList/IconListSettings.tsx +55 -17
- package/src/components/sections/IconList/index.tsx +10 -3
- package/src/components/sections/LinkHeading/index.tsx +1 -1
- package/src/components/sections/Media/MediaBlock.tsx +13 -2
- package/src/components/sections/Media/index.tsx +12 -4
- package/src/components/sections/Reference/ReferenceList.tsx +214 -0
- package/src/components/sections/Reference/ReferenceSettings.tsx +159 -0
- package/src/components/sections/Reference/index.tsx +47 -0
- package/src/components/sections/SectionSummary/SectionSummaryBlock.tsx +476 -0
- package/src/components/sections/SectionSummary/SectionSummarySettings.tsx +126 -0
- package/src/components/sections/SectionSummary/index.tsx +149 -0
- package/src/components/sections/SubHeading/index.tsx +1 -1
- package/src/components/sections/SubSubHeading/index.tsx +1 -1
- package/src/components/sections/brand-guide.ts +4 -3
- package/src/components/sections/core-sections.ts +2 -0
- package/src/components/shared/BrandSwatchesContext.ts +13 -0
- package/src/components/shared/Button.tsx +47 -34
- package/src/components/shared/Checkbox.tsx +21 -12
- package/src/components/shared/ConfirmDialog.tsx +87 -0
- package/src/components/shared/ConfirmInline.tsx +90 -0
- package/src/components/shared/ErrorBoundary.tsx +6 -18
- package/src/components/shared/Fab.tsx +15 -5
- package/src/components/shared/FabStack.tsx +28 -0
- package/src/components/shared/HistoryChangesModal.tsx +43 -41
- package/src/components/shared/HistoryPopover.tsx +7 -20
- package/src/components/shared/ImageBackgroundField.tsx +92 -0
- package/src/components/shared/{UploadRejectionAlert.tsx → InlineAlert.tsx} +21 -5
- package/src/components/shared/Input.tsx +23 -7
- package/src/components/shared/Navigation.tsx +22 -17
- package/src/components/shared/Notice.tsx +59 -0
- package/src/components/shared/Popover.tsx +7 -11
- package/src/components/shared/ReferenceSourcesContext.ts +27 -0
- package/src/components/shared/Select.tsx +5 -2
- package/src/components/shared/SplitButton.tsx +11 -17
- package/src/components/shared/SummaryAnchorsContext.ts +11 -0
- package/src/components/shared/Textarea.tsx +17 -2
- package/src/components/shared/ToolbarFrame.tsx +28 -0
- package/src/components/shared/VideoSourceField.tsx +1 -1
- package/src/components/shared/copy.ts +18 -0
- package/src/components/shared/icons.tsx +1 -17
- package/src/components/shell/AudienceAddForm.tsx +2 -2
- package/src/components/shell/AudienceDetailsPanel.tsx +23 -5
- package/src/components/shell/AudienceRow.tsx +22 -15
- package/src/components/shell/BugReportFAB.tsx +50 -40
- package/src/components/shell/CredentialList.tsx +33 -13
- package/src/components/shell/DocInspector.tsx +3 -12
- package/src/components/shell/DocumentEditorOverlay.tsx +33 -23
- package/src/components/shell/EditorContext.tsx +7 -0
- package/src/components/shell/EditorLoginForm.tsx +26 -36
- package/src/components/shell/EditorModal.tsx +8 -10
- package/src/components/shell/EditorShell.tsx +501 -338
- package/src/components/shell/HistoryToolbar.tsx +24 -26
- package/src/components/shell/MediaFolderTile.tsx +8 -3
- package/src/components/shell/MediaLibraryModal.tsx +59 -60
- package/src/components/shell/ProcessingIndicator.tsx +2 -2
- package/src/components/shell/RestoreModal.tsx +17 -16
- package/src/components/shell/SetPasswordForm.tsx +3 -3
- package/src/components/shell/SiteSettingsChatbot.tsx +61 -42
- package/src/components/shell/SiteSettingsDisplay.tsx +10 -20
- package/src/components/shell/SiteSettingsModal.tsx +24 -2
- package/src/components/shell/SiteSettingsTags.tsx +143 -0
- package/src/components/shell/SiteSettingsUsers.tsx +36 -26
- package/src/components/shell/SiteSettingsViewerAccess.tsx +2 -2
- package/src/components/shell/ViewerLoginForm.tsx +5 -4
- package/src/components/shell/reference-sources.ts +36 -0
- package/src/deck/index.ts +2 -2
- package/src/document/index.ts +2 -2
- package/src/hooks/useBlockDnd.ts +11 -0
- package/src/hooks/useBuildStatus.ts +53 -6
- package/src/hooks/useDocumentUploads.ts +1 -1
- package/src/hooks/useEditorPersistence.ts +141 -35
- package/src/hooks/useEditorPublish.ts +27 -31
- package/src/hooks/useMediaPipeline.ts +30 -24
- package/src/hooks/useNotice.ts +45 -0
- package/src/hooks/useSortableNavRow.ts +11 -0
- package/src/hooks/useSortableRow.ts +22 -2
- package/src/hooks/useStackedEscape.ts +62 -0
- package/src/lib/block-dnd.ts +6 -1
- package/src/lib/block-move.ts +3 -0
- package/src/lib/brand-swatches.ts +32 -0
- package/src/lib/container-ops.ts +5 -3
- package/src/lib/dexie.ts +24 -2
- package/src/lib/env.ts +9 -0
- package/src/lib/events.ts +1 -2
- package/src/lib/image-background.ts +31 -0
- package/src/lib/image-variant-plan.ts +92 -0
- package/src/lib/index-ops.ts +9 -18
- package/src/lib/index.ts +20 -4
- package/src/lib/loader.ts +28 -88
- package/src/lib/media-ops.ts +112 -0
- package/src/lib/nav-tree.ts +104 -4
- package/src/lib/nav.ts +196 -36
- package/src/lib/pages.ts +2 -3
- package/src/lib/platform-broker.ts +32 -14
- package/src/lib/reference-type.ts +3 -0
- package/src/lib/reference-validation.ts +69 -0
- package/src/lib/references.ts +130 -0
- package/src/lib/registry.ts +37 -0
- package/src/lib/sidecar-diagnostics.ts +29 -0
- package/src/lib/sidecars.ts +221 -0
- package/src/lib/slug.ts +6 -0
- package/src/lib/storage-tier.ts +38 -0
- package/src/lib/tags.ts +165 -0
- package/src/lib/theme-vars.ts +23 -0
- package/src/media/index.ts +1 -1
- package/src/media/queue.ts +3 -0
- package/src/media/utils.ts +19 -1
- package/src/media/{videoPoster.ts → video-poster.ts} +2 -2
- package/src/media/worker.ts +17 -8
- package/src/schemas/index.ts +1 -0
- package/src/schemas/media.ts +7 -2
- package/src/schemas/shared.ts +24 -1
- package/src/schemas/site-config.ts +6 -1
- package/src/schemas/tags.ts +33 -0
- package/src/storage/memory.ts +178 -0
- package/src/storage/types.ts +16 -3
- package/src/types/database.ts +2 -0
- package/dist/chunk-DNY72JZN.js +0 -86
- package/dist/chunk-F2LYQPXV.js +0 -77
- package/dist/chunk-JH762VUH.js +0 -128
- package/dist/chunk-K7DYZXVU.js +0 -138
- package/dist/components/primitives/defineHeadingSection.d.ts.map +0 -1
- package/dist/components/primitives/gridDrop.d.ts.map +0 -1
- package/dist/components/shared/UploadRejectionAlert.d.ts.map +0 -1
- package/dist/components/shell/BuildStatusIndicator.d.ts +0 -7
- package/dist/components/shell/BuildStatusIndicator.d.ts.map +0 -1
- package/dist/components/shell/blockMoveDispatch.d.ts.map +0 -1
- package/dist/hooks/index.d.ts +0 -9
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/lib/grid.d.ts +0 -2
- package/dist/lib/grid.d.ts.map +0 -1
- package/dist/lib/safeRedirect.d.ts.map +0 -1
- package/dist/media/videoPoster.d.ts.map +0 -1
- package/src/components/brandguide/ColorSwatchSettings.d.ts.map +0 -1
- package/src/components/brandguide/Colors.d.ts.map +0 -1
- package/src/components/primitives/CustomParagraph.d.ts.map +0 -1
- package/src/components/primitives/EditableGrid.d.ts.map +0 -1
- package/src/components/primitives/EditablePlainText.d.ts.map +0 -1
- package/src/components/primitives/EditableRichText.d.ts.map +0 -1
- package/src/components/primitives/HeadingSection.d.ts.map +0 -1
- package/src/components/primitives/IconPicker.d.ts.map +0 -1
- package/src/components/primitives/LinkPopover.d.ts.map +0 -1
- package/src/components/primitives/MediaSettingsForms.d.ts.map +0 -1
- package/src/components/primitives/ResolvedMedia.d.ts.map +0 -1
- package/src/components/primitives/RichTextToolbar.d.ts.map +0 -1
- package/src/components/primitives/tiptap-presets.d.ts.map +0 -1
- package/src/components/primitives/useEditableCollection.d.ts.map +0 -1
- package/src/components/primitives/useEditablePlainText.d.ts.map +0 -1
- package/src/components/primitives/useEditableRichText.d.ts.map +0 -1
- package/src/components/sections/Button/CTAButton.d.ts.map +0 -1
- package/src/components/sections/Button/index.d.ts.map +0 -1
- package/src/components/sections/Colors/index.d.ts.map +0 -1
- package/src/components/sections/IconList/IconList.d.ts.map +0 -1
- package/src/components/sections/IconList/IconListSettings.d.ts.map +0 -1
- package/src/components/sections/IconList/index.d.ts.map +0 -1
- package/src/components/sections/LinkHeading/index.d.ts.map +0 -1
- package/src/components/sections/Prose/Prose.d.ts.map +0 -1
- package/src/components/sections/Prose/index.d.ts.map +0 -1
- package/src/components/sections/SubHeading/index.d.ts.map +0 -1
- package/src/components/sections/SubSubHeading/index.d.ts.map +0 -1
- package/src/components/sections/register-schemas.d.ts.map +0 -1
- package/src/components/shared/Button.d.ts.map +0 -1
- package/src/components/shared/Checkbox.d.ts.map +0 -1
- package/src/components/shared/FormLabel.d.ts.map +0 -1
- package/src/components/shared/IconButton.d.ts.map +0 -1
- package/src/components/shared/Input.d.ts.map +0 -1
- package/src/components/shared/Select.d.ts.map +0 -1
- package/src/components/shared/icons.d.ts.map +0 -1
- package/src/components/shell/BuildStatusIndicator.tsx +0 -59
- package/src/components/shell/MediaLibraryContext.d.ts.map +0 -1
- package/src/hooks/index.ts +0 -8
- package/src/hooks/useResolvedMedia.d.ts.map +0 -1
- package/src/lib/cn.d.ts.map +0 -1
- package/src/lib/grid.d.ts.map +0 -1
- package/src/lib/grid.ts +0 -7
- package/src/lib/icons.d.ts.map +0 -1
- package/src/lib/loader.d.ts.map +0 -1
- package/src/lib/nav.d.ts.map +0 -1
- package/src/lib/registry.d.ts.map +0 -1
- package/src/lib/sanitize.d.ts.map +0 -1
- package/src/media/github.d.ts.map +0 -1
- package/src/media/index.d.ts.map +0 -1
- package/src/media/queue.d.ts.map +0 -1
- package/src/media/resolve.d.ts.map +0 -1
- package/src/media/types.d.ts.map +0 -1
- package/src/media/utils.d.ts.map +0 -1
- package/src/media/videoPoster.d.ts.map +0 -1
- package/src/schemas/auth.d.ts.map +0 -1
- package/src/schemas/media-grid-options.d.ts.map +0 -1
- package/src/schemas/media.d.ts.map +0 -1
- package/src/schemas/sections.d.ts.map +0 -1
- package/src/schemas/shared.d.ts.map +0 -1
- package/src/schemas/site-config.d.ts.map +0 -1
- /package/dist/{chunk-B7VBSE5X.js → chunk-3JDTXOIG.js} +0 -0
- /package/dist/{chunk-CXZ5YJG4.js → chunk-L45X7DKX.js} +0 -0
- /package/src/components/primitives/{gridDrop.ts → grid-drop.ts} +0 -0
- /package/src/components/shell/{blockMoveDispatch.ts → block-move-dispatch.ts} +0 -0
- /package/src/lib/{safeRedirect.ts → safe-redirect.ts} +0 -0
|
@@ -11,6 +11,17 @@ interface UseSortableRowOptions {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
+
* One of three sibling drag-and-drop position hooks, split by location type
|
|
15
|
+
* rather than unified behind a generic `useSortable({ axis })`: this one (flat
|
|
16
|
+
* index — section-ordering lists, `EditableList`), `useSortableNavRow`
|
|
17
|
+
* (NavLocation — the Pages modal's group-aware nav tree), and `useBlockDnd`
|
|
18
|
+
* (block/container id + index — the section canvas, root and nested). A
|
|
19
|
+
* fourth location type earns its own hook on the same shape (rowRef/handleRef,
|
|
20
|
+
* lazy atlaskit import, closest-edge state, a ref for the latest callback)
|
|
21
|
+
* rather than a parameter bag bolted onto an existing one — see
|
|
22
|
+
* docs/superpowers/specs/2026-09-04-editor-ui-primitives-consolidation.md § D6
|
|
23
|
+
* for why a shared `useSortable` was deferred.
|
|
24
|
+
*
|
|
14
25
|
* Closest-edge drag-to-reorder wiring for a single list row, shared by the
|
|
15
26
|
* section- and page-ordering modals. Attach `rowRef` to the row element and
|
|
16
27
|
* `handleRef` to the drag handle, and render
|
|
@@ -30,6 +41,15 @@ export function useSortableRow<R extends HTMLElement, H extends HTMLElement>({
|
|
|
30
41
|
const [isDragging, setIsDragging] = useState(false);
|
|
31
42
|
const [closestEdge, setClosestEdge] = useState<"top" | "bottom" | null>(null);
|
|
32
43
|
|
|
44
|
+
// Read through a ref so a changed `onReorder` identity doesn't re-register
|
|
45
|
+
// the atlaskit bindings mid-drag (which cancels the drag) — the same class
|
|
46
|
+
// of bug EditableList's `onReorderRef` fixed (2026-08-03). `index` stays a
|
|
47
|
+
// real effect dependency: a stale index would report the wrong
|
|
48
|
+
// `fromIndex`/`toIndex` on drop, the hazard useSortableNavRow's `locationOf`
|
|
49
|
+
// comment warns about for its own (non-re-subscribing) case.
|
|
50
|
+
const onReorderRef = useRef(onReorder);
|
|
51
|
+
onReorderRef.current = onReorder;
|
|
52
|
+
|
|
33
53
|
useEffect(() => {
|
|
34
54
|
if (!enabled) return;
|
|
35
55
|
const row = rowRef.current;
|
|
@@ -79,7 +99,7 @@ export function useSortableRow<R extends HTMLElement, H extends HTMLElement>({
|
|
|
79
99
|
const rawEdge = extractClosestEdge(self.data);
|
|
80
100
|
const edge = rawEdge === "top" || rawEdge === "bottom" ? rawEdge : null;
|
|
81
101
|
const toIndex = computeReorderTarget(fromIndex, index, edge);
|
|
82
|
-
if (toIndex !== null)
|
|
102
|
+
if (toIndex !== null) onReorderRef.current(fromIndex, toIndex);
|
|
83
103
|
},
|
|
84
104
|
});
|
|
85
105
|
|
|
@@ -93,7 +113,7 @@ export function useSortableRow<R extends HTMLElement, H extends HTMLElement>({
|
|
|
93
113
|
cancelled = true;
|
|
94
114
|
cleanup?.();
|
|
95
115
|
};
|
|
96
|
-
}, [index, dragType,
|
|
116
|
+
}, [index, dragType, enabled]);
|
|
97
117
|
|
|
98
118
|
return { rowRef, handleRef, isDragging, closestEdge };
|
|
99
119
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useEffect, useRef, type RefObject } from "react";
|
|
2
|
+
|
|
3
|
+
export interface UseStackedEscapeOptions {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Runs first, before the layer check would otherwise fall through to
|
|
7
|
+
* `onEscape`; returning `true` swallows the keypress entirely (the document
|
|
8
|
+
* editor overlay's blur-a-focused-field-first step).
|
|
9
|
+
*/
|
|
10
|
+
before?: (e: KeyboardEvent) => boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Shared "a modal above me owns Escape" rule. `EditorModal` marks its
|
|
15
|
+
* outermost layer with `data-modal-layer`; anything that might render BELOW
|
|
16
|
+
* one — a `Popover`, the doc file pane, the document editor overlay, and
|
|
17
|
+
* `EditorModal` itself (relative to another `EditorModal` opened on top of
|
|
18
|
+
* it) — must not react to an Escape meant for that layer instead.
|
|
19
|
+
*
|
|
20
|
+
* Attach the returned ref to your own `data-modal-layer` element (only
|
|
21
|
+
* `EditorModal` does) so the check can exclude it — otherwise it would always
|
|
22
|
+
* find itself and never fire. Callers that aren't a layer themselves (Popover,
|
|
23
|
+
* DocFilePane, the overlay) just ignore the return value: any layer at all
|
|
24
|
+
* then means something is stacked above them.
|
|
25
|
+
*
|
|
26
|
+
* For a tagged caller, "above" means a layer that FOLLOWS its own layer in
|
|
27
|
+
* DOM order (`compareDocumentPosition` + `DOCUMENT_POSITION_FOLLOWING`), not
|
|
28
|
+
* just "any other layer" — modals are appended later in DOM order than the
|
|
29
|
+
* ones already open, so this is what lets two stacked `EditorModal`s (e.g.
|
|
30
|
+
* Site Settings opening the Media Library over itself) resolve Escape to the
|
|
31
|
+
* topmost one only, then the next one down once that one closes.
|
|
32
|
+
*/
|
|
33
|
+
export function useStackedEscape<T extends HTMLElement = HTMLElement>(
|
|
34
|
+
onEscape: () => void,
|
|
35
|
+
{ enabled, before }: UseStackedEscapeOptions,
|
|
36
|
+
): RefObject<T | null> {
|
|
37
|
+
const layerRef = useRef<T | null>(null);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!enabled) return;
|
|
41
|
+
|
|
42
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
43
|
+
if (e.key !== "Escape") return;
|
|
44
|
+
const own = layerRef.current;
|
|
45
|
+
const layers = document.querySelectorAll<HTMLElement>("[data-modal-layer]");
|
|
46
|
+
const above = Array.from(layers).some((el) => {
|
|
47
|
+
if (el === own) return false;
|
|
48
|
+
if (!own) return true;
|
|
49
|
+
return Boolean(own.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING);
|
|
50
|
+
});
|
|
51
|
+
if (above) return;
|
|
52
|
+
if (before?.(e)) return;
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
onEscape();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
document.addEventListener("keydown", onKeyDown);
|
|
58
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
59
|
+
}, [enabled, onEscape, before]);
|
|
60
|
+
|
|
61
|
+
return layerRef;
|
|
62
|
+
}
|
package/src/lib/block-dnd.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface BlockDragData {
|
|
|
11
11
|
index: number;
|
|
12
12
|
/** True if the dragged block is itself a container (used for the depth guard). */
|
|
13
13
|
isContainer: boolean;
|
|
14
|
+
/** True if the dragged block is a Reference, which only expands at the page root. */
|
|
15
|
+
isReference?: boolean;
|
|
14
16
|
[key: string | symbol]: unknown;
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -27,6 +29,7 @@ export function buildBlockDragData(args: {
|
|
|
27
29
|
containerId: string;
|
|
28
30
|
index: number;
|
|
29
31
|
isContainer: boolean;
|
|
32
|
+
isReference?: boolean;
|
|
30
33
|
}): BlockDragData {
|
|
31
34
|
return { dragType: "block", ...args };
|
|
32
35
|
}
|
|
@@ -43,11 +46,13 @@ export function isBlockDragData(data: Record<string | symbol, unknown>): data is
|
|
|
43
46
|
* May `source` drop into `dropContainerId`?
|
|
44
47
|
* - A container block may only land at the page root (v1 one-level nesting → no
|
|
45
48
|
* container-in-container; MAX_BLOCK_DEPTH=2).
|
|
49
|
+
* - So may a Reference: it is expanded into its sources only at the page root,
|
|
50
|
+
* so inside a container it would render nothing.
|
|
46
51
|
* - Nothing may drop onto itself.
|
|
47
52
|
*/
|
|
48
53
|
export function canDropBlock(source: BlockDragData, dropContainerId: string): boolean {
|
|
49
54
|
if (source.blockId === dropContainerId) return false;
|
|
50
|
-
if (source.isContainer && dropContainerId !== ROOT_CONTAINER_ID) return false;
|
|
55
|
+
if ((source.isContainer || source.isReference) && dropContainerId !== ROOT_CONTAINER_ID) return false;
|
|
51
56
|
return true;
|
|
52
57
|
}
|
|
53
58
|
|
package/src/lib/block-move.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { LoadedSection } from "./loader";
|
|
|
2
2
|
import type { Section } from "../schemas/sections";
|
|
3
3
|
import type { SiteIndex, SectionMeta } from "../schemas/site-config";
|
|
4
4
|
import { ROOT_CONTAINER_ID, canDropBlock } from "./block-dnd";
|
|
5
|
+
import { REFERENCE_TYPE } from "./reference-type";
|
|
5
6
|
import { getContainerChildren, reorderChild, insertChildAt, removeChildAt, placeBlockAtColumn, trimTrailingSpacers } from "./container-ops";
|
|
6
7
|
import { reorderVisibleSectionInPage, visibleInsertPosition, addSectionToPage, removeSectionFromPages } from "./pages";
|
|
7
8
|
|
|
@@ -96,6 +97,7 @@ export function applyBlockMove(
|
|
|
96
97
|
containerId: fromContainerId,
|
|
97
98
|
index: fromIndex,
|
|
98
99
|
isContainer: isContainerSection(draggedSection),
|
|
100
|
+
isReference: draggedSection.type === REFERENCE_TYPE,
|
|
99
101
|
};
|
|
100
102
|
if (!canDropBlock(dragData, toContainerId)) return noop(state);
|
|
101
103
|
|
|
@@ -200,6 +202,7 @@ function applyColumnPlacement(
|
|
|
200
202
|
containerId: fromContainerId,
|
|
201
203
|
index: fromIndex,
|
|
202
204
|
isContainer: isContainerSection(draggedSection),
|
|
205
|
+
isReference: draggedSection.type === REFERENCE_TYPE,
|
|
203
206
|
};
|
|
204
207
|
if (!canDropBlock(dragData, toContainerId)) return noop(state);
|
|
205
208
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Section } from "../schemas/sections";
|
|
2
|
+
import type { ColorItem } from "../components/sections/Colors/schema";
|
|
3
|
+
|
|
4
|
+
export interface BrandSwatch {
|
|
5
|
+
hex: string;
|
|
6
|
+
name: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type Block = { type?: unknown; content?: unknown };
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Every hex value from every Colors section, walking container children, in
|
|
13
|
+
* page order and deduped case-insensitively. Swatches are offered as plain hex
|
|
14
|
+
* values: color items carry no stable id, so a picked swatch is copied, not linked.
|
|
15
|
+
*/
|
|
16
|
+
export function collectBrandSwatches(sections: Section[]): BrandSwatch[] {
|
|
17
|
+
const seen = new Map<string, BrandSwatch>();
|
|
18
|
+
const visit = (block: Block) => {
|
|
19
|
+
const content = (block.content ?? {}) as { colors?: unknown; children?: unknown };
|
|
20
|
+
if (block.type === "colors" && Array.isArray(content.colors)) {
|
|
21
|
+
for (const item of content.colors as ColorItem[]) {
|
|
22
|
+
for (const space of item.spaces) {
|
|
23
|
+
const hex = space.hex?.toLowerCase();
|
|
24
|
+
if (hex && !seen.has(hex)) seen.set(hex, { hex, name: item.name });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(content.children)) (content.children as Block[]).forEach(visit);
|
|
29
|
+
};
|
|
30
|
+
sections.forEach(visit);
|
|
31
|
+
return [...seen.values()];
|
|
32
|
+
}
|
package/src/lib/container-ops.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ReactNode } from "react";
|
|
|
2
2
|
import type { Section } from "../schemas/sections";
|
|
3
3
|
import { getAllSections } from "./registry";
|
|
4
4
|
import { sortInsertMenuOptions } from "./insert-menu";
|
|
5
|
+
import { REFERENCE_TYPE } from "./reference-type";
|
|
5
6
|
|
|
6
7
|
interface ContainerContent {
|
|
7
8
|
columns: number;
|
|
@@ -37,13 +38,14 @@ export function reorderChild(container: Section, from: number, to: number): Sect
|
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* Block types insertable as a container CHILD — excludes `container` itself
|
|
40
|
-
* (v1 enforces one level of container nesting)
|
|
41
|
-
*
|
|
41
|
+
* (v1 enforces one level of container nesting) and `reference`, which only
|
|
42
|
+
* expands at the top level of a page. Shared so the depth guard has a single,
|
|
43
|
+
* testable source of truth (the container toolbar's "+" picker uses it).
|
|
42
44
|
*/
|
|
43
45
|
export function childInsertableTypes(): { type: string; label: string; icon: ReactNode }[] {
|
|
44
46
|
return sortInsertMenuOptions(
|
|
45
47
|
getAllSections()
|
|
46
|
-
.filter((d) => d.type !== "container" && d.type !== "spacer")
|
|
48
|
+
.filter((d) => d.type !== "container" && d.type !== "spacer" && d.type !== REFERENCE_TYPE)
|
|
47
49
|
.map((d) => ({ type: d.type, label: d.label, icon: d.icon })),
|
|
48
50
|
);
|
|
49
51
|
}
|
package/src/lib/dexie.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
// The editor's offline draft store (IndexedDB via Dexie): unsaved section
|
|
2
|
+
// edits, the working index/nav, site config, pending media, and a sha-keyed
|
|
3
|
+
// cache of the last loaded content. Nothing here is authoritative — GitHub is.
|
|
4
|
+
// Schema versions only ever append; an EMPTY `version(N)` bump is intentional
|
|
5
|
+
// (see the per-version notes in the constructor), never a leftover to remove.
|
|
1
6
|
import Dexie from "dexie";
|
|
2
7
|
import type { SectionContent } from "../schemas/sections";
|
|
3
8
|
import type { SiteIndex, SectionMeta, SiteConfig, Page } from "../schemas/site-config";
|
|
4
9
|
import type { NavEntry } from "../schemas/nav";
|
|
10
|
+
import type { TagEntry } from "../schemas/tags";
|
|
5
11
|
import type { LoadedSection } from "./loader";
|
|
6
12
|
import type { MediaManifest, MediaItem } from "../media/types";
|
|
7
13
|
import type { DocumentManifest, DocumentManifestEntry } from "../schemas/documents";
|
|
@@ -19,6 +25,9 @@ interface SiteIndexRow {
|
|
|
19
25
|
sections: Record<string, SectionMeta>;
|
|
20
26
|
/** Optional: rows written before page groups shipped have no nav. */
|
|
21
27
|
nav?: NavEntry[];
|
|
28
|
+
/** Optional: rows written before section tags shipped have none. Restored
|
|
29
|
+
* as absent (not []), which writers read as "leave tags.json alone". */
|
|
30
|
+
tags?: TagEntry[];
|
|
22
31
|
deletedSections: string[];
|
|
23
32
|
updatedAt: string;
|
|
24
33
|
}
|
|
@@ -311,7 +320,10 @@ export async function restoreLocalChanges(): Promise<{
|
|
|
311
320
|
const siteId = metaRow?.siteId || getDb().siteId;
|
|
312
321
|
return {
|
|
313
322
|
sections,
|
|
314
|
-
siteIndex: {
|
|
323
|
+
siteIndex: {
|
|
324
|
+
siteId, pages: indexRow.pages, sections: indexRow.sections, nav: indexRow.nav,
|
|
325
|
+
...(indexRow.tags !== undefined ? { tags: indexRow.tags } : {}),
|
|
326
|
+
},
|
|
315
327
|
siteConfig: configRow?.config,
|
|
316
328
|
deletedSections: indexRow.deletedSections ?? [],
|
|
317
329
|
};
|
|
@@ -345,6 +357,7 @@ export async function persistSiteIndex(index: SiteIndex, deletedSections: string
|
|
|
345
357
|
pages: index.pages,
|
|
346
358
|
sections: index.sections,
|
|
347
359
|
nav: index.nav,
|
|
360
|
+
tags: index.tags,
|
|
348
361
|
deletedSections,
|
|
349
362
|
updatedAt: now,
|
|
350
363
|
});
|
|
@@ -465,6 +478,7 @@ export async function persistAll(
|
|
|
465
478
|
pages: siteIndex.pages,
|
|
466
479
|
sections: siteIndex.sections,
|
|
467
480
|
nav: siteIndex.nav,
|
|
481
|
+
tags: siteIndex.tags,
|
|
468
482
|
// Record the deletion INTENT, not just its effect on the order. The
|
|
469
483
|
// restore path reads this back; when it was hardcoded `[]` that path
|
|
470
484
|
// had to re-derive deletions by diffing this snapshot against a fresh
|
|
@@ -497,6 +511,12 @@ export async function persistAll(
|
|
|
497
511
|
* cache hit then served pre-upload media ("No Image" on images the published site
|
|
498
512
|
* rendered fine) and an empty document manifest ("File missing" on committed
|
|
499
513
|
* documents). Passing them positionally makes forgetting a compile error.
|
|
514
|
+
*
|
|
515
|
+
* `tagsDegraded` is required for the same reason. A degraded tags read caches
|
|
516
|
+
* as "not loaded" (the index without `tags`), so a later cache-hit load stays
|
|
517
|
+
* read-only for tags instead of trusting the partial list. Only the cold load
|
|
518
|
+
* used to strip it, so a conflict recovery, remote sync or save re-primed the
|
|
519
|
+
* row with the partial list and the next cache hit re-enabled tag editing.
|
|
500
520
|
*/
|
|
501
521
|
export async function cacheContent(
|
|
502
522
|
sha: string,
|
|
@@ -504,6 +524,7 @@ export async function cacheContent(
|
|
|
504
524
|
index: SiteIndex,
|
|
505
525
|
siteConfig: Record<string, unknown>,
|
|
506
526
|
manifests: { media: MediaManifest; documents: DocumentManifest },
|
|
527
|
+
tagsDegraded: boolean,
|
|
507
528
|
diff?: {
|
|
508
529
|
savedBranchSha?: string | null;
|
|
509
530
|
changedSectionIds?: string[];
|
|
@@ -512,11 +533,12 @@ export async function cacheContent(
|
|
|
512
533
|
},
|
|
513
534
|
): Promise<void> {
|
|
514
535
|
const now = new Date().toISOString();
|
|
536
|
+
const { tags: _partialTags, ...untaggedIndex } = index;
|
|
515
537
|
await getDb().contentCache.put({
|
|
516
538
|
key: "current",
|
|
517
539
|
sha,
|
|
518
540
|
sections,
|
|
519
|
-
index,
|
|
541
|
+
index: tagsDegraded ? untaggedIndex : index,
|
|
520
542
|
siteConfig,
|
|
521
543
|
updatedAt: now,
|
|
522
544
|
savedBranchSha: diff?.savedBranchSha ?? null,
|
package/src/lib/env.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// env() is a byte-for-byte twin of packages/platform/src/env.ts: platform cannot
|
|
2
|
+
// import primitives without dragging it into apps/admin's bundle, so keep both.
|
|
1
3
|
declare global {
|
|
2
4
|
interface ImportMeta {
|
|
3
5
|
readonly env?: Record<string, string | undefined>;
|
|
@@ -11,3 +13,10 @@ export function env(key: string): string {
|
|
|
11
13
|
""
|
|
12
14
|
);
|
|
13
15
|
}
|
|
16
|
+
|
|
17
|
+
/** Vite replaces `import.meta.env.PROD` with a boolean literal at build time
|
|
18
|
+
* (packages are `noExternal`, so that covers this file too), which is why the
|
|
19
|
+
* declared string type above is bypassed here. False under Node and vitest. */
|
|
20
|
+
export function isProd(): boolean {
|
|
21
|
+
return (import.meta.env?.PROD as unknown) === true;
|
|
22
|
+
}
|
package/src/lib/events.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SiteNav } from "./nav";
|
|
2
2
|
|
|
3
3
|
export interface TypedEvent<T> {
|
|
4
4
|
dispatch(detail: T): void;
|
|
@@ -19,7 +19,6 @@ export function createEvent<T>(name: string): TypedEvent<T> {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export const editModeEvent = createEvent<{ isEditMode: boolean }>("editmodechange");
|
|
22
|
-
export const navChangeEvent = createEvent<NavItem[]>("sitenavchange");
|
|
23
22
|
export const darkModeEvent = createEvent<string>("sitedarkmode");
|
|
24
23
|
export const siteNameChangeEvent = createEvent<string>("sitenamechange");
|
|
25
24
|
export const historySelectEvent = createEvent<{ sha: string; date: string }>("history-select");
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import type { ImageBackground, ImageBackgroundSurface } from "../schemas/shared";
|
|
3
|
+
|
|
4
|
+
// Class names are spelled out in full so Tailwind's source scan emits them.
|
|
5
|
+
// The surface-light/-dark tokens deliberately do NOT flip under `.dark`: a dark
|
|
6
|
+
// plate chosen for light mode must stay dark. The per-mode switch comes from the
|
|
7
|
+
// `dark:` variant instead, so it follows the theme toggle with no JS. An unset
|
|
8
|
+
// dark mode clears a light-mode plate rather than inheriting it.
|
|
9
|
+
const LIGHT_MODE: Record<ImageBackgroundSurface, string | undefined> = {
|
|
10
|
+
none: undefined,
|
|
11
|
+
light: "bg-surface-light",
|
|
12
|
+
dark: "bg-surface-dark",
|
|
13
|
+
};
|
|
14
|
+
const DARK_MODE: Record<ImageBackgroundSurface, string | undefined> = {
|
|
15
|
+
none: "dark:bg-transparent",
|
|
16
|
+
light: "dark:bg-surface-light",
|
|
17
|
+
dark: "dark:bg-surface-dark",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export interface ImageBackdrop {
|
|
21
|
+
className?: string;
|
|
22
|
+
style?: CSSProperties;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function imageBackdrop(bg: ImageBackground | undefined): ImageBackdrop | undefined {
|
|
26
|
+
if (!bg) return undefined;
|
|
27
|
+
if (bg.mode === "custom") return { style: { backgroundColor: bg.color } };
|
|
28
|
+
const light = LIGHT_MODE[bg.light];
|
|
29
|
+
if (!light && bg.dark === "none") return undefined;
|
|
30
|
+
return { className: [light, DARK_MODE[bg.dark]].filter(Boolean).join(" ") };
|
|
31
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { sanitizeMediaName } from "../media/utils";
|
|
2
|
+
import type { MediaConfig, MediaItem, Variant } from "../schemas/media";
|
|
3
|
+
|
|
4
|
+
// The one place an uploaded image's identity, storage folder, variant widths,
|
|
5
|
+
// variant paths and manifest entry are decided. Two pixel adapters sit behind
|
|
6
|
+
// it: the editor's OffscreenCanvas worker (media/worker.ts) and the sharp path
|
|
7
|
+
// (authoring processImageBuffers, which the MCP connector calls). They used to
|
|
8
|
+
// build all of this separately and agree only because a comment said so; the
|
|
9
|
+
// site's media settings and dedup each drifted between them once. Pure and
|
|
10
|
+
// browser-safe — the worker imports it.
|
|
11
|
+
|
|
12
|
+
export interface MediaIdentity {
|
|
13
|
+
id: string;
|
|
14
|
+
hash: string;
|
|
15
|
+
originalName: string;
|
|
16
|
+
/** Storage dir under assets/images/. Never changes once committed. */
|
|
17
|
+
folder: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** `hash` is the 16-hex content hash both sides compute (hashFileBuffer / hashBuffer). */
|
|
21
|
+
export function mediaIdentity(hash: string, fileName: string): MediaIdentity {
|
|
22
|
+
const originalName = sanitizeMediaName(fileName);
|
|
23
|
+
return { id: hash, hash, originalName, folder: `${originalName}-${hash}` };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Repo path of one stored file in a media folder: a variant width, or `poster`. */
|
|
27
|
+
export function imageVariantPath(folder: string, key: number | string): string {
|
|
28
|
+
return `assets/images/${folder}/${key}.webp`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ImageVariantPlan extends MediaIdentity {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
/** WebP quality, 1-100. */
|
|
35
|
+
quality: number;
|
|
36
|
+
/** Ascending by width. */
|
|
37
|
+
variants: { width: number; path: string }[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function planImageVariants(input: {
|
|
41
|
+
hash: string;
|
|
42
|
+
fileName: string;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
media: Pick<MediaConfig, "sizes" | "quality">;
|
|
46
|
+
}): ImageVariantPlan {
|
|
47
|
+
const identity = mediaIdentity(input.hash, input.fileName);
|
|
48
|
+
// Never upscale; an image narrower than every configured size still gets one
|
|
49
|
+
// variant, at its own width.
|
|
50
|
+
const widths = input.media.sizes.filter((s) => s <= input.width).sort((a, b) => a - b);
|
|
51
|
+
if (widths.length === 0) widths.push(input.width);
|
|
52
|
+
return {
|
|
53
|
+
...identity,
|
|
54
|
+
width: input.width,
|
|
55
|
+
height: input.height,
|
|
56
|
+
quality: input.media.quality,
|
|
57
|
+
variants: widths.map((width) => ({ width, path: imageVariantPath(identity.folder, width) })),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type ImageManifestEntry = Omit<MediaItem, "kind" | "storage" | "url" | "duration" | "folderId" | "hidden"> & {
|
|
62
|
+
kind: "image";
|
|
63
|
+
storage: "github";
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* `rendered` is what the adapter measured for each planned width (heights come
|
|
68
|
+
* from the encoder, not the plan). `size` is the adapter's byte count for the
|
|
69
|
+
* item: the editor records its largest variant, the sharp path the original's
|
|
70
|
+
* length — they differ today and this module does not decide that.
|
|
71
|
+
*/
|
|
72
|
+
export function imageManifestEntry(plan: ImageVariantPlan, rendered: Variant[], size: number): ImageManifestEntry {
|
|
73
|
+
const variants = plan.variants.map(({ width }) => {
|
|
74
|
+
const out = rendered.find((r) => r.width === width);
|
|
75
|
+
if (!out) throw new Error(`[image-variant-plan] no rendered variant for planned width ${width}`);
|
|
76
|
+
return { width, height: out.height, size: out.size };
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
id: plan.id,
|
|
80
|
+
hash: plan.hash,
|
|
81
|
+
kind: "image",
|
|
82
|
+
originalName: plan.originalName,
|
|
83
|
+
width: plan.width,
|
|
84
|
+
height: plan.height,
|
|
85
|
+
mimeType: "image/webp",
|
|
86
|
+
size,
|
|
87
|
+
folder: plan.folder,
|
|
88
|
+
variants,
|
|
89
|
+
alt: "",
|
|
90
|
+
storage: "github",
|
|
91
|
+
};
|
|
92
|
+
}
|
package/src/lib/index-ops.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { IndexSchema, PageStatusSchema, RESERVED_SLUGS, SLUG_RE, type SiteIndex, type SectionMeta } from "../schemas/site-config";
|
|
3
|
-
import type {
|
|
3
|
+
import type { NavGroupEntry } from "../schemas/nav";
|
|
4
4
|
import type { NavLocation } from "./nav-tree";
|
|
5
5
|
// Page and nav mutations are shared with the editor rather than reimplemented:
|
|
6
6
|
// both surfaces must agree on what "delete a page" or "remove a group" means, and
|
|
7
7
|
// a second implementation here is how they would drift.
|
|
8
8
|
import { addPage as addPageToIndex, deletePage, slugifyPageSlug, uniquePageSlug } from "./pages";
|
|
9
|
+
import { liftSidecars } from "./sidecars";
|
|
9
10
|
import {
|
|
10
11
|
addGroup, deleteGroup, groupOfPage, moveNavEntry, navEntries, reconcileNav,
|
|
11
12
|
renameGroup, setGroupStartCollapsed,
|
|
@@ -254,11 +255,12 @@ export function applyIndexOps(
|
|
|
254
255
|
};
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
// IndexSchema strips `nav` (that strip is what keeps the
|
|
258
|
-
// index.json), so the authored nav
|
|
259
|
-
// available to the nav ops below
|
|
260
|
-
//
|
|
261
|
-
|
|
258
|
+
// IndexSchema strips `nav` (that strip is what keeps the Sidecar out of
|
|
259
|
+
// index.json), so the authored nav is lifted off the RAW input to be
|
|
260
|
+
// available to the nav ops below — as fresh entries, so no op can mutate the
|
|
261
|
+
// caller's index. reconcileNav is total, so an unreadable nav degrades to a
|
|
262
|
+
// flat one rather than failing.
|
|
263
|
+
const lifted = liftSidecars(rawIndex);
|
|
262
264
|
|
|
263
265
|
// Own copy: the caller's index is also its knownSiteTypes source and may be
|
|
264
266
|
// logged, so nothing here mutates it. Reassigned by the page/nav ops, which
|
|
@@ -267,18 +269,7 @@ export function applyIndexOps(
|
|
|
267
269
|
...base.data,
|
|
268
270
|
pages: base.data.pages.map((p) => ({ ...p, order: [...p.order] })),
|
|
269
271
|
sections: Object.fromEntries(Object.entries(base.data.sections).map(([k, v]) => [k, { ...v }])),
|
|
270
|
-
|
|
271
|
-
// op that spliced in place would mutate the caller's index — the one thing
|
|
272
|
-
// this function's own comment promises it never does.
|
|
273
|
-
...(Array.isArray(rawNav)
|
|
274
|
-
? {
|
|
275
|
-
nav: (rawNav as NavEntry[]).map((entry) =>
|
|
276
|
-
entry && typeof entry === "object" && "pageIds" in entry
|
|
277
|
-
? { ...entry, pageIds: [...(entry as { pageIds: string[] }).pageIds] }
|
|
278
|
-
: { ...entry },
|
|
279
|
-
),
|
|
280
|
-
}
|
|
281
|
-
: {}),
|
|
272
|
+
...(lifted.nav ? { nav: lifted.nav.entries } : {}),
|
|
282
273
|
};
|
|
283
274
|
|
|
284
275
|
const removed = new Set<string>();
|
package/src/lib/index.ts
CHANGED
|
@@ -4,6 +4,23 @@ export { audiencePasses } from "./pages";
|
|
|
4
4
|
export { resolveChatbotName, resolveThinkingPhrases, DEFAULT_CHATBOT_NAME } from "./chatbot";
|
|
5
5
|
export { generateNavLinks, toSectionId, type NavItem } from "./nav";
|
|
6
6
|
export { navEntries, pagesInNavOrder, groupOfPage, groupDisplayLabel, reconcileNav } from "./nav-tree";
|
|
7
|
+
export { siteTags, tagDisplayLabel, reconcileTags } from "./tags";
|
|
8
|
+
export {
|
|
9
|
+
NAV,
|
|
10
|
+
TAGS,
|
|
11
|
+
SIDECARS,
|
|
12
|
+
readSidecar,
|
|
13
|
+
readSidecarText,
|
|
14
|
+
liftSidecars,
|
|
15
|
+
planSidecarWrite,
|
|
16
|
+
type SidecarDefinition,
|
|
17
|
+
type SidecarFileState,
|
|
18
|
+
type SidecarWritePlan,
|
|
19
|
+
type SidecarRead,
|
|
20
|
+
type SidecarDiagnostic,
|
|
21
|
+
} from "./sidecars";
|
|
22
|
+
export { resolveReference, type ReferenceContent } from "./references";
|
|
23
|
+
export { REFERENCE_TYPE } from "./reference-type";
|
|
7
24
|
export {
|
|
8
25
|
deriveContrast,
|
|
9
26
|
contrastColor,
|
|
@@ -15,12 +32,11 @@ export {
|
|
|
15
32
|
} from "./contrast";
|
|
16
33
|
export { primaryVarValue, accentVarValue, onPrimaryVarValue } from "./theme-vars";
|
|
17
34
|
export { sanitizeHtml, ensureSanitizer } from "./sanitize";
|
|
18
|
-
export { gridColsClass } from "./grid";
|
|
19
35
|
export { getIcon, curatedIcons, type IconEntry } from "./icons";
|
|
20
36
|
export { buildGoogleFontsUrl } from "./google-fonts";
|
|
21
37
|
export { formatTimestamp } from "./timestamp";
|
|
22
|
-
export { safeRedirect } from "./
|
|
23
|
-
export { createEvent, editModeEvent,
|
|
38
|
+
export { safeRedirect } from "./safe-redirect";
|
|
39
|
+
export { createEvent, editModeEvent, darkModeEvent, type TypedEvent } from "./events";
|
|
24
40
|
export {
|
|
25
41
|
createRegistry,
|
|
26
42
|
defineSection,
|
|
@@ -42,7 +58,7 @@ export {
|
|
|
42
58
|
export {
|
|
43
59
|
mergeSiteContent,
|
|
44
60
|
loadStaticSiteContent,
|
|
45
|
-
loadSiteContent,
|
|
46
61
|
type LoadedSection,
|
|
47
62
|
type SiteContent,
|
|
63
|
+
type SidecarReads,
|
|
48
64
|
} from "./loader";
|