canopycms 0.0.68-int.98 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2131 -0
- package/README.md +47 -63
- package/dist/ai/generate.d.ts +5 -0
- package/dist/ai/generate.js +244 -115
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/json-to-markdown.d.ts +21 -1
- package/dist/ai/json-to-markdown.js +120 -57
- package/dist/ai/references.d.ts +72 -0
- package/dist/ai/references.js +223 -0
- package/dist/ai/resolve-branch.js +9 -2
- package/dist/ai/to-plain-text.d.ts +17 -8
- package/dist/ai/to-plain-text.js +18 -15
- package/dist/ai/types.d.ts +84 -3
- package/dist/api/admin-branch-health.d.ts +24 -1
- package/dist/api/admin-branch-health.js +52 -20
- package/dist/api/admin.d.ts +23 -5
- package/dist/api/admin.js +36 -1
- package/dist/api/assets.js +88 -78
- package/dist/api/branch-create-window.d.ts +12 -0
- package/dist/api/branch-create-window.js +13 -0
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +1 -1
- package/dist/api/branch-review.d.ts +3 -3
- package/dist/api/branch-review.js +16 -7
- package/dist/api/branch-status.d.ts +16 -6
- package/dist/api/branch-status.js +57 -12
- package/dist/api/branch-withdraw.d.ts +2 -2
- package/dist/api/branch-withdraw.js +8 -3
- package/dist/api/branch.d.ts +25 -12
- package/dist/api/branch.js +164 -103
- package/dist/api/client.d.ts +78 -58
- package/dist/api/client.js +150 -117
- package/dist/api/comments.d.ts +12 -3
- package/dist/api/comments.js +118 -9
- package/dist/api/content.d.ts +9 -9
- package/dist/api/content.js +131 -22
- package/dist/api/entries-constants.d.ts +14 -3
- package/dist/api/entries-constants.js +14 -3
- package/dist/api/entries.d.ts +40 -2
- package/dist/api/entries.js +102 -6
- package/dist/api/github-sync.d.ts +19 -0
- package/dist/api/github-sync.js +50 -3
- package/dist/api/groups.d.ts +4 -4
- package/dist/api/groups.js +2 -1
- package/dist/api/guards.js +23 -3
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +1 -0
- package/dist/api/permissions.d.ts +21 -2
- package/dist/api/permissions.js +50 -3
- package/dist/api/request-deadline.d.ts +59 -0
- package/dist/api/request-deadline.js +73 -0
- package/dist/api/resolve-references.js +8 -7
- package/dist/api/route-builder.d.ts +14 -0
- package/dist/api/route-builder.js +14 -1
- package/dist/api/schema.d.ts +11 -9
- package/dist/api/schema.js +2 -0
- package/dist/api/settings-helpers.d.ts +5 -1
- package/dist/api/settings-helpers.js +10 -2
- package/dist/api/types.d.ts +18 -0
- package/dist/api/users-constants.d.ts +6 -0
- package/dist/api/users-constants.js +6 -0
- package/dist/assets/asset-url.d.ts +28 -16
- package/dist/assets/asset-url.js +51 -25
- package/dist/assets/finalize.js +3 -0
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/materialize.d.ts +153 -0
- package/dist/assets/materialize.js +402 -0
- package/dist/assets/store-local.d.ts +19 -5
- package/dist/assets/store-local.js +69 -10
- package/dist/assets/store-s3.d.ts +38 -7
- package/dist/assets/store-s3.js +128 -22
- package/dist/assets/transform-directives.d.ts +52 -13
- package/dist/assets/transform-directives.js +87 -27
- package/dist/assets/transform.d.ts +3 -3
- package/dist/assets/transform.js +13 -8
- package/dist/assets/types.d.ts +31 -4
- package/dist/auth/cache.d.ts +1 -1
- package/dist/auth/cache.js +1 -1
- package/dist/auth/caching-auth-plugin.d.ts +2 -0
- package/dist/auth/caching-auth-plugin.js +12 -2
- package/dist/auth/file-based-auth-cache.d.ts +8 -0
- package/dist/auth/file-based-auth-cache.js +18 -8
- package/dist/auth/person-name.d.ts +5 -0
- package/dist/auth/person-name.js +8 -0
- package/dist/auth/plugin.d.ts +10 -1
- package/dist/auth/types.d.ts +2 -0
- package/dist/auth/user-metadata-lookup.d.ts +21 -0
- package/dist/auth/user-metadata-lookup.js +116 -0
- package/dist/authorization/branch.d.ts +1 -1
- package/dist/authorization/branch.js +12 -13
- package/dist/authorization/groups/schema.d.ts +4 -4
- package/dist/authorization/helpers.d.ts +8 -0
- package/dist/authorization/helpers.js +8 -0
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/protected-branch.d.ts +5 -4
- package/dist/authorization/protected-branch.js +7 -5
- package/dist/branch-health.d.ts +35 -8
- package/dist/branch-health.js +54 -18
- package/dist/branch-metadata-error.d.ts +27 -0
- package/dist/branch-metadata-error.js +23 -0
- package/dist/branch-metadata-file.d.ts +205 -24
- package/dist/branch-metadata-file.js +126 -25
- package/dist/branch-metadata.d.ts +45 -6
- package/dist/branch-metadata.js +142 -50
- package/dist/branch-provisioning.d.ts +167 -0
- package/dist/branch-provisioning.js +501 -0
- package/dist/branch-registry.d.ts +8 -0
- package/dist/branch-registry.js +61 -9
- package/dist/branch-schema-cache.d.ts +29 -12
- package/dist/branch-schema-cache.js +64 -21
- package/dist/branch-sparse.d.ts +23 -0
- package/dist/branch-sparse.js +118 -0
- package/dist/branch-workspace.d.ts +42 -3
- package/dist/branch-workspace.js +239 -100
- package/dist/build/asset-refs.d.ts +94 -0
- package/dist/build/asset-refs.js +267 -0
- package/dist/build/generate-ai-content.js +5 -0
- package/dist/build/inline-flight.d.ts +37 -0
- package/dist/build/inline-flight.js +142 -0
- package/dist/cli/asset-refs.d.ts +52 -0
- package/dist/cli/asset-refs.js +194 -0
- package/dist/cli/cli.d.ts +15 -1
- package/dist/cli/cli.js +8543 -3193
- package/dist/cli/configured-asset-store.d.ts +12 -0
- package/dist/cli/configured-asset-store.js +46 -0
- package/dist/cli/generate-ai-content.js +4244 -1072
- package/dist/cli/init.js +217 -126
- package/dist/cli/project-detect.d.ts +2 -0
- package/dist/cli/project-detect.js +2 -0
- package/dist/cli/template-files/Dockerfile.cms.template +13 -5
- package/dist/cli/template-files/cms-stack.ts.template +16 -13
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/comment-store.d.ts +25 -0
- package/dist/comment-store.js +43 -8
- package/dist/config/flatten.js +2 -0
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schemas/config.d.ts +12 -29
- package/dist/config/schemas/config.js +9 -12
- package/dist/config/schemas/field.d.ts +3 -0
- package/dist/config/schemas/field.js +58 -4
- package/dist/config/schemas/media.d.ts +4 -13
- package/dist/config/schemas/media.js +5 -8
- package/dist/config/schemas/url.d.ts +2 -20
- package/dist/config/schemas/url.js +2 -25
- package/dist/config/types.d.ts +116 -22
- package/dist/config/types.js +3 -9
- package/dist/config/validation.d.ts +25 -4
- package/dist/config/validation.js +116 -3
- package/dist/content-id-index.js +2 -2
- package/dist/content-index-generation.d.ts +1 -1
- package/dist/content-index-generation.js +1 -1
- package/dist/content-listing.d.ts +10 -1
- package/dist/content-listing.js +22 -5
- package/dist/content-reader.d.ts +9 -0
- package/dist/content-reader.js +16 -11
- package/dist/content-store.d.ts +75 -12
- package/dist/content-store.js +249 -86
- package/dist/content-tree.js +2 -2
- package/dist/context.js +5 -2
- package/dist/dangling-reference-log.d.ts +17 -0
- package/dist/dangling-reference-log.js +29 -0
- package/dist/dev-content-watcher.d.ts +1 -1
- package/dist/dev-content-watcher.js +1 -1
- package/dist/editor/BranchManager.d.ts +23 -7
- package/dist/editor/BranchManager.js +119 -54
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +1 -2
- package/dist/editor/CommentsPanel.d.ts +14 -0
- package/dist/editor/CommentsPanel.js +68 -43
- package/dist/editor/Editor.d.ts +11 -5
- package/dist/editor/Editor.js +891 -218
- package/dist/editor/EditorAuthGate.d.ts +7 -1
- package/dist/editor/EditorAuthGate.js +41 -9
- package/dist/editor/EntryNavigator.d.ts +22 -0
- package/dist/editor/EntryNavigator.js +353 -105
- package/dist/editor/FormHeader.d.ts +25 -0
- package/dist/editor/FormHeader.js +82 -0
- package/dist/editor/FormRenderer.d.ts +27 -3
- package/dist/editor/FormRenderer.js +171 -76
- package/dist/editor/PreviewFrame.d.ts +40 -0
- package/dist/editor/PreviewFrame.js +215 -0
- package/dist/editor/PreviewPane.d.ts +47 -0
- package/dist/editor/PreviewPane.js +147 -0
- package/dist/editor/PreviewToolbarTools.d.ts +22 -0
- package/dist/editor/PreviewToolbarTools.js +73 -0
- package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
- package/dist/editor/admin/SystemHealthPanel.js +163 -33
- package/dist/editor/admin/useSystemHealth.d.ts +18 -0
- package/dist/editor/admin/useSystemHealth.js +70 -1
- package/dist/editor/branch-status.d.ts +17 -0
- package/dist/editor/branch-status.js +29 -0
- package/dist/editor/canopy-path.d.ts +9 -6
- package/dist/editor/canopy-path.js +8 -11
- package/dist/editor/client-reference-resolver.d.ts +43 -16
- package/dist/editor/client-reference-resolver.js +155 -64
- package/dist/editor/comments/BranchComments.d.ts +1 -1
- package/dist/editor/comments/BranchComments.js +2 -2
- package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
- package/dist/editor/comments/CloseRefusedNotice.js +7 -0
- package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
- package/dist/editor/comments/CommentThreadsPopover.js +274 -0
- package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
- package/dist/editor/comments/CommentWriteAlert.js +13 -0
- package/dist/editor/comments/EntryComments.d.ts +10 -4
- package/dist/editor/comments/EntryComments.js +14 -17
- package/dist/editor/comments/FieldWrapper.d.ts +18 -4
- package/dist/editor/comments/FieldWrapper.js +62 -28
- package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
- package/dist/editor/comments/InlineCommentThread.js +11 -47
- package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
- package/dist/editor/comments/ThreadCarousel.js +18 -21
- package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
- package/dist/editor/comments/ThreadReplyControls.js +92 -0
- package/dist/editor/comments/field-comment-context.d.ts +14 -0
- package/dist/editor/comments/field-comment-context.js +14 -0
- package/dist/editor/comments/form-comments.d.ts +48 -0
- package/dist/editor/comments/form-comments.js +178 -0
- package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
- package/dist/editor/comments/item-anchor-copy.js +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
- package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
- package/dist/editor/comments/popover-placement.d.ts +18 -0
- package/dist/editor/comments/popover-placement.js +58 -0
- package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
- package/dist/editor/comments/use-tracked-writes.js +53 -0
- package/dist/editor/components/BranchAccessList.d.ts +15 -0
- package/dist/editor/components/BranchAccessList.js +52 -0
- package/dist/editor/components/BranchLockBanner.d.ts +22 -0
- package/dist/editor/components/BranchLockBanner.js +39 -0
- package/dist/editor/components/BranchPill.d.ts +32 -0
- package/dist/editor/components/BranchPill.js +33 -0
- package/dist/editor/components/BranchesDrawer.d.ts +11 -0
- package/dist/editor/components/BranchesDrawer.js +5 -0
- package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
- package/dist/editor/components/ConfirmDeleteModal.js +3 -2
- package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
- package/dist/editor/components/DestructiveMenuItem.js +8 -0
- package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
- package/dist/editor/components/EditorCrashScreen.js +22 -0
- package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
- package/dist/editor/components/EditorErrorBoundary.js +40 -0
- package/dist/editor/components/EditorHeader.d.ts +56 -106
- package/dist/editor/components/EditorHeader.js +130 -131
- package/dist/editor/components/EditorRail.d.ts +49 -0
- package/dist/editor/components/EditorRail.js +65 -0
- package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
- package/dist/editor/components/EntryBreadcrumb.js +56 -0
- package/dist/editor/components/EntryCreateModal.d.ts +12 -7
- package/dist/editor/components/EntryCreateModal.js +51 -57
- package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
- package/dist/editor/components/NoEditPermissionNotice.js +5 -4
- package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
- package/dist/editor/components/QuickOpenPalette.js +66 -0
- package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
- package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
- package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
- package/dist/editor/components/ReasonedMenuItem.js +15 -0
- package/dist/editor/components/ReferencedByList.d.ts +11 -0
- package/dist/editor/components/ReferencedByList.js +28 -0
- package/dist/editor/components/RelativeTime.d.ts +10 -0
- package/dist/editor/components/RelativeTime.js +10 -0
- package/dist/editor/components/RenameEntryModal.d.ts +9 -1
- package/dist/editor/components/RenameEntryModal.js +19 -31
- package/dist/editor/components/RetryToastMessage.d.ts +9 -0
- package/dist/editor/components/RetryToastMessage.js +6 -0
- package/dist/editor/components/SaveAllResult.d.ts +25 -0
- package/dist/editor/components/SaveAllResult.js +86 -0
- package/dist/editor/components/SaveSplitButton.d.ts +30 -0
- package/dist/editor/components/SaveSplitButton.js +108 -0
- package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
- package/dist/editor/components/StagedChangesDrawer.js +92 -0
- package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
- package/dist/editor/components/UnavailableEntryNotice.js +9 -0
- package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
- package/dist/editor/components/UnavailableTypeMessage.js +9 -0
- package/dist/editor/components/UndoToastMessage.d.ts +18 -0
- package/dist/editor/components/UndoToastMessage.js +10 -0
- package/dist/editor/components/UserBadge.d.ts +2 -5
- package/dist/editor/components/UserBadge.js +62 -33
- package/dist/editor/components/ValidationSummary.d.ts +14 -0
- package/dist/editor/components/ValidationSummary.js +24 -0
- package/dist/editor/components/index.d.ts +2 -2
- package/dist/editor/components/index.js +2 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -2
- package/dist/editor/context/ApiClientContext.js +19 -8
- package/dist/editor/context/AssetContext.d.ts +13 -35
- package/dist/editor/context/AssetContext.js +12 -31
- package/dist/editor/context/EditorStateContext.d.ts +4 -4
- package/dist/editor/context/EditorStateContext.js +4 -4
- package/dist/editor/context/SWRProvider.d.ts +3 -3
- package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
- package/dist/editor/context/SiteMdxAllowContext.js +7 -0
- package/dist/editor/context/index.d.ts +2 -1
- package/dist/editor/context/index.js +2 -1
- package/dist/editor/contrast.d.ts +19 -0
- package/dist/editor/contrast.js +41 -0
- package/dist/editor/copy.d.ts +18 -0
- package/dist/editor/copy.js +18 -0
- package/dist/editor/editor-config.js +16 -0
- package/dist/editor/editor-utils.d.ts +34 -8
- package/dist/editor/editor-utils.js +42 -20
- package/dist/editor/entry-search.d.ts +20 -0
- package/dist/editor/entry-search.js +34 -0
- package/dist/editor/field-breadcrumb.d.ts +12 -0
- package/dist/editor/field-breadcrumb.js +85 -0
- package/dist/editor/field-props.d.ts +86 -0
- package/dist/editor/field-props.js +27 -0
- package/dist/editor/field-target.d.ts +30 -0
- package/dist/editor/field-target.js +77 -0
- package/dist/editor/fields/BlockField.d.ts +12 -0
- package/dist/editor/fields/BlockField.js +89 -73
- package/dist/editor/fields/CodeField.d.ts +2 -0
- package/dist/editor/fields/CodeField.js +6 -2
- package/dist/editor/fields/DateTimeField.d.ts +4 -29
- package/dist/editor/fields/DateTimeField.js +79 -41
- package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
- package/dist/editor/fields/ExpandAllButton.js +4 -0
- package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
- package/dist/editor/fields/FieldCrashFallback.js +30 -0
- package/dist/editor/fields/FieldLabel.d.ts +37 -0
- package/dist/editor/fields/FieldLabel.js +19 -0
- package/dist/editor/fields/ImageField.d.ts +4 -0
- package/dist/editor/fields/ImageField.js +29 -14
- package/dist/editor/fields/InlineGroupField.js +4 -3
- package/dist/editor/fields/ItemList.d.ts +42 -0
- package/dist/editor/fields/ItemList.js +130 -0
- package/dist/editor/fields/MarkdownField.d.ts +32 -0
- package/dist/editor/fields/MarkdownField.js +223 -46
- package/dist/editor/fields/MdxImageDialog.js +1 -1
- package/dist/editor/fields/NumberField.d.ts +2 -0
- package/dist/editor/fields/NumberField.js +8 -5
- package/dist/editor/fields/NumberListField.d.ts +2 -0
- package/dist/editor/fields/NumberListField.js +19 -16
- package/dist/editor/fields/ObjectField.d.ts +2 -7
- package/dist/editor/fields/ObjectField.js +15 -5
- package/dist/editor/fields/ObjectListField.d.ts +29 -0
- package/dist/editor/fields/ObjectListField.js +57 -0
- package/dist/editor/fields/ReferenceField.d.ts +2 -0
- package/dist/editor/fields/ReferenceField.js +34 -9
- package/dist/editor/fields/SelectField.d.ts +2 -0
- package/dist/editor/fields/SelectField.js +11 -2
- package/dist/editor/fields/StringListField.d.ts +4 -1
- package/dist/editor/fields/StringListField.js +22 -8
- package/dist/editor/fields/TextField.d.ts +2 -0
- package/dist/editor/fields/TextField.js +6 -2
- package/dist/editor/fields/ToggleField.d.ts +2 -0
- package/dist/editor/fields/ToggleField.js +8 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
- package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
- package/dist/editor/fields/form-expansion.d.ts +9 -0
- package/dist/editor/fields/form-expansion.js +2 -0
- package/dist/editor/fields/item-expansion.d.ts +15 -0
- package/dist/editor/fields/item-expansion.js +60 -0
- package/dist/editor/fields/list-item-keys.d.ts +8 -0
- package/dist/editor/fields/list-item-keys.js +50 -0
- package/dist/editor/fields/list-item-title.d.ts +20 -0
- package/dist/editor/fields/list-item-title.js +85 -0
- package/dist/editor/fields/markdown-export-options.d.ts +2 -0
- package/dist/editor/fields/markdown-export-options.js +8 -0
- package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
- package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
- package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
- package/dist/editor/fields/mdx-jsx-support.js +157 -69
- package/dist/editor/fields/rich-text-failures.d.ts +5 -0
- package/dist/editor/fields/rich-text-failures.js +26 -0
- package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
- package/dist/editor/fields/toolbar-wrap.js +35 -0
- package/dist/editor/form-outline.d.ts +13 -0
- package/dist/editor/form-outline.js +70 -0
- package/dist/editor/group-manager/GroupCard.d.ts +4 -1
- package/dist/editor/group-manager/GroupCard.js +12 -3
- package/dist/editor/group-manager/GroupForm.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
- package/dist/editor/group-manager/MemberList.d.ts +2 -1
- package/dist/editor/group-manager/MemberList.js +15 -4
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
- package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
- package/dist/editor/group-manager/index.js +34 -5
- package/dist/editor/group-manager/types.d.ts +5 -2
- package/dist/editor/hooks/create-branch-request.d.ts +20 -0
- package/dist/editor/hooks/create-branch-request.js +54 -0
- package/dist/editor/hooks/save-all.d.ts +68 -0
- package/dist/editor/hooks/save-all.js +61 -0
- package/dist/editor/hooks/useBranchActions.d.ts +11 -1
- package/dist/editor/hooks/useBranchActions.js +42 -19
- package/dist/editor/hooks/useBranchManager.d.ts +21 -0
- package/dist/editor/hooks/useBranchManager.js +321 -125
- package/dist/editor/hooks/useBranchesData.d.ts +8 -4
- package/dist/editor/hooks/useBranchesData.js +9 -5
- package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
- package/dist/editor/hooks/useCommentSystem.js +79 -55
- package/dist/editor/hooks/useCommentsData.d.ts +11 -7
- package/dist/editor/hooks/useCommentsData.js +20 -19
- package/dist/editor/hooks/useDraftManager.d.ts +77 -3
- package/dist/editor/hooks/useDraftManager.js +887 -94
- package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
- package/dist/editor/hooks/useEditorLayout.js +98 -20
- package/dist/editor/hooks/useEntriesData.d.ts +2 -1
- package/dist/editor/hooks/useEntriesData.js +18 -4
- package/dist/editor/hooks/useEntryManager.d.ts +41 -2
- package/dist/editor/hooks/useEntryManager.js +227 -41
- package/dist/editor/hooks/useGroupManager.js +13 -16
- package/dist/editor/hooks/usePermissionManager.js +14 -6
- package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
- package/dist/editor/hooks/usePreviewMarks.js +33 -0
- package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
- package/dist/editor/hooks/useReferenceResolution.js +34 -177
- package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
- package/dist/editor/hooks/useSchemaManager.js +97 -39
- package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
- package/dist/editor/hooks/useUserMetadata.js +76 -47
- package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
- package/dist/editor/hooks/user-metadata-batcher.js +33 -0
- package/dist/editor/media/AssetCard.d.ts +6 -7
- package/dist/editor/media/AssetCard.js +24 -31
- package/dist/editor/media/AssetListRow.d.ts +16 -0
- package/dist/editor/media/AssetListRow.js +41 -0
- package/dist/editor/media/CropStep.js +6 -1
- package/dist/editor/media/MediaLibrary.d.ts +4 -3
- package/dist/editor/media/MediaLibrary.js +11 -4
- package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
- package/dist/editor/media/MediaLibraryBody.js +195 -80
- package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
- package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
- package/dist/editor/media/crop-math.d.ts +3 -4
- package/dist/editor/media/crop-math.js +11 -22
- package/dist/editor/media/editor-image-src.d.ts +8 -0
- package/dist/editor/media/editor-image-src.js +10 -0
- package/dist/editor/media/format-bytes.d.ts +2 -0
- package/dist/editor/media/format-bytes.js +23 -0
- package/dist/editor/media/media-library-prefs.d.ts +23 -0
- package/dist/editor/media/media-library-prefs.js +49 -0
- package/dist/editor/media/media-library-view.d.ts +34 -0
- package/dist/editor/media/media-library-view.js +40 -0
- package/dist/editor/media/useAssetLibrary.d.ts +30 -0
- package/dist/editor/media/useAssetLibrary.js +126 -0
- package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
- package/dist/editor/media/useStableAssetOrder.js +37 -0
- package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
- package/dist/editor/media/useThumbnailFailure.js +16 -0
- package/dist/editor/permission-manager/GroupSelector.js +2 -2
- package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
- package/dist/editor/permission-manager/PermissionEditor.js +15 -4
- package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
- package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
- package/dist/editor/permission-manager/UserSelector.js +3 -3
- package/dist/editor/permission-manager/index.js +12 -3
- package/dist/editor/permission-manager/types.d.ts +5 -2
- package/dist/editor/platform.d.ts +3 -0
- package/dist/editor/platform.js +9 -0
- package/dist/editor/preview-asset-base.d.ts +9 -0
- package/dist/editor/preview-asset-base.js +17 -0
- package/dist/editor/preview-bridge.d.ts +51 -27
- package/dist/editor/preview-bridge.js +103 -144
- package/dist/editor/preview-marks.d.ts +15 -0
- package/dist/editor/preview-marks.js +74 -0
- package/dist/editor/preview-path.d.ts +12 -0
- package/dist/editor/preview-path.js +45 -1
- package/dist/editor/preview-scale.d.ts +27 -0
- package/dist/editor/preview-scale.js +34 -0
- package/dist/editor/raw-asset-base.d.ts +5 -0
- package/dist/editor/raw-asset-base.js +14 -0
- package/dist/editor/relative-time.d.ts +4 -4
- package/dist/editor/relative-time.js +16 -8
- package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
- package/dist/editor/schema-editor/CollectionEditor.js +361 -62
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
- package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
- package/dist/editor/schema-editor/collection-draft.js +40 -0
- package/dist/editor/schema-editor/index.d.ts +1 -1
- package/dist/editor/schema-label.d.ts +10 -0
- package/dist/editor/schema-label.js +17 -0
- package/dist/editor/settings-conflict.d.ts +5 -0
- package/dist/editor/settings-conflict.js +8 -0
- package/dist/editor/shell/ActivityRail.d.ts +37 -0
- package/dist/editor/shell/ActivityRail.js +91 -0
- package/dist/editor/shell/EditorShell.d.ts +17 -0
- package/dist/editor/shell/EditorShell.js +31 -0
- package/dist/editor/shell/PaneLayout.d.ts +28 -0
- package/dist/editor/shell/PaneLayout.js +116 -0
- package/dist/editor/shell/SidePanelHost.d.ts +35 -0
- package/dist/editor/shell/SidePanelHost.js +184 -0
- package/dist/editor/shell/TopBar.d.ts +12 -0
- package/dist/editor/shell/TopBar.js +14 -0
- package/dist/editor/shell/host-chrome.d.ts +16 -0
- package/dist/editor/shell/host-chrome.js +69 -0
- package/dist/editor/slug.d.ts +16 -0
- package/dist/editor/slug.js +43 -0
- package/dist/editor/theme.d.ts +2 -1
- package/dist/editor/theme.js +314 -13
- package/dist/editor/unanswered.d.ts +17 -0
- package/dist/editor/unanswered.js +26 -0
- package/dist/editor/unavailable-entry-type.d.ts +20 -0
- package/dist/editor/unavailable-entry-type.js +28 -0
- package/dist/editor/undo-removal.d.ts +57 -0
- package/dist/editor/undo-removal.js +163 -0
- package/dist/editor/user-display.d.ts +4 -0
- package/dist/editor/user-display.js +5 -0
- package/dist/editor/utils/confirm-modal.d.ts +8 -0
- package/dist/editor/utils/confirm-modal.js +12 -0
- package/dist/editor/utils/editor-errors.d.ts +19 -0
- package/dist/editor/utils/editor-errors.js +32 -0
- package/dist/editor/utils/focus-return.d.ts +56 -0
- package/dist/editor/utils/focus-return.js +106 -0
- package/dist/entry-link-resolver.d.ts +11 -1
- package/dist/entry-link-resolver.js +65 -5
- package/dist/entry-schema-registry.d.ts +3 -3
- package/dist/entry-schema-registry.js +7 -4
- package/dist/entry-schema.d.ts +49 -3
- package/dist/entry-schema.js +18 -0
- package/dist/git-manager.d.ts +172 -10
- package/dist/git-manager.js +449 -107
- package/dist/github-service.d.ts +39 -2
- package/dist/github-service.js +101 -7
- package/dist/http/handler.js +74 -9
- package/dist/http/types.d.ts +2 -0
- package/dist/http/worker-not-ready.d.ts +9 -4
- package/dist/http/worker-not-ready.js +59 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/item-keys.d.ts +46 -0
- package/dist/item-keys.js +235 -0
- package/dist/operating-mode/editor-mode-check.d.ts +15 -0
- package/dist/operating-mode/editor-mode-check.js +24 -0
- package/dist/operating-mode/mode-env.d.ts +13 -14
- package/dist/operating-mode/mode-env.js +13 -14
- package/dist/operating-mode/types.d.ts +2 -2
- package/dist/paths/branch.d.ts +0 -1
- package/dist/paths/branch.js +1 -8
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/validation.js +0 -2
- package/dist/preview.d.ts +8 -0
- package/dist/preview.js +7 -0
- package/dist/reference-resolver.js +1 -0
- package/dist/resolve-canopy-user.d.ts +1 -1
- package/dist/resolve-canopy-user.js +1 -1
- package/dist/schema/meta-loader.d.ts +18 -8
- package/dist/schema/meta-loader.js +42 -9
- package/dist/schema/registry-fingerprint.d.ts +14 -0
- package/dist/schema/registry-fingerprint.js +63 -0
- package/dist/schema/resolver.d.ts +7 -4
- package/dist/schema/resolver.js +7 -6
- package/dist/schema/schema-store.d.ts +7 -10
- package/dist/schema/schema-store.js +13 -11
- package/dist/schema/schema-unavailable-error.d.ts +11 -0
- package/dist/schema/schema-unavailable-error.js +15 -0
- package/dist/schema/types.d.ts +22 -0
- package/dist/schema-registry-record.d.ts +35 -0
- package/dist/schema-registry-record.js +134 -0
- package/dist/server.d.ts +79 -9
- package/dist/server.js +62 -8
- package/dist/services.d.ts +33 -5
- package/dist/services.js +155 -37
- package/dist/settings-workspace.d.ts +23 -3
- package/dist/settings-workspace.js +159 -45
- package/dist/stamp-on-publish.d.ts +36 -0
- package/dist/stamp-on-publish.js +71 -0
- package/dist/static/index.d.ts +58 -5
- package/dist/static/index.js +133 -3
- package/dist/static/seo.d.ts +5 -5
- package/dist/static/seo.js +5 -5
- package/dist/submission-attribution.d.ts +8 -0
- package/dist/submission-attribution.js +22 -0
- package/dist/system-users.d.ts +12 -0
- package/dist/system-users.js +12 -0
- package/dist/task-queue/cms-task-queue.d.ts +1 -1
- package/dist/task-queue/cms-task-queue.js +1 -1
- package/dist/task-queue/index.d.ts +1 -1
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/task-queue.d.ts +6 -0
- package/dist/task-queue/task-queue.js +29 -0
- package/dist/task-queue/worker-status.d.ts +35 -9
- package/dist/task-queue/worker-status.js +84 -17
- package/dist/types.d.ts +90 -9
- package/dist/url-collision.js +3 -3
- package/dist/url-exclusivity-fixtures.d.ts +8 -1
- package/dist/url-exclusivity-fixtures.js +11 -1
- package/dist/user.js +2 -1
- package/dist/utils/atomic-write.js +2 -1
- package/dist/utils/base-branch.d.ts +13 -0
- package/dist/utils/base-branch.js +23 -0
- package/dist/utils/content-serialize.d.ts +15 -7
- package/dist/utils/content-serialize.js +353 -51
- package/dist/utils/content-write-lock.d.ts +6 -1
- package/dist/utils/content-write-lock.js +21 -6
- package/dist/utils/debug.d.ts +1 -1
- package/dist/utils/debug.js +5 -3
- package/dist/utils/error.js +13 -2
- package/dist/utils/escape-text.d.ts +7 -0
- package/dist/utils/escape-text.js +27 -0
- package/dist/utils/fs.d.ts +12 -4
- package/dist/utils/fs.js +18 -5
- package/dist/utils/git.d.ts +21 -1
- package/dist/utils/git.js +63 -8
- package/dist/utils/json-source-splice.d.ts +14 -0
- package/dist/utils/json-source-splice.js +120 -0
- package/dist/utils/markdown-body-splice.d.ts +39 -0
- package/dist/utils/markdown-body-splice.js +421 -0
- package/dist/utils/occ-json-write.js +18 -12
- package/dist/utils/provision-log.d.ts +25 -0
- package/dist/utils/provision-log.js +49 -0
- package/dist/utils/provisioning-lock.d.ts +32 -1
- package/dist/utils/provisioning-lock.js +78 -32
- package/dist/utils/sanitize-href.d.ts +9 -23
- package/dist/utils/sanitize-href.js +14 -28
- package/dist/utils/title-field.d.ts +10 -0
- package/dist/utils/title-field.js +47 -0
- package/dist/utils/yaml-source-splice.d.ts +58 -0
- package/dist/utils/yaml-source-splice.js +515 -0
- package/dist/validation/block-structural-keys.d.ts +1 -1
- package/dist/validation/block-structural-keys.js +1 -1
- package/dist/validation/deletion-checker.d.ts +21 -29
- package/dist/validation/deletion-checker.js +41 -117
- package/dist/validation/entry-validator.d.ts +6 -10
- package/dist/validation/entry-validator.js +19 -26
- package/dist/validation/field-traversal.d.ts +22 -0
- package/dist/validation/field-traversal.js +39 -8
- package/dist/validation/markdown-safety.d.ts +68 -0
- package/dist/validation/markdown-safety.js +596 -0
- package/dist/validation/mdx-allowlist.d.ts +55 -0
- package/dist/validation/mdx-allowlist.js +183 -0
- package/dist/validation/reference-validator.d.ts +2 -0
- package/dist/validation/reference-validator.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/branch-policy.d.ts +124 -0
- package/dist/worker/branch-policy.js +243 -0
- package/dist/worker/bundle-header.d.ts +117 -0
- package/dist/worker/bundle-header.js +253 -0
- package/dist/worker/cms-worker.d.ts +236 -142
- package/dist/worker/cms-worker.js +772 -285
- package/dist/worker/gateway-egress.d.ts +43 -0
- package/dist/worker/gateway-egress.js +209 -0
- package/dist/worker/gateway-instance.d.ts +42 -0
- package/dist/worker/gateway-instance.js +129 -0
- package/dist/worker/git-process.d.ts +81 -0
- package/dist/worker/git-process.js +234 -0
- package/dist/worker/git-sync.d.ts +34 -17
- package/dist/worker/git-sync.js +394 -131
- package/dist/worker/github-auth.d.ts +9 -9
- package/dist/worker/github-auth.js +13 -15
- package/dist/worker/github-gateway-http.d.ts +62 -0
- package/dist/worker/github-gateway-http.js +977 -0
- package/dist/worker/github-gateway-wire.d.ts +590 -0
- package/dist/worker/github-gateway-wire.js +488 -0
- package/dist/worker/github-gateway.d.ts +238 -0
- package/dist/worker/github-gateway.js +726 -0
- package/dist/worker/github-mirror-upkeep.d.ts +75 -0
- package/dist/worker/github-mirror-upkeep.js +266 -0
- package/dist/worker/github-mirror.d.ts +364 -0
- package/dist/worker/github-mirror.js +1030 -0
- package/dist/worker/github-transfer.d.ts +56 -0
- package/dist/worker/github-transfer.js +444 -0
- package/dist/worker/history-rewrite.d.ts +4 -5
- package/dist/worker/history-rewrite.js +12 -17
- package/dist/worker/provisioned-workspace.d.ts +5 -5
- package/dist/worker/provisioned-workspace.js +5 -5
- package/dist/worker/rebase.d.ts +1 -1
- package/dist/worker/rebase.js +58 -54
- package/dist/worker/remote-git-maintenance.d.ts +3 -0
- package/dist/worker/remote-git-maintenance.js +12 -0
- package/dist/worker/schema-gate.d.ts +49 -0
- package/dist/worker/schema-gate.js +226 -0
- package/dist/worker/self-checks.d.ts +107 -0
- package/dist/worker/self-checks.js +358 -0
- package/dist/worker/shared-repo-git.d.ts +96 -0
- package/dist/worker/shared-repo-git.js +459 -0
- package/dist/worker/sparse-cone.d.ts +20 -0
- package/dist/worker/sparse-cone.js +136 -0
- package/dist/worker/stale-mirror.d.ts +82 -0
- package/dist/worker/stale-mirror.js +130 -0
- package/dist/worker/task-runner.d.ts +5 -3
- package/dist/worker/task-runner.js +287 -186
- package/dist/worker/worker-context.d.ts +36 -37
- package/package.json +35 -7
- package/dist/editor/EditorPanes.d.ts +0 -10
- package/dist/editor/EditorPanes.js +0 -98
- package/dist/editor/components/EditorFooter.d.ts +0 -11
- package/dist/editor/components/EditorFooter.js +0 -9
- package/dist/editor/components/EditorSidebar.d.ts +0 -67
- package/dist/editor/components/EditorSidebar.js +0 -22
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface TopBarProps {
|
|
3
|
+
/** Where you are: the breadcrumb and anything that describes the open entry. */
|
|
4
|
+
leading: ReactNode;
|
|
5
|
+
/** What you can do: the branch and the actions on it. */
|
|
6
|
+
trailing: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The shell's top bar: one 48px row from `md` up. Narrower, `leading` takes a row of its own
|
|
10
|
+
* above `trailing`, which wraps rather than clip a control. Layout only.
|
|
11
|
+
*/
|
|
12
|
+
export declare function TopBar({ leading, trailing }: TopBarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Box, Group } from '@mantine/core';
|
|
4
|
+
const TOP_BAR_HEIGHT = 48;
|
|
5
|
+
/**
|
|
6
|
+
* The shell's top bar: one 48px row from `md` up. Narrower, `leading` takes a row of its own
|
|
7
|
+
* above `trailing`, which wraps rather than clip a control. Layout only.
|
|
8
|
+
*/
|
|
9
|
+
export function TopBar({ leading, trailing }) {
|
|
10
|
+
return (_jsxs(Group, { gap: "xs", wrap: "wrap", align: "center", px: "sm", py: 6, mih: TOP_BAR_HEIGHT, style: {
|
|
11
|
+
borderBottom: '1px solid var(--canopy-input-border)',
|
|
12
|
+
background: 'var(--mantine-color-body)',
|
|
13
|
+
}, children: [_jsx(Box, { flex: { base: '1 0 100%', md: '1 1 0%' }, miw: 0, children: leading }), _jsx(Group, { gap: 6, wrap: "wrap", align: "center", justify: "flex-end", flex: { base: '1 0 100%', md: '0 1 auto' }, miw: 0, children: trailing })] }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @internal Exported for tests. The host page's chrome around `anchor`, an element the editor
|
|
4
|
+
* renders in place: the `<body>` child holding it, plus every `<body>` child the same copy of React
|
|
5
|
+
* rendered (a Next.js root layout's header and footer). That copy's fiber key has a random suffix,
|
|
6
|
+
* so portal containers and the roots other libraries create, such as MDXEditor's popup
|
|
7
|
+
* container, never match it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findHostChrome(anchor: Element): HTMLElement[];
|
|
10
|
+
/**
|
|
11
|
+
* Makes the host's chrome inert and hidden while the editor is mounted: Tab never leaves the
|
|
12
|
+
* editor, and chrome with its own z-index never paints over the shell. Applied once, at mount,
|
|
13
|
+
* since an element added later may be a third-party popup that must stay usable; unmount restores
|
|
14
|
+
* exactly what this changed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useHideHostChrome(anchorRef: RefObject<Element | null>): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
const REACT_FIBER_KEY_PREFIX = '__reactFiber$';
|
|
4
|
+
function reactFiberKey(element) {
|
|
5
|
+
return Object.keys(element).find((key) => key.startsWith(REACT_FIBER_KEY_PREFIX));
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* @internal Exported for tests. The host page's chrome around `anchor`, an element the editor
|
|
9
|
+
* renders in place: the `<body>` child holding it, plus every `<body>` child the same copy of React
|
|
10
|
+
* rendered (a Next.js root layout's header and footer). That copy's fiber key has a random suffix,
|
|
11
|
+
* so portal containers and the roots other libraries create, such as MDXEditor's popup
|
|
12
|
+
* container, never match it.
|
|
13
|
+
*/
|
|
14
|
+
export function findHostChrome(anchor) {
|
|
15
|
+
const body = anchor.ownerDocument.body;
|
|
16
|
+
let root = anchor;
|
|
17
|
+
while (root.parentElement && root.parentElement !== body)
|
|
18
|
+
root = root.parentElement;
|
|
19
|
+
if (root.parentElement !== body)
|
|
20
|
+
return [];
|
|
21
|
+
const fiberKey = reactFiberKey(anchor);
|
|
22
|
+
const siblings = fiberKey
|
|
23
|
+
? Array.from(body.children).filter((child) => child !== root && fiberKey in child)
|
|
24
|
+
: [];
|
|
25
|
+
return [root, ...siblings].filter((element) => element instanceof HTMLElement);
|
|
26
|
+
}
|
|
27
|
+
/** Per element, so a second editor mounted at once never restores what the first still hides. */
|
|
28
|
+
const holds = new WeakMap();
|
|
29
|
+
function hide(element) {
|
|
30
|
+
let hold = holds.get(element);
|
|
31
|
+
if (!hold) {
|
|
32
|
+
const wasInert = element.hasAttribute('inert');
|
|
33
|
+
const { visibility } = element.style;
|
|
34
|
+
element.setAttribute('inert', '');
|
|
35
|
+
element.style.visibility = 'hidden';
|
|
36
|
+
hold = {
|
|
37
|
+
count: 0,
|
|
38
|
+
restore: () => {
|
|
39
|
+
if (!wasInert)
|
|
40
|
+
element.removeAttribute('inert');
|
|
41
|
+
element.style.visibility = visibility;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
holds.set(element, hold);
|
|
45
|
+
}
|
|
46
|
+
hold.count++;
|
|
47
|
+
const held = hold;
|
|
48
|
+
return () => {
|
|
49
|
+
if (--held.count > 0)
|
|
50
|
+
return;
|
|
51
|
+
holds.delete(element);
|
|
52
|
+
held.restore();
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Makes the host's chrome inert and hidden while the editor is mounted: Tab never leaves the
|
|
57
|
+
* editor, and chrome with its own z-index never paints over the shell. Applied once, at mount,
|
|
58
|
+
* since an element added later may be a third-party popup that must stay usable; unmount restores
|
|
59
|
+
* exactly what this changed.
|
|
60
|
+
*/
|
|
61
|
+
export function useHideHostChrome(anchorRef) {
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const anchor = anchorRef.current;
|
|
64
|
+
if (!anchor)
|
|
65
|
+
return;
|
|
66
|
+
const releases = findHostChrome(anchor).map(hide);
|
|
67
|
+
return () => releases.forEach((release) => release());
|
|
68
|
+
}, [anchorRef]);
|
|
69
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Slug derivation and validation shared by the create and rename modals. */
|
|
2
|
+
/** A URL slug for a title: ASCII lowercase letters, digits and single hyphens, empty when none remain. */
|
|
3
|
+
export declare function slugFromTitle(title: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* The message for a slug the user may not use, or null when it is fine.
|
|
6
|
+
*
|
|
7
|
+
* Delegates to `parseSlug` rather than restating its rule: the server refuses to CREATE an
|
|
8
|
+
* entry whose slug fails it (api/content.ts and ContentStore.write's [SLUG] guards), and the
|
|
9
|
+
* static build fails outright on one that slipped through (static/index.ts's
|
|
10
|
+
* assertRoutableSlugs). A second, hand-maintained copy of the charset/length/separator rules
|
|
11
|
+
* here could only ever drift out of agreement with the boundary that actually decides.
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateEntrySlug(value: string, opts?: {
|
|
14
|
+
existingSlugs?: ReadonlySet<string>;
|
|
15
|
+
currentSlug?: string;
|
|
16
|
+
}): string | null;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Slug derivation and validation shared by the create and rename modals. */
|
|
2
|
+
// Imported from '../paths/validation.js' directly, NOT the `paths` barrel, which pulls
|
|
3
|
+
// node:fs into the browser bundle (pnpm lint:bundle enforces this).
|
|
4
|
+
import { parseSlug } from '../paths/validation.js';
|
|
5
|
+
const MAX_SLUG_LENGTH = 64;
|
|
6
|
+
/** A URL slug for a title: ASCII lowercase letters, digits and single hyphens, empty when none remain. */
|
|
7
|
+
export function slugFromTitle(title) {
|
|
8
|
+
const slug = title
|
|
9
|
+
.normalize('NFKD')
|
|
10
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
11
|
+
.toLowerCase()
|
|
12
|
+
.replace(/&/g, ' and ')
|
|
13
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
14
|
+
.replace(/^-+|-+$/g, '');
|
|
15
|
+
return slug.slice(0, MAX_SLUG_LENGTH).replace(/-+$/, '');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The message for a slug the user may not use, or null when it is fine.
|
|
19
|
+
*
|
|
20
|
+
* Delegates to `parseSlug` rather than restating its rule: the server refuses to CREATE an
|
|
21
|
+
* entry whose slug fails it (api/content.ts and ContentStore.write's [SLUG] guards), and the
|
|
22
|
+
* static build fails outright on one that slipped through (static/index.ts's
|
|
23
|
+
* assertRoutableSlugs). A second, hand-maintained copy of the charset/length/separator rules
|
|
24
|
+
* here could only ever drift out of agreement with the boundary that actually decides.
|
|
25
|
+
*/
|
|
26
|
+
export function validateEntrySlug(value, opts = {}) {
|
|
27
|
+
if (!value.trim())
|
|
28
|
+
return 'Enter a slug';
|
|
29
|
+
const parsed = parseSlug(value);
|
|
30
|
+
if (!parsed.ok)
|
|
31
|
+
return parsed.error;
|
|
32
|
+
// `parseSlug` lowercases before testing, so it accepts 'My-Post' and hands back 'my-post'.
|
|
33
|
+
// Keep the field itself strict: the value typed here is what the duplicate check below and
|
|
34
|
+
// the create request are keyed on, so silently normalizing would let 'My-Post' sail past a
|
|
35
|
+
// collision with an existing 'my-post' and land as a 409 from the server instead of an
|
|
36
|
+
// inline message here.
|
|
37
|
+
if (parsed.slug !== value)
|
|
38
|
+
return 'Use lowercase letters';
|
|
39
|
+
if (value !== opts.currentSlug && opts.existingSlugs?.has(value)) {
|
|
40
|
+
return 'An entry with this slug already exists';
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
package/dist/editor/theme.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type MantineColorScheme, type MantineColorsTuple, type MantineThemeOverride } from '@mantine/core';
|
|
3
3
|
import '@mantine/core/styles.css';
|
|
4
|
+
import '@mantine/dates/styles.css';
|
|
4
5
|
import '@mantine/notifications/styles.css';
|
|
5
6
|
import '@mantine/dropzone/styles.css';
|
|
6
7
|
import '@mdxeditor/editor/style.css';
|
|
@@ -54,7 +55,7 @@ export declare const createCanopyTheme: (options?: Pick<CanopyThemeOptions, "col
|
|
|
54
55
|
headings?: {
|
|
55
56
|
fontFamily?: string | undefined;
|
|
56
57
|
fontWeight?: string | undefined;
|
|
57
|
-
textWrap?: "
|
|
58
|
+
textWrap?: "balance" | "nowrap" | "wrap" | "stable" | "pretty" | undefined;
|
|
58
59
|
sizes?: {
|
|
59
60
|
h1?: {
|
|
60
61
|
fontSize?: string | undefined;
|
package/dist/editor/theme.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
|
-
import { DEFAULT_THEME, MantineProvider, createTheme, } from '@mantine/core';
|
|
4
|
+
import { Alert, ActionIcon, Badge, Button, Checkbox, DEFAULT_THEME, Drawer, Input, MantineProvider, Modal, Notification, Radio, Switch, Tabs, Text, Tooltip, getDefaultZIndex, getPrimaryShade, mergeThemeOverrides, createTheme, darken, } from '@mantine/core';
|
|
5
5
|
import { Notifications } from '@mantine/notifications';
|
|
6
6
|
import { ModalsProvider } from '@mantine/modals';
|
|
7
7
|
import { generateColors } from '@mantine/colors-generator';
|
|
8
|
+
import { composite, contrastRatio, isMeasurable, readableOnScale } from './contrast.js';
|
|
8
9
|
import '@mantine/core/styles.css';
|
|
10
|
+
import '@mantine/dates/styles.css';
|
|
9
11
|
import '@mantine/notifications/styles.css';
|
|
10
12
|
import '@mantine/dropzone/styles.css';
|
|
11
13
|
import '@mdxeditor/editor/style.css';
|
|
@@ -38,29 +40,328 @@ const toScale = (input, fallbackKey, fallback) => {
|
|
|
38
40
|
}
|
|
39
41
|
return fallbackScale;
|
|
40
42
|
};
|
|
43
|
+
// Icon-only close buttons are named "Close". Every Modal and Drawer one keeps it under a caller's
|
|
44
|
+
// `closeButtonProps` unless that sets `aria-label`; a toast's or Alert's is replaced whole.
|
|
45
|
+
const CLOSE_BUTTON_PROPS = { 'aria-label': 'Close' };
|
|
46
|
+
// Filled red is red.8 under white; filled orange is orange.6 under black, since no orange shade
|
|
47
|
+
// reaches 4.5:1 under white; a filled primary is `--canopy-primary-fill`. Callers pass a plain
|
|
48
|
+
// `color`.
|
|
49
|
+
const isPrimary = (theme, color) => color === undefined || color === theme.primaryColor;
|
|
50
|
+
const checkboxOnRing = (theme, props) => isPrimary(theme, props.color)
|
|
51
|
+
? {
|
|
52
|
+
'--checkbox-color': props.variant === 'outline' ? undefined : 'var(--canopy-focus-ring)',
|
|
53
|
+
'--checkbox-icon-color': props.iconColor ? undefined : 'var(--canopy-focus-ring-contrast)',
|
|
54
|
+
}
|
|
55
|
+
: {};
|
|
56
|
+
const radioOnRing = (theme, props) => isPrimary(theme, props.color)
|
|
57
|
+
? {
|
|
58
|
+
'--radio-color': props.variant === 'outline' ? undefined : 'var(--canopy-focus-ring)',
|
|
59
|
+
'--radio-icon-color': props.iconColor ? undefined : 'var(--canopy-focus-ring-contrast)',
|
|
60
|
+
}
|
|
61
|
+
: {};
|
|
62
|
+
const canopyComponents = {
|
|
63
|
+
Button: Button.extend({
|
|
64
|
+
// The editor's default control size; a per-call `size` is only for a deliberate exception.
|
|
65
|
+
defaultProps: { size: 'xs' },
|
|
66
|
+
vars: (theme, props) => {
|
|
67
|
+
if ((props.variant ?? 'filled') !== 'filled')
|
|
68
|
+
return { root: {} };
|
|
69
|
+
if (props.color === 'red') {
|
|
70
|
+
return {
|
|
71
|
+
root: { '--button-bg': theme.colors.red[8], '--button-hover': theme.colors.red[9] },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (props.color === 'orange') {
|
|
75
|
+
return {
|
|
76
|
+
root: {
|
|
77
|
+
'--button-bg': theme.colors.orange[6],
|
|
78
|
+
'--button-hover': theme.colors.orange[7],
|
|
79
|
+
'--button-color': theme.black,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (isPrimary(theme, props.color)) {
|
|
84
|
+
return {
|
|
85
|
+
root: {
|
|
86
|
+
'--button-bg': 'var(--canopy-primary-fill)',
|
|
87
|
+
'--button-hover': 'var(--canopy-primary-fill-hover)',
|
|
88
|
+
'--button-color': 'var(--mantine-color-white)',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { root: {} };
|
|
93
|
+
},
|
|
94
|
+
}),
|
|
95
|
+
Badge: Badge.extend({
|
|
96
|
+
// Sentence case, as every other label; an xs badge's 9px is too small for lowercase.
|
|
97
|
+
styles: { root: { textTransform: 'none', '--badge-fz-xs': 'var(--badge-fz-sm)' } },
|
|
98
|
+
vars: (theme, props) => (props.variant ?? 'filled') === 'filled' && isPrimary(theme, props.color)
|
|
99
|
+
? {
|
|
100
|
+
root: {
|
|
101
|
+
'--badge-bg': 'var(--canopy-primary-fill)',
|
|
102
|
+
'--badge-color': 'var(--mantine-color-white)',
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
: { root: {} },
|
|
106
|
+
}),
|
|
107
|
+
ActionIcon: ActionIcon.extend({
|
|
108
|
+
defaultProps: { size: 'sm' },
|
|
109
|
+
vars: (theme, props) => (props.variant ?? 'filled') === 'filled' && isPrimary(theme, props.color)
|
|
110
|
+
? {
|
|
111
|
+
root: {
|
|
112
|
+
'--ai-bg': 'var(--canopy-primary-fill)',
|
|
113
|
+
'--ai-hover': 'var(--canopy-primary-fill-hover)',
|
|
114
|
+
'--ai-color': 'var(--mantine-color-white)',
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
: { root: {} },
|
|
118
|
+
}),
|
|
119
|
+
// Tooltips open on focus and touch too, so an icon-only control's name reaches the keyboard.
|
|
120
|
+
Tooltip: Tooltip.extend({ defaultProps: { events: { hover: true, focus: true, touch: true } } }),
|
|
121
|
+
// A default input's border is `--canopy-input-border`; errored and focused ones keep Mantine's.
|
|
122
|
+
Input: Input.extend({
|
|
123
|
+
styles: (_theme, props) => props.error || (props.variant ?? 'default') !== 'default'
|
|
124
|
+
? {}
|
|
125
|
+
: { wrapper: { '--input-bd': 'var(--canopy-input-border)' } },
|
|
126
|
+
}),
|
|
127
|
+
// Checkbox, Radio and Tabs name their colour inline even when none is given, and a Switch when
|
|
128
|
+
// one is, past the focus-ring alias; a primary one is pointed at the ring here, and its tick,
|
|
129
|
+
// dot or thumb takes the colour that reads on it.
|
|
130
|
+
Checkbox: Checkbox.extend({ vars: (theme, props) => ({ root: checkboxOnRing(theme, props) }) }),
|
|
131
|
+
CheckboxIndicator: Checkbox.Indicator.extend({
|
|
132
|
+
vars: (theme, props) => ({ indicator: checkboxOnRing(theme, props) }),
|
|
133
|
+
}),
|
|
134
|
+
Radio: Radio.extend({ vars: (theme, props) => ({ root: radioOnRing(theme, props) }) }),
|
|
135
|
+
RadioIndicator: Radio.Indicator.extend({
|
|
136
|
+
vars: (theme, props) => ({ indicator: radioOnRing(theme, props) }),
|
|
137
|
+
}),
|
|
138
|
+
// Pills put text on the colour, which the ring does not measure for.
|
|
139
|
+
Tabs: Tabs.extend({
|
|
140
|
+
vars: (theme, props) => ({
|
|
141
|
+
root: isPrimary(theme, props.color) && props.variant !== 'pills'
|
|
142
|
+
? { '--tabs-color': 'var(--canopy-focus-ring)' }
|
|
143
|
+
: {},
|
|
144
|
+
}),
|
|
145
|
+
}),
|
|
146
|
+
Switch: Switch.extend({
|
|
147
|
+
vars: (theme, props) => ({
|
|
148
|
+
root: isPrimary(theme, props.color) ? { '--switch-color': 'var(--canopy-focus-ring)' } : {},
|
|
149
|
+
}),
|
|
150
|
+
styles: (theme, props) => isPrimary(theme, props.color)
|
|
151
|
+
? { root: { '--canopy-switch-thumb-on': 'var(--canopy-focus-ring-contrast)' } }
|
|
152
|
+
: {},
|
|
153
|
+
}),
|
|
154
|
+
// Dark dimmed text is nearly as bright as body text, so it also takes the dimmed font style.
|
|
155
|
+
// Every input's description, Checkbox's, Radio's and Switch's included, is an InputWrapper's.
|
|
156
|
+
InputWrapper: Input.Wrapper.extend({
|
|
157
|
+
styles: { description: { fontStyle: 'var(--canopy-dimmed-font-style)' } },
|
|
158
|
+
}),
|
|
159
|
+
// Dimmed Text takes the same style.
|
|
160
|
+
Text: Text.extend({
|
|
161
|
+
styles: (_theme, props) => props.c === 'dimmed' ? { root: { fontStyle: 'var(--canopy-dimmed-font-style)' } } : {},
|
|
162
|
+
}),
|
|
163
|
+
ModalCloseButton: Modal.CloseButton.extend({ defaultProps: CLOSE_BUTTON_PROPS }),
|
|
164
|
+
DrawerCloseButton: Drawer.CloseButton.extend({ defaultProps: CLOSE_BUTTON_PROPS }),
|
|
165
|
+
// Mantine dims a titled toast's text to gray.6 / dark.2, under 4.5:1 on its surface.
|
|
166
|
+
Notification: Notification.extend({
|
|
167
|
+
defaultProps: { closeButtonProps: CLOSE_BUTTON_PROPS },
|
|
168
|
+
styles: { description: { color: 'var(--mantine-color-text)' } },
|
|
169
|
+
}),
|
|
170
|
+
// A light yellow Alert's title, icon and close button are yellow on pale yellow, under 2:1, so
|
|
171
|
+
// they take the text colour; the tint and the icon's shape still mark it a warning.
|
|
172
|
+
Alert: Alert.extend({
|
|
173
|
+
defaultProps: { closeButtonLabel: 'Close' },
|
|
174
|
+
vars: (_theme, props) => props.color === 'yellow' && (props.variant ?? 'light') === 'light'
|
|
175
|
+
? { root: { '--alert-color': 'var(--mantine-color-text)' } }
|
|
176
|
+
: { root: {} },
|
|
177
|
+
}),
|
|
178
|
+
};
|
|
41
179
|
export const createCanopyTheme = (options) => {
|
|
42
180
|
const { colors, themeOverride } = options ?? {};
|
|
43
181
|
const brand = toScale(colors?.brand, 'indigo', defaultCanopyColors.brand);
|
|
44
182
|
const primary = toScale(colors?.primary ?? colors?.brand, 'blue', defaultCanopyColors.primary);
|
|
45
183
|
const neutral = toScale(colors?.neutral, 'gray', defaultCanopyColors.neutral);
|
|
46
184
|
const accent = toScale(colors?.accent, 'teal', defaultCanopyColors.accent);
|
|
47
|
-
|
|
185
|
+
const base = createTheme({
|
|
48
186
|
primaryColor: 'brand',
|
|
49
|
-
|
|
187
|
+
// Where `--canopy-focus-ring` and `--canopy-primary-fill` start on the primary scale.
|
|
188
|
+
primaryShade: { light: 7, dark: 5 },
|
|
50
189
|
defaultRadius: 'md',
|
|
51
|
-
colors: {
|
|
52
|
-
...DEFAULT_THEME.colors,
|
|
53
|
-
brand,
|
|
54
|
-
primary,
|
|
55
|
-
neutral,
|
|
56
|
-
accent,
|
|
57
|
-
...(themeOverride?.colors ?? {}),
|
|
58
|
-
},
|
|
190
|
+
colors: { ...DEFAULT_THEME.colors, brand, primary, neutral, accent },
|
|
59
191
|
fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif',
|
|
60
|
-
|
|
192
|
+
components: canopyComponents,
|
|
193
|
+
});
|
|
194
|
+
// Deep merge, so an override that sets only some colours or one component's props keeps the rest.
|
|
195
|
+
return mergeThemeOverrides(base, themeOverride ?? {});
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* A colour's text, light and subtle variants and outline take the first step, from the primary
|
|
199
|
+
* shade in light mode or Mantine's dark text shade 4, reaching 4.5:1 on its hovered light tint
|
|
200
|
+
* over the lowest-contrast surface (gray.1, dark.4); past the scale's end, the end shade darkened
|
|
201
|
+
* or lightened. A colour, gray or dark scale it cannot measure (`var()`, oklch) keeps Mantine's.
|
|
202
|
+
*/
|
|
203
|
+
const readableColourVariables = (theme, scheme) => {
|
|
204
|
+
const variables = {};
|
|
205
|
+
const shade = getPrimaryShade(theme, scheme);
|
|
206
|
+
if (!theme.colors.gray.every(isMeasurable) || !theme.colors.dark.every(isMeasurable)) {
|
|
207
|
+
return variables;
|
|
208
|
+
}
|
|
209
|
+
for (const [name, scale] of Object.entries(theme.colors)) {
|
|
210
|
+
if (scale.length !== 10 || !scale.every(isMeasurable))
|
|
211
|
+
continue;
|
|
212
|
+
const { shade: step, value } = scheme === 'light'
|
|
213
|
+
? readableOnScale(scale, {
|
|
214
|
+
from: shade,
|
|
215
|
+
toward: 'darker',
|
|
216
|
+
background: composite(scale[shade], 0.12, theme.colors.gray[1]),
|
|
217
|
+
})
|
|
218
|
+
: readableOnScale(scale, {
|
|
219
|
+
from: 4,
|
|
220
|
+
toward: 'lighter',
|
|
221
|
+
background: composite(scale[Math.max(shade - 2, 0)], 0.2, theme.colors.dark[4]),
|
|
222
|
+
});
|
|
223
|
+
const colour = step === undefined ? value : `var(--mantine-color-${name}-${step})`;
|
|
224
|
+
variables[`--mantine-color-${name}-text`] = colour;
|
|
225
|
+
variables[`--mantine-color-${name}-light-color`] = colour;
|
|
226
|
+
variables[`--mantine-color-${name}-outline`] = colour;
|
|
227
|
+
}
|
|
228
|
+
return variables;
|
|
229
|
+
};
|
|
230
|
+
/** `--canopy-primary-fill`: the first step from the primary shade with white at 4.5:1 on it. */
|
|
231
|
+
const primaryFill = (theme, scheme) => {
|
|
232
|
+
const scale = theme.colors[theme.primaryColor];
|
|
233
|
+
if (!scale.every(isMeasurable)) {
|
|
234
|
+
return {
|
|
235
|
+
'--canopy-primary-fill': `var(--mantine-color-${theme.primaryColor}-filled)`,
|
|
236
|
+
'--canopy-primary-fill-hover': `var(--mantine-color-${theme.primaryColor}-filled-hover)`,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const { shade, value } = readableOnScale(scale, {
|
|
240
|
+
from: getPrimaryShade(theme, scheme),
|
|
241
|
+
toward: 'darker',
|
|
242
|
+
background: theme.white,
|
|
61
243
|
});
|
|
244
|
+
const step = (n) => `var(--mantine-color-${theme.primaryColor}-${n})`;
|
|
245
|
+
return shade === undefined
|
|
246
|
+
? { '--canopy-primary-fill': value, '--canopy-primary-fill-hover': darken(value, 0.1) }
|
|
247
|
+
: {
|
|
248
|
+
'--canopy-primary-fill': step(shade),
|
|
249
|
+
'--canopy-primary-fill-hover': step(shade === 9 ? 8 : shade + 1),
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* `--canopy-focus-ring`: the first step from the primary shade, darker in light mode and lighter in
|
|
254
|
+
* dark, at 3:1 on gray.1 or dark.5. Mantine draws focus rings, focused borders and a checked
|
|
255
|
+
* Switch in `--mantine-primary-color-filled`, so that becomes the ring; `canopyComponents` points
|
|
256
|
+
* Checkbox, Radio and Tabs at it. A tick on it is white, or black where white is under 3:1.
|
|
257
|
+
*/
|
|
258
|
+
const focusRing = (theme, scheme) => {
|
|
259
|
+
const scale = theme.colors[theme.primaryColor];
|
|
260
|
+
const surface = scheme === 'light' ? theme.colors.gray[1] : theme.colors.dark[5];
|
|
261
|
+
const ring = scale.every(isMeasurable) && isMeasurable(surface)
|
|
262
|
+
? readableOnScale(scale, {
|
|
263
|
+
from: getPrimaryShade(theme, scheme),
|
|
264
|
+
toward: scheme === 'light' ? 'darker' : 'lighter',
|
|
265
|
+
background: surface,
|
|
266
|
+
minimum: 3,
|
|
267
|
+
})
|
|
268
|
+
: undefined;
|
|
269
|
+
const contrast = ring && contrastRatio(theme.white, ring.value) < 3 ? theme.black : theme.white;
|
|
270
|
+
return {
|
|
271
|
+
'--canopy-focus-ring': ring === undefined
|
|
272
|
+
? `var(--mantine-color-${theme.primaryColor}-filled)`
|
|
273
|
+
: ring.shade === undefined
|
|
274
|
+
? ring.value
|
|
275
|
+
: `var(--mantine-color-${theme.primaryColor}-${ring.shade})`,
|
|
276
|
+
'--canopy-focus-ring-contrast': contrast,
|
|
277
|
+
'--mantine-primary-color-filled': 'var(--canopy-focus-ring)',
|
|
278
|
+
};
|
|
62
279
|
};
|
|
280
|
+
/**
|
|
281
|
+
* docs/ux-guidelines.md "Colour and contrast" says what each token is for; `theme.test.tsx` pins
|
|
282
|
+
* every ratio for the default palette. Dark dimmed mixes dark.1 with dark.2, since dark.1 alone
|
|
283
|
+
* reads as body text; placeholders sit further from it, so they never pass for a value.
|
|
284
|
+
*/
|
|
285
|
+
const canopyCssVariablesResolver = (theme) => ({
|
|
286
|
+
variables: {
|
|
287
|
+
'--canopy-count-bg': 'color-mix(in srgb, var(--mantine-primary-color-filled) 20%, var(--mantine-color-body))',
|
|
288
|
+
'--canopy-count-bg-orange': 'color-mix(in srgb, var(--mantine-color-orange-filled) 20%, var(--mantine-color-body))',
|
|
289
|
+
},
|
|
290
|
+
light: {
|
|
291
|
+
...readableColourVariables(theme, 'light'),
|
|
292
|
+
'--mantine-color-dimmed': 'var(--mantine-color-gray-7)',
|
|
293
|
+
'--mantine-color-placeholder': 'color-mix(in srgb, var(--mantine-color-gray-6) 60%, var(--mantine-color-gray-7))',
|
|
294
|
+
'--canopy-danger-text': 'var(--mantine-color-red-9)',
|
|
295
|
+
'--canopy-input-border': 'color-mix(in srgb, var(--mantine-color-gray-6) 80%, var(--mantine-color-gray-7))',
|
|
296
|
+
'--canopy-surface-subtle': 'var(--mantine-color-gray-0)',
|
|
297
|
+
'--canopy-surface-muted': 'var(--mantine-color-gray-1)',
|
|
298
|
+
'--canopy-dimmed-font-style': 'normal',
|
|
299
|
+
...primaryFill(theme, 'light'),
|
|
300
|
+
...focusRing(theme, 'light'),
|
|
301
|
+
},
|
|
302
|
+
dark: {
|
|
303
|
+
...readableColourVariables(theme, 'dark'),
|
|
304
|
+
'--mantine-color-dimmed': 'color-mix(in srgb, var(--mantine-color-dark-1) 85%, var(--mantine-color-dark-2))',
|
|
305
|
+
'--mantine-color-placeholder': 'color-mix(in srgb, var(--mantine-color-dark-2) 60%, var(--mantine-color-dark-1))',
|
|
306
|
+
'--canopy-danger-text': 'var(--mantine-color-red-3)',
|
|
307
|
+
'--canopy-input-border': 'color-mix(in srgb, var(--mantine-color-dark-2) 80%, var(--mantine-color-dark-1))',
|
|
308
|
+
'--canopy-surface-subtle': 'var(--mantine-color-dark-6)',
|
|
309
|
+
'--canopy-surface-muted': 'var(--mantine-color-dark-5)',
|
|
310
|
+
'--canopy-dimmed-font-style': 'italic',
|
|
311
|
+
...primaryFill(theme, 'dark'),
|
|
312
|
+
...focusRing(theme, 'dark'),
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
/**
|
|
316
|
+
* What Mantine draws from class rules, out of the theme variables' reach: unchecked control borders,
|
|
317
|
+
* Switch thumbs, white text on the primary colour (moved to the fill), and dimmed text Mantine
|
|
318
|
+
* draws itself (a blocked menu item, a combobox's empty message, outside days). Outside days lose
|
|
319
|
+
* Mantine's half opacity, under 4.5:1.
|
|
320
|
+
*/
|
|
321
|
+
const CANOPY_STYLES = `
|
|
322
|
+
.mantine-Checkbox-input:not(:checked, :disabled, [data-indeterminate], [data-error]),
|
|
323
|
+
.mantine-CheckboxIndicator-indicator:not([data-checked], [data-disabled], [data-indeterminate]),
|
|
324
|
+
.mantine-Radio-radio:not(:checked, :disabled, [data-error]),
|
|
325
|
+
.mantine-RadioIndicator-indicator:not([data-checked], [data-disabled]) {
|
|
326
|
+
border-color: var(--canopy-input-border);
|
|
327
|
+
}
|
|
328
|
+
.mantine-Switch-input:not(:checked, :disabled, [data-disabled]) + .mantine-Switch-track:not([data-error]) {
|
|
329
|
+
--switch-bd: var(--canopy-input-border);
|
|
330
|
+
}
|
|
331
|
+
.mantine-Switch-input:not(:checked, :disabled, [data-disabled]) + .mantine-Switch-track > .mantine-Switch-thumb {
|
|
332
|
+
--switch-thumb-bd: var(--canopy-input-border);
|
|
333
|
+
}
|
|
334
|
+
.mantine-Switch-input:checked:not(:disabled, [data-disabled]) + .mantine-Switch-track > .mantine-Switch-thumb {
|
|
335
|
+
--switch-thumb-bg: var(--canopy-switch-thumb-on, var(--mantine-color-white));
|
|
336
|
+
--switch-thumb-bd: var(--canopy-switch-thumb-on, var(--mantine-color-white));
|
|
337
|
+
}
|
|
338
|
+
[data-combobox-selected] {
|
|
339
|
+
--mantine-primary-color-filled: var(--canopy-primary-fill);
|
|
340
|
+
}
|
|
341
|
+
.mantine-DateTimePicker-day[data-selected],
|
|
342
|
+
.mantine-DateTimePicker-pickerControl[data-selected] {
|
|
343
|
+
background-color: var(--canopy-primary-fill);
|
|
344
|
+
}
|
|
345
|
+
.mantine-DateTimePicker-day[data-selected]:hover,
|
|
346
|
+
.mantine-DateTimePicker-pickerControl[data-selected]:hover {
|
|
347
|
+
background-color: var(--canopy-primary-fill-hover);
|
|
348
|
+
}
|
|
349
|
+
input.mantine-TimeInput-input::-webkit-datetime-edit-hour-field:focus,
|
|
350
|
+
input.mantine-TimeInput-input::-webkit-datetime-edit-minute-field:focus,
|
|
351
|
+
input.mantine-TimeInput-input::-webkit-datetime-edit-second-field:focus,
|
|
352
|
+
input.mantine-TimeInput-input::-webkit-datetime-edit-ampm-field:focus {
|
|
353
|
+
background-color: var(--canopy-primary-fill);
|
|
354
|
+
}
|
|
355
|
+
.mantine-Menu-item[aria-disabled='true'],
|
|
356
|
+
.mantine-Combobox-empty,
|
|
357
|
+
.mantine-DateTimePicker-day[data-outside] {
|
|
358
|
+
font-style: var(--canopy-dimmed-font-style);
|
|
359
|
+
}
|
|
360
|
+
.mantine-DateTimePicker-day[data-outside]:not([data-disabled]) {
|
|
361
|
+
opacity: 1;
|
|
362
|
+
}
|
|
363
|
+
`;
|
|
63
364
|
export const CanopyCMSProvider = ({ children, colors, colorScheme = 'light', themeOverride, withNotifications = true, }) => {
|
|
64
365
|
const theme = useMemo(() => createCanopyTheme({ colors, themeOverride }), [colors, themeOverride]);
|
|
65
|
-
return (
|
|
366
|
+
return (_jsxs(MantineProvider, { theme: theme, defaultColorScheme: colorScheme, cssVariablesResolver: canopyCssVariablesResolver, children: [_jsx("style", { "data-canopy-styles": true, dangerouslySetInnerHTML: { __html: CANOPY_STYLES } }), _jsxs(ModalsProvider, { modalProps: { zIndex: getDefaultZIndex('popover') }, children: [withNotifications ? _jsx(Notifications, { position: "bottom-right" }) : null, children] })] }));
|
|
66
367
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ApiResponse } from '../api/types.js';
|
|
2
|
+
/** A write a gateway answered with a 5xx page (how a slow request ends behind CloudFront). */
|
|
3
|
+
export declare class UnansweredError extends Error {
|
|
4
|
+
readonly name = "UnansweredError";
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
/** Whether a refused response is a gateway's 5xx page rather than the API's answer. */
|
|
8
|
+
export declare function isGatewayFailure(result: ApiResponse): boolean;
|
|
9
|
+
/** Whether `err` leaves a write's outcome unknown: a timeout, or a gateway's 5xx page. */
|
|
10
|
+
export declare function isUnanswered(err: unknown): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A failed write whose outcome is unknown, so its message is a warning (yellow), not an error
|
|
13
|
+
* (docs/ux-guidelines.md, Loading, empty and error states).
|
|
14
|
+
*/
|
|
15
|
+
export declare class MayHaveLandedError extends Error {
|
|
16
|
+
readonly name = "MayHaveLandedError";
|
|
17
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isApiTimeoutError, isNonApiResponse, WRITE_TIMED_OUT_MESSAGE } from '../api/client.js';
|
|
2
|
+
/** A write a gateway answered with a 5xx page (how a slow request ends behind CloudFront). */
|
|
3
|
+
export class UnansweredError extends Error {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(WRITE_TIMED_OUT_MESSAGE);
|
|
6
|
+
this.name = 'UnansweredError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/** Whether a refused response is a gateway's 5xx page rather than the API's answer. */
|
|
10
|
+
export function isGatewayFailure(result) {
|
|
11
|
+
return !result.ok && isNonApiResponse(result) && result.status >= 500;
|
|
12
|
+
}
|
|
13
|
+
/** Whether `err` leaves a write's outcome unknown: a timeout, or a gateway's 5xx page. */
|
|
14
|
+
export function isUnanswered(err) {
|
|
15
|
+
return isApiTimeoutError(err) || err instanceof UnansweredError;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A failed write whose outcome is unknown, so its message is a warning (yellow), not an error
|
|
19
|
+
* (docs/ux-guidelines.md, Loading, empty and error states).
|
|
20
|
+
*/
|
|
21
|
+
export class MayHaveLandedError extends Error {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
this.name = 'MayHaveLandedError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author-facing wording for an entry type the running code cannot resolve (see
|
|
3
|
+
* `EntryTypeUnavailable`). Dependency-free so any client module can import it.
|
|
4
|
+
*/
|
|
5
|
+
/** `ApiResponse.code` of the 503 the API answers with for an entry of an unavailable type. */
|
|
6
|
+
export declare const SCHEMA_UNAVAILABLE_CODE = "SCHEMA_UNAVAILABLE";
|
|
7
|
+
/**
|
|
8
|
+
* The message split around the schema refs, so a renderer can set the refs in a code style.
|
|
9
|
+
* With no refs (a 503 on an entry the schema did not flag) the parenthetical is omitted.
|
|
10
|
+
*/
|
|
11
|
+
export declare function unavailableTypeMessageParts(schemaRefs: readonly string[]): {
|
|
12
|
+
before: string;
|
|
13
|
+
after: string;
|
|
14
|
+
};
|
|
15
|
+
/** The distinct schema refs of the unavailable entry types in `entryTypes`, in order. */
|
|
16
|
+
export declare function unavailableSchemaRefs(entryTypes: ReadonlyArray<{
|
|
17
|
+
unavailable?: {
|
|
18
|
+
schemaRef: string;
|
|
19
|
+
};
|
|
20
|
+
}> | undefined): string[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author-facing wording for an entry type the running code cannot resolve (see
|
|
3
|
+
* `EntryTypeUnavailable`). Dependency-free so any client module can import it.
|
|
4
|
+
*/
|
|
5
|
+
/** `ApiResponse.code` of the 503 the API answers with for an entry of an unavailable type. */
|
|
6
|
+
export const SCHEMA_UNAVAILABLE_CODE = 'SCHEMA_UNAVAILABLE';
|
|
7
|
+
const HEAD = "This section uses a content type this editor version doesn't know yet";
|
|
8
|
+
const TAIL = 'It usually appears after the editor finishes updating; reload in a few minutes.';
|
|
9
|
+
/**
|
|
10
|
+
* The message split around the schema refs, so a renderer can set the refs in a code style.
|
|
11
|
+
* With no refs (a 503 on an entry the schema did not flag) the parenthetical is omitted.
|
|
12
|
+
*/
|
|
13
|
+
export function unavailableTypeMessageParts(schemaRefs) {
|
|
14
|
+
const hasRefs = schemaRefs.length > 0;
|
|
15
|
+
return {
|
|
16
|
+
before: hasRefs ? `${HEAD} (` : HEAD,
|
|
17
|
+
after: `${hasRefs ? ')' : ''}. ${TAIL}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** The distinct schema refs of the unavailable entry types in `entryTypes`, in order. */
|
|
21
|
+
export function unavailableSchemaRefs(entryTypes) {
|
|
22
|
+
const refs = [];
|
|
23
|
+
for (const et of entryTypes ?? []) {
|
|
24
|
+
if (et.unavailable && !refs.includes(et.unavailable.schemaRef))
|
|
25
|
+
refs.push(et.unavailable.schemaRef);
|
|
26
|
+
}
|
|
27
|
+
return refs;
|
|
28
|
+
}
|