@drawnagency/primitives 0.1.112 → 0.1.114
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/auth/types.d.ts +1 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/{chunk-GPPVYLEI.js → chunk-45FA7Z55.js} +1 -1
- package/dist/{chunk-REDDTTGJ.js → chunk-4Y2JQQZL.js} +19 -1
- package/dist/chunk-5GFACGSN.js +6 -0
- package/dist/chunk-5KSAS4VY.js +275 -0
- package/dist/{chunk-5KNXTMUC.js → chunk-7SAAJVDE.js} +408 -28
- package/dist/{chunk-S2L3BPLS.js → chunk-7SX42OP4.js} +1 -1
- package/dist/{chunk-GGXZZ77Z.js → chunk-AASEGXNT.js} +18 -1
- package/dist/{chunk-WKZ7OENC.js → chunk-BQ5TZZUE.js} +5 -1
- package/dist/chunk-DIMDRBFK.js +11 -0
- package/dist/{chunk-WUJ3XNFI.js → chunk-GGYY3JQJ.js} +19 -24
- package/dist/{chunk-VLPELTPI.js → chunk-IP2SEBAJ.js} +5 -1
- package/dist/{chunk-IINIZBQB.js → chunk-JCDZAFX2.js} +30 -10
- package/dist/chunk-JR24U7FJ.js +120 -0
- package/dist/{chunk-SW6PCQQD.js → chunk-KQA772WQ.js} +2 -1
- package/dist/{chunk-Z2LO4PSQ.js → chunk-N3G7DOU3.js} +609 -61
- package/dist/chunk-OAGJBCSH.js +67 -0
- package/dist/{chunk-VT3PYGVW.js → chunk-PLANHXS7.js} +191 -61
- package/dist/{chunk-OGGZ5AXT.js → chunk-PNSCDBU7.js} +38 -56
- package/dist/{chunk-HSXMOS5Q.js → chunk-PTY2RG2K.js} +5 -2
- package/dist/{chunk-EPWBPIV6.js → chunk-PZPGJZRG.js} +9 -8
- package/dist/{chunk-P3ZNCHW7.js → chunk-QHMKIODQ.js} +19 -5
- package/dist/{chunk-HBULBDGP.js → chunk-S37DZPHW.js} +1 -1
- package/dist/{chunk-4I5OO5UB.js → chunk-TEOAKGZA.js} +0 -1
- package/dist/chunk-VUYCRBJK.js +174 -0
- package/dist/{chunk-4RNF2DRG.js → chunk-XDEPXTBY.js} +0 -2
- package/dist/{chunk-3SZNUCXI.js → chunk-Y5QECJX7.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 +20 -5
- 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 +148 -77
- 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 +17 -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 +12 -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 +19 -17
- package/dist/components/sections/register.js +19 -17
- 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 +1 -0
- 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 +11 -18
- 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 +2 -2
- package/dist/hooks/useEditorPublish.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 +67 -49
- 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.map +1 -1
- package/dist/lib/dexie.js +9 -1
- 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/index-ops.js +3 -3
- package/dist/lib/index.d.ts +6 -4
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +29 -21
- package/dist/lib/loader.d.ts +21 -7
- package/dist/lib/loader.d.ts.map +1 -1
- package/dist/lib/nav-tree.d.ts +1 -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/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/tags.d.ts +58 -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 +8 -4
- package/dist/media/resolve.d.ts +2 -0
- package/dist/media/resolve.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/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 +14 -8
- package/dist/schemas/shared.d.ts +26 -0
- package/dist/schemas/shared.d.ts.map +1 -1
- package/dist/schemas/site-config.d.ts +7 -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 +1 -1
- package/dist/types/database.d.ts +8 -0
- package/dist/types/database.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/auth/cookies.ts +111 -0
- package/src/auth/types.ts +1 -0
- package/src/collab/rebase.ts +26 -2
- 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 +7 -7
- 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 +48 -35
- 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 +499 -339
- 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 +20 -21
- package/src/components/shell/SiteSettingsModal.tsx +24 -2
- package/src/components/shell/SiteSettingsTags.tsx +143 -0
- package/src/components/shell/SiteSettingsUsers.tsx +85 -28
- 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 +18 -27
- package/src/hooks/useMediaPipeline.ts +1 -1
- 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 +15 -1
- 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/index.ts +5 -4
- package/src/lib/loader.ts +54 -55
- package/src/lib/nav-tree.ts +71 -0
- package/src/lib/nav.ts +196 -36
- 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/tags.ts +148 -0
- package/src/lib/theme-vars.ts +23 -0
- package/src/media/index.ts +1 -1
- package/src/media/resolve.ts +3 -1
- package/src/media/utils.ts +18 -0
- package/src/media/{videoPoster.ts → video-poster.ts} +2 -2
- package/src/schemas/index.ts +1 -0
- package/src/schemas/shared.ts +24 -1
- package/src/schemas/site-config.ts +9 -1
- package/src/schemas/tags.ts +33 -0
- package/src/storage/types.ts +1 -1
- package/src/types/database.ts +6 -0
- package/dist/chunk-BR4MIPTM.js +0 -138
- package/dist/chunk-DNY72JZN.js +0 -86
- package/dist/chunk-F2LYQPXV.js +0 -77
- package/dist/chunk-TALRVOGO.js +0 -128
- 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
|
@@ -3,8 +3,20 @@ import { DragHandle as DragHandleIcon } from "../shared/icons";
|
|
|
3
3
|
import { IconButton } from "../shared/IconButton";
|
|
4
4
|
import { Tooltip, Kbd } from "../shared/Tooltip";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
interface DragHandleProps {
|
|
7
|
+
tooltipSide?: "bottom" | "right";
|
|
8
|
+
/**
|
|
9
|
+
* Set by callers offering a keyboard alternative (SectionWrapper's Move
|
|
10
|
+
* up/down buttons) so the handle itself is reachable by keyboard and its
|
|
11
|
+
* `aria-describedby` hint announces the alternative. Callers with no
|
|
12
|
+
* keyboard alternative leave this at the default -1 (drag-only, mouse/touch).
|
|
13
|
+
*/
|
|
14
|
+
tabIndex?: number;
|
|
15
|
+
"aria-describedby"?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const DragHandle = forwardRef<HTMLButtonElement, DragHandleProps>(function DragHandle(
|
|
19
|
+
{ tooltipSide, tabIndex = -1, "aria-describedby": ariaDescribedBy },
|
|
8
20
|
ref,
|
|
9
21
|
) {
|
|
10
22
|
return (
|
|
@@ -14,7 +26,8 @@ export const DragHandle = forwardRef<HTMLButtonElement, { tooltipSide?: "bottom"
|
|
|
14
26
|
icon={<DragHandleIcon size={18} />}
|
|
15
27
|
label="Drag to reorder section"
|
|
16
28
|
className="pointer-events-auto cursor-grab active:cursor-grabbing rounded-md text-base-contrast-light/80 hover:bg-base-contrast-light/10 hover:text-base-contrast"
|
|
17
|
-
tabIndex={
|
|
29
|
+
tabIndex={tabIndex}
|
|
30
|
+
aria-describedby={ariaDescribedBy}
|
|
18
31
|
/>
|
|
19
32
|
</Tooltip>
|
|
20
33
|
);
|
|
@@ -1,20 +1,46 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { cn } from "../../lib/cn";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
|
-
* The
|
|
3
|
-
*
|
|
5
|
+
* The insertion line shown at an edge of a row/cell during a closest-edge
|
|
6
|
+
* drag-to-reorder, paired with `useSortableRow`'s (or `useSortableNavRow`'s)
|
|
7
|
+
* `closestEdge`. `top`/`bottom` render a horizontal line spanning the row;
|
|
8
|
+
* `left`/`right` render a vertical one spanning its height.
|
|
4
9
|
*
|
|
5
|
-
* `inset` starts
|
|
6
|
-
* distinguishing "drop inside this group" from "drop before this group"
|
|
10
|
+
* `inset` starts a horizontal line at the nested-row indent — the ONLY thing
|
|
11
|
+
* distinguishing "drop inside this group" from "drop before this group", and
|
|
7
12
|
* a group's last member slot from the top-level slot that follows it.
|
|
13
|
+
*
|
|
14
|
+
* `style` is the escape hatch for a caller whose perpendicular offset differs
|
|
15
|
+
* from the default (a wider cell gutter, a caller-specific `top`) — it wins
|
|
16
|
+
* over the default Tailwind transform/position via normal inline-style
|
|
17
|
+
* precedence, so callers only need to override the property that differs.
|
|
8
18
|
*/
|
|
9
|
-
export function DropEdgeIndicator({
|
|
19
|
+
export function DropEdgeIndicator({
|
|
20
|
+
edge,
|
|
21
|
+
inset = false,
|
|
22
|
+
style,
|
|
23
|
+
}: {
|
|
24
|
+
edge: "top" | "bottom" | "left" | "right" | null;
|
|
25
|
+
inset?: boolean;
|
|
26
|
+
style?: CSSProperties;
|
|
27
|
+
}) {
|
|
10
28
|
if (!edge) return null;
|
|
29
|
+
const horizontal = edge === "top" || edge === "bottom";
|
|
11
30
|
return (
|
|
12
31
|
<div
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
32
|
+
data-drop-edge={edge}
|
|
33
|
+
className={cn(
|
|
34
|
+
"absolute z-10 bg-primary",
|
|
35
|
+
horizontal
|
|
36
|
+
? cn("right-0 h-0.5", inset ? "left-6" : "left-0")
|
|
37
|
+
: "top-0 bottom-0 w-0.5",
|
|
38
|
+
edge === "top" && "top-0 -translate-y-1/2",
|
|
39
|
+
edge === "bottom" && "bottom-0 translate-y-1/2",
|
|
40
|
+
edge === "left" && "left-0 -translate-x-1",
|
|
41
|
+
edge === "right" && "right-0 translate-x-1",
|
|
42
|
+
)}
|
|
43
|
+
style={style}
|
|
18
44
|
/>
|
|
19
45
|
);
|
|
20
46
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Plus } from "lucide-react";
|
|
2
2
|
import { IconButton } from "../shared/IconButton";
|
|
3
3
|
import { Tooltip, Kbd } from "../shared/Tooltip";
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ export function InsertButton({ index, onInsert }: InsertButtonProps) {
|
|
|
11
11
|
return (
|
|
12
12
|
<Tooltip content={<><Kbd>Click</Kbd> to add below<br /><Kbd>Alt+Click</Kbd> to add above</>}>
|
|
13
13
|
<IconButton
|
|
14
|
-
icon={<
|
|
14
|
+
icon={<Plus size={18} />}
|
|
15
15
|
label="Add section"
|
|
16
16
|
className="pointer-events-auto rounded-md text-base-contrast-light/80 hover:bg-base-contrast-light/10 hover:text-base-contrast"
|
|
17
17
|
tabIndex={-1}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import { ChevronDown } from "lucide-react";
|
|
1
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
2
|
+
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
3
3
|
import type { NavGroupEntry } from "../../schemas/nav";
|
|
4
4
|
import type { NavLocation } from "../../lib/nav-tree";
|
|
5
5
|
import { groupDisplayLabel } from "../../lib/nav-tree";
|
|
6
6
|
import { pluralize } from "../../lib/text";
|
|
7
7
|
import { cn } from "../../lib/cn";
|
|
8
8
|
import { Button } from "../shared/Button";
|
|
9
|
+
import { ConfirmInline } from "../shared/ConfirmInline";
|
|
10
|
+
import { IconButton } from "../shared/IconButton";
|
|
9
11
|
import { Input } from "../shared/Input";
|
|
10
12
|
import { Toggle } from "../shared/Toggle";
|
|
11
13
|
import { DragHandle } from "./DragHandle";
|
|
@@ -15,6 +17,9 @@ import { useSortableNavRow } from "../../hooks/useSortableNavRow";
|
|
|
15
17
|
interface Props {
|
|
16
18
|
group: NavGroupEntry;
|
|
17
19
|
entryIndex: number;
|
|
20
|
+
/** Total top-level entries — groups move among these only (never into a
|
|
21
|
+
* group, unlike a page). */
|
|
22
|
+
entryCount: number;
|
|
18
23
|
memberCount: number;
|
|
19
24
|
/** Opens the settings panel on mount. The `+ Add group` flow sets this so a
|
|
20
25
|
* brand-new group lands with its label input focused. */
|
|
@@ -35,17 +40,21 @@ interface Props {
|
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
export function NavGroupRow({
|
|
38
|
-
group, entryIndex, memberCount, autoOpenSettings = false,
|
|
43
|
+
group, entryIndex, entryCount, memberCount, autoOpenSettings = false,
|
|
39
44
|
onRename, onSetStartCollapsed, onDelete, onMove, onDragStateChange,
|
|
40
45
|
}: Props) {
|
|
41
46
|
const [settingsOpen, setSettingsOpen] = useState(autoOpenSettings);
|
|
42
47
|
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
43
48
|
const [showError, setShowError] = useState(false);
|
|
49
|
+
const deleteButtonRef = useRef<HTMLButtonElement>(null);
|
|
44
50
|
|
|
45
51
|
const { rowRef, handleRef, isDragging, closestEdge } = useSortableNavRow<HTMLDivElement, HTMLButtonElement>({
|
|
46
52
|
row: { kind: "group", groupId: group.id, index: entryIndex },
|
|
47
53
|
entryIndex, kind: "group", onMove,
|
|
48
54
|
});
|
|
55
|
+
const dragHintId = useId();
|
|
56
|
+
const moveTo = (delta: 1 | -1) =>
|
|
57
|
+
onMove({ groupId: null, index: entryIndex }, { groupId: null, index: entryIndex + delta });
|
|
49
58
|
|
|
50
59
|
// Surface the hook's drag state upward so the modal can collapse this group
|
|
51
60
|
// while it is the one being dragged.
|
|
@@ -65,8 +74,27 @@ export function NavGroupRow({
|
|
|
65
74
|
return (
|
|
66
75
|
<div ref={rowRef} data-testid={`nav-row-group-${group.id}`} className={cn("relative flex items-start gap-1", isDragging && "opacity-50")}>
|
|
67
76
|
<DropEdgeIndicator edge={closestEdge} />
|
|
68
|
-
<div className="flex shrink-0 items-center py-2 [&_[role=tooltip]]:hidden">
|
|
69
|
-
<DragHandle ref={handleRef} />
|
|
77
|
+
<div className="flex shrink-0 items-center gap-1 py-2 [&_[role=tooltip]]:hidden">
|
|
78
|
+
<DragHandle ref={handleRef} tabIndex={0} aria-describedby={dragHintId} />
|
|
79
|
+
<div className="flex flex-col">
|
|
80
|
+
<IconButton
|
|
81
|
+
icon={<ChevronUp size={12} />}
|
|
82
|
+
label="Move up"
|
|
83
|
+
size="sm"
|
|
84
|
+
disabled={entryIndex === 0}
|
|
85
|
+
onClick={() => moveTo(-1)}
|
|
86
|
+
/>
|
|
87
|
+
<IconButton
|
|
88
|
+
icon={<ChevronDown size={12} />}
|
|
89
|
+
label="Move down"
|
|
90
|
+
size="sm"
|
|
91
|
+
disabled={entryIndex === entryCount - 1}
|
|
92
|
+
onClick={() => moveTo(1)}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
<span id={dragHintId} className="sr-only">
|
|
96
|
+
Use Move up / Move down to reorder with the keyboard.
|
|
97
|
+
</span>
|
|
70
98
|
</div>
|
|
71
99
|
<div className="min-w-0 flex-1 rounded-md border border-base-200 bg-base">
|
|
72
100
|
<div className="flex items-center">
|
|
@@ -106,17 +134,18 @@ export function NavGroupRow({
|
|
|
106
134
|
</div>
|
|
107
135
|
|
|
108
136
|
{confirmingDelete ? (
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
137
|
+
<ConfirmInline
|
|
138
|
+
message={`Delete this group? ${pluralize(memberCount, "page")} will move to the top level.`}
|
|
139
|
+
confirmLabel="Delete"
|
|
140
|
+
confirmAriaLabel="Confirm delete"
|
|
141
|
+
tone="neutral"
|
|
142
|
+
onConfirm={onDelete}
|
|
143
|
+
onCancel={() => setConfirmingDelete(false)}
|
|
144
|
+
returnFocusTo={deleteButtonRef}
|
|
145
|
+
/>
|
|
118
146
|
) : (
|
|
119
147
|
<Button
|
|
148
|
+
ref={deleteButtonRef}
|
|
120
149
|
variant="destructive" size="sm" aria-label="Delete group" className="self-start"
|
|
121
150
|
onClick={() => (memberCount === 0 ? onDelete() : setConfirmingDelete(true))}
|
|
122
151
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useCallback, useState, useEffect } from "react";
|
|
2
|
-
import { Check, ChevronDown, Home } from "lucide-react";
|
|
1
|
+
import { useCallback, useState, useEffect, useId } from "react";
|
|
2
|
+
import { Check, ChevronDown, ChevronUp, Home } from "lucide-react";
|
|
3
3
|
import type { SiteIndex, Page } from "../../schemas/site-config";
|
|
4
4
|
import type { Audience } from "../../auth/types";
|
|
5
5
|
// Sanctioned outside->inside import: document/ is a sealed subtree, but the
|
|
@@ -7,6 +7,8 @@ import type { Audience } from "../../auth/types";
|
|
|
7
7
|
// sanctioned import in schemas/site-config.ts and lib/pages.ts).
|
|
8
8
|
import type { DocumentOptions } from "../../document/engine/settings";
|
|
9
9
|
import { Button } from "../shared/Button";
|
|
10
|
+
import { ConfirmDialog } from "../shared/ConfirmDialog";
|
|
11
|
+
import { IconButton } from "../shared/IconButton";
|
|
10
12
|
import { Input } from "../shared/Input";
|
|
11
13
|
import { Toggle } from "../shared/Toggle";
|
|
12
14
|
import { AudienceIndicator } from "./AudienceIndicator";
|
|
@@ -80,7 +82,17 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
80
82
|
|
|
81
83
|
// `location` is optional: the archived flat block renders inert rows with no
|
|
82
84
|
// nav position, exactly as it did when draggability keyed off `dragIndex`.
|
|
83
|
-
|
|
85
|
+
// `liveSiblingRawIndexes` is the ordered list of RAW positions (within the
|
|
86
|
+
// group's `pageIds`, or within the top-level `entries`) that Move up/down
|
|
87
|
+
// may cross into — i.e. every LIVE sibling's raw slot, archived ones
|
|
88
|
+
// excluded. `location.index` is itself a raw position (drag needs it to
|
|
89
|
+
// splice correctly — see the ORIGINAL pageIds index comment below), so
|
|
90
|
+
// comparing it against a raw-space list (not a live COUNT) is what keeps an
|
|
91
|
+
// archived page sitting between two live ones from producing a wrongly
|
|
92
|
+
// disabled button or a click that silently swaps past the archived page
|
|
93
|
+
// with no visible reorder (drag can cross a group boundary; the keyboard
|
|
94
|
+
// pair deliberately cannot).
|
|
95
|
+
const renderPage = (page: Page, location?: NavLocation, entryIndex?: number, liveSiblingRawIndexes?: number[]) => (
|
|
84
96
|
<PageRow
|
|
85
97
|
key={page.id}
|
|
86
98
|
page={page}
|
|
@@ -90,6 +102,7 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
90
102
|
otherSlugs={index.pages.filter((p) => p.id !== page.id).map((p) => p.slug)}
|
|
91
103
|
location={location}
|
|
92
104
|
entryIndex={entryIndex}
|
|
105
|
+
liveSiblingRawIndexes={liveSiblingRawIndexes}
|
|
93
106
|
onMove={props.onMoveNavEntry}
|
|
94
107
|
onToggleExpand={() => toggleExpand(page.id)}
|
|
95
108
|
onSetHome={() => props.onSetHome(page.id)}
|
|
@@ -108,14 +121,28 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
108
121
|
/>
|
|
109
122
|
);
|
|
110
123
|
|
|
124
|
+
const entries = navEntries(index);
|
|
125
|
+
const entryCount = entries.length;
|
|
126
|
+
// Raw top-level positions that are "live" for Move up/down purposes: every
|
|
127
|
+
// group (always visible) plus every non-archived page — mirrors
|
|
128
|
+
// isLiveTopEntry in lib/nav-tree.ts, which describeNavMove's "N of M" uses.
|
|
129
|
+
const liveTopIndexes = entries
|
|
130
|
+
.map((entry, i) => ({ entry, i }))
|
|
131
|
+
.filter(({ entry }) => {
|
|
132
|
+
if (entry.kind === "group") return true;
|
|
133
|
+
const page = index.pages.find((p) => p.id === entry.pageId);
|
|
134
|
+
return page?.status === "live";
|
|
135
|
+
})
|
|
136
|
+
.map(({ i }) => i);
|
|
137
|
+
|
|
111
138
|
return (
|
|
112
139
|
<div className="flex flex-col gap-2 overflow-y-auto">
|
|
113
140
|
<div className="flex flex-col gap-2">
|
|
114
|
-
{
|
|
141
|
+
{entries.map((entry, entryIndex) => {
|
|
115
142
|
if (entry.kind === "page") {
|
|
116
143
|
const page = index.pages.find((p) => p.id === entry.pageId);
|
|
117
144
|
if (!page || page.status !== "live") return null;
|
|
118
|
-
return renderPage(page, { groupId: null, index: entryIndex }, entryIndex);
|
|
145
|
+
return renderPage(page, { groupId: null, index: entryIndex }, entryIndex, liveTopIndexes);
|
|
119
146
|
}
|
|
120
147
|
|
|
121
148
|
// CRITICAL: carry the ORIGINAL pageIds index (`pi`) through the filter.
|
|
@@ -134,6 +161,7 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
134
161
|
<NavGroupRow
|
|
135
162
|
group={entry}
|
|
136
163
|
entryIndex={entryIndex}
|
|
164
|
+
entryCount={entryCount}
|
|
137
165
|
memberCount={members.length}
|
|
138
166
|
autoOpenSettings={newGroupId === entry.id}
|
|
139
167
|
onRename={(label) => props.onRenameGroup(entry.id, label)}
|
|
@@ -146,7 +174,7 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
146
174
|
<div data-testid={`nav-group-members-${entry.id}`} className="ml-6 flex flex-col gap-2">
|
|
147
175
|
{members.length === 0
|
|
148
176
|
? <EmptyGroupDropzone groupId={entry.id} onMove={props.onMoveNavEntry} />
|
|
149
|
-
: members.map(({ page, pi }) => renderPage(page, { groupId: entry.id, index: pi }, entryIndex))}
|
|
177
|
+
: members.map(({ page, pi }) => renderPage(page, { groupId: entry.id, index: pi }, entryIndex, members.map((m) => m.pi)))}
|
|
150
178
|
</div>
|
|
151
179
|
)}
|
|
152
180
|
</div>
|
|
@@ -156,7 +184,7 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
156
184
|
|
|
157
185
|
{/* The only target for "after the last entry" when that entry is a group:
|
|
158
186
|
every edge of a trailing group resolves to a position inside it. */}
|
|
159
|
-
<TailDropzone entryCount={
|
|
187
|
+
<TailDropzone entryCount={entryCount} onMove={props.onMoveNavEntry} />
|
|
160
188
|
|
|
161
189
|
<div className="mt-2 flex gap-2">
|
|
162
190
|
<Button
|
|
@@ -194,11 +222,16 @@ export function PagesModal(props: PagesModalProps) {
|
|
|
194
222
|
}
|
|
195
223
|
|
|
196
224
|
function PageRow({
|
|
197
|
-
page, audiences, expanded, isNew, otherSlugs, location, entryIndex, onMove, onToggleExpand, onSetHome, onSetArchived, onSetFields, onSetAudience, onSetDocument, onRequestDelete,
|
|
225
|
+
page, audiences, expanded, isNew, otherSlugs, location, entryIndex, liveSiblingRawIndexes, onMove, onToggleExpand, onSetHome, onSetArchived, onSetFields, onSetAudience, onSetDocument, onRequestDelete,
|
|
198
226
|
}: {
|
|
199
227
|
page: Page; audiences: Audience[]; expanded: boolean;
|
|
200
228
|
isNew: boolean; otherSlugs: string[];
|
|
201
229
|
location?: NavLocation; entryIndex?: number;
|
|
230
|
+
/** Ordered RAW positions of every LIVE sibling (the enclosing group's
|
|
231
|
+
* `pageIds`, or the top-level `entries`, whichever `location.groupId`
|
|
232
|
+
* selects) — see the comment on `renderPage` in PagesModal. Drag can cross
|
|
233
|
+
* a group boundary; the keyboard pair deliberately cannot. */
|
|
234
|
+
liveSiblingRawIndexes?: number[];
|
|
202
235
|
onMove: (from: NavLocation, to: NavLocation) => void;
|
|
203
236
|
onToggleExpand: () => void; onSetHome: () => void; onSetArchived: (v: boolean) => void;
|
|
204
237
|
onSetFields: (patch: Partial<Pick<Page, "title" | "slug" | "showInNav">>) => void;
|
|
@@ -211,6 +244,19 @@ function PageRow({
|
|
|
211
244
|
row: { kind: "page", pageId: page.id, groupId: location?.groupId ?? null, index: location?.index ?? 0 },
|
|
212
245
|
entryIndex: entryIndex ?? 0, kind: "page", onMove, enabled: draggable,
|
|
213
246
|
});
|
|
247
|
+
const dragHintId = useId();
|
|
248
|
+
// Neighbours are resolved among LIVE siblings only, then translated back to
|
|
249
|
+
// the neighbour's own raw index — never `location.index + delta`, which
|
|
250
|
+
// would step into an archived page's raw slot instead of the next visible
|
|
251
|
+
// row (see the `liveSiblingRawIndexes` comment on PagesModal's renderPage).
|
|
252
|
+
const liveIndex = liveSiblingRawIndexes?.indexOf(location?.index ?? -1) ?? -1;
|
|
253
|
+
const canMoveUp = draggable && liveIndex > 0;
|
|
254
|
+
const canMoveDown = draggable && liveSiblingRawIndexes !== undefined && liveIndex !== -1 && liveIndex < liveSiblingRawIndexes.length - 1;
|
|
255
|
+
const moveTo = (delta: 1 | -1) => {
|
|
256
|
+
const neighbourRawIndex = liveSiblingRawIndexes?.[liveIndex + delta];
|
|
257
|
+
if (neighbourRawIndex === undefined) return;
|
|
258
|
+
onMove(location!, { groupId: location!.groupId, index: neighbourRawIndex });
|
|
259
|
+
};
|
|
214
260
|
|
|
215
261
|
// The slug input edits a local draft; only valid values commit to the index,
|
|
216
262
|
// which must always hold a non-empty, unique, non-reserved slug.
|
|
@@ -297,8 +343,27 @@ function PageRow({
|
|
|
297
343
|
>
|
|
298
344
|
<DropEdgeIndicator edge={closestEdge} inset={location?.groupId != null} />
|
|
299
345
|
{draggable && (
|
|
300
|
-
<div className="flex shrink-0 items-center py-2 [&_[role=tooltip]]:hidden">
|
|
301
|
-
<DragHandle ref={handleRef} />
|
|
346
|
+
<div className="flex shrink-0 items-center gap-1 py-2 [&_[role=tooltip]]:hidden">
|
|
347
|
+
<DragHandle ref={handleRef} tabIndex={0} aria-describedby={dragHintId} />
|
|
348
|
+
<div className="flex flex-col">
|
|
349
|
+
<IconButton
|
|
350
|
+
icon={<ChevronUp size={12} />}
|
|
351
|
+
label="Move up"
|
|
352
|
+
size="sm"
|
|
353
|
+
disabled={!canMoveUp}
|
|
354
|
+
onClick={() => moveTo(-1)}
|
|
355
|
+
/>
|
|
356
|
+
<IconButton
|
|
357
|
+
icon={<ChevronDown size={12} />}
|
|
358
|
+
label="Move down"
|
|
359
|
+
size="sm"
|
|
360
|
+
disabled={!canMoveDown}
|
|
361
|
+
onClick={() => moveTo(1)}
|
|
362
|
+
/>
|
|
363
|
+
</div>
|
|
364
|
+
<span id={dragHintId} className="sr-only">
|
|
365
|
+
Use Move up / Move down to reorder with the keyboard.
|
|
366
|
+
</span>
|
|
302
367
|
</div>
|
|
303
368
|
)}
|
|
304
369
|
<div className={cn("min-w-0 flex-1 rounded-md border border-base-200 bg-base", isDragging && "outline outline-2 outline-primary/50")}>
|
|
@@ -455,21 +520,29 @@ function DeleteConfirm({ page, onCancel, onConfirm }: { page: Page; onCancel: ()
|
|
|
455
520
|
// type-the-name guard pre-satisfied ("" === "").
|
|
456
521
|
const confirmName = pageDisplayTitle(page.title);
|
|
457
522
|
return (
|
|
458
|
-
<
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
523
|
+
<ConfirmDialog
|
|
524
|
+
isOpen
|
|
525
|
+
embedded
|
|
526
|
+
title="Delete this page?"
|
|
527
|
+
body={
|
|
528
|
+
<div className="flex flex-col gap-3">
|
|
529
|
+
<p className="text-sm text-base-contrast">
|
|
530
|
+
Deleting <strong>{confirmName}</strong> permanently removes the page and its{" "}
|
|
531
|
+
<strong>{pluralize(n, "section")}</strong>. This is recoverable only via GitHub version history.
|
|
532
|
+
</p>
|
|
533
|
+
<Input
|
|
534
|
+
label={`Type the page name "${confirmName}" to confirm`}
|
|
535
|
+
value={typed}
|
|
536
|
+
onChange={setTyped}
|
|
537
|
+
placeholder={confirmName}
|
|
538
|
+
/>
|
|
539
|
+
</div>
|
|
540
|
+
}
|
|
541
|
+
confirmLabel="Delete"
|
|
542
|
+
tone="destructive"
|
|
543
|
+
confirmDisabled={typed !== confirmName}
|
|
544
|
+
onConfirm={onConfirm}
|
|
545
|
+
onCancel={onCancel}
|
|
546
|
+
/>
|
|
474
547
|
);
|
|
475
548
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { useState, useRef, useEffect } from "react";
|
|
2
|
-
import { ArrowRightLeft, Plus } from "lucide-react";
|
|
1
|
+
import { useState, useRef, useEffect, useId } from "react";
|
|
2
|
+
import { ArrowRightLeft, Plus, ChevronUp, ChevronDown } from "lucide-react";
|
|
3
3
|
import type { Edge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
|
|
4
4
|
import { DragHandle } from "./DragHandle";
|
|
5
|
+
import { DropEdgeIndicator } from "./DropEdgeIndicator";
|
|
5
6
|
import { InsertButton } from "./InsertButton";
|
|
6
7
|
import { DeleteButton } from "./DeleteButton";
|
|
7
8
|
import { SettingsButton } from "./SettingsButton";
|
|
8
9
|
import { IconButton } from "../shared/IconButton";
|
|
9
|
-
import { Tooltip
|
|
10
|
+
import { Tooltip } from "../shared/Tooltip";
|
|
10
11
|
import { StatusIndicator } from "./StatusIndicator";
|
|
11
12
|
import { AudienceIndicator } from "./AudienceIndicator";
|
|
13
|
+
import { TagIndicator } from "./TagIndicator";
|
|
12
14
|
import { LockBadge } from "./LockBadge";
|
|
13
15
|
import { SettingsForm } from "./SettingsForm";
|
|
14
16
|
import { useEditorContext } from "../shell/EditorContext";
|
|
@@ -16,6 +18,7 @@ import { useEditorModal } from "../shell/EditorModalContext";
|
|
|
16
18
|
import type { WrapperProps } from "../../lib/registry";
|
|
17
19
|
import { buildBlockDragData, buildBlockDropData, isBlockDragData, canDropBlock } from "../../lib/block-dnd";
|
|
18
20
|
import { cn } from "../../lib/cn";
|
|
21
|
+
import { REFERENCE_TYPE } from "../../lib/reference-type";
|
|
19
22
|
|
|
20
23
|
export function SectionWrapper({
|
|
21
24
|
sectionId,
|
|
@@ -24,6 +27,7 @@ export function SectionWrapper({
|
|
|
24
27
|
dirty,
|
|
25
28
|
index,
|
|
26
29
|
isLast,
|
|
30
|
+
sectionCount,
|
|
27
31
|
containerId,
|
|
28
32
|
isContainerBlock,
|
|
29
33
|
definition,
|
|
@@ -31,6 +35,7 @@ export function SectionWrapper({
|
|
|
31
35
|
audiences,
|
|
32
36
|
access,
|
|
33
37
|
onAccessChange,
|
|
38
|
+
tagging,
|
|
34
39
|
onStatusChange,
|
|
35
40
|
onSectionChange,
|
|
36
41
|
onReorder,
|
|
@@ -64,6 +69,7 @@ export function SectionWrapper({
|
|
|
64
69
|
const handleRef = useRef<HTMLButtonElement>(null);
|
|
65
70
|
const [isDragging, setIsDragging] = useState(false);
|
|
66
71
|
const [closestEdge, setClosestEdge] = useState<Edge | null>(null);
|
|
72
|
+
const dragHintId = useId();
|
|
67
73
|
|
|
68
74
|
const hasSettings = !!(
|
|
69
75
|
(definition.settings || definition.settingsForm) &&
|
|
@@ -120,6 +126,7 @@ export function SectionWrapper({
|
|
|
120
126
|
containerId,
|
|
121
127
|
index,
|
|
122
128
|
isContainer: isContainerBlock,
|
|
129
|
+
isReference: sectionType === REFERENCE_TYPE,
|
|
123
130
|
}),
|
|
124
131
|
onGenerateDragPreview: () => {
|
|
125
132
|
dropElement.style.opacity = "0.4";
|
|
@@ -182,7 +189,7 @@ export function SectionWrapper({
|
|
|
182
189
|
// be torn down on lock-acquire (cleanup above) and re-run against the fresh
|
|
183
190
|
// handle node on lock-release — without it, a locked-then-released section's
|
|
184
191
|
// registration stays bound to the old unmounted handle and reorder breaks.
|
|
185
|
-
}, [sectionId, index, containerId, isContainerBlock, isEditMode, isLocked]);
|
|
192
|
+
}, [sectionId, sectionType, index, containerId, isContainerBlock, isEditMode, isLocked]);
|
|
186
193
|
|
|
187
194
|
function handleSettingsClick() {
|
|
188
195
|
if (!onSectionChange) return;
|
|
@@ -278,11 +285,14 @@ export function SectionWrapper({
|
|
|
278
285
|
<div
|
|
279
286
|
className={cn(
|
|
280
287
|
"absolute left-0 bottom-full z-30 hover:z-[60] mb-1 flex items-center gap-1.5 transition-opacity",
|
|
281
|
-
|
|
288
|
+
// group-focus-within: this cluster's own tab stops (DragHandle,
|
|
289
|
+
// Move up/down) would otherwise be focusable but invisible —
|
|
290
|
+
// hover alone doesn't cover keyboard navigation.
|
|
291
|
+
alwaysShow ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100",
|
|
282
292
|
)}
|
|
283
293
|
>
|
|
284
294
|
<div className="relative -ml-[34px] flex flex-col items-center">
|
|
285
|
-
<DragHandle ref={handleRef} />
|
|
295
|
+
<DragHandle ref={handleRef} tabIndex={0} aria-describedby={dragHintId} />
|
|
286
296
|
{onRequestInsert && !isDragging && chromeReady && (
|
|
287
297
|
// Below xl the gutter can't fit the plus beside the handle, so it
|
|
288
298
|
// hangs below it (absolute → no row-height contribution: the handle
|
|
@@ -295,6 +305,27 @@ export function SectionWrapper({
|
|
|
295
305
|
<span className="pointer-events-none select-none whitespace-nowrap text-sm capitalize text-base-contrast-light/80">
|
|
296
306
|
{definition.label}
|
|
297
307
|
</span>
|
|
308
|
+
{onReorder && (
|
|
309
|
+
<div className="pointer-events-auto flex items-center">
|
|
310
|
+
<IconButton
|
|
311
|
+
icon={<ChevronUp size={14} />}
|
|
312
|
+
label={sectionCount ? `Move up (position ${index + 1} of ${sectionCount})` : "Move up"}
|
|
313
|
+
size="sm"
|
|
314
|
+
disabled={index === 0}
|
|
315
|
+
onClick={() => onReorder(index, index - 1)}
|
|
316
|
+
/>
|
|
317
|
+
<IconButton
|
|
318
|
+
icon={<ChevronDown size={14} />}
|
|
319
|
+
label={sectionCount ? `Move down (position ${index + 1} of ${sectionCount})` : "Move down"}
|
|
320
|
+
size="sm"
|
|
321
|
+
disabled={isLast}
|
|
322
|
+
onClick={() => onReorder(index, index + 1)}
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
)}
|
|
326
|
+
<span id={dragHintId} className="sr-only">
|
|
327
|
+
Use Move up / Move down to reorder with the keyboard.
|
|
328
|
+
</span>
|
|
298
329
|
</div>
|
|
299
330
|
)}
|
|
300
331
|
|
|
@@ -331,9 +362,18 @@ export function SectionWrapper({
|
|
|
331
362
|
onChange={(newAccess) => onAccessChange?.(newAccess)}
|
|
332
363
|
/>
|
|
333
364
|
</div>
|
|
365
|
+
<div className="pointer-events-auto">
|
|
366
|
+
<TagIndicator
|
|
367
|
+
tags={tagging.tags}
|
|
368
|
+
assignedIds={tagging.assignedIds}
|
|
369
|
+
disabled={isLocked || !tagging.onToggle || !tagging.onCreate}
|
|
370
|
+
onToggle={(tagId, tagged) => tagging.onToggle?.(tagId, tagged)}
|
|
371
|
+
onCreate={(label) => tagging.onCreate?.(label)}
|
|
372
|
+
/>
|
|
373
|
+
</div>
|
|
334
374
|
|
|
335
375
|
{!isLocked && onAddChild && (
|
|
336
|
-
<Tooltip className="pointer-events-auto" content=
|
|
376
|
+
<Tooltip className="pointer-events-auto" content="Add a block">
|
|
337
377
|
<IconButton
|
|
338
378
|
icon={<Plus size={16} />}
|
|
339
379
|
label="Add block"
|
|
@@ -344,7 +384,7 @@ export function SectionWrapper({
|
|
|
344
384
|
)}
|
|
345
385
|
|
|
346
386
|
{!isLocked && onMoveSection && (
|
|
347
|
-
<Tooltip className="pointer-events-auto" content=
|
|
387
|
+
<Tooltip className="pointer-events-auto" content="Move to page">
|
|
348
388
|
<IconButton
|
|
349
389
|
icon={<ArrowRightLeft size={16} />}
|
|
350
390
|
label="Move to page"
|
|
@@ -355,31 +395,32 @@ export function SectionWrapper({
|
|
|
355
395
|
)}
|
|
356
396
|
|
|
357
397
|
{!isLocked && hasSettings && (
|
|
358
|
-
<Tooltip className="pointer-events-auto" content=
|
|
398
|
+
<Tooltip className="pointer-events-auto" content="Edit settings">
|
|
359
399
|
<SettingsButton onClick={handleSettingsClick} />
|
|
360
400
|
</Tooltip>
|
|
361
401
|
)}
|
|
362
402
|
|
|
363
403
|
{!isLocked && onDelete && (
|
|
364
|
-
<Tooltip className="pointer-events-auto" content=
|
|
404
|
+
<Tooltip className="pointer-events-auto" content="Delete section">
|
|
365
405
|
<DeleteButton onDelete={onDelete} />
|
|
366
406
|
</Tooltip>
|
|
367
407
|
)}
|
|
368
408
|
</div>
|
|
369
409
|
|
|
370
|
-
{/* Drop indicator — centered in the section's own padding-top
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
410
|
+
{/* Drop indicator — centered in the section's own padding-top. Bottom
|
|
411
|
+
only ever shows on the last section: every other slot's "insert
|
|
412
|
+
after me" is the next section's own "top" line, so showing both
|
|
413
|
+
would double the line. */}
|
|
414
|
+
<DropEdgeIndicator
|
|
415
|
+
edge={closestEdge === "bottom" && !isLast ? null : closestEdge}
|
|
416
|
+
style={
|
|
417
|
+
closestEdge === "top"
|
|
418
|
+
? { top: "calc(var(--section-gap) / 2 * -1)" }
|
|
419
|
+
: closestEdge === "bottom"
|
|
420
|
+
? { transform: "none" }
|
|
421
|
+
: undefined
|
|
422
|
+
}
|
|
423
|
+
/>
|
|
383
424
|
|
|
384
425
|
{isLocked ? (
|
|
385
426
|
// React 19 supports the boolean `inert` prop — blocks focus, pointer,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Settings } from "lucide-react";
|
|
2
2
|
import { IconButton } from "../shared/IconButton";
|
|
3
3
|
|
|
4
4
|
interface SettingsButtonProps {
|
|
@@ -8,7 +8,7 @@ interface SettingsButtonProps {
|
|
|
8
8
|
export function SettingsButton({ onClick }: SettingsButtonProps) {
|
|
9
9
|
return (
|
|
10
10
|
<IconButton
|
|
11
|
-
icon={<
|
|
11
|
+
icon={<Settings size={16} />}
|
|
12
12
|
label="Section settings"
|
|
13
13
|
onClick={onClick}
|
|
14
14
|
className="pointer-events-auto"
|