@drawnagency/primitives 0.1.113 → 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/{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-Z7W3DQTR.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-NHN2LSIU.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-KR2MHTNJ.js → chunk-N3G7DOU3.js} +609 -61
- package/dist/chunk-OAGJBCSH.js +67 -0
- package/dist/{chunk-6BZ2KNTP.js → chunk-PLANHXS7.js} +191 -61
- package/dist/{chunk-VWWY5TL5.js → chunk-PNSCDBU7.js} +38 -56
- package/dist/{chunk-AHALSCQH.js → chunk-PTY2RG2K.js} +1 -1
- package/dist/{chunk-BDFTMGCL.js → chunk-PZPGJZRG.js} +9 -8
- package/dist/{chunk-FRE2CCLV.js → chunk-QHMKIODQ.js} +17 -4
- 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-DS4GCYV2.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.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/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 +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 +1 -1
- package/dist/types/database.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/auth/cookies.ts +111 -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 +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 +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 +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 +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/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 +6 -1
- package/src/schemas/tags.ts +33 -0
- package/src/storage/types.ts +1 -1
- 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
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { ListChecks } from "lucide-react";
|
|
4
|
+
import { defineSection } from "../../../lib/registry";
|
|
5
|
+
import { LinkValueSchema, DEFAULT_LINK } from "../../../schemas/link";
|
|
6
|
+
import { SummaryAnchorsContext } from "../../shared/SummaryAnchorsContext";
|
|
7
|
+
import { SectionSummaryBlock, type SectionSummaryOptions } from "./SectionSummaryBlock";
|
|
8
|
+
import { SectionSummarySettings } from "./SectionSummarySettings";
|
|
9
|
+
|
|
10
|
+
// The end-of-section TL;DR plate, promoted from Siete's site-local section (#59).
|
|
11
|
+
// The type id and content shape are unchanged, so existing Siete content loads
|
|
12
|
+
// as-is; nav/navLabel are the only additions.
|
|
13
|
+
|
|
14
|
+
const itemSchema = z.object({
|
|
15
|
+
headline: z.string().default("").describe("The principle, short and bold, e.g. \"Saturation > Subtlety\"."),
|
|
16
|
+
explainer: z
|
|
17
|
+
.string()
|
|
18
|
+
.default("")
|
|
19
|
+
.describe("Optional one-sentence explainer rendered softly beneath the headline."),
|
|
20
|
+
link: LinkValueSchema.default(DEFAULT_LINK).describe(
|
|
21
|
+
"Optional jump-link trailing the principle, back to the sub-section it distills. Set with the link picker: an internal page/section (label auto-derived from the page or section name) or an external URL. An empty link renders nothing, but its space is reserved so the layout stays stable.",
|
|
22
|
+
),
|
|
23
|
+
linkLabel: z
|
|
24
|
+
.string()
|
|
25
|
+
.default("")
|
|
26
|
+
.describe(
|
|
27
|
+
"The jump-link label. Auto-derived from the linked page or section name for internal links (kept in sync as you edit); for external links it falls back to the URL.",
|
|
28
|
+
),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const schema = z.object({
|
|
32
|
+
type: z.literal("section_summary"),
|
|
33
|
+
content: z.object({
|
|
34
|
+
kicker: z
|
|
35
|
+
.string()
|
|
36
|
+
.default("")
|
|
37
|
+
.describe('Uppercase label in the plate\'s top-left, e.g. "Brand Color — Summary".'),
|
|
38
|
+
accent: z
|
|
39
|
+
.string()
|
|
40
|
+
.default("")
|
|
41
|
+
.describe('Script flourish in the plate\'s top-right, e.g. "tl;dr".'),
|
|
42
|
+
items: z
|
|
43
|
+
.array(itemSchema)
|
|
44
|
+
.default([])
|
|
45
|
+
.describe("The summary principles, in display order (numbered automatically)."),
|
|
46
|
+
footNote: z
|
|
47
|
+
.string()
|
|
48
|
+
.default("")
|
|
49
|
+
.describe(
|
|
50
|
+
'Contextual note in the footer\'s bottom-left, e.g. "Brand Color · 06 principles". Empty = auto "<count> principles".',
|
|
51
|
+
),
|
|
52
|
+
}),
|
|
53
|
+
options: z
|
|
54
|
+
.object({
|
|
55
|
+
showAccent: z.boolean().describe("Show the script accent (default true).").optional(),
|
|
56
|
+
showFooter: z.boolean().describe("Show the footer row (default true).").optional(),
|
|
57
|
+
showCopy: z
|
|
58
|
+
.boolean()
|
|
59
|
+
.describe("Show the copy-summary action in the footer (default true).")
|
|
60
|
+
.optional(),
|
|
61
|
+
numbered: z.boolean().describe("Show the accent-colored item numerals (default true).").optional(),
|
|
62
|
+
nav: z
|
|
63
|
+
.enum(["off", "heading", "subheading"])
|
|
64
|
+
.describe(
|
|
65
|
+
'Put this plate in the page nav: "heading" = top level (like a Link Heading), "subheading" = nested under the preceding Link Heading (dropped from the nav if there is none, like a Sub Heading). Absent or "off" = not in the nav.',
|
|
66
|
+
)
|
|
67
|
+
.optional(),
|
|
68
|
+
navLabel: z
|
|
69
|
+
.string()
|
|
70
|
+
.describe(
|
|
71
|
+
"The plate's nav entry text; REQUIRED while nav is on (no label = no entry). Its anchor is derived from it, suffixed -2, -3… if another anchor on the page already has it.",
|
|
72
|
+
)
|
|
73
|
+
.optional(),
|
|
74
|
+
})
|
|
75
|
+
.default({}),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export default defineSection({
|
|
79
|
+
type: "section_summary",
|
|
80
|
+
category: "brand-guide",
|
|
81
|
+
label: "TL;DR / Summary",
|
|
82
|
+
icon: <ListChecks size={18} />,
|
|
83
|
+
schema,
|
|
84
|
+
authoringNote:
|
|
85
|
+
"An end-of-section TL;DR plate: numbered principles (bold headline + optional one-sentence explainer) with " +
|
|
86
|
+
"an optional jump-link trailing each explainer back to the sub-section it distills. Place it as the LAST " +
|
|
87
|
+
"block of a major section. Each principle's jump-link is set with the link picker — an internal page/section " +
|
|
88
|
+
"(its label auto-derived from the page or section name) or an external URL; an empty link renders nothing. " +
|
|
89
|
+
'The footer shows footNote (or an auto "<count> principles" note) plus a copy action that puts the whole ' +
|
|
90
|
+
'summary on the clipboard as plain text (kicker + "• headline — explainer" lines). Fully functional on the ' +
|
|
91
|
+
"logged-out viewer — no hydration. Optionally appears in the page nav (options.nav heading/subheading with a " +
|
|
92
|
+
"required options.navLabel). Headlines/explainers are composed from truths in the section above; never " +
|
|
93
|
+
"introduce facts here that the section itself does not state.",
|
|
94
|
+
component: function SectionSummarySection({ content, options, onChange, openModal }) {
|
|
95
|
+
const c = content.content;
|
|
96
|
+
const set = (patch: Partial<typeof c>) => onChange?.({ ...content, content: { ...c, ...patch } });
|
|
97
|
+
const id = (content as { id?: string }).id;
|
|
98
|
+
const opts = (options ?? {}) as SectionSummaryOptions;
|
|
99
|
+
const editorAnchor = useContext(SummaryAnchorsContext)[id ?? ""];
|
|
100
|
+
const navAnchor = editorAnchor?.anchor ?? (content as { navAnchor?: string }).navAnchor;
|
|
101
|
+
const navOn = opts.nav === "heading" || opts.nav === "subheading";
|
|
102
|
+
const navHint = !navOn
|
|
103
|
+
? undefined
|
|
104
|
+
: !opts.navLabel?.trim()
|
|
105
|
+
? "Not in the nav: add a nav label in Settings."
|
|
106
|
+
: editorAnchor && !editorAnchor.inNav
|
|
107
|
+
? "Not in the nav: a Subheading needs a Link Heading above it."
|
|
108
|
+
: undefined;
|
|
109
|
+
return (
|
|
110
|
+
<SectionSummaryBlock
|
|
111
|
+
sectionId={id}
|
|
112
|
+
kicker={c.kicker}
|
|
113
|
+
accent={c.accent}
|
|
114
|
+
footNote={c.footNote}
|
|
115
|
+
items={c.items}
|
|
116
|
+
options={opts}
|
|
117
|
+
isEditMode={!!onChange}
|
|
118
|
+
openModal={openModal}
|
|
119
|
+
onKickerChange={onChange ? (kicker) => set({ kicker }) : undefined}
|
|
120
|
+
onAccentChange={onChange ? (accent) => set({ accent }) : undefined}
|
|
121
|
+
onFootNoteChange={onChange ? (footNote) => set({ footNote }) : undefined}
|
|
122
|
+
onItemsChange={onChange ? (items) => set({ items }) : undefined}
|
|
123
|
+
navAnchor={navAnchor}
|
|
124
|
+
navHint={navHint}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
},
|
|
128
|
+
// Inserts ready-to-use with one starter row to overwrite — no empty state to
|
|
129
|
+
// climb out of.
|
|
130
|
+
defaults: () => ({
|
|
131
|
+
type: "section_summary" as const,
|
|
132
|
+
content: {
|
|
133
|
+
kicker: "Summary",
|
|
134
|
+
accent: "tl;dr",
|
|
135
|
+
items: [
|
|
136
|
+
{
|
|
137
|
+
headline: "First principle",
|
|
138
|
+
explainer: "One sentence on why it matters.",
|
|
139
|
+
link: DEFAULT_LINK,
|
|
140
|
+
linkLabel: "",
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
footNote: "",
|
|
144
|
+
},
|
|
145
|
+
options: {},
|
|
146
|
+
}),
|
|
147
|
+
getLabel: (content) => content.content.kicker || "TL;DR / Summary",
|
|
148
|
+
settingsForm: SectionSummarySettings,
|
|
149
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Heading3 } from "lucide-react";
|
|
2
|
-
import { defineHeadingSection } from "../../primitives/
|
|
2
|
+
import { defineHeadingSection } from "../../primitives/define-heading-section";
|
|
3
3
|
|
|
4
4
|
export default defineHeadingSection({
|
|
5
5
|
type: "sub_sub_heading",
|
|
@@ -2,13 +2,14 @@ import colors from "./Colors";
|
|
|
2
2
|
import iconList from "./IconList";
|
|
3
3
|
import doDontMedia from "./DoDontMedia";
|
|
4
4
|
import documentSection from "./Document";
|
|
5
|
+
import sectionSummary from "./SectionSummary";
|
|
5
6
|
|
|
6
7
|
/** Opinionated brand-guide sections. Self-contained subtree: a build that does
|
|
7
|
-
* not import this module drops these sections (and their cmyk/pantone schemas
|
|
8
|
-
*
|
|
8
|
+
* not import this module drops these sections (and their cmyk/pantone schemas,
|
|
9
|
+
* do/dont compositions and the TL;DR plate) entirely. Exposed at
|
|
9
10
|
* `@drawnagency/primitives/components/sections/brand-guide`. */
|
|
10
11
|
// Un-annotated for the same generic-variance reason as coreSectionDefs.
|
|
11
|
-
export const brandGuideSectionDefs = [colors, iconList, doDontMedia, documentSection];
|
|
12
|
+
export const brandGuideSectionDefs = [colors, iconList, doDontMedia, documentSection, sectionSummary];
|
|
12
13
|
|
|
13
14
|
export { ColorSpaceSchema, ColorItemSchema } from "./Colors/schema";
|
|
14
15
|
export type { ColorSpace, ColorItem } from "./Colors/schema";
|
|
@@ -7,6 +7,7 @@ import video from "./Video";
|
|
|
7
7
|
import button from "./Button";
|
|
8
8
|
import container from "./Container";
|
|
9
9
|
import spacer from "./Spacer";
|
|
10
|
+
import reference from "./Reference";
|
|
10
11
|
|
|
11
12
|
/** Generic, brand-agnostic built-in sections. A non-brand site can register
|
|
12
13
|
* exactly these (plus its own custom sections) and tree-shake the brand-guide
|
|
@@ -25,4 +26,5 @@ export const coreSectionDefs = [
|
|
|
25
26
|
button,
|
|
26
27
|
container,
|
|
27
28
|
spacer,
|
|
29
|
+
reference,
|
|
28
30
|
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import type { BrandSwatch } from "../../lib/brand-swatches";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hex values from every Colors section site-wide, for color pickers in
|
|
6
|
+
* settings forms. A form only receives its own section's values, so EditorShell
|
|
7
|
+
* provides these from all loaded sections (collectBrandSwatches).
|
|
8
|
+
*/
|
|
9
|
+
export const BrandSwatchesContext = createContext<BrandSwatch[]>([]);
|
|
10
|
+
|
|
11
|
+
export function useBrandSwatches(): BrandSwatch[] {
|
|
12
|
+
return useContext(BrandSwatchesContext);
|
|
13
|
+
}
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode, Ref } from "react";
|
|
2
2
|
import { cn } from "../../lib/cn";
|
|
3
3
|
|
|
4
4
|
export type ButtonVariant = "primary" | "brand" | "secondary" | "destructive" | "ghost";
|
|
5
5
|
export type ButtonSize = "sm" | "md";
|
|
6
6
|
export type ButtonTone = "neutral" | "destructive";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface ButtonCommon {
|
|
9
9
|
variant?: ButtonVariant;
|
|
10
10
|
size?: ButtonSize;
|
|
11
11
|
tone?: ButtonTone;
|
|
12
12
|
fullWidth?: boolean;
|
|
13
13
|
isLoading?: boolean;
|
|
14
14
|
loadingLabel?: string;
|
|
15
|
+
className?: string;
|
|
15
16
|
children?: ReactNode;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
// Same discriminated-union shape as Fab: `href` renders an <a> with identical
|
|
20
|
+
// classes (ref excluded — an <a> ref is a different element type, and no
|
|
21
|
+
// caller needs one today); its absence renders a <button> and accepts a ref.
|
|
22
|
+
export type ButtonProps =
|
|
23
|
+
| ({ href: string } & ButtonCommon & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "children" | "className">)
|
|
24
|
+
| ({ href?: undefined; ref?: Ref<HTMLButtonElement> } & ButtonCommon &
|
|
25
|
+
Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "className">);
|
|
26
|
+
|
|
18
27
|
const boxSize: Record<ButtonSize, string> = {
|
|
19
28
|
sm: "rounded px-3 py-1.5 text-xs font-medium",
|
|
20
29
|
md: "rounded px-4 py-2 text-sm font-medium",
|
|
@@ -30,48 +39,52 @@ const variantClasses: Record<Exclude<ButtonVariant, "ghost">, string> = {
|
|
|
30
39
|
brand: "bg-primary text-primary-contrast hover:opacity-90",
|
|
31
40
|
secondary: "border border-base-200 text-base-contrast hover:bg-base-accent",
|
|
32
41
|
destructive:
|
|
33
|
-
"border border-
|
|
42
|
+
"border border-danger text-danger hover:bg-danger hover:text-white",
|
|
34
43
|
};
|
|
35
44
|
|
|
36
45
|
const ghostToneClasses: Record<ButtonTone, string> = {
|
|
37
46
|
neutral: "text-base-contrast-light hover:text-base-contrast",
|
|
38
|
-
destructive: "text-
|
|
47
|
+
destructive: "text-danger hover:text-danger-hover",
|
|
39
48
|
};
|
|
40
49
|
|
|
41
|
-
export
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
...rest
|
|
53
|
-
},
|
|
54
|
-
ref,
|
|
55
|
-
) {
|
|
50
|
+
export function Button({
|
|
51
|
+
variant = "primary",
|
|
52
|
+
size = "sm",
|
|
53
|
+
tone = "neutral",
|
|
54
|
+
fullWidth = false,
|
|
55
|
+
isLoading = false,
|
|
56
|
+
loadingLabel,
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
...rest
|
|
60
|
+
}: ButtonProps) {
|
|
56
61
|
const isGhost = variant === "ghost";
|
|
57
|
-
const
|
|
62
|
+
const disabled = rest.href === undefined ? rest.disabled || isLoading : false;
|
|
58
63
|
const label = isLoading && loadingLabel ? loadingLabel : children;
|
|
59
64
|
|
|
65
|
+
const classes = cn(
|
|
66
|
+
"inline-flex items-center justify-center transition-colors",
|
|
67
|
+
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary",
|
|
68
|
+
isGhost ? ghostSize[size] : boxSize[size],
|
|
69
|
+
isGhost ? ghostToneClasses[tone] : variantClasses[variant],
|
|
70
|
+
fullWidth && "w-full",
|
|
71
|
+
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
72
|
+
className,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (rest.href !== undefined) {
|
|
76
|
+
return (
|
|
77
|
+
<a className={classes} {...(rest as AnchorHTMLAttributes<HTMLAnchorElement>)}>
|
|
78
|
+
{label}
|
|
79
|
+
</a>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { ref, disabled: _disabled, ...buttonRest } = rest as { ref?: Ref<HTMLButtonElement> } &
|
|
84
|
+
ButtonHTMLAttributes<HTMLButtonElement>;
|
|
60
85
|
return (
|
|
61
|
-
<button
|
|
62
|
-
ref={ref}
|
|
63
|
-
disabled={resolvedDisabled}
|
|
64
|
-
className={cn(
|
|
65
|
-
"inline-flex items-center justify-center transition-colors",
|
|
66
|
-
isGhost ? ghostSize[size] : boxSize[size],
|
|
67
|
-
isGhost ? ghostToneClasses[tone] : variantClasses[variant],
|
|
68
|
-
fullWidth && "w-full",
|
|
69
|
-
resolvedDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
70
|
-
className,
|
|
71
|
-
)}
|
|
72
|
-
{...rest}
|
|
73
|
-
>
|
|
86
|
+
<button ref={ref} disabled={disabled} className={classes} {...buttonRest}>
|
|
74
87
|
{label}
|
|
75
88
|
</button>
|
|
76
89
|
);
|
|
77
|
-
}
|
|
90
|
+
}
|
|
@@ -48,18 +48,10 @@ export function Checkbox({
|
|
|
48
48
|
onChange={(e) => onChange(e.target.checked)}
|
|
49
49
|
className="sr-only"
|
|
50
50
|
/>
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
className={cn(
|
|
54
|
-
|
|
55
|
-
checked
|
|
56
|
-
? "border-primary bg-primary text-primary-contrast"
|
|
57
|
-
: "border-base-300 bg-base hover:border-primary",
|
|
58
|
-
disabled && "pointer-events-none",
|
|
59
|
-
)}
|
|
60
|
-
>
|
|
61
|
-
{checked && <Check size={14} strokeWidth={3} />}
|
|
62
|
-
</span>
|
|
51
|
+
<CheckboxBox
|
|
52
|
+
checked={checked}
|
|
53
|
+
className={cn(!checked && "hover:border-primary", disabled && "pointer-events-none")}
|
|
54
|
+
/>
|
|
63
55
|
</span>
|
|
64
56
|
{startAdornment}
|
|
65
57
|
<div className="text-sm">
|
|
@@ -71,3 +63,20 @@ export function Checkbox({
|
|
|
71
63
|
</label>
|
|
72
64
|
);
|
|
73
65
|
}
|
|
66
|
+
|
|
67
|
+
/** The visual square alone, for rows whose own element carries the checkbox
|
|
68
|
+
* role (a menu item, a picker row) and so can't nest a labelled input. */
|
|
69
|
+
export function CheckboxBox({ checked, className }: { checked: boolean; className?: string }) {
|
|
70
|
+
return (
|
|
71
|
+
<span
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
className={cn(
|
|
74
|
+
"flex h-5 w-5 shrink-0 items-center justify-center rounded border transition-colors",
|
|
75
|
+
checked ? "border-primary bg-primary text-primary-contrast" : "border-base-300 bg-base",
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
>
|
|
79
|
+
{checked && <Check size={14} strokeWidth={3} />}
|
|
80
|
+
</span>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { Button } from "./Button";
|
|
3
|
+
import { EditorModal } from "../shell/EditorModal";
|
|
4
|
+
|
|
5
|
+
// Stable identity: EditorModal wires this into useStackedEscape, whose effect
|
|
6
|
+
// deps include it — a fresh `() => {}` literal every render (while `busy`)
|
|
7
|
+
// would tear down and re-add its Escape listener on every render instead of
|
|
8
|
+
// just when `busy` actually flips.
|
|
9
|
+
const NOOP = () => {};
|
|
10
|
+
|
|
11
|
+
export interface ConfirmDialogProps {
|
|
12
|
+
isOpen: boolean;
|
|
13
|
+
title: string;
|
|
14
|
+
body?: ReactNode;
|
|
15
|
+
confirmLabel: string;
|
|
16
|
+
cancelLabel?: string;
|
|
17
|
+
tone?: "destructive" | "neutral";
|
|
18
|
+
busy?: boolean;
|
|
19
|
+
busyLabel?: string;
|
|
20
|
+
/** The typed-name page delete gates on this. */
|
|
21
|
+
confirmDisabled?: boolean;
|
|
22
|
+
onConfirm: () => void;
|
|
23
|
+
onCancel: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Renders title/body/buttons with no `EditorModal` wrapper — for a confirm
|
|
26
|
+
* that appears inside an ALREADY-OPEN `EditorModal` (PagesModal's typed-name
|
|
27
|
+
* delete, HistoryChangesModal's restore mode-swap). Two nested EditorModals
|
|
28
|
+
* would each register their own document Escape listener, so one Escape
|
|
29
|
+
* would close both.
|
|
30
|
+
*/
|
|
31
|
+
embedded?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function ConfirmDialog({
|
|
35
|
+
isOpen,
|
|
36
|
+
title,
|
|
37
|
+
body,
|
|
38
|
+
confirmLabel,
|
|
39
|
+
cancelLabel = "Cancel",
|
|
40
|
+
tone = "destructive",
|
|
41
|
+
busy = false,
|
|
42
|
+
busyLabel,
|
|
43
|
+
confirmDisabled = false,
|
|
44
|
+
onConfirm,
|
|
45
|
+
onCancel,
|
|
46
|
+
embedded = false,
|
|
47
|
+
}: ConfirmDialogProps) {
|
|
48
|
+
if (!isOpen) return null;
|
|
49
|
+
|
|
50
|
+
const buttons = (
|
|
51
|
+
<div className="flex justify-end gap-3">
|
|
52
|
+
<Button type="button" variant="secondary" size="md" onClick={onCancel} disabled={busy}>
|
|
53
|
+
{cancelLabel}
|
|
54
|
+
</Button>
|
|
55
|
+
<Button
|
|
56
|
+
type="button"
|
|
57
|
+
variant={tone === "destructive" ? "destructive" : "primary"}
|
|
58
|
+
size="md"
|
|
59
|
+
onClick={onConfirm}
|
|
60
|
+
disabled={confirmDisabled}
|
|
61
|
+
isLoading={busy}
|
|
62
|
+
loadingLabel={busyLabel}
|
|
63
|
+
>
|
|
64
|
+
{confirmLabel}
|
|
65
|
+
</Button>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (embedded) {
|
|
70
|
+
return (
|
|
71
|
+
<div className="flex flex-col gap-3">
|
|
72
|
+
<h4 className="text-base font-semibold text-base-contrast">{title}</h4>
|
|
73
|
+
{body}
|
|
74
|
+
{buttons}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<EditorModal isOpen={isOpen} onClose={busy ? NOOP : onCancel} title={title} size="standard">
|
|
81
|
+
<div className="flex flex-col gap-3">
|
|
82
|
+
{body}
|
|
83
|
+
{buttons}
|
|
84
|
+
</div>
|
|
85
|
+
</EditorModal>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useEffect, useRef, type ReactNode, type RefObject } from "react";
|
|
2
|
+
import { cn } from "../../lib/cn";
|
|
3
|
+
import { Button } from "./Button";
|
|
4
|
+
|
|
5
|
+
export type ConfirmTone = "destructive" | "neutral";
|
|
6
|
+
|
|
7
|
+
const toneClasses: Record<ConfirmTone, string> = {
|
|
8
|
+
destructive: "border-danger bg-danger-bg text-danger",
|
|
9
|
+
neutral: "border-base-200 bg-base text-base-contrast",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export interface ConfirmInlineProps {
|
|
13
|
+
message: ReactNode;
|
|
14
|
+
confirmLabel: string;
|
|
15
|
+
cancelLabel?: string;
|
|
16
|
+
tone: ConfirmTone;
|
|
17
|
+
busy?: boolean;
|
|
18
|
+
confirmDisabled?: boolean;
|
|
19
|
+
/** Overrides the confirm button's accessible name when the visible label is
|
|
20
|
+
* ambiguous across multiple rows (NavGroupRow's pinned "Confirm delete"). */
|
|
21
|
+
confirmAriaLabel?: string;
|
|
22
|
+
/** Sits between Cancel and confirm as `Button variant="secondary"` — the
|
|
23
|
+
* folder delete's "Move contents to parent" is the one user today. */
|
|
24
|
+
secondaryAction?: { label: string; onClick: () => void };
|
|
25
|
+
onConfirm: () => void;
|
|
26
|
+
onCancel: () => void;
|
|
27
|
+
/** Focus returns here on unmount — the row's trigger button, typically. */
|
|
28
|
+
returnFocusTo?: RefObject<HTMLElement | null>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function ConfirmInline({
|
|
32
|
+
message,
|
|
33
|
+
confirmLabel,
|
|
34
|
+
cancelLabel = "Cancel",
|
|
35
|
+
tone,
|
|
36
|
+
busy = false,
|
|
37
|
+
confirmDisabled = false,
|
|
38
|
+
confirmAriaLabel,
|
|
39
|
+
secondaryAction,
|
|
40
|
+
onConfirm,
|
|
41
|
+
onCancel,
|
|
42
|
+
returnFocusTo,
|
|
43
|
+
}: ConfirmInlineProps) {
|
|
44
|
+
const cancelRef = useRef<HTMLButtonElement>(null);
|
|
45
|
+
|
|
46
|
+
// Focus moves to Cancel on mount and back to the trigger on unmount — a
|
|
47
|
+
// destructive/neutral confirm appearing inline (not in a trapped modal)
|
|
48
|
+
// still owes a keyboard user a predictable landing spot.
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
cancelRef.current?.focus();
|
|
51
|
+
return () => {
|
|
52
|
+
returnFocusTo?.current?.focus();
|
|
53
|
+
};
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- mount/unmount only
|
|
55
|
+
}, []);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<div
|
|
59
|
+
role="alertdialog"
|
|
60
|
+
aria-live="assertive"
|
|
61
|
+
className={cn(
|
|
62
|
+
"flex flex-col items-center gap-2 rounded-lg border px-4 py-3 lg:flex-row lg:justify-between",
|
|
63
|
+
toneClasses[tone],
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
<p className="text-center text-sm lg:text-left">{message}</p>
|
|
67
|
+
<div className="flex shrink-0 flex-wrap items-center justify-end gap-2">
|
|
68
|
+
<Button type="button" ref={cancelRef} variant="secondary" size="sm" onClick={onCancel} disabled={busy}>
|
|
69
|
+
{cancelLabel}
|
|
70
|
+
</Button>
|
|
71
|
+
{secondaryAction && (
|
|
72
|
+
<Button type="button" variant="secondary" size="sm" onClick={secondaryAction.onClick} disabled={busy}>
|
|
73
|
+
{secondaryAction.label}
|
|
74
|
+
</Button>
|
|
75
|
+
)}
|
|
76
|
+
<Button
|
|
77
|
+
type="button"
|
|
78
|
+
variant={tone === "destructive" ? "destructive" : "primary"}
|
|
79
|
+
size="sm"
|
|
80
|
+
onClick={onConfirm}
|
|
81
|
+
disabled={confirmDisabled}
|
|
82
|
+
isLoading={busy}
|
|
83
|
+
aria-label={confirmAriaLabel}
|
|
84
|
+
>
|
|
85
|
+
{confirmLabel}
|
|
86
|
+
</Button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, type ReactNode, type ErrorInfo } from "react";
|
|
2
|
+
import { AlertTriangle } from "lucide-react";
|
|
2
3
|
import { cn } from "../../lib/cn";
|
|
3
4
|
import { Button } from "./Button";
|
|
4
5
|
|
|
@@ -46,36 +47,23 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|
|
46
47
|
<div
|
|
47
48
|
role="alert"
|
|
48
49
|
className={cn(
|
|
49
|
-
"flex flex-col items-center justify-center gap-3 rounded border border-
|
|
50
|
-
"dark:border-red-900/40 dark:bg-red-950/20",
|
|
50
|
+
"flex flex-col items-center justify-center gap-3 rounded border border-danger bg-danger-bg px-6 py-10 text-center",
|
|
51
51
|
)}
|
|
52
52
|
>
|
|
53
|
-
<
|
|
54
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
55
|
-
viewBox="0 0 20 20"
|
|
56
|
-
fill="currentColor"
|
|
57
|
-
className="h-6 w-6 text-red-500"
|
|
58
|
-
aria-hidden="true"
|
|
59
|
-
>
|
|
60
|
-
<path
|
|
61
|
-
fillRule="evenodd"
|
|
62
|
-
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z"
|
|
63
|
-
clipRule="evenodd"
|
|
64
|
-
/>
|
|
65
|
-
</svg>
|
|
53
|
+
<AlertTriangle className="h-6 w-6 text-danger" aria-hidden="true" />
|
|
66
54
|
|
|
67
|
-
<p className="text-sm font-medium text-
|
|
55
|
+
<p className="text-sm font-medium text-danger">
|
|
68
56
|
This section couldn't be rendered
|
|
69
57
|
</p>
|
|
70
58
|
|
|
71
59
|
{this.props.label && (
|
|
72
|
-
<p className="text-xs text-
|
|
60
|
+
<p className="text-xs text-danger">
|
|
73
61
|
Section: {this.props.label}
|
|
74
62
|
</p>
|
|
75
63
|
)}
|
|
76
64
|
|
|
77
65
|
{this.state.error && (
|
|
78
|
-
<p className="max-w-md text-xs text-
|
|
66
|
+
<p className="max-w-md text-xs text-danger">
|
|
79
67
|
{this.state.error.message}
|
|
80
68
|
</p>
|
|
81
69
|
)}
|
|
@@ -24,9 +24,18 @@ interface FabCommon {
|
|
|
24
24
|
/** Accessible name — FABs are icon-only. */
|
|
25
25
|
label: string;
|
|
26
26
|
column: "viewer" | "editor";
|
|
27
|
-
/** Vertical slot (bottom-*) plus any per-FAB extras.
|
|
27
|
+
/** Vertical slot (bottom-*) plus any per-FAB extras. Ignored when `stacked`
|
|
28
|
+
* — `FabStack` owns spacing then. */
|
|
28
29
|
className?: string;
|
|
29
30
|
children: ReactNode;
|
|
31
|
+
/** Renders as a static, non-fixed member of a `FabStack` instead of an
|
|
32
|
+
* independently viewport-fixed button: `relative`, no `bottom-*`/`right-*`
|
|
33
|
+
* of its own. React context can't cross the viewer page's separate Astro
|
|
34
|
+
* islands, so this is a prop, not a stacking context — `FabStack` is
|
|
35
|
+
* editor-shell only; the viewer page's FABs never set it. `fab-stacked`
|
|
36
|
+
* suppresses the lg+ position rule base.css gives `.fab-container-right`
|
|
37
|
+
* (see FabStack), so the two positioning mechanisms don't compound. */
|
|
38
|
+
stacked?: boolean;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
export type FabProps =
|
|
@@ -34,12 +43,13 @@ export type FabProps =
|
|
|
34
43
|
| ({ href?: undefined; ref?: Ref<HTMLButtonElement> } & FabCommon &
|
|
35
44
|
Omit<ComponentPropsWithoutRef<"button">, "children" | "className" | "aria-label" | "type">);
|
|
36
45
|
|
|
37
|
-
export default function Fab({ label, column, className, children, ...rest }: FabProps) {
|
|
46
|
+
export default function Fab({ label, column, className, children, stacked, ...rest }: FabProps) {
|
|
38
47
|
const classes = cn(
|
|
39
|
-
"cursor-pointer
|
|
48
|
+
"cursor-pointer flex items-center justify-center rounded-full bg-primary text-primary-contrast shadow-lg hover:opacity-90 transition-opacity",
|
|
49
|
+
stacked ? "relative" : "fixed",
|
|
40
50
|
column === "viewer"
|
|
41
|
-
? "
|
|
42
|
-
: "
|
|
51
|
+
? cn("h-12 w-12 viewer-fab", !stacked && "z-40 right-4")
|
|
52
|
+
: cn("h-10 w-10 fab-container-right", stacked ? "fab-stacked" : "z-50 right-4 lg:right-auto"),
|
|
43
53
|
className,
|
|
44
54
|
);
|
|
45
55
|
if (rest.href !== undefined) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
interface FabStackProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Vertical stack for the /edit FAB column — EditorShell's own FABs
|
|
8
|
+
* (mode toggle, doc-edit, BugReportFAB) share this rhythm so they can never
|
|
9
|
+
* overlap. ChatWidget's launcher stays independently `fixed` (a React
|
|
10
|
+
* context here can't reach it anyway: the viewer page renders each `<Fab>`
|
|
11
|
+
* as its own Astro island, and the chat launcher lives inside the
|
|
12
|
+
* ChatWidget island).
|
|
13
|
+
*
|
|
14
|
+
* Positioning lives on the container only: `right-4 lg:right-auto` plus
|
|
15
|
+
* `fab-container-right`, whose lg+ rule in base.css re-sets `right` to the
|
|
16
|
+
* content edge. That rule skips `.fab-stacked`, so stacked children are never
|
|
17
|
+
* shifted twice — but it means the container MUST carry the class: without
|
|
18
|
+
* it, `lg:right-auto` leaves the fixed column with no horizontal inset at all
|
|
19
|
+
* and it falls back to its static position over the page content. Children
|
|
20
|
+
* render with `stacked` (relative, no position classes of their own) and
|
|
21
|
+
* contribute only spacing via this flex column. */
|
|
22
|
+
export function FabStack({ children }: FabStackProps) {
|
|
23
|
+
return (
|
|
24
|
+
<div className="fab-container-right fixed z-50 bottom-16 right-4 lg:right-auto flex flex-col items-end gap-4">
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|