@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
|
@@ -5,6 +5,7 @@ import { ColorPicker } from "../shared/ColorPicker";
|
|
|
5
5
|
import { FontPicker } from "../shared/FontPicker";
|
|
6
6
|
import { Input } from "../shared/Input";
|
|
7
7
|
import { Select } from "../shared/Select";
|
|
8
|
+
import { Textarea } from "../shared/Textarea";
|
|
8
9
|
import { SubTabs } from "../shared/SubTabs";
|
|
9
10
|
import { FormLabel } from "../shared/FormLabel";
|
|
10
11
|
import { useMediaLibrary } from "./MediaLibraryContext";
|
|
@@ -12,22 +13,13 @@ import { contrastRatio, wcagLevel, suggestAccessibleOn } from "../../lib/contras
|
|
|
12
13
|
import { cn } from "../../lib/cn";
|
|
13
14
|
import { buildGoogleFontsUrl } from "../../lib/google-fonts";
|
|
14
15
|
import type { SiteConfig } from "../../schemas/site-config";
|
|
15
|
-
import
|
|
16
|
+
import { imageThumbnailUrl } from "../../media/utils";
|
|
16
17
|
|
|
17
18
|
interface Props {
|
|
18
19
|
siteConfig: SiteConfig;
|
|
19
20
|
onChange: (config: SiteConfig) => void;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
// Smallest generated variant for the editor-preview thumbnail (mirrors
|
|
23
|
-
// DocInspector's thumbSrc) — avoids needing a MediaProvider in this context.
|
|
24
|
-
function thumbSrc(imageId: string, item: MediaItem | undefined): string | null {
|
|
25
|
-
if (!item || item.kind !== "image") return null;
|
|
26
|
-
if (item.mimeType === "image/svg+xml") return `/api/media/${imageId}/original.svg`;
|
|
27
|
-
const widths = item.variants.map((v) => v.width).sort((a, b) => a - b);
|
|
28
|
-
if (widths.length === 0) return null;
|
|
29
|
-
return `/api/media/${imageId}/${widths[0]}.webp`;
|
|
30
|
-
}
|
|
31
23
|
|
|
32
24
|
const darkModeOptions = [
|
|
33
25
|
{ label: "Light", value: "light" },
|
|
@@ -63,7 +55,7 @@ function ContrastRow({ label, entries }: { label: string; entries: ContrastEntry
|
|
|
63
55
|
<span className="text-base-contrast-light">{label}</span>
|
|
64
56
|
{entries.map((e) => {
|
|
65
57
|
const level = wcagLevel(e.ratio);
|
|
66
|
-
const tone = level.aa ? "text-
|
|
58
|
+
const tone = level.aa ? "text-success" : level.aaLarge ? "text-warning" : "text-danger";
|
|
67
59
|
const mark = level.aa ? "AA" : level.aaLarge ? "large only" : "fail";
|
|
68
60
|
return (
|
|
69
61
|
<span key={e.mode} className="inline-flex items-center gap-1">
|
|
@@ -154,16 +146,14 @@ export function SiteSettingsDisplay({ siteConfig, onChange }: Props) {
|
|
|
154
146
|
/>
|
|
155
147
|
|
|
156
148
|
<div>
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
id="site-description"
|
|
149
|
+
<Textarea
|
|
150
|
+
label="Description"
|
|
160
151
|
aria-label="Site description"
|
|
161
152
|
rows={2}
|
|
162
153
|
maxLength={300}
|
|
163
154
|
value={siteConfig.description ?? ""}
|
|
164
|
-
onChange={(
|
|
155
|
+
onChange={(value) => update({ description: value || null })}
|
|
165
156
|
placeholder="Short summary for search results and social shares."
|
|
166
|
-
className="w-full rounded border border-base-200 bg-base px-3 py-2 text-sm text-base-contrast"
|
|
167
157
|
/>
|
|
168
158
|
<div className="mt-1 flex items-start justify-between gap-2">
|
|
169
159
|
<p className="text-xs text-base-contrast/70">
|
|
@@ -214,13 +204,13 @@ export function SiteSettingsDisplay({ siteConfig, onChange }: Props) {
|
|
|
214
204
|
)}
|
|
215
205
|
</div>
|
|
216
206
|
<p className="mt-1 text-xs text-base-contrast/70">SVG or PNG, up to 100KB. Shown in browser tabs.</p>
|
|
217
|
-
{faviconError && <p className="mt-1 text-xs text-
|
|
207
|
+
{faviconError && <p className="mt-1 text-xs text-danger">{faviconError}</p>}
|
|
218
208
|
</div>
|
|
219
209
|
|
|
220
210
|
{(() => {
|
|
221
211
|
const logo = siteConfig.logo;
|
|
222
|
-
const lightSrc = logo ?
|
|
223
|
-
const darkSrc = logo?.dark ?
|
|
212
|
+
const lightSrc = logo ? imageThumbnailUrl(mediaLibrary?.manifest.images[logo.light.imageId]) : null;
|
|
213
|
+
const darkSrc = logo?.dark ? imageThumbnailUrl(mediaLibrary?.manifest.images[logo.dark.imageId]) : null;
|
|
224
214
|
const needsDarkHint = logo != null && siteConfig.darkMode !== "light" && !logo.dark && !logo.invertInDark;
|
|
225
215
|
|
|
226
216
|
return (
|
|
@@ -302,7 +292,7 @@ export function SiteSettingsDisplay({ siteConfig, onChange }: Props) {
|
|
|
302
292
|
/>
|
|
303
293
|
|
|
304
294
|
{needsDarkHint && (
|
|
305
|
-
<p className="text-xs text-
|
|
295
|
+
<p className="text-xs text-warning">
|
|
306
296
|
Add a dark variant or enable invert so the logo stays legible in dark mode.
|
|
307
297
|
</p>
|
|
308
298
|
)}
|
|
@@ -7,6 +7,8 @@ import { SiteSettingsDisplay } from "./SiteSettingsDisplay";
|
|
|
7
7
|
import { SiteSettingsUsers } from "./SiteSettingsUsers";
|
|
8
8
|
import { SiteSettingsChatbot } from "./SiteSettingsChatbot";
|
|
9
9
|
import { SiteSettingsDecks } from "./SiteSettingsDecks";
|
|
10
|
+
import { SiteSettingsTags } from "./SiteSettingsTags";
|
|
11
|
+
import type { SiteTagging } from "../../lib/registry";
|
|
10
12
|
import type { SiteConfig } from "../../schemas/site-config";
|
|
11
13
|
import type { Audience } from "../../auth/types";
|
|
12
14
|
|
|
@@ -27,9 +29,13 @@ interface Props {
|
|
|
27
29
|
passwordToggle: boolean;
|
|
28
30
|
};
|
|
29
31
|
currentUser: { email: string; role: "owner" | "editor" } | null;
|
|
32
|
+
tagging: SiteTagging;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
export function SiteSettingsModal({
|
|
35
|
+
export function SiteSettingsModal({
|
|
36
|
+
isOpen, onClose, siteConfig, onSiteConfigChange, onAudiencesChange, audiences, chatbotPlatformEnabled, capabilities, currentUser,
|
|
37
|
+
tagging,
|
|
38
|
+
}: Props) {
|
|
33
39
|
const [signOutError, setSignOutError] = useState<string | null>(null);
|
|
34
40
|
|
|
35
41
|
async function handleSignOut() {
|
|
@@ -92,6 +98,22 @@ export function SiteSettingsModal({ isOpen, onClose, siteConfig, onSiteConfigCha
|
|
|
92
98
|
</div>
|
|
93
99
|
),
|
|
94
100
|
},
|
|
101
|
+
{
|
|
102
|
+
id: "tags",
|
|
103
|
+
label: "Tags",
|
|
104
|
+
show: true,
|
|
105
|
+
content: (
|
|
106
|
+
<div data-testid="site-settings-tab-panel" className="flex flex-1 flex-col overflow-y-auto px-6 py-4">
|
|
107
|
+
<SiteSettingsTags
|
|
108
|
+
tags={tagging.tags}
|
|
109
|
+
editable={tagging.editable}
|
|
110
|
+
onCreate={(label) => tagging.onCreate(label)}
|
|
111
|
+
onRename={tagging.onRename}
|
|
112
|
+
onDelete={tagging.onDelete}
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
),
|
|
116
|
+
},
|
|
95
117
|
{
|
|
96
118
|
id: "display",
|
|
97
119
|
label: "Display",
|
|
@@ -130,7 +152,7 @@ export function SiteSettingsModal({ isOpen, onClose, siteConfig, onSiteConfigCha
|
|
|
130
152
|
<span className="ml-1 capitalize">({currentUser.role})</span>
|
|
131
153
|
)}
|
|
132
154
|
{signOutError && (
|
|
133
|
-
<span className="ml-2 text-
|
|
155
|
+
<span className="ml-2 text-danger">— {signOutError}</span>
|
|
134
156
|
)}
|
|
135
157
|
</div>
|
|
136
158
|
<Button
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { useRef, useState, type FormEvent } from "react";
|
|
2
|
+
import { pluralize } from "../../lib/text";
|
|
3
|
+
import { findTagByLabel, tagDisplayLabel } from "../../lib/tags";
|
|
4
|
+
import type { TagEntry } from "../../schemas/tags";
|
|
5
|
+
import { Button } from "../shared/Button";
|
|
6
|
+
import { ConfirmInline } from "../shared/ConfirmInline";
|
|
7
|
+
import { Input } from "../shared/Input";
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
/** The site's tag registry, already reconciled (siteTags). */
|
|
11
|
+
tags: TagEntry[];
|
|
12
|
+
/** False when the registry was never loaded, or loaded degraded; the tab then edits nothing. */
|
|
13
|
+
editable: boolean;
|
|
14
|
+
onCreate: (label: string) => void;
|
|
15
|
+
onRename: (tagId: string, label: string) => void;
|
|
16
|
+
onDelete: (tagId: string) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function SiteSettingsTags({ tags, editable, onCreate, onRename, onDelete }: Props) {
|
|
20
|
+
const [draft, setDraft] = useState("");
|
|
21
|
+
const [error, setError] = useState<string | null>(null);
|
|
22
|
+
|
|
23
|
+
function submit(e: FormEvent) {
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
const label = draft.trim();
|
|
26
|
+
if (!label) return;
|
|
27
|
+
if (findTagByLabel(tags, label)) {
|
|
28
|
+
setError(`A tag named "${label}" already exists.`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
onCreate(label);
|
|
32
|
+
setDraft("");
|
|
33
|
+
setError(null);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const header = (
|
|
37
|
+
<div>
|
|
38
|
+
<h3 className="mb-1 text-sm font-medium text-base-contrast">Section tags</h3>
|
|
39
|
+
<p className="text-xs text-base-contrast-light">
|
|
40
|
+
Tags group related sections across pages. Put them on a section from the Tags pill above it. Viewers never see
|
|
41
|
+
tag names.
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (!editable) {
|
|
47
|
+
return (
|
|
48
|
+
<div className="space-y-4">
|
|
49
|
+
{header}
|
|
50
|
+
<p className="text-xs text-danger">Tags could not be loaded in full for this session, so they are read-only. Reload the editor to manage them.</p>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className="space-y-4">
|
|
57
|
+
{header}
|
|
58
|
+
|
|
59
|
+
<form onSubmit={submit} className="flex items-start gap-2">
|
|
60
|
+
<Input
|
|
61
|
+
label="New tag"
|
|
62
|
+
hideLabel
|
|
63
|
+
className="flex-1"
|
|
64
|
+
value={draft}
|
|
65
|
+
placeholder="New tag name"
|
|
66
|
+
error={error ?? undefined}
|
|
67
|
+
onChange={(v) => { setDraft(v); setError(null); }}
|
|
68
|
+
/>
|
|
69
|
+
<Button type="submit" variant="secondary">Add tag</Button>
|
|
70
|
+
</form>
|
|
71
|
+
|
|
72
|
+
{tags.length === 0 ? (
|
|
73
|
+
<p className="text-xs text-base-contrast-light">No tags yet.</p>
|
|
74
|
+
) : (
|
|
75
|
+
<ul className="space-y-2">
|
|
76
|
+
{tags.map((t) => (
|
|
77
|
+
<TagRow
|
|
78
|
+
key={t.id}
|
|
79
|
+
tag={t}
|
|
80
|
+
duplicate={t.label.trim() !== "" && findTagByLabel(tags, t.label)?.id !== t.id}
|
|
81
|
+
onRename={(label) => onRename(t.id, label)}
|
|
82
|
+
onDelete={() => onDelete(t.id)}
|
|
83
|
+
/>
|
|
84
|
+
))}
|
|
85
|
+
</ul>
|
|
86
|
+
)}
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function TagRow({ tag, duplicate, onRename, onDelete }: {
|
|
92
|
+
tag: TagEntry;
|
|
93
|
+
/** An earlier tag already has this name — inline creates would pick that one. */
|
|
94
|
+
duplicate: boolean;
|
|
95
|
+
onRename: (label: string) => void;
|
|
96
|
+
onDelete: () => void;
|
|
97
|
+
}) {
|
|
98
|
+
const [confirming, setConfirming] = useState(false);
|
|
99
|
+
const deleteRef = useRef<HTMLButtonElement>(null);
|
|
100
|
+
const count = tag.sectionIds.length;
|
|
101
|
+
const name = tagDisplayLabel(tag.label);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<li className="rounded-md border border-base-200 px-3 py-2">
|
|
105
|
+
<div className="flex items-center gap-3">
|
|
106
|
+
<Input
|
|
107
|
+
label="Tag name"
|
|
108
|
+
hideLabel
|
|
109
|
+
className="min-w-0 flex-1"
|
|
110
|
+
value={tag.label}
|
|
111
|
+
placeholder="Untitled tag"
|
|
112
|
+
error={duplicate ? "Another tag already has this name." : undefined}
|
|
113
|
+
onChange={onRename}
|
|
114
|
+
/>
|
|
115
|
+
<span className="shrink-0 text-xs text-base-contrast/60">{pluralize(count, "section")}</span>
|
|
116
|
+
{!confirming && (
|
|
117
|
+
<Button
|
|
118
|
+
ref={deleteRef}
|
|
119
|
+
variant="destructive"
|
|
120
|
+
size="sm"
|
|
121
|
+
aria-label={`Delete tag ${name}`}
|
|
122
|
+
onClick={() => (count === 0 ? onDelete() : setConfirming(true))}
|
|
123
|
+
>
|
|
124
|
+
Delete
|
|
125
|
+
</Button>
|
|
126
|
+
)}
|
|
127
|
+
</div>
|
|
128
|
+
{confirming && (
|
|
129
|
+
<div className="mt-2">
|
|
130
|
+
<ConfirmInline
|
|
131
|
+
message={`Delete "${name}"? It is removed from ${pluralize(count, "section")}. The sections themselves stay.`}
|
|
132
|
+
confirmLabel="Delete"
|
|
133
|
+
confirmAriaLabel="Confirm delete"
|
|
134
|
+
tone="destructive"
|
|
135
|
+
onConfirm={onDelete}
|
|
136
|
+
onCancel={() => setConfirming(false)}
|
|
137
|
+
returnFocusTo={deleteRef}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
</li>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Fragment, useState, useEffect, type FormEvent } from "react";
|
|
1
|
+
import { Fragment, useRef, useState, useEffect, type FormEvent, type RefObject } from "react";
|
|
2
2
|
import { ChevronDown } from "lucide-react";
|
|
3
3
|
import type { Role } from "../../auth/types";
|
|
4
4
|
import { Button } from "../shared/Button";
|
|
5
|
+
import { ConfirmInline } from "../shared/ConfirmInline";
|
|
6
|
+
import { Input } from "../shared/Input";
|
|
5
7
|
|
|
6
8
|
interface User {
|
|
7
9
|
id: string;
|
|
@@ -21,12 +23,25 @@ export function SiteSettingsUsers({ currentUser }: Props) {
|
|
|
21
23
|
const [inviteRole, setInviteRole] = useState<Role>("editor");
|
|
22
24
|
const [error, setError] = useState<string | null>(null);
|
|
23
25
|
const [confirmingRevoke, setConfirmingRevoke] = useState<string | null>(null);
|
|
26
|
+
// One stable ref object per user, so a row's Remove button and its
|
|
27
|
+
// ConfirmInline share the same object across the swap — the button
|
|
28
|
+
// reattaches to it (layout phase) before ConfirmInline's cleanup effect
|
|
29
|
+
// (passive phase) reads it back to return focus.
|
|
30
|
+
const removeButtonRefs = useRef(new Map<string, RefObject<HTMLButtonElement | null>>());
|
|
31
|
+
function getRemoveButtonRef(userId: string): RefObject<HTMLButtonElement | null> {
|
|
32
|
+
let ref = removeButtonRefs.current.get(userId);
|
|
33
|
+
if (!ref) {
|
|
34
|
+
ref = { current: null };
|
|
35
|
+
removeButtonRefs.current.set(userId, ref);
|
|
36
|
+
}
|
|
37
|
+
return ref;
|
|
38
|
+
}
|
|
24
39
|
|
|
25
40
|
async function loadUsers() {
|
|
26
41
|
try {
|
|
27
42
|
const res = await fetch("/api/auth/users");
|
|
28
43
|
if (!res.ok) {
|
|
29
|
-
setError("
|
|
44
|
+
setError("Couldn't load users");
|
|
30
45
|
setUsers([]);
|
|
31
46
|
return;
|
|
32
47
|
}
|
|
@@ -163,27 +178,10 @@ export function SiteSettingsUsers({ currentUser }: Props) {
|
|
|
163
178
|
<div className="flex items-center justify-end border-b border-base-200 py-2">
|
|
164
179
|
{currentUser?.email === user.email ? (
|
|
165
180
|
<span className="text-xs text-base-contrast-light">—</span>
|
|
166
|
-
) : confirmingRevoke === user.id ? (
|
|
167
|
-
<span className="flex items-center gap-1">
|
|
168
|
-
<Button
|
|
169
|
-
type="button"
|
|
170
|
-
variant="ghost"
|
|
171
|
-
tone="destructive"
|
|
172
|
-
onClick={() => confirmRevoke(user.id)}
|
|
173
|
-
>
|
|
174
|
-
Confirm
|
|
175
|
-
</Button>
|
|
176
|
-
<Button
|
|
177
|
-
type="button"
|
|
178
|
-
variant="ghost"
|
|
179
|
-
onClick={() => setConfirmingRevoke(null)}
|
|
180
|
-
>
|
|
181
|
-
Cancel
|
|
182
|
-
</Button>
|
|
183
|
-
</span>
|
|
184
|
-
) : (
|
|
181
|
+
) : confirmingRevoke === user.id ? null : (
|
|
185
182
|
<Button
|
|
186
183
|
type="button"
|
|
184
|
+
ref={getRemoveButtonRef(user.id)}
|
|
187
185
|
variant="ghost"
|
|
188
186
|
tone="destructive"
|
|
189
187
|
onClick={() => handleRevoke(user.id)}
|
|
@@ -192,20 +190,32 @@ export function SiteSettingsUsers({ currentUser }: Props) {
|
|
|
192
190
|
</Button>
|
|
193
191
|
)}
|
|
194
192
|
</div>
|
|
193
|
+
{confirmingRevoke === user.id && (
|
|
194
|
+
<div className="col-span-3 pb-2">
|
|
195
|
+
<ConfirmInline
|
|
196
|
+
message={`Remove ${user.email}?`}
|
|
197
|
+
confirmLabel="Remove"
|
|
198
|
+
tone="destructive"
|
|
199
|
+
onConfirm={() => confirmRevoke(user.id)}
|
|
200
|
+
onCancel={() => setConfirmingRevoke(null)}
|
|
201
|
+
returnFocusTo={getRemoveButtonRef(user.id)}
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
)}
|
|
195
205
|
</Fragment>
|
|
196
206
|
))}
|
|
197
207
|
</div>
|
|
198
208
|
|
|
199
209
|
<form onSubmit={handleInvite} className="grid grid-cols-[1fr_7rem_5rem] text-sm">
|
|
200
210
|
<div className="pr-2">
|
|
201
|
-
<
|
|
211
|
+
<Input
|
|
212
|
+
label="Email address"
|
|
213
|
+
hideLabel
|
|
202
214
|
type="email"
|
|
203
215
|
placeholder="Email address"
|
|
204
216
|
value={inviteEmail}
|
|
205
|
-
onChange={
|
|
217
|
+
onChange={setInviteEmail}
|
|
206
218
|
required
|
|
207
|
-
aria-label="Email address"
|
|
208
|
-
className="w-full rounded border border-base-200 bg-base px-3 py-2 text-sm text-base-contrast focus:border-base-contrast focus:outline-none focus:ring-1 focus:ring-base-contrast"
|
|
209
219
|
/>
|
|
210
220
|
</div>
|
|
211
221
|
<div className="pr-2">
|
|
@@ -234,7 +244,7 @@ export function SiteSettingsUsers({ currentUser }: Props) {
|
|
|
234
244
|
Role changes take effect the next time the user signs in, or within 24 hours.
|
|
235
245
|
</p>
|
|
236
246
|
|
|
237
|
-
{error && <p className="text-sm text-
|
|
247
|
+
{error && <p className="text-sm text-danger">{error}</p>}
|
|
238
248
|
</div>
|
|
239
249
|
);
|
|
240
250
|
}
|
|
@@ -153,7 +153,7 @@ export function SiteSettingsViewerAccess({ audienceManagement, passwordToggle, o
|
|
|
153
153
|
// Deliberately a hard stop rather than an empty list: rendering the normal UI
|
|
154
154
|
// here would show "no audiences" for a site that has them.
|
|
155
155
|
if (loadError) {
|
|
156
|
-
return <p className="text-sm text-
|
|
156
|
+
return <p className="text-sm text-danger">{loadError}</p>;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
return (
|
|
@@ -182,7 +182,7 @@ export function SiteSettingsViewerAccess({ audienceManagement, passwordToggle, o
|
|
|
182
182
|
? "Viewers must sign in with a username and password to see any content."
|
|
183
183
|
: "Viewers must select an audience and enter a password to see any content."}
|
|
184
184
|
</p>
|
|
185
|
-
{toggleError && <p className="text-xs text-
|
|
185
|
+
{toggleError && <p className="text-xs text-danger">{toggleError}</p>}
|
|
186
186
|
</div>
|
|
187
187
|
)}
|
|
188
188
|
|
|
@@ -3,7 +3,8 @@ import { Input } from "../shared/Input";
|
|
|
3
3
|
import { PasswordInput } from "../shared/PasswordInput";
|
|
4
4
|
import { Button } from "../shared/Button";
|
|
5
5
|
import { Select } from "../shared/Select";
|
|
6
|
-
import { safeRedirect } from "../../lib/
|
|
6
|
+
import { safeRedirect } from "../../lib/safe-redirect";
|
|
7
|
+
import { COPY } from "../shared/copy";
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
/** Audience mode only. Empty (and unused) in credential mode — the page must
|
|
@@ -55,7 +56,7 @@ export function ViewerLoginForm({ audiences, mode = "audience", next }: Props) {
|
|
|
55
56
|
|
|
56
57
|
if (!response.ok) {
|
|
57
58
|
const data = await response.json().catch(() => ({}));
|
|
58
|
-
setError(data.error ||
|
|
59
|
+
setError(data.error || COPY.auth.signInFallback);
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -99,7 +100,7 @@ export function ViewerLoginForm({ audiences, mode = "audience", next }: Props) {
|
|
|
99
100
|
)}
|
|
100
101
|
|
|
101
102
|
{error && (
|
|
102
|
-
<p className="text-sm text-
|
|
103
|
+
<p className="text-sm text-danger">{error}</p>
|
|
103
104
|
)}
|
|
104
105
|
|
|
105
106
|
<Button
|
|
@@ -108,7 +109,7 @@ export function ViewerLoginForm({ audiences, mode = "audience", next }: Props) {
|
|
|
108
109
|
size="md"
|
|
109
110
|
disabled={loading || (credentialMode ? username.trim().length === 0 : !audience)}
|
|
110
111
|
isLoading={loading}
|
|
111
|
-
loadingLabel="Verifying
|
|
112
|
+
loadingLabel="Verifying…"
|
|
112
113
|
className="w-full"
|
|
113
114
|
>
|
|
114
115
|
Enter
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Audience } from "../../schemas/auth";
|
|
2
|
+
import type { SiteIndex } from "../../schemas/site-config";
|
|
3
|
+
import type { LoadedSection } from "../../lib/loader";
|
|
4
|
+
import type { MediaManifest } from "../../media/types";
|
|
5
|
+
import { pageById } from "../../lib/pages";
|
|
6
|
+
import { pageReferenceCopies } from "../../lib/nav";
|
|
7
|
+
import type { ReferenceSources } from "../shared/ReferenceSourcesContext";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* What References resolve against in the Published preview: main's content
|
|
11
|
+
* (`viewIndex` once the history/view fetch lands, else the `mainIndex` the
|
|
12
|
+
* load reported), live sections only — the same content and page the viewer
|
|
13
|
+
* would expand. Null when there is no published view to resolve against, and
|
|
14
|
+
* the canvas falls back to the working copy.
|
|
15
|
+
*/
|
|
16
|
+
export function publishedReferenceSources(opts: {
|
|
17
|
+
viewSections: LoadedSection[] | null;
|
|
18
|
+
viewIndex: SiteIndex | null;
|
|
19
|
+
mainIndex: SiteIndex | null;
|
|
20
|
+
activePageId: string | null;
|
|
21
|
+
audiences: Audience[];
|
|
22
|
+
mediaManifest: MediaManifest;
|
|
23
|
+
jumpToSection: (sectionId: string) => void;
|
|
24
|
+
}): ReferenceSources | null {
|
|
25
|
+
const { viewSections, activePageId, audiences, mediaManifest, jumpToSection } = opts;
|
|
26
|
+
const index = opts.viewIndex ?? opts.mainIndex;
|
|
27
|
+
if (!viewSections || !index || !activePageId) return null;
|
|
28
|
+
const byId = new Map(viewSections.map((s) => [s.section.id, s]));
|
|
29
|
+
const pageSections = (pageById(index, activePageId)?.order ?? [])
|
|
30
|
+
.flatMap((id) => byId.get(id) ?? [])
|
|
31
|
+
.filter((s) => s.meta.status === "live");
|
|
32
|
+
return {
|
|
33
|
+
index, sections: viewSections, audiences, mediaManifest, jumpToSection,
|
|
34
|
+
copies: pageReferenceCopies(pageSections, { index, allSections: viewSections }),
|
|
35
|
+
};
|
|
36
|
+
}
|
package/src/deck/index.ts
CHANGED
|
@@ -25,6 +25,6 @@ export {
|
|
|
25
25
|
type DeckMediaAsset,
|
|
26
26
|
type DeckMediaResolver,
|
|
27
27
|
} from "./media";
|
|
28
|
-
export { DeckTextEditProvider, EditableText,
|
|
28
|
+
export { DeckTextEditProvider, EditableText, type DeckTextEditor } from "./editing";
|
|
29
29
|
export { useStageScale } from "./useStageScale";
|
|
30
|
-
export { deckAlign, surfaceInk, DECK_ELEVATION, SURFACE_BACKGROUND, type
|
|
30
|
+
export { deckAlign, surfaceInk, DECK_ELEVATION, SURFACE_BACKGROUND, type DeckSurface } from "./tokens";
|
package/src/document/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * from "./engine/settings";
|
|
|
6
6
|
export { splitProseBlocks } from "./engine/blocks";
|
|
7
7
|
export { harvest } from "./engine/harvest";
|
|
8
8
|
export * from "./engine/paginate";
|
|
9
|
-
export { layoutMasonryPage, type MasonryOpts, type
|
|
9
|
+
export { layoutMasonryPage, type MasonryOpts, type Sized } from "./engine/masonry";
|
|
10
10
|
|
|
11
11
|
export { DocPage, type DocMeta } from "./components/DocPage";
|
|
12
12
|
export { DocSectionPage, type DocHost } from "./components/DocSectionPage";
|
|
@@ -14,5 +14,5 @@ export { DocCoverPage } from "./components/DocCoverPage";
|
|
|
14
14
|
export { useDocPages } from "./components/useDocPages";
|
|
15
15
|
|
|
16
16
|
// Task 3 — shared document shell (presentation + editing).
|
|
17
|
-
export { DocViewer
|
|
17
|
+
export { DocViewer } from "./components/DocViewer";
|
|
18
18
|
export { DocRail, entryId, type RailEntry } from "./components/DocRail";
|
package/src/hooks/useBlockDnd.ts
CHANGED
|
@@ -15,6 +15,17 @@ export interface UseBlockDndArgs {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
+
* One of three sibling drag-and-drop position hooks, split by location type
|
|
19
|
+
* rather than unified behind a generic `useSortable({ axis })`: this one
|
|
20
|
+
* (block/container id + index — the section canvas, root and nested),
|
|
21
|
+
* `useSortableRow` (flat index — section-ordering lists), and
|
|
22
|
+
* `useSortableNavRow` (NavLocation — the Pages modal's group-aware nav tree).
|
|
23
|
+
* A fourth location type earns its own hook on the same shape (rowRef/
|
|
24
|
+
* handleRef, lazy atlaskit import, closest-edge state, a ref for the latest
|
|
25
|
+
* callback) rather than a parameter bag bolted onto an existing one — see
|
|
26
|
+
* docs/superpowers/specs/2026-09-04-editor-ui-primitives-consolidation.md
|
|
27
|
+
* § D6 for why a shared `useSortable` was deferred.
|
|
28
|
+
*
|
|
18
29
|
* Wires a block as a unified drag source + drop target. Manages only this block's
|
|
19
30
|
* local hover edge + dragging flag — the actual move dispatch is centralized in the
|
|
20
31
|
* EditorContent monitor (a later task), so nested targets never double-fire. The edge
|
|
@@ -12,7 +12,7 @@ interface BuildStatusResponse {
|
|
|
12
12
|
interface BuildStatusResult {
|
|
13
13
|
state: BuildState;
|
|
14
14
|
elapsedSeconds: number;
|
|
15
|
-
startTracking: () => void;
|
|
15
|
+
startTracking: (commitSha?: string) => void;
|
|
16
16
|
dismiss: () => void;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -40,6 +40,15 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
40
40
|
const fadeRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
41
41
|
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
42
42
|
const giveUpRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
43
|
+
const expectedCommit = useRef<string | null>(null);
|
|
44
|
+
// Commits already on the status row when tracking began (an earlier build,
|
|
45
|
+
// possibly still running) versus commits first seen building afterwards (a
|
|
46
|
+
// later publish by a peer or the MCP connector, which supersedes ours).
|
|
47
|
+
const firstTrackedPoll = useRef(false);
|
|
48
|
+
const preexistingCommits = useRef(new Set<string>());
|
|
49
|
+
const laterBuilds = useRef(new Set<string>());
|
|
50
|
+
const trackingGeneration = useRef(0);
|
|
51
|
+
const pollInFlight = useRef(false);
|
|
43
52
|
const isPolling = useRef(false);
|
|
44
53
|
const mountedRef = useRef(true);
|
|
45
54
|
|
|
@@ -80,7 +89,7 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
80
89
|
|
|
81
90
|
const fetchStatus = useCallback(async (): Promise<BuildStatusResponse | null> => {
|
|
82
91
|
try {
|
|
83
|
-
const res = await fetch("/api/build-status");
|
|
92
|
+
const res = await fetch("/api/build-status", { signal: AbortSignal.timeout(10_000) });
|
|
84
93
|
if (!res.ok) return null;
|
|
85
94
|
const data = await res.json();
|
|
86
95
|
const validStates = ["building", "ready", "error"];
|
|
@@ -107,6 +116,29 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
107
116
|
return;
|
|
108
117
|
}
|
|
109
118
|
|
|
119
|
+
const expected = expectedCommit.current;
|
|
120
|
+
if (expected && data.commitSha && data.commitSha !== expected) {
|
|
121
|
+
// Netlify builds serially, so a different commit is either an older
|
|
122
|
+
// build finishing late or a newer publish. No clock can tell them apart
|
|
123
|
+
// (the row is server time, this is browser time), so go by order seen:
|
|
124
|
+
// accept a different commit's result only if it began building after
|
|
125
|
+
// tracking did. A provider that reports no commit is accepted as-is.
|
|
126
|
+
const commit = data.commitSha;
|
|
127
|
+
const first = firstTrackedPoll.current;
|
|
128
|
+
firstTrackedPoll.current = false;
|
|
129
|
+
if (first || preexistingCommits.current.has(commit)) {
|
|
130
|
+
preexistingCommits.current.add(commit);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (data.state === "building") {
|
|
134
|
+
laterBuilds.current.add(commit);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!laterBuilds.current.has(commit)) return;
|
|
138
|
+
} else if (expected) {
|
|
139
|
+
firstTrackedPoll.current = false;
|
|
140
|
+
}
|
|
141
|
+
|
|
110
142
|
setState(data.state);
|
|
111
143
|
|
|
112
144
|
if (data.state === "ready" || data.state === "error") {
|
|
@@ -133,8 +165,13 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
133
165
|
isPolling.current = true;
|
|
134
166
|
|
|
135
167
|
pollRef.current = setInterval(async () => {
|
|
136
|
-
|
|
137
|
-
|
|
168
|
+
if (pollInFlight.current) return;
|
|
169
|
+
pollInFlight.current = true;
|
|
170
|
+
const generation = trackingGeneration.current;
|
|
171
|
+
try {
|
|
172
|
+
const data = await fetchStatus();
|
|
173
|
+
if (generation === trackingGeneration.current && isPolling.current) handleStatusUpdate(data, false);
|
|
174
|
+
} finally { pollInFlight.current = false; }
|
|
138
175
|
}, POLL_INTERVAL);
|
|
139
176
|
}, [fetchStatus, handleStatusUpdate]);
|
|
140
177
|
|
|
@@ -148,9 +185,10 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
148
185
|
// real remount in production.
|
|
149
186
|
mountedRef.current = true;
|
|
150
187
|
|
|
188
|
+
const initialGeneration = trackingGeneration.current;
|
|
151
189
|
async function check() {
|
|
152
190
|
const data = await fetchStatus();
|
|
153
|
-
if (cancelled) return;
|
|
191
|
+
if (cancelled || initialGeneration !== trackingGeneration.current) return;
|
|
154
192
|
|
|
155
193
|
if (data && data.state === "building") {
|
|
156
194
|
const ageMs = Date.now() - Date.parse(data.updatedAt);
|
|
@@ -183,7 +221,13 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
183
221
|
};
|
|
184
222
|
}, [fetchStatus, handleStatusUpdate, startPolling, startTimer, stopPolling, stopTimer, armGiveUp, clearGiveUp]);
|
|
185
223
|
|
|
186
|
-
const startTracking = useCallback(() => {
|
|
224
|
+
const startTracking = useCallback((commitSha?: string) => {
|
|
225
|
+
trackingGeneration.current++;
|
|
226
|
+
expectedCommit.current = commitSha ?? null;
|
|
227
|
+
firstTrackedPoll.current = true;
|
|
228
|
+
preexistingCommits.current = new Set();
|
|
229
|
+
laterBuilds.current = new Set();
|
|
230
|
+
if (fadeRef.current) { clearTimeout(fadeRef.current); fadeRef.current = null; }
|
|
187
231
|
if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
|
|
188
232
|
setState("building");
|
|
189
233
|
startTimer();
|
|
@@ -192,6 +236,9 @@ export function useBuildStatus(): BuildStatusResult {
|
|
|
192
236
|
}, [startPolling, startTimer, armGiveUp]);
|
|
193
237
|
|
|
194
238
|
const dismiss = useCallback(() => {
|
|
239
|
+
trackingGeneration.current++;
|
|
240
|
+
expectedCommit.current = null;
|
|
241
|
+
if (fadeRef.current) { clearTimeout(fadeRef.current); fadeRef.current = null; }
|
|
195
242
|
if (clearRef.current) { clearTimeout(clearRef.current); clearRef.current = null; }
|
|
196
243
|
setState("idle");
|
|
197
244
|
stopPolling();
|
|
@@ -32,7 +32,7 @@ interface UseDocumentUploadsInput {
|
|
|
32
32
|
* invisible here, so without this the dedup below cannot tell a live
|
|
33
33
|
* document from a doomed one. No-op for an id that isn't doomed. */
|
|
34
34
|
undeleteDocument?: (id: string) => void;
|
|
35
|
-
/** Same channel the media pipeline uses — surfaces in
|
|
35
|
+
/** Same channel the media pipeline uses — surfaces in InlineAlert. */
|
|
36
36
|
onUploadError?: (message: string) => void;
|
|
37
37
|
}
|
|
38
38
|
|