@contentful/field-editor-rich-text 2.0.0-next.11 → 2.0.0-next.12

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.
@@ -3,15 +3,15 @@ import { toSlatejsDocument, toContentfulDocument } from '@contentful/contentful-
3
3
  import { useEntities, ScheduledIconWithTooltip, MissingEntityCard, AssetThumbnail, getScheduleTooltipContent, EntityProvider } from '@contentful/field-editor-reference';
4
4
  import { entityHelpers, shortenStorageUnit, isValidImage, ModalDialogLauncher, FieldConnector } from '@contentful/field-editor-shared';
5
5
  import { TOP_LEVEL_BLOCKS, BLOCKS, CONTAINERS, VOID_BLOCKS, INLINES, TABLE_BLOCKS, HEADINGS, TEXT_CONTAINERS, LIST_ITEM_BLOCKS, MARKS, EMPTY_DOCUMENT } from '@contentful/rich-text-types';
6
- import { usePlateEditorRef, getNodes, getText, toggleNodeType, getAbove, onKeyDownToggleElement, setNodes, isAncestorEmpty, getParent, isSelectionAtBlockStart, isSelectionAtBlockEnd, isFirstChild, insertNodes, moveChildren, isBlockAboveEmpty, mockPlugin, getPluginType, ELEMENT_DEFAULT, findNode, someHtmlElement, isMarkActive, toggleMark, match, KEY_DESERIALIZE_HTML, someNode, getChildren as getChildren$1, getBlockAbove, getLastChildPath, createDeserializeHtmlPlugin, createDeserializeAstPlugin, Plate } from '@udecode/plate-core';
6
+ import { usePlateEditorRef, getNodes, getText, toggleNodeType, getAbove, onKeyDownToggleElement, setNodes, isAncestorEmpty, getParent, isSelectionAtBlockStart, isSelectionAtBlockEnd, isFirstChild, insertNodes, moveChildren, isBlockAboveEmpty, mockPlugin, getPluginType, ELEMENT_DEFAULT, findNode, someHtmlElement, isMarkActive, toggleMark, match, KEY_DESERIALIZE_HTML, someNode, getChildren as getChildren$1, getBlockAbove, getLastChildPath, createDeserializeHtmlPlugin, createDeserializeAstPlugin, createPlateEditor, Plate } from '@udecode/plate-core';
7
7
  import { css, cx } from 'emotion';
8
8
  import deepEquals from 'fast-deep-equal';
9
9
  import noop from 'lodash-es/noop';
10
- import { Text, Element, Editor, Transforms, Range, Path, Node } from 'slate';
11
10
  import constate from 'constate';
12
11
  import { createDeserializeDocxPlugin } from '@udecode/plate-serializer-docx';
13
12
  import { createSoftBreakPlugin as createSoftBreakPlugin$1, createExitBreakPlugin as createExitBreakPlugin$1 } from '@udecode/plate-break';
14
13
  import isHotkey from 'is-hotkey';
14
+ import { Text, Element, Editor, Transforms, Range, Path, Node } from 'slate';
15
15
  import { ReactEditor, useSelected, useReadOnly, useFocused } from 'slate-react';
16
16
  import { AssetCard, Menu, Text as Text$1, Notification, EntryCard, MenuItem, Button, Flex, Icon, InlineEntryCard, Tooltip, ModalContent, Form, FormControl, TextInput, Select, FormLabel, TextLink, ModalControls, IconButton } from '@contentful/f36-components';
17
17
  import mimetype from '@contentful/mimetype';
@@ -357,41 +357,6 @@ var _constate = /*#__PURE__*/constate(useContentfulEditorHook),
357
357
  ContentfulEditorProvider = _constate[0],
358
358
  useContentfulEditor = _constate[1];
359
359
 
