@contentful/field-editor-rich-text 3.15.0 → 3.15.1
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/dist/cjs/ContentfulEditorProvider.js +8 -8
- package/dist/cjs/RichTextEditor.js +22 -20
- package/dist/cjs/RichTextEditor.styles.js +2 -1
- package/dist/cjs/SdkProvider.js +7 -5
- package/dist/cjs/SyncEditorChanges.js +15 -6
- package/dist/cjs/Toolbar/_tests_/toolbar.test.js +17 -15
- package/dist/cjs/Toolbar/components/EmbedEntityWidget.js +14 -10
- package/dist/cjs/Toolbar/components/EmbeddedEntityDropdownButton.js +10 -8
- package/dist/cjs/Toolbar/components/StickyToolbarWrapper.js +2 -2
- package/dist/cjs/Toolbar/index.js +33 -30
- package/dist/cjs/__fixtures__/FakeSdk.js +3 -3
- package/dist/cjs/__fixtures__/asset/index.js +10 -10
- package/dist/cjs/__fixtures__/content-type/index.js +1 -1
- package/dist/cjs/__fixtures__/entry/index.js +7 -7
- package/dist/cjs/__fixtures__/fixtures.js +8 -6
- package/dist/cjs/__fixtures__/locale/index.js +2 -2
- package/dist/cjs/__fixtures__/space/index.js +1 -1
- package/dist/cjs/constants/Schema.js +1 -0
- package/dist/cjs/dialogs/HypelinkDialog/HyperlinkDialog.js +43 -38
- package/dist/cjs/dialogs/openRichTextDialog.js +6 -4
- package/dist/cjs/dialogs/renderRichTextDialog.js +6 -4
- package/dist/cjs/helpers/__tests__/removeInternalMarks.test.js +10 -10
- package/dist/cjs/helpers/callbacks.js +3 -3
- package/dist/cjs/helpers/config.js +2 -2
- package/dist/cjs/helpers/editor.js +53 -44
- package/dist/cjs/helpers/environment.js +3 -3
- package/dist/cjs/helpers/formatDateAndTime.js +5 -4
- package/dist/cjs/helpers/getAllowedResourcesForNodeType.js +22 -5
- package/dist/cjs/helpers/getLinkedContentTypeIdsForNodeType.js +29 -5
- package/dist/cjs/helpers/nodeFactory.js +6 -6
- package/dist/cjs/helpers/sdkNavigatorSlideIn.js +14 -6
- package/dist/cjs/helpers/sdkNavigatorSlideIn.spec.js +3 -2
- package/dist/cjs/helpers/toSlateValue.js +14 -3
- package/dist/cjs/helpers/transformers.js +5 -5
- package/dist/cjs/helpers/validations.js +12 -9
- package/dist/cjs/index.js +7 -5
- package/dist/cjs/internal/constants.js +4 -2
- package/dist/cjs/internal/hooks.js +8 -6
- package/dist/cjs/internal/misc.js +15 -12
- package/dist/cjs/internal/queries.js +115 -108
- package/dist/cjs/internal/transforms.js +51 -48
- package/dist/cjs/internal/types/editor.js +3 -1
- package/dist/cjs/plugins/Break/createExitBreakPlugin.test.js +4 -3
- package/dist/cjs/plugins/Break/createResetNodePlugin.js +1 -0
- package/dist/cjs/plugins/Break/createSoftBreakPlugin.test.js +3 -3
- package/dist/cjs/plugins/CommandPalette/components/CommandList.js +35 -33
- package/dist/cjs/plugins/CommandPalette/components/CommandList.styles.js +1 -1
- package/dist/cjs/plugins/CommandPalette/components/CommandPrompt.js +7 -5
- package/dist/cjs/plugins/CommandPalette/hooks/useCommandList.js +7 -3
- package/dist/cjs/plugins/CommandPalette/onKeyDown.js +6 -1
- package/dist/cjs/plugins/CommandPalette/onKeyDown.spec.js +6 -4
- package/dist/cjs/plugins/CommandPalette/useCommands.js +3 -3
- package/dist/cjs/plugins/CommandPalette/utils/fetchEntries.js +2 -0
- package/dist/cjs/plugins/CommandPalette/utils/trimLeadingSlash.js +6 -1
- package/dist/cjs/plugins/DragAndDrop/index.js +9 -1
- package/dist/cjs/plugins/EmbeddedEntityBlock/LinkedEntityBlock.js +10 -8
- package/dist/cjs/plugins/EmbeddedEntityBlock/index.js +3 -3
- package/dist/cjs/plugins/EmbeddedEntityInline/FetchingWrappedInlineEntryCard.js +19 -17
- package/dist/cjs/plugins/EmbeddedEntityInline/LinkedEntityInline.js +9 -7
- package/dist/cjs/plugins/EmbeddedResourceBlock/LinkedResourceBlock.js +5 -5
- package/dist/cjs/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +13 -11
- package/dist/cjs/plugins/EmbeddedResourceInline/LinkedResourceInline.js +5 -5
- package/dist/cjs/plugins/Heading/__tests__/createHeadingPlugin.test.js +32 -32
- package/dist/cjs/plugins/Heading/components/Heading.js +13 -10
- package/dist/cjs/plugins/Heading/components/ToolbarHeadingButton.js +19 -11
- package/dist/cjs/plugins/Heading/createHeadingPlugin.js +7 -2
- package/dist/cjs/plugins/Hr/index.js +19 -14
- package/dist/cjs/plugins/Hyperlink/HyperlinkModal.js +32 -28
- package/dist/cjs/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +8 -8
- package/dist/cjs/plugins/Hyperlink/components/EntityHyperlink.js +8 -6
- package/dist/cjs/plugins/Hyperlink/components/ResourceHyperlink.js +8 -6
- package/dist/cjs/plugins/Hyperlink/components/ToolbarHyperlinkButton.js +6 -4
- package/dist/cjs/plugins/Hyperlink/components/UrlHyperlink.js +7 -5
- package/dist/cjs/plugins/Hyperlink/components/styles.js +1 -1
- package/dist/cjs/plugins/Hyperlink/createHyperlinkPlugin.js +10 -4
- package/dist/cjs/plugins/Hyperlink/useEntityInfo.js +6 -3
- package/dist/cjs/plugins/Hyperlink/useResourceEntityInfo.js +6 -4
- package/dist/cjs/plugins/Hyperlink/utils.js +4 -4
- package/dist/cjs/plugins/List/__tests__/createListPlugin.test.js +13 -13
- package/dist/cjs/plugins/List/__tests__/insertListBreak.test.js +29 -25
- package/dist/cjs/plugins/List/__tests__/insertListFragment.test.js +22 -22
- package/dist/cjs/plugins/List/components/List.js +9 -7
- package/dist/cjs/plugins/List/components/ListItem.js +6 -4
- package/dist/cjs/plugins/List/components/ToolbarListButton.js +7 -5
- package/dist/cjs/plugins/List/createListPlugin.js +4 -0
- package/dist/cjs/plugins/List/insertListBreak.js +13 -4
- package/dist/cjs/plugins/List/insertListFragment.js +18 -5
- package/dist/cjs/plugins/List/onKeyDownList.js +7 -4
- package/dist/cjs/plugins/List/transforms/insertListItem.js +17 -2
- package/dist/cjs/plugins/List/transforms/moveListItemDown.js +8 -2
- package/dist/cjs/plugins/List/transforms/moveListItems.js +7 -2
- package/dist/cjs/plugins/List/transforms/moveListItems.test.js +15 -14
- package/dist/cjs/plugins/List/transforms/toggleList.js +8 -3
- package/dist/cjs/plugins/List/transforms/toggleList.spec.js +28 -28
- package/dist/cjs/plugins/List/transforms/unwrapList.js +7 -2
- package/dist/cjs/plugins/List/utils.js +12 -11
- package/dist/cjs/plugins/List/withList.js +6 -2
- package/dist/cjs/plugins/Marks/Bold.js +9 -7
- package/dist/cjs/plugins/Marks/Code.js +15 -7
- package/dist/cjs/plugins/Marks/Italic.js +9 -7
- package/dist/cjs/plugins/Marks/Subscript.js +10 -8
- package/dist/cjs/plugins/Marks/Superscript.js +10 -8
- package/dist/cjs/plugins/Marks/Underline.js +6 -4
- package/dist/cjs/plugins/Marks/components/MarkToolbarButton.js +9 -7
- package/dist/cjs/plugins/Marks/helpers.js +5 -5
- package/dist/cjs/plugins/Normalizer/baseRules.js +2 -0
- package/dist/cjs/plugins/Normalizer/createNormalizerPlugin.test.js +12 -12
- package/dist/cjs/plugins/Normalizer/utils.js +4 -3
- package/dist/cjs/plugins/Normalizer/withNormalizer.js +23 -3
- package/dist/cjs/plugins/Paragraph/Paragraph.js +6 -4
- package/dist/cjs/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +32 -32
- package/dist/cjs/plugins/Paragraph/createParagraphPlugin.js +3 -2
- package/dist/cjs/plugins/PasteHTML/createPasteHTMLPlugin.js +9 -6
- package/dist/cjs/plugins/PasteHTML/utils/__tests__/sanitizeHTML.test.js +2 -0
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeAnchors.js +9 -0
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeHTML.js +17 -2
- package/dist/cjs/plugins/PasteHTML/utils/sanitizeSheets.js +13 -1
- package/dist/cjs/plugins/Quote/__test__/createQuotePlugin.test.js +21 -21
- package/dist/cjs/plugins/Quote/components/Quote.js +6 -4
- package/dist/cjs/plugins/Quote/components/ToolbarQuoteButton.js +6 -4
- package/dist/cjs/plugins/Quote/createQuotePlugin.js +1 -0
- package/dist/cjs/plugins/Quote/toggleQuote.js +5 -5
- package/dist/cjs/plugins/Quote/withQuote.js +4 -2
- package/dist/cjs/plugins/SelectOnBackspace/createSelectOnBackspacePlugin.js +1 -0
- package/dist/cjs/plugins/Table/__tests__/createTablePlugin.test.js +22 -22
- package/dist/cjs/plugins/Table/__tests__/helpers.test.js +4 -4
- package/dist/cjs/plugins/Table/actions/addColumn.js +5 -4
- package/dist/cjs/plugins/Table/actions/addRow.js +6 -3
- package/dist/cjs/plugins/Table/components/Cell.js +7 -5
- package/dist/cjs/plugins/Table/components/HeaderCell.js +7 -5
- package/dist/cjs/plugins/Table/components/Row.js +6 -4
- package/dist/cjs/plugins/Table/components/Table.js +8 -6
- package/dist/cjs/plugins/Table/components/TableActions.js +19 -16
- package/dist/cjs/plugins/Table/components/ToolbarButton.js +7 -4
- package/dist/cjs/plugins/Table/createTablePlugin.js +11 -1
- package/dist/cjs/plugins/Table/helpers.js +16 -12
- package/dist/cjs/plugins/Table/insertTableFragment.js +15 -2
- package/dist/cjs/plugins/Table/onKeyDownTable.js +10 -2
- package/dist/cjs/plugins/Table/tableTracking.js +6 -6
- package/dist/cjs/plugins/Text/__tests__/createTextPlugin.test.js +19 -17
- package/dist/cjs/plugins/Text/createTextPlugin.js +22 -5
- package/dist/cjs/plugins/Tracking/createTrackingPlugin.js +5 -4
- package/dist/cjs/plugins/Tracking/utils.js +6 -3
- package/dist/cjs/plugins/Voids/createVoidsPlugin.js +5 -0
- package/dist/cjs/plugins/Voids/transformVoid.js +1 -0
- package/dist/cjs/plugins/index.js +15 -3
- package/dist/cjs/plugins/shared/EmbeddedBlockToolbarIcon.js +12 -10
- package/dist/cjs/plugins/shared/EmbeddedBlockUtil.js +16 -6
- package/dist/cjs/plugins/shared/EmbeddedInlineToolbarIcon.js +10 -8
- package/dist/cjs/plugins/shared/EmbeddedInlineUtil.js +9 -5
- package/dist/cjs/plugins/shared/FetchingWrappedAssetCard.js +13 -11
- package/dist/cjs/plugins/shared/FetchingWrappedEntryCard.js +14 -12
- package/dist/cjs/plugins/shared/FetchingWrappedResourceCard.js +14 -11
- package/dist/cjs/plugins/shared/LinkedBlockWrapper.js +8 -4
- package/dist/cjs/plugins/shared/LinkedInlineWrapper.js +10 -6
- package/dist/cjs/plugins/shared/ResourceNewBadge.js +5 -3
- package/dist/cjs/plugins/shared/ToolbarButton.js +8 -6
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedAssetCard.test.js +10 -5
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedEntryCard.test.js +11 -6
- package/dist/cjs/plugins/shared/__tests__/FetchingWrappedResourceCard.test.js +15 -13
- package/dist/cjs/plugins/shared/utils.js +4 -1
- package/dist/cjs/test-utils/assertOutput.js +1 -0
- package/dist/cjs/test-utils/hyperscript.d.js +1 -0
- package/dist/cjs/test-utils/randomId.js +3 -1
- package/dist/cjs/test-utils/validation.js +8 -5
- package/dist/esm/ContentfulEditorProvider.js +4 -1
- package/dist/esm/RichTextEditor.js +13 -13
- package/dist/esm/RichTextEditor.styles.js +1 -0
- package/dist/esm/SdkProvider.js +2 -2
- package/dist/esm/SyncEditorChanges.js +18 -3
- package/dist/esm/Toolbar/_tests_/toolbar.test.js +12 -12
- package/dist/esm/Toolbar/components/EmbedEntityWidget.js +10 -8
- package/dist/esm/Toolbar/components/EmbeddedEntityDropdownButton.js +6 -6
- package/dist/esm/Toolbar/components/StickyToolbarWrapper.js +1 -1
- package/dist/esm/Toolbar/index.js +28 -27
- package/dist/esm/__fixtures__/FakeSdk.js +3 -3
- package/dist/esm/constants/Schema.js +1 -0
- package/dist/esm/dialogs/HypelinkDialog/HyperlinkDialog.js +34 -31
- package/dist/esm/dialogs/openRichTextDialog.js +2 -2
- package/dist/esm/dialogs/renderRichTextDialog.js +2 -2
- package/dist/esm/helpers/__tests__/removeInternalMarks.test.js +10 -10
- package/dist/esm/helpers/callbacks.js +1 -1
- package/dist/esm/helpers/config.js +9 -1
- package/dist/esm/helpers/editor.js +22 -6
- package/dist/esm/helpers/extractNodes.js +3 -1
- package/dist/esm/helpers/formatDateAndTime.js +11 -2
- package/dist/esm/helpers/getAllowedResourcesForNodeType.js +19 -2
- package/dist/esm/helpers/getLinkedContentTypeIdsForNodeType.js +26 -2
- package/dist/esm/helpers/sdkNavigatorSlideIn.js +20 -6
- package/dist/esm/helpers/sdkNavigatorSlideIn.spec.js +1 -0
- package/dist/esm/helpers/toSlateValue.js +17 -3
- package/dist/esm/helpers/validations.js +5 -1
- package/dist/esm/internal/misc.js +23 -2
- package/dist/esm/internal/queries.js +11 -2
- package/dist/esm/internal/transforms.js +14 -3
- package/dist/esm/internal/types/editor.js +3 -1
- package/dist/esm/plugins/Break/createExitBreakPlugin.test.js +4 -3
- package/dist/esm/plugins/Break/createResetNodePlugin.js +1 -0
- package/dist/esm/plugins/Break/createSoftBreakPlugin.test.js +3 -3
- package/dist/esm/plugins/CommandPalette/components/CommandList.js +30 -30
- package/dist/esm/plugins/CommandPalette/components/CommandPrompt.js +2 -2
- package/dist/esm/plugins/CommandPalette/createCommandPalettePlugin.js +11 -1
- package/dist/esm/plugins/CommandPalette/hooks/useCommandList.js +2 -0
- package/dist/esm/plugins/CommandPalette/onKeyDown.js +5 -0
- package/dist/esm/plugins/CommandPalette/onKeyDown.spec.js +2 -2
- package/dist/esm/plugins/CommandPalette/useCommands.js +3 -3
- package/dist/esm/plugins/CommandPalette/utils/fetchEntries.js +2 -0
- package/dist/esm/plugins/CommandPalette/utils/trimLeadingSlash.js +6 -1
- package/dist/esm/plugins/DragAndDrop/index.js +9 -1
- package/dist/esm/plugins/EmbeddedEntityBlock/LinkedEntityBlock.js +6 -6
- package/dist/esm/plugins/EmbeddedEntityInline/FetchingWrappedInlineEntryCard.js +14 -14
- package/dist/esm/plugins/EmbeddedEntityInline/LinkedEntityInline.js +5 -5
- package/dist/esm/plugins/EmbeddedResourceBlock/LinkedResourceBlock.js +4 -4
- package/dist/esm/plugins/EmbeddedResourceInline/FetchingWrappedResourceInlineCard.js +9 -9
- package/dist/esm/plugins/EmbeddedResourceInline/LinkedResourceInline.js +4 -4
- package/dist/esm/plugins/Heading/__tests__/createHeadingPlugin.test.js +32 -32
- package/dist/esm/plugins/Heading/components/Heading.js +8 -7
- package/dist/esm/plugins/Heading/components/ToolbarHeadingButton.js +14 -8
- package/dist/esm/plugins/Heading/createHeadingPlugin.js +6 -1
- package/dist/esm/plugins/Hr/index.js +8 -5
- package/dist/esm/plugins/Hyperlink/HyperlinkModal.js +25 -23
- package/dist/esm/plugins/Hyperlink/__tests__/createHyperlinkPlugin.test.js +8 -8
- package/dist/esm/plugins/Hyperlink/components/EntityHyperlink.js +4 -4
- package/dist/esm/plugins/Hyperlink/components/ResourceHyperlink.js +4 -4
- package/dist/esm/plugins/Hyperlink/components/ToolbarHyperlinkButton.js +2 -2
- package/dist/esm/plugins/Hyperlink/components/UrlHyperlink.js +3 -3
- package/dist/esm/plugins/Hyperlink/createHyperlinkPlugin.js +5 -1
- package/dist/esm/plugins/Hyperlink/useEntityInfo.js +6 -3
- package/dist/esm/plugins/Hyperlink/useResourceEntityInfo.js +2 -2
- package/dist/esm/plugins/Hyperlink/utils.js +1 -1
- package/dist/esm/plugins/List/__tests__/createListPlugin.test.js +13 -13
- package/dist/esm/plugins/List/__tests__/insertListBreak.test.js +29 -25
- package/dist/esm/plugins/List/__tests__/insertListFragment.test.js +22 -22
- package/dist/esm/plugins/List/components/List.js +1 -1
- package/dist/esm/plugins/List/components/ListItem.js +1 -1
- package/dist/esm/plugins/List/components/ToolbarListButton.js +3 -3
- package/dist/esm/plugins/List/createListPlugin.js +4 -0
- package/dist/esm/plugins/List/insertListBreak.js +13 -4
- package/dist/esm/plugins/List/insertListFragment.js +18 -5
- package/dist/esm/plugins/List/onKeyDownList.js +5 -2
- package/dist/esm/plugins/List/transforms/insertListItem.js +20 -3
- package/dist/esm/plugins/List/transforms/moveListItemDown.js +8 -2
- package/dist/esm/plugins/List/transforms/moveListItems.js +7 -2
- package/dist/esm/plugins/List/transforms/moveListItems.test.js +15 -14
- package/dist/esm/plugins/List/transforms/toggleList.js +8 -3
- package/dist/esm/plugins/List/transforms/toggleList.spec.js +28 -28
- package/dist/esm/plugins/List/transforms/unwrapList.js +7 -2
- package/dist/esm/plugins/List/utils.js +7 -2
- package/dist/esm/plugins/List/withList.js +6 -2
- package/dist/esm/plugins/Marks/Bold.js +2 -2
- package/dist/esm/plugins/Marks/Code.js +8 -2
- package/dist/esm/plugins/Marks/Italic.js +2 -2
- package/dist/esm/plugins/Marks/Subscript.js +2 -2
- package/dist/esm/plugins/Marks/Superscript.js +2 -2
- package/dist/esm/plugins/Marks/Underline.js +2 -2
- package/dist/esm/plugins/Marks/components/MarkToolbarButton.js +4 -4
- package/dist/esm/plugins/Marks/helpers.js +1 -1
- package/dist/esm/plugins/Normalizer/baseRules.js +4 -0
- package/dist/esm/plugins/Normalizer/createNormalizerPlugin.test.js +12 -12
- package/dist/esm/plugins/Normalizer/utils.js +1 -0
- package/dist/esm/plugins/Normalizer/withNormalizer.js +22 -2
- package/dist/esm/plugins/Paragraph/Paragraph.js +1 -1
- package/dist/esm/plugins/Paragraph/__tests__/createParagraphPlugin.test.js +32 -32
- package/dist/esm/plugins/Paragraph/createParagraphPlugin.js +2 -1
- package/dist/esm/plugins/PasteHTML/createPasteHTMLPlugin.js +9 -3
- package/dist/esm/plugins/PasteHTML/utils/__tests__/sanitizeHTML.test.js +2 -0
- package/dist/esm/plugins/PasteHTML/utils/sanitizeAnchors.js +27 -1
- package/dist/esm/plugins/PasteHTML/utils/sanitizeHTML.js +17 -2
- package/dist/esm/plugins/PasteHTML/utils/sanitizeSheets.js +13 -1
- package/dist/esm/plugins/Quote/__test__/createQuotePlugin.test.js +21 -21
- package/dist/esm/plugins/Quote/components/Quote.js +1 -1
- package/dist/esm/plugins/Quote/components/ToolbarQuoteButton.js +2 -2
- package/dist/esm/plugins/Quote/createQuotePlugin.js +1 -0
- package/dist/esm/plugins/Quote/shouldResetQuote.js +6 -1
- package/dist/esm/plugins/Quote/toggleQuote.js +1 -1
- package/dist/esm/plugins/Quote/withQuote.js +4 -2
- package/dist/esm/plugins/SelectOnBackspace/createSelectOnBackspacePlugin.js +1 -0
- package/dist/esm/plugins/Table/__tests__/createTablePlugin.test.js +22 -22
- package/dist/esm/plugins/Table/__tests__/helpers.test.js +4 -4
- package/dist/esm/plugins/Table/actions/addColumn.js +2 -1
- package/dist/esm/plugins/Table/actions/addRow.js +3 -0
- package/dist/esm/plugins/Table/components/Cell.js +2 -2
- package/dist/esm/plugins/Table/components/HeaderCell.js +2 -2
- package/dist/esm/plugins/Table/components/Row.js +1 -1
- package/dist/esm/plugins/Table/components/Table.js +3 -3
- package/dist/esm/plugins/Table/components/TableActions.js +12 -11
- package/dist/esm/plugins/Table/components/ToolbarButton.js +3 -2
- package/dist/esm/plugins/Table/createTablePlugin.js +11 -1
- package/dist/esm/plugins/Table/helpers.js +10 -1
- package/dist/esm/plugins/Table/insertTableFragment.js +15 -2
- package/dist/esm/plugins/Table/onKeyDownTable.js +10 -2
- package/dist/esm/plugins/Table/tableTracking.js +6 -6
- package/dist/esm/plugins/Text/__tests__/createTextPlugin.test.js +19 -17
- package/dist/esm/plugins/Text/createTextPlugin.js +22 -5
- package/dist/esm/plugins/Tracking/createTrackingPlugin.js +2 -1
- package/dist/esm/plugins/Tracking/utils.js +1 -0
- package/dist/esm/plugins/Voids/createVoidsPlugin.js +5 -0
- package/dist/esm/plugins/Voids/transformVoid.js +4 -1
- package/dist/esm/plugins/index.js +12 -0
- package/dist/esm/plugins/shared/EmbeddedBlockToolbarIcon.js +5 -5
- package/dist/esm/plugins/shared/EmbeddedBlockUtil.js +15 -5
- package/dist/esm/plugins/shared/EmbeddedInlineToolbarIcon.js +5 -5
- package/dist/esm/plugins/shared/EmbeddedInlineUtil.js +8 -4
- package/dist/esm/plugins/shared/FetchingWrappedAssetCard.js +8 -8
- package/dist/esm/plugins/shared/FetchingWrappedEntryCard.js +9 -9
- package/dist/esm/plugins/shared/FetchingWrappedResourceCard.js +9 -8
- package/dist/esm/plugins/shared/LinkedBlockWrapper.js +7 -3
- package/dist/esm/plugins/shared/LinkedInlineWrapper.js +5 -3
- package/dist/esm/plugins/shared/ResourceNewBadge.js +1 -1
- package/dist/esm/plugins/shared/ToolbarButton.js +3 -3
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedAssetCard.test.js +5 -2
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedEntryCard.test.js +5 -2
- package/dist/esm/plugins/shared/__tests__/FetchingWrappedResourceCard.test.js +8 -8
- package/dist/esm/plugins/shared/utils.js +4 -1
- package/dist/esm/test-utils/assertOutput.js +1 -0
- package/dist/esm/test-utils/hyperscript.d.js +1 -0
- package/dist/esm/test-utils/jsx.js +5 -1
- package/dist/esm/test-utils/randomId.js +3 -1
- package/dist/esm/test-utils/setEmptyDataAttribute.js +4 -1
- package/dist/esm/test-utils/validation.js +7 -4
- package/package.json +2 -2
|
@@ -67,7 +67,11 @@ export function insertEmptyParagraph(editor, options) {
|
|
|
67
67
|
export function getElementFromCurrentSelection(editor) {
|
|
68
68
|
if (!editor.selection) return [];
|
|
69
69
|
return Array.from(getNodeEntries(editor, {
|
|
70
|
-
|
|
70
|
+
/**
|
|
71
|
+
* editor.select is a Range, which includes anchor and focus, the beginning and the end of a selection
|
|
72
|
+
* when using only editor.selection.focus, we might get only the end of the selection, or where the text cursor is
|
|
73
|
+
* and in some cases getting the next element instead of the one we want
|
|
74
|
+
**/ at: editor.selection,
|
|
71
75
|
match: (node)=>isElement(node)
|
|
72
76
|
})).flat();
|
|
73
77
|
}
|
|
@@ -88,11 +92,13 @@ export function getTableSize(table) {
|
|
|
88
92
|
numColumns
|
|
89
93
|
};
|
|
90
94
|
}
|
|
95
|
+
// TODO: move to hyperlink plugin
|
|
91
96
|
export function insertLink(editor, options) {
|
|
92
97
|
if (editor.selection) {
|
|
93
98
|
wrapLink(editor, options);
|
|
94
99
|
}
|
|
95
100
|
}
|
|
101
|
+
// TODO: move to hyperlink plugin
|
|
96
102
|
export function isLinkActive(editor) {
|
|
97
103
|
if (!editor) {
|
|
98
104
|
return false;
|
|
@@ -102,16 +108,18 @@ export function isLinkActive(editor) {
|
|
|
102
108
|
}));
|
|
103
109
|
return !!link;
|
|
104
110
|
}
|
|
111
|
+
// TODO: move to hyperlink plugin
|
|
105
112
|
export function unwrapLink(editor) {
|
|
106
113
|
unwrapNodes(editor, {
|
|
107
114
|
match: (node)=>!isEditor(node) && isElement(node) && LINK_TYPES.includes(node.type)
|
|
108
115
|
});
|
|
109
116
|
}
|
|
110
|
-
|
|
117
|
+
// TODO: move to hyperlink plugin
|
|
118
|
+
export function wrapLink(editor, { text, url, target, type, path }) {
|
|
111
119
|
if (isLinkActive(editor) && !path) {
|
|
112
120
|
unwrapLink(editor);
|
|
113
121
|
}
|
|
114
|
-
const { selection
|
|
122
|
+
const { selection } = editor;
|
|
115
123
|
const isCollapsed = selection && isSelectionCollapsed(selection);
|
|
116
124
|
const link = {
|
|
117
125
|
type,
|
|
@@ -132,6 +140,7 @@ export function wrapLink(editor, { text , url , target , type , path }) {
|
|
|
132
140
|
target
|
|
133
141
|
};
|
|
134
142
|
}
|
|
143
|
+
// TODO: always set the selection to the end of the inserted link
|
|
135
144
|
if (path) {
|
|
136
145
|
setNodes(editor, link, {
|
|
137
146
|
at: path
|
|
@@ -158,15 +167,19 @@ export function getAncestorPathFromSelection(editor) {
|
|
|
158
167
|
return getPathLevels(editor.selection.focus.path).find((level)=>level.length === 1);
|
|
159
168
|
}
|
|
160
169
|
export const isAtEndOfTextSelection = (editor)=>editor.selection?.focus.offset === getText(editor, editor.selection?.focus.path).length;
|
|
161
|
-
|
|
170
|
+
/**
|
|
171
|
+
* This traversal strategy is unfortunately necessary because Slate doesn't
|
|
172
|
+
* expose something like Node.next(editor).
|
|
173
|
+
*/ export function getNextNode(editor) {
|
|
162
174
|
if (!editor.selection) {
|
|
163
175
|
return null;
|
|
164
176
|
}
|
|
165
177
|
const descendants = getNodeDescendants(editor, {
|
|
166
178
|
from: editor.selection.focus.path
|
|
167
179
|
});
|
|
180
|
+
// eslint-disable-next-line no-constant-condition -- TODO: explain this disable
|
|
168
181
|
while(true){
|
|
169
|
-
const { done
|
|
182
|
+
const { done, value } = descendants.next();
|
|
170
183
|
if (done) {
|
|
171
184
|
return null;
|
|
172
185
|
}
|
|
@@ -179,20 +192,23 @@ export function getNextNode(editor) {
|
|
|
179
192
|
}
|
|
180
193
|
export const INLINE_TYPES = Object.values(INLINES);
|
|
181
194
|
export const isInlineOrText = (node)=>{
|
|
195
|
+
// either text or inline elements
|
|
182
196
|
return isText(node) || isElement(node) && INLINE_TYPES.includes(node.type);
|
|
183
197
|
};
|
|
184
198
|
export const focus = (editor)=>{
|
|
185
199
|
const x = window.scrollX;
|
|
186
200
|
const y = window.scrollY;
|
|
187
201
|
focusEditor(editor);
|
|
202
|
+
// Safari has issues with `editor.focus({ preventScroll: true })`, it ignores the option `preventScroll`
|
|
188
203
|
if (IS_SAFARI) {
|
|
189
204
|
setTimeout(function() {
|
|
190
|
-
window.scrollTo(x, y);
|
|
205
|
+
window.scrollTo(x, y); // restore position
|
|
191
206
|
}, 0);
|
|
192
207
|
}
|
|
193
208
|
};
|
|
194
209
|
export function toggleElement(editor, options, editorOptions) {
|
|
195
210
|
toggleNodeType(editor, options, editorOptions);
|
|
211
|
+
// We must reset `data` from one element to another
|
|
196
212
|
setNodes(editor, {
|
|
197
213
|
data: {}
|
|
198
214
|
});
|
|
@@ -7,7 +7,9 @@ function extractNodes(editor, path, match) {
|
|
|
7
7
|
mode: 'lowest'
|
|
8
8
|
})).map(([node])=>node);
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* It filters out all paragraphs and headings from a path and convert them into paragraphs.
|
|
12
|
+
*/ export function extractParagraphs(editor, path) {
|
|
11
13
|
return extractNodes(editor, path, {
|
|
12
14
|
type: TEXT_CONTAINERS
|
|
13
15
|
}).map((node)=>({
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: explain this disable
|
|
1
2
|
import moment from 'moment';
|
|
2
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @param {Date|string} date A valid constructor argument for moment()
|
|
5
|
+
* @param {boolean=} short Render only Today/Tomorrow/Yesterday if valid. Defaults to false
|
|
6
|
+
*/ export const formatDate = (date, short)=>{
|
|
3
7
|
switch(moment().startOf('day').diff(moment(date).startOf('day'), 'days')){
|
|
4
8
|
case 0:
|
|
5
9
|
return short ? 'Today' : `Today, ${moment(date).format('DD MMM YYYY')}`;
|
|
@@ -11,7 +15,12 @@ export const formatDate = (date, short)=>{
|
|
|
11
15
|
return moment(date).format('ddd, DD MMM YYYY');
|
|
12
16
|
}
|
|
13
17
|
};
|
|
14
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Returns the time portion of a date in the local time in the format H:MM AM/PM
|
|
20
|
+
*
|
|
21
|
+
* == Examples
|
|
22
|
+
* * `T15:36:45.000Z` => 3:36 PM (if in +0:00 offset)
|
|
23
|
+
*/ export const formatTime = (date)=>{
|
|
15
24
|
return moment.utc(date).local().format('h:mm A');
|
|
16
25
|
};
|
|
17
26
|
export const formatDateAndTime = (date, short)=>{
|
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import find from 'lodash/find';
|
|
1
|
+
/* eslint-disable you-dont-need-lodash-underscore/find */ import find from 'lodash/find';
|
|
2
2
|
import flow from 'lodash/flow';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Given a field object and a rich text node type, return a list of allowed
|
|
6
|
+
* resources associated with the node type, based on that node type's
|
|
7
|
+
* `allowedResources` property.
|
|
8
|
+
*
|
|
9
|
+
* The navigation here is explained by the `nodes` validation having signature:
|
|
10
|
+
* { nodes: { [nodeType]: { allowedResources: AllowedResource[] } } }
|
|
11
|
+
*
|
|
12
|
+
* We defensively navigate through this object because
|
|
13
|
+
* 1) the field may not have a `validations` array,
|
|
14
|
+
* 2) the `validations` array may be empty,
|
|
15
|
+
* 3) the `validations` array may not have a `nodes` validation, and
|
|
16
|
+
* 4) the `nodes` validation may not validate the `nodeType`.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} field
|
|
19
|
+
* @param {string} nodeType
|
|
20
|
+
* @returns {AllowedResource[]}
|
|
21
|
+
*/ export default function getAllowedResourcesForNodeType(field, nodeType) {
|
|
5
22
|
return flow((validations)=>find(validations, 'nodes'), (validations)=>get(validations, [
|
|
6
23
|
'nodes',
|
|
7
24
|
nodeType,
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
import find from 'lodash/find';
|
|
1
|
+
/* eslint-disable you-dont-need-lodash-underscore/find */ import find from 'lodash/find';
|
|
2
2
|
import flow from 'lodash/flow';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Given a field object and a rich text node type, return a list of valid
|
|
6
|
+
* content type IDs associated with the node type, based on that node type's
|
|
7
|
+
* `linkContentType` validation.
|
|
8
|
+
*
|
|
9
|
+
* If there is no such validation or the validation is empty, return an empty
|
|
10
|
+
* array.
|
|
11
|
+
*
|
|
12
|
+
* The navigation here is explained by the `nodes` validation having signature:
|
|
13
|
+
* { nodes: { [nodeType]: validationObject[] } }
|
|
14
|
+
*
|
|
15
|
+
* We defensively navigate through this object because
|
|
16
|
+
* 1) the field may not have a `validations` array,
|
|
17
|
+
* 2) the `validations` array may be empty,
|
|
18
|
+
* 3) the `validations` array may not have a `nodes` validation,
|
|
19
|
+
* 4) the `nodes` validation may not validate the `nodeType`, and
|
|
20
|
+
* 5) the `nodeType` validations may not have a `linkContentType` validation.
|
|
21
|
+
*
|
|
22
|
+
* Note that passing an empty array will result in all possible content types
|
|
23
|
+
* being whitelisted.
|
|
24
|
+
*
|
|
25
|
+
* @param {object} field
|
|
26
|
+
* @param {string} nodeType
|
|
27
|
+
* @returns {string[]}
|
|
28
|
+
*/ export default function getLinkedContentTypeIdsForNodeType(field, nodeType) {
|
|
5
29
|
return flow((v)=>find(v, 'nodes'), (v)=>get(v, [
|
|
6
30
|
'nodes',
|
|
7
31
|
nodeType
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import noop from 'lodash/noop';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Allows to observe when the current slide-in navigation slide gets e.g.
|
|
4
|
+
* re-activated after opening another slide on top. This is useful as the sdk
|
|
5
|
+
* does not give full insights into e.g. whether sdk.dialogs.selectSingleEntry()
|
|
6
|
+
* with `withCreate: true` option opens the slide-in navigation to edit the
|
|
7
|
+
* created entry after returning it.
|
|
8
|
+
*/ export function watchCurrentSlide(navigator) {
|
|
3
9
|
const onActiveCallbacks = new Set();
|
|
4
10
|
let wasSlideClosed = false;
|
|
5
11
|
let initialSlideLevel;
|
|
@@ -8,26 +14,34 @@ export function watchCurrentSlide(navigator) {
|
|
|
8
14
|
wasClosed: wasSlideClosed,
|
|
9
15
|
isActive: !wasSlideClosed && lastSlideLevel === initialSlideLevel
|
|
10
16
|
});
|
|
11
|
-
const off = navigator.onSlideInNavigation(({ oldSlideLevel
|
|
17
|
+
const off = navigator.onSlideInNavigation(({ oldSlideLevel, newSlideLevel })=>{
|
|
12
18
|
if (initialSlideLevel === undefined) {
|
|
13
19
|
initialSlideLevel = oldSlideLevel;
|
|
14
20
|
}
|
|
15
21
|
lastSlideLevel = newSlideLevel;
|
|
16
22
|
if (newSlideLevel < initialSlideLevel) {
|
|
17
23
|
wasSlideClosed = true;
|
|
18
|
-
off();
|
|
24
|
+
off(); // No more point in watching, slide got closed.
|
|
19
25
|
onActiveCallbacks.clear();
|
|
20
26
|
}
|
|
21
27
|
if (status().isActive && newSlideLevel !== oldSlideLevel) {
|
|
22
28
|
onActiveCallbacks.forEach((cb)=>cb());
|
|
23
29
|
}
|
|
24
30
|
});
|
|
25
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Call to unsubscribe from navigator events when the watcher is no longer
|
|
33
|
+
* needed.
|
|
34
|
+
*/ function unwatch() {
|
|
26
35
|
off();
|
|
27
36
|
onActiveCallbacks.clear();
|
|
28
37
|
}
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Fires immediately when the slide is currently active, or at the point when
|
|
40
|
+
* it becomes active again, if there are slides on top that get closed. Does not
|
|
41
|
+
* fire when the observed slide gets closed, and then re-opened through browser
|
|
42
|
+
* back, as this technically opens a new slide and editor instance.
|
|
43
|
+
*/ function onActive(cb) {
|
|
44
|
+
if (wasSlideClosed) return noop; // Can't re-activate already closed slide.
|
|
31
45
|
if (status().isActive) {
|
|
32
46
|
cb();
|
|
33
47
|
}
|
|
@@ -195,6 +195,7 @@ describe('watchCurrentSlide().unwatch()', ()=>{
|
|
|
195
195
|
newSlideLevel: 0
|
|
196
196
|
});
|
|
197
197
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
198
|
+
// Demonstrate that normally this would fire an event if it wasn't for the unwatch()
|
|
198
199
|
expect(spy2).toHaveBeenCalledTimes(1);
|
|
199
200
|
});
|
|
200
201
|
});
|
|
@@ -2,7 +2,10 @@ import { toSlatejsDocument } from '@contentful/contentful-slatejs-adapter';
|
|
|
2
2
|
import { EMPTY_DOCUMENT } from '@contentful/rich-text-types';
|
|
3
3
|
import schema from '../constants/Schema';
|
|
4
4
|
const isTextElement = (node)=>'text' in node;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Ensures all nodes have a child leaf text element. This should be handled by
|
|
7
|
+
* Slate but its behavior has proven to be buggy and unpredictable.
|
|
8
|
+
*/ function sanitizeIncomingSlateDoc(nodes = []) {
|
|
6
9
|
return nodes.map((node)=>{
|
|
7
10
|
if (isTextElement(node)) {
|
|
8
11
|
return node;
|
|
@@ -24,12 +27,23 @@ function sanitizeIncomingSlateDoc(nodes = []) {
|
|
|
24
27
|
};
|
|
25
28
|
});
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Converts a Contentful rich text document to the corresponding slate editor
|
|
32
|
+
* value
|
|
33
|
+
*/ export const toSlateValue = (doc)=>{
|
|
34
|
+
/**
|
|
35
|
+
* For legacy reasons, a document may not have any content at all
|
|
36
|
+
* e.g:
|
|
37
|
+
*
|
|
38
|
+
* {nodeType: document, data: {}, content: []}
|
|
39
|
+
*
|
|
40
|
+
* Rendering such document will break the Slate editor
|
|
41
|
+
*/ const hasContent = (doc)=>{
|
|
29
42
|
return (doc?.content || []).length > 0;
|
|
30
43
|
};
|
|
31
44
|
const slateDoc = toSlatejsDocument({
|
|
32
45
|
document: doc && hasContent(doc) ? doc : EMPTY_DOCUMENT,
|
|
46
|
+
// TODO: get rid of schema, https://github.com/contentful/field-editors/pull/1065#discussion_r826723248
|
|
33
47
|
schema
|
|
34
48
|
});
|
|
35
49
|
return sanitizeIncomingSlateDoc(slateDoc);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BLOCKS, INLINES, TOP_LEVEL_BLOCKS } from '@contentful/rich-text-types';
|
|
1
|
+
/* eslint-disable you-dont-need-lodash-underscore/find */ import { BLOCKS, INLINES, TOP_LEVEL_BLOCKS } from '@contentful/rich-text-types';
|
|
2
2
|
import find from 'lodash/find';
|
|
3
3
|
import flow from 'lodash/flow';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
|
+
// TODO: Move these into separate package (maybe rich-text-types) and share with FE.
|
|
5
6
|
export const VALIDATIONS = {
|
|
6
7
|
ENABLED_MARKS: 'enabledMarks',
|
|
7
8
|
ENABLED_NODE_TYPES: 'enabledNodeTypes'
|
|
@@ -12,9 +13,12 @@ export const DEFAULT_ENABLED_NODE_TYPES = [
|
|
|
12
13
|
'text'
|
|
13
14
|
];
|
|
14
15
|
export const VALIDATABLE_NODE_TYPES = [].concat(TOP_LEVEL_BLOCKS).filter((type)=>type !== BLOCKS.PARAGRAPH).concat(Object.values(INLINES));
|
|
16
|
+
// TODO: Memoize
|
|
15
17
|
const getRichTextValidation = (field, validationType)=>flow((v)=>find(v, validationType), (v)=>get(v, validationType))(field.validations);
|
|
16
18
|
const isFormattingOptionEnabled = (field, validationType, nodeTypeOrMark)=>{
|
|
17
19
|
const enabledFormattings = getRichTextValidation(field, validationType);
|
|
20
|
+
// TODO: In the future, validations will always be opt-in. In that case
|
|
21
|
+
// we don't need this step.
|
|
18
22
|
if (enabledFormattings === undefined) {
|
|
19
23
|
return true;
|
|
20
24
|
}
|
|
@@ -3,7 +3,27 @@ import { normalize } from './transforms';
|
|
|
3
3
|
export const createPlateEditor = (options = {})=>{
|
|
4
4
|
return p.createPlateEditor(options);
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The only reason for this helper to exist is to run the initial normalization
|
|
8
|
+
* before mounting the Plate editor component which in turn avoids the false
|
|
9
|
+
* trigger of `onChange`.
|
|
10
|
+
*
|
|
11
|
+
* Background:
|
|
12
|
+
*
|
|
13
|
+
* Due to legacy behavior, it's possible to have "valid" RT document (based on
|
|
14
|
+
* the schema from rich-text-types) that doesn't make sense. For example, links
|
|
15
|
+
* with no text nodes?[1]. Solving that requires an initial normalization pass
|
|
16
|
+
* which modifies the slate tree by definition -> triggering onChange.
|
|
17
|
+
*
|
|
18
|
+
* The initial onChange trigger is undesirable as the user may not have touched
|
|
19
|
+
* the RT content yet or the editor is rendered as readonly.
|
|
20
|
+
*
|
|
21
|
+
* Ideally, we should not initialize the editor twice but that's the only
|
|
22
|
+
* way that I could get this to work. Improvements are welcome.
|
|
23
|
+
*
|
|
24
|
+
* [1]: See cypress/e2e/rich-text/.../invalidDocumentNormalizable.js for more
|
|
25
|
+
* examples.
|
|
26
|
+
*/ export const normalizeInitialValue = (options, initialValue)=>{
|
|
7
27
|
const editor = createPlateEditor(options);
|
|
8
28
|
if (initialValue) {
|
|
9
29
|
editor.children = initialValue;
|
|
@@ -29,5 +49,6 @@ export const fromDOMPoint = (editor, domPoint, opts = {
|
|
|
29
49
|
return p.toSlatePoint(editor, domPoint, opts);
|
|
30
50
|
};
|
|
31
51
|
export const mockPlugin = (plugin)=>{
|
|
32
|
-
return p.mockPlugin(
|
|
52
|
+
return p.mockPlugin(// TODO check if there is a way around this ugly casting
|
|
53
|
+
plugin);
|
|
33
54
|
};
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Re-exporting Plate/Slate queries (aka selectors) to reduce
|
|
3
|
+
* the blast radius of version upgrades
|
|
4
|
+
*/ import * as p from '@udecode/plate-common';
|
|
2
5
|
import * as s from 'slate';
|
|
3
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Get text content at location
|
|
8
|
+
*/ export const getText = (editor, at)=>{
|
|
4
9
|
return p.getEditorString(editor, at);
|
|
5
10
|
};
|
|
6
11
|
export const isText = (value)=>{
|
|
@@ -30,6 +35,7 @@ export const getNodeEntry = (editor, at, options)=>{
|
|
|
30
35
|
export const getNodeEntries = (editor, options)=>{
|
|
31
36
|
return p.getNodeEntries(editor, options);
|
|
32
37
|
};
|
|
38
|
+
// TODO: Ancestor may not be the correct type for root
|
|
33
39
|
export const getNodeChildren = (root, path, options)=>{
|
|
34
40
|
return p.getNodeChildren(root, path, options);
|
|
35
41
|
};
|
|
@@ -40,6 +46,7 @@ export const someNode = (editor, options)=>{
|
|
|
40
46
|
return p.someNode(editor, options);
|
|
41
47
|
};
|
|
42
48
|
export const getChildren = (entry)=>{
|
|
49
|
+
// Node.children crashes when given a text node
|
|
43
50
|
if (s.Text.isText(entry[0])) {
|
|
44
51
|
return [];
|
|
45
52
|
}
|
|
@@ -49,6 +56,7 @@ export const isFirstChild = (path)=>{
|
|
|
49
56
|
return p.isFirstChild(path);
|
|
50
57
|
};
|
|
51
58
|
export const getDescendantNodeByPath = (root, path)=>{
|
|
59
|
+
// @ts-expect-error
|
|
52
60
|
return s.Node.get(root, path);
|
|
53
61
|
};
|
|
54
62
|
export const getNodeDescendants = (root, options)=>{
|
|
@@ -60,6 +68,7 @@ export const getNodeDescendants = (root, options)=>{
|
|
|
60
68
|
export const isRangeCollapsed = (range)=>{
|
|
61
69
|
return p.isCollapsed(range);
|
|
62
70
|
};
|
|
71
|
+
// TODO: simplify
|
|
63
72
|
export const isRangeAcrossBlocks = (editor, options)=>{
|
|
64
73
|
return p.isRangeAcrossBlocks(editor, options);
|
|
65
74
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as p from '@udecode/plate-common';
|
|
2
2
|
import { getEndPoint, isNode } from './queries';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Apply editor normalization rules
|
|
5
|
+
*/ export const normalize = (editor, options = {
|
|
4
6
|
force: true
|
|
5
7
|
})=>{
|
|
6
8
|
return p.normalizeEditor(editor, options);
|
|
@@ -8,7 +10,9 @@ export const normalize = (editor, options = {
|
|
|
8
10
|
export const withoutNormalizing = (editor, fn)=>{
|
|
9
11
|
return p.withoutNormalizing(editor, fn);
|
|
10
12
|
};
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Set the selection to a location
|
|
15
|
+
*/ export const setSelection = (editor, props)=>{
|
|
12
16
|
return p.setSelection(editor, props);
|
|
13
17
|
};
|
|
14
18
|
export const select = (editor, location)=>{
|
|
@@ -77,7 +81,14 @@ export const moveNodes = (editor, opts)=>{
|
|
|
77
81
|
export const deleteFragment = (editor, options)=>{
|
|
78
82
|
return p.deleteFragment(editor, options);
|
|
79
83
|
};
|
|
80
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Plate api doesn't allow to modify (easily) the editor value
|
|
86
|
+
* programmatically after the editor instance is created.
|
|
87
|
+
*
|
|
88
|
+
* This function is inspired by:
|
|
89
|
+
* https://github.com/udecode/plate/issues/1269#issuecomment-1057643622
|
|
90
|
+
*/ export const setEditorValue = (editor, nodes)=>{
|
|
91
|
+
// Replaces editor content while keeping change history
|
|
81
92
|
withoutNormalizing(editor, ()=>{
|
|
82
93
|
const children = [
|
|
83
94
|
...editor.children
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { KEY_EXIT_BREAK } from '@udecode/plate-break';
|
|
1
|
+
/** @jsx jsx */ import { KEY_EXIT_BREAK } from '@udecode/plate-break';
|
|
2
2
|
import { jsx, createTestEditor, mockPlugin } from '../../test-utils';
|
|
3
3
|
import { createExitBreakPlugin } from './createExitBreakPlugin';
|
|
4
4
|
describe('Exit Break', ()=>{
|
|
5
|
+
// https://slate-js.slack.com/archives/C013QHXSCG1/p1640853996467300
|
|
5
6
|
it('derives its config from other plugins', ()=>{
|
|
6
|
-
const input = jsx("editor", null, jsx("hp", null, jsx("htext", null)));
|
|
7
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", null)));
|
|
7
8
|
const rules = [
|
|
8
9
|
{
|
|
9
10
|
hotkey: 'enter',
|
|
@@ -14,7 +15,7 @@ describe('Exit Break', ()=>{
|
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
];
|
|
17
|
-
const { editor
|
|
18
|
+
const { editor } = createTestEditor({
|
|
18
19
|
input,
|
|
19
20
|
plugins: [
|
|
20
21
|
mockPlugin({}),
|
|
@@ -8,6 +8,7 @@ export const createResetNodePlugin = ()=>createDefaultResetNodePlugin({
|
|
|
8
8
|
const rules = editor.plugins.flatMap((p)=>{
|
|
9
9
|
return p.resetNode || [];
|
|
10
10
|
});
|
|
11
|
+
// set defaultType to Paragraph if not set
|
|
11
12
|
for (const rule of rules){
|
|
12
13
|
if (!rule.defaultType) {
|
|
13
14
|
rule.defaultType = BLOCKS.PARAGRAPH;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { KEY_SOFT_BREAK } from '@udecode/plate-break';
|
|
1
|
+
/** @jsx jsx */ import { KEY_SOFT_BREAK } from '@udecode/plate-break';
|
|
2
2
|
import { jsx, createTestEditor, mockPlugin } from '../../test-utils';
|
|
3
3
|
import { createSoftBreakPlugin } from './createSoftBreakPlugin';
|
|
4
4
|
describe('Soft Break', ()=>{
|
|
5
5
|
it('derives its config from other plugins', ()=>{
|
|
6
|
-
const input = jsx("editor", null, jsx("hp", null, jsx("htext", null)));
|
|
6
|
+
const input = /*#__PURE__*/ jsx("editor", null, /*#__PURE__*/ jsx("hp", null, /*#__PURE__*/ jsx("htext", null)));
|
|
7
7
|
const rules = [
|
|
8
8
|
{
|
|
9
9
|
hotkey: 'ctrl+enter',
|
|
@@ -18,7 +18,7 @@ describe('Soft Break', ()=>{
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
];
|
|
21
|
-
const { editor
|
|
21
|
+
const { editor } = createTestEditor({
|
|
22
22
|
input,
|
|
23
23
|
plugins: [
|
|
24
24
|
mockPlugin({
|
|
@@ -7,47 +7,47 @@ import { useSdkContext } from '../../../SdkProvider';
|
|
|
7
7
|
import { useCommandList } from '../hooks/useCommandList';
|
|
8
8
|
import { useCommands } from '../useCommands';
|
|
9
9
|
import styles from './CommandList.styles';
|
|
10
|
-
const Group = ({ commandGroup
|
|
10
|
+
const Group = ({ commandGroup, selectedItem })=>/*#__PURE__*/ React.createElement("section", {
|
|
11
11
|
key: commandGroup.group
|
|
12
|
-
}, React.createElement(SectionHeading, {
|
|
12
|
+
}, /*#__PURE__*/ React.createElement(SectionHeading, {
|
|
13
13
|
as: "h3",
|
|
14
14
|
marginBottom: "spacingS",
|
|
15
15
|
marginTop: "spacingS",
|
|
16
16
|
marginLeft: "spacingM",
|
|
17
17
|
marginRight: "spacingM"
|
|
18
|
-
}, commandGroup.group), commandGroup.commands.map((command)
|
|
18
|
+
}, commandGroup.group), commandGroup.commands.map((command)=>/*#__PURE__*/ React.createElement("button", {
|
|
19
19
|
key: command.id,
|
|
20
20
|
id: command.id,
|
|
21
21
|
className: cx(styles.menuItem, {
|
|
22
22
|
[styles.menuItemSelected]: command.id === selectedItem
|
|
23
23
|
}),
|
|
24
24
|
onClick: command.callback
|
|
25
|
-
}, command.label)), React.createElement("hr", {
|
|
25
|
+
}, command.label)), /*#__PURE__*/ React.createElement("hr", {
|
|
26
26
|
className: styles.menuDivider,
|
|
27
27
|
"aria-orientation": "horizontal"
|
|
28
28
|
}));
|
|
29
|
-
const Asset = ({ command
|
|
29
|
+
const Asset = ({ command, selectedItem })=>/*#__PURE__*/ React.createElement("button", {
|
|
30
30
|
key: command.id,
|
|
31
31
|
id: command.id,
|
|
32
32
|
className: cx(styles.menuItem, {
|
|
33
33
|
[styles.menuItemSelected]: command.id === selectedItem
|
|
34
34
|
}),
|
|
35
35
|
onClick: command.callback
|
|
36
|
-
}, React.createElement(Flex, {
|
|
36
|
+
}, /*#__PURE__*/ React.createElement(Flex, {
|
|
37
37
|
alignItems: "center",
|
|
38
38
|
gap: "spacingS"
|
|
39
|
-
}, command.thumbnail ? React.createElement("img", {
|
|
39
|
+
}, command.thumbnail ? /*#__PURE__*/ React.createElement("img", {
|
|
40
40
|
width: "30",
|
|
41
41
|
height: "30",
|
|
42
42
|
src: command.thumbnail,
|
|
43
43
|
alt: "",
|
|
44
44
|
className: styles.thumbnail
|
|
45
|
-
}) : React.createElement(AssetIcon, {
|
|
45
|
+
}) : /*#__PURE__*/ React.createElement(AssetIcon, {
|
|
46
46
|
width: "30",
|
|
47
47
|
height: "30",
|
|
48
48
|
className: styles.thumbnail
|
|
49
|
-
}), React.createElement("span", null, command.label)));
|
|
50
|
-
const Item = ({ command
|
|
49
|
+
}), /*#__PURE__*/ React.createElement("span", null, command.label)));
|
|
50
|
+
const Item = ({ command, selectedItem })=>/*#__PURE__*/ React.createElement("button", {
|
|
51
51
|
key: command.id,
|
|
52
52
|
id: command.id,
|
|
53
53
|
className: cx(styles.menuItem, {
|
|
@@ -55,70 +55,70 @@ const Item = ({ command , selectedItem })=>React.createElement("button", {
|
|
|
55
55
|
}),
|
|
56
56
|
onClick: command.callback
|
|
57
57
|
}, command.label);
|
|
58
|
-
const CommandListItems = ({ commandItems
|
|
59
|
-
return React.createElement(React.Fragment, null, commandItems.map((command)=>{
|
|
60
|
-
return 'group' in command ? React.createElement(Group, {
|
|
58
|
+
const CommandListItems = ({ commandItems, selectedItem })=>{
|
|
59
|
+
return /*#__PURE__*/ React.createElement(React.Fragment, null, commandItems.map((command)=>{
|
|
60
|
+
return 'group' in command ? /*#__PURE__*/ React.createElement(Group, {
|
|
61
61
|
key: command.group,
|
|
62
62
|
commandGroup: command,
|
|
63
63
|
selectedItem: selectedItem
|
|
64
|
-
}) : command.asset ? React.createElement(Asset, {
|
|
64
|
+
}) : command.asset ? /*#__PURE__*/ React.createElement(Asset, {
|
|
65
65
|
key: command.id,
|
|
66
66
|
command: command,
|
|
67
67
|
selectedItem: selectedItem
|
|
68
|
-
}) : React.createElement(Item, {
|
|
68
|
+
}) : /*#__PURE__*/ React.createElement(Item, {
|
|
69
69
|
key: command.id,
|
|
70
70
|
command: command,
|
|
71
71
|
selectedItem: selectedItem
|
|
72
72
|
});
|
|
73
73
|
}));
|
|
74
74
|
};
|
|
75
|
-
export const CommandList = ({ query
|
|
75
|
+
export const CommandList = ({ query, editor, textContainer })=>{
|
|
76
76
|
const sdk = useSdkContext();
|
|
77
77
|
const popoverContainer = React.useRef(null);
|
|
78
78
|
const popper = usePopper(textContainer, popoverContainer?.current, {
|
|
79
79
|
placement: 'bottom-start'
|
|
80
80
|
});
|
|
81
81
|
const commandItems = useCommands(sdk, query, editor);
|
|
82
|
-
const { selectedItem
|
|
82
|
+
const { selectedItem, isOpen } = useCommandList(commandItems, popoverContainer);
|
|
83
83
|
if (!commandItems.length) {
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
|
-
return React.createElement("div", {
|
|
86
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
87
87
|
className: styles.container,
|
|
88
88
|
tabIndex: -1,
|
|
89
89
|
contentEditable: false
|
|
90
|
-
}, React.createElement("div", {
|
|
90
|
+
}, /*#__PURE__*/ React.createElement("div", {
|
|
91
91
|
role: "alert"
|
|
92
|
-
}, React.createElement(ScreenReaderOnly, null, "Richtext commands. Currently focused item: ", selectedItem, ". Press ", React.createElement("kbd", null, "enter"), " to select, ", React.createElement("kbd", null, "arrows"), " to navigate, ", React.createElement("kbd", null, "escape"), " to close.")), React.createElement(Portal, null, React.createElement("div", {
|
|
92
|
+
}, /*#__PURE__*/ React.createElement(ScreenReaderOnly, null, "Richtext commands. Currently focused item: ", selectedItem, ". Press ", /*#__PURE__*/ React.createElement("kbd", null, "enter"), " to select, ", /*#__PURE__*/ React.createElement("kbd", null, "arrows"), " to navigate, ", /*#__PURE__*/ React.createElement("kbd", null, "escape"), " to close.")), /*#__PURE__*/ React.createElement(Portal, null, /*#__PURE__*/ React.createElement("div", {
|
|
93
93
|
"aria-hidden": true,
|
|
94
94
|
ref: popoverContainer,
|
|
95
95
|
className: styles.menuPoper,
|
|
96
96
|
style: popper.styles.popper,
|
|
97
97
|
...popper.attributes.popper
|
|
98
|
-
}, React.createElement(Popover, {
|
|
98
|
+
}, /*#__PURE__*/ React.createElement(Popover, {
|
|
99
99
|
isOpen: isOpen,
|
|
100
100
|
usePortal: false,
|
|
101
|
-
autoFocus: false
|
|
102
|
-
}, React.createElement(Popover.Trigger, null, React.createElement("span", null)), React.createElement(Popover.Content, {
|
|
101
|
+
/* eslint-disable-next-line jsx-a11y/no-autofocus -- we want to keep focus on text input*/ autoFocus: false
|
|
102
|
+
}, /*#__PURE__*/ React.createElement(Popover.Trigger, null, /*#__PURE__*/ React.createElement("span", null)), /*#__PURE__*/ React.createElement(Popover.Content, {
|
|
103
103
|
className: styles.menuContent,
|
|
104
104
|
testId: "rich-text-commands"
|
|
105
|
-
}, React.createElement("header", {
|
|
105
|
+
}, /*#__PURE__*/ React.createElement("header", {
|
|
106
106
|
className: styles.menuHeader
|
|
107
|
-
}, React.createElement(SectionHeading, {
|
|
107
|
+
}, /*#__PURE__*/ React.createElement(SectionHeading, {
|
|
108
108
|
marginBottom: "none"
|
|
109
|
-
}, "Richtext commands")), React.createElement("div", {
|
|
109
|
+
}, "Richtext commands")), /*#__PURE__*/ React.createElement("div", {
|
|
110
110
|
className: styles.menuList,
|
|
111
111
|
"data-test-id": "rich-text-commands-list"
|
|
112
|
-
}, React.createElement(CommandListItems, {
|
|
112
|
+
}, /*#__PURE__*/ React.createElement(CommandListItems, {
|
|
113
113
|
commandItems: commandItems,
|
|
114
114
|
selectedItem: selectedItem
|
|
115
|
-
})), React.createElement("footer", {
|
|
115
|
+
})), /*#__PURE__*/ React.createElement("footer", {
|
|
116
116
|
className: styles.menuFooter
|
|
117
|
-
}, React.createElement(Stack, {
|
|
117
|
+
}, /*#__PURE__*/ React.createElement(Stack, {
|
|
118
118
|
as: "ul",
|
|
119
119
|
margin: "none",
|
|
120
120
|
padding: "none",
|
|
121
121
|
spacing: "spacingS",
|
|
122
122
|
className: styles.footerList
|
|
123
|
-
}, React.createElement("li", null, React.createElement("kbd", null, "↑"), React.createElement("kbd", null, "↓"), " to navigate"), React.createElement("li", null, React.createElement("kbd", null, "↵"), " to confirm"), React.createElement("li", null, React.createElement("kbd", null, "esc"), " to close"))))))));
|
|
123
|
+
}, /*#__PURE__*/ React.createElement("li", null, /*#__PURE__*/ React.createElement("kbd", null, "↑"), /*#__PURE__*/ React.createElement("kbd", null, "↓"), " to navigate"), /*#__PURE__*/ React.createElement("li", null, /*#__PURE__*/ React.createElement("kbd", null, "↵"), " to confirm"), /*#__PURE__*/ React.createElement("li", null, /*#__PURE__*/ React.createElement("kbd", null, "esc"), " to close"))))))));
|
|
124
124
|
};
|