360
- var isTextElement = function isTextElement(node) {
361
- return 'text' in node;
362
- };
363
- /**
364
- * Ensures incoming void nodes have a child leaf text element.
365
- */
366
-
367
-
368
- function sanitizeIncomingSlateDoc(nodes) {
369
- if (nodes === void 0) {
370
- nodes = [];
371
- }
372
-
373
- return nodes.map(function (node) {
374
- var _node$children;
375
-
376
- if (isTextElement(node)) {
377
- return node;
378
- }
379
-
380
- if (node.isVoid && ((_node$children = node.children) == null ? void 0 : _node$children.length) === 0) {
381
- return _extends({}, node, {
382
- children: [{
383
- text: '',
384
- data: {}
385
- }]
386
- });
387
- }
388
-
389
- return _extends({}, node, {
390
- children: sanitizeIncomingSlateDoc(node.children)
391
- });
392
- });
393
- }
394
-
395
360
  var createSoftBreakPlugin = function createSoftBreakPlugin() {
396
361
  return createSoftBreakPlugin$1({
397
362
  then: function then(editor) {
@@ -2684,7 +2649,7 @@ function extractNodes(editor, path, match) {
2684
2649
  return Array.from(getNodes(editor, {
2685
2650
  match: match,
2686
2651
  at: path,
2687
- mode: 'all'
2652
+ mode: 'lowest'
2688
2653
  })).map(function (_ref) {
2689
2654
  var node = _ref[0];
2690
2655
  return node;
@@ -5968,61 +5933,79 @@ var StickyToolbarWrapper = function StickyToolbarWrapper(_ref) {
5968
5933
  }, children);
5969
5934
  };
5970
5935
 
5936
+ /**
5937
+ * For legacy reasons, a document may not have any content at all
5938
+ * e.g:
5939
+ *
5940
+ * {nodeType: document, data: {}, content: []}
5941
+ *
5942
+ * Rendering such document will break the Slate editor
5943
+ */
5944
+
5945
+ var hasContent = function hasContent(doc) {
5946
+ if (!doc) {
5947
+ return false;
5948
+ }
5949
+
5950
+ return doc.content.length > 0;
5951
+ };
5952
+
5953
+ var useNormalizedSlateValue = function useNormalizedSlateValue(_ref) {
5954
+ var id = _ref.id,
5955
+ incomingDoc = _ref.incomingDoc,
5956
+ plugins = _ref.plugins;
5957
+ return useMemo(function () {
5958
+ var editor = createPlateEditor({
5959
+ id: id,
5960
+ plugins: plugins,
5961
+ disableCorePlugins: disableCorePlugins
5962
+ });
5963
+ var doc = toSlatejsDocument({
5964
+ document: hasContent(incomingDoc) ? incomingDoc : EMPTY_DOCUMENT,
5965
+ schema: schema
5966
+ }); // Sets editor value & kicks normalization
5967
+
5968
+ Transforms.insertNodes(editor, doc); // TODO: return the editor itself to avoid recompiling & initializing all
5969
+ // of the plugins again. It's currently not possible due to a bug in Plate
5970
+ // with initialValues
5971
+ // See: https://slate-js.slack.com/archives/C013QHXSCG1/p1645112799942819
5972
+
5973
+ return editor.children;
5974
+ }, [id, plugins, incomingDoc]);
5975
+ };
5976
+
5971
5977
  var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
5972
5978
  var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
5979
+ var id = getContentfulEditorId(props.sdk);
5973
5980
  var tracking = useTrackingContext();
5974
- var editor = useContentfulEditor();
5975
-
5976
- var _useState = useState([]),
5977
- value = _useState[0],
5978
- setValue = _useState[1];
5979
-
5980
- var classNames = cx(styles$j.editor, props.minHeight !== undefined ? css({
5981
- minHeight: props.minHeight
5982
- }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
5983
5981
  var plugins = React__default.useMemo(function () {
5984
5982
  return getPlugins(props.sdk, tracking);
5985
5983
  }, [props.sdk, tracking]);
5986
- React__default.useEffect(function () {
5987
- if (!editor) {
5988
- return;
5989
- }
5990
-
5991
- var docFromAdapter = toSlatejsDocument({
5992
- document: props.value || EMPTY_DOCUMENT,
5993
- schema: schema
5994
- });
5995
- var doc = sanitizeIncomingSlateDoc(docFromAdapter); // Slate throws an error if the value on the initial render is invalid
5996
- // so we directly set the value on the editor in order
5997
- // to be able to trigger normalization on the initial value before rendering
5998
- // TODO: use https://plate.udecode.io/docs/Plate#normalizeinitialvalue when working
5999
-
6000
- editor.children = doc;
6001
- Editor.normalize(editor, {
6002
- force: true
6003
- }); // We set the value so that the rendering can take over from here
6004
-
6005
- setValue(editor.children);
6006
- }, [props.value, editor]);
5984
+ var initialValue = useNormalizedSlateValue({
5985
+ id: id,
5986
+ incomingDoc: props.value,
5987
+ plugins: plugins
5988
+ });
5989
+ var classNames = cx(styles$j.editor, props.minHeight !== undefined ? css({
5990
+ minHeight: props.minHeight
5991
+ }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
6007
5992
  return /*#__PURE__*/React__default.createElement("div", {
6008
5993
  className: styles$j.root,
6009
5994
  "data-test-id": "rich-text-editor"
6010
5995
  }, /*#__PURE__*/React__default.createElement(Plate, {
6011
- id: getContentfulEditorId(props.sdk),
6012
- value: value,
5996
+ id: id,
5997
+ initialValue: initialValue,
6013
5998
  plugins: plugins,
6014
5999
  disableCorePlugins: disableCorePlugins,
6015
6000
  editableProps: {
6016
6001
  className: classNames,
6017
6002
  readOnly: props.isDisabled
6018
6003
  },
6019
- onChange: function onChange(slateDoc) {
6020
- setValue(slateDoc);
6021
- var contentfulDoc = toContentfulDocument({
6022
- document: slateDoc,
6004
+ onChange: function onChange(document) {
6005
+ props.onChange == null ? void 0 : props.onChange(toContentfulDocument({
6006
+ document: document,
6023
6007
  schema: schema
6024
- });
6025
- props.onChange == null ? void 0 : props.onChange(contentfulDoc);
6008
+ }));
6026
6009
  }
6027
6010
  }, !props.isToolbarHidden && /*#__PURE__*/React__default.createElement(StickyToolbarWrapper, {
6028
6011
  isDisabled: props.isDisabled