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

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.
Files changed (58) hide show
  1. package/dist/ContentfulEditorProvider.d.ts +6 -5
  2. package/dist/RichTextEditor.d.ts +1 -1
  3. package/dist/field-editor-rich-text.cjs.development.js +555 -425
  4. package/dist/field-editor-rich-text.cjs.development.js.map +1 -1
  5. package/dist/field-editor-rich-text.cjs.production.min.js +1 -1
  6. package/dist/field-editor-rich-text.cjs.production.min.js.map +1 -1
  7. package/dist/field-editor-rich-text.esm.js +558 -428
  8. package/dist/field-editor-rich-text.esm.js.map +1 -1
  9. package/dist/helpers/editor.d.ts +16 -18
  10. package/dist/helpers/extractNodes.d.ts +2 -3
  11. package/dist/helpers/transformers.d.ts +6 -6
  12. package/dist/plugins/EmbeddedEntityBlock/ToolbarIcon.d.ts +1 -2
  13. package/dist/plugins/EmbeddedEntityBlock/Util.d.ts +2 -1
  14. package/dist/plugins/EmbeddedEntityBlock/index.d.ts +2 -3
  15. package/dist/plugins/EmbeddedEntityInline/index.d.ts +1 -2
  16. package/dist/plugins/Hr/index.d.ts +2 -3
  17. package/dist/plugins/Hyperlink/HyperlinkModal.d.ts +3 -4
  18. package/dist/plugins/Hyperlink/index.d.ts +1 -2
  19. package/dist/plugins/Hyperlink/utils.d.ts +2 -2
  20. package/dist/plugins/List/insertListBreak.d.ts +2 -2
  21. package/dist/plugins/List/insertListFragment.d.ts +3 -2
  22. package/dist/plugins/List/transforms/insertListItem.d.ts +2 -2
  23. package/dist/plugins/List/utils.d.ts +6 -7
  24. package/dist/plugins/List/withList.d.ts +2 -1
  25. package/dist/plugins/Marks/Bold.d.ts +7 -5
  26. package/dist/plugins/Marks/Code.d.ts +7 -5
  27. package/dist/plugins/Marks/Italic.d.ts +7 -5
  28. package/dist/plugins/Marks/Underline.d.ts +7 -5
  29. package/dist/plugins/Marks/components/MarkToolbarButton.d.ts +13 -0
  30. package/dist/plugins/Marks/helpers.d.ts +4 -0
  31. package/dist/plugins/Normalizer/types.d.ts +4 -3
  32. package/dist/plugins/Normalizer/utils.d.ts +2 -2
  33. package/dist/plugins/Normalizer/withNormalizer.d.ts +2 -2
  34. package/dist/plugins/Quote/toggleQuote.d.ts +5 -3
  35. package/dist/plugins/Table/actions/addColumn.d.ts +3 -3
  36. package/dist/plugins/Table/actions/addRow.d.ts +3 -3
  37. package/dist/plugins/Table/actions/setHeader.d.ts +2 -2
  38. package/dist/plugins/Table/addTableTrackingEvents.d.ts +2 -3
  39. package/dist/plugins/Table/createTablePlugin.d.ts +1 -2
  40. package/dist/plugins/Table/helpers.d.ts +7 -7
  41. package/dist/plugins/Tracking/createTrackingPlugin.d.ts +10 -0
  42. package/dist/plugins/Tracking/index.d.ts +1 -0
  43. package/dist/plugins/Tracking/utils.d.ts +2 -0
  44. package/dist/plugins/TrailingParagraph/index.d.ts +2 -1
  45. package/dist/plugins/Voids/transformVoid.d.ts +2 -2
  46. package/dist/plugins/index.d.ts +2 -2
  47. package/dist/plugins/links-tracking.d.ts +1 -2
  48. package/dist/test-utils/assertOutput.d.ts +2 -2
  49. package/dist/test-utils/createEditor.d.ts +5 -6
  50. package/dist/test-utils/jsx.d.ts +1 -1
  51. package/dist/test-utils/mockPlugin.d.ts +1 -1
  52. package/dist/test-utils/setEmptyDataAttribute.d.ts +2 -2
  53. package/dist/types.d.ts +6 -2
  54. package/dist/useNormalizedSlateValue.d.ts +7 -0
  55. package/dist/useOnValueChanged.d.ts +7 -0
  56. package/package.json +1 -1
  57. package/dist/TrackingProvider.d.ts +0 -11
  58. package/dist/helpers/sanitizeSlateDoc.d.ts +0 -5
@@ -1,18 +1,17 @@
1
- import React__default, { useMemo, createElement, useEffect, useState, memo, Fragment, useCallback } from 'react';
2
- import { toSlatejsDocument, toContentfulDocument } from '@contentful/contentful-slatejs-adapter';
1
+ import React__default, { useContext, createContext, useMemo, createElement, useEffect, useState, memo, Fragment, useCallback } from 'react';
3
2
  import { useEntities, ScheduledIconWithTooltip, MissingEntityCard, AssetThumbnail, getScheduleTooltipContent, EntityProvider } from '@contentful/field-editor-reference';
4
3
  import { entityHelpers, shortenStorageUnit, isValidImage, ModalDialogLauncher, FieldConnector } from '@contentful/field-editor-shared';
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';
4
+ import { BLOCKS, INLINES, TABLE_BLOCKS, HEADINGS, TEXT_CONTAINERS, LIST_ITEM_BLOCKS, MARKS, CONTAINERS, TOP_LEVEL_BLOCKS, VOID_BLOCKS, EMPTY_DOCUMENT } from '@contentful/rich-text-types';
5
+ import { usePlateEditorState, usePlateEditorRef, getNodes, getText, toggleNodeType, getAbove, setNodes, isAncestorEmpty, getParent, isSelectionAtBlockStart, isSelectionAtBlockEnd, isFirstChild, insertNodes, moveChildren, isBlockAboveEmpty, mockPlugin, getPluginType, ELEMENT_DEFAULT, findNode, isMarkActive, toggleMark, someHtmlElement, match, KEY_DESERIALIZE_HTML, someNode, getChildren as getChildren$1, getBlockAbove, getLastChildPath, createDeserializeHtmlPlugin, createDeserializeAstPlugin, createPlateEditor, Plate } from '@udecode/plate-core';
7
6
  import { css, cx } from 'emotion';
8
7
  import deepEquals from 'fast-deep-equal';
9
8
  import noop from 'lodash-es/noop';
10
- import { Text, Element, Editor, Transforms, Range, Path, Node } from 'slate';
11
- import constate from 'constate';
12
9
  import { createDeserializeDocxPlugin } from '@udecode/plate-serializer-docx';
13
10
  import { createSoftBreakPlugin as createSoftBreakPlugin$1, createExitBreakPlugin as createExitBreakPlugin$1 } from '@udecode/plate-break';
14
11
  import isHotkey from 'is-hotkey';
12
+ import { Text, Element, Editor, Transforms, Range, Path, Node, Point } from 'slate';
15
13
  import { ReactEditor, useSelected, useReadOnly, useFocused } from 'slate-react';
14
+ import constate from 'constate';
16
15
  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
16
  import mimetype from '@contentful/mimetype';
18
17
  import get from 'lodash-es/get';
@@ -27,7 +26,10 @@ import isPlainObject from 'is-plain-obj';
27
26
  import { createParagraphPlugin as createParagraphPlugin$1 } from '@udecode/plate-paragraph';
28
27
  import { createSelectOnBackspacePlugin as createSelectOnBackspacePlugin$1 } from '@udecode/plate-select';
29
28
  import { ELEMENT_TABLE, ELEMENT_TR, getEmptyRowNode, ELEMENT_TD, ELEMENT_TH, getEmptyCellNode, insertTable, deleteRow, deleteColumn, deleteTable, createTablePlugin as createTablePlugin$1, onKeyDownTable } from '@udecode/plate-table';
29
+ import { toContentfulDocument, toSlatejsDocument } from '@contentful/contentful-slatejs-adapter';
30
+ import { documentToPlainTextString } from '@contentful/rich-text-plain-text-renderer';
30
31
  import { createTrailingBlockPlugin } from '@udecode/plate-trailing-block';
32
+ import debounce from 'lodash-es/debounce';
31
33
  import PropTypes from 'prop-types';
32
34
 
33
35
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
@@ -237,159 +239,35 @@ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
237
239
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
238
240
  }
239
241
 
240
- var _extends2, _extends4, _inlines;
241
- var inlines = /*#__PURE__*/Object.values(INLINES).map(function (type) {
242
- return {
243
- type: type
244
- };
245
- });
246
- var schema = {
247
- document: {
248
- nodes: [{
249
- types: /*#__PURE__*/TOP_LEVEL_BLOCKS.map(function (type) {
250
- return {
251
- type: type
252
- };
253
- })
254
- }]
255
- },
256
- blocks: /*#__PURE__*/_extends((_extends2 = {}, _extends2[BLOCKS.PARAGRAPH] = {
257
- nodes: [{
258
- match: /*#__PURE__*/[].concat(inlines, [{
259
- object: 'text'
260
- }])
261
- }]
262
- }, _extends2[BLOCKS.HEADING_1] = {
263
- nodes: [{
264
- match: /*#__PURE__*/[].concat(inlines, [{
265
- object: 'text'
266
- }])
267
- }]
268
- }, _extends2[BLOCKS.HEADING_2] = {
269
- nodes: [{
270
- match: /*#__PURE__*/[].concat(inlines, [{
271
- object: 'text'
272
- }])
273
- }]
274
- }, _extends2[BLOCKS.HEADING_3] = {
275
- nodes: [{
276
- match: /*#__PURE__*/[].concat(inlines, [{
277
- object: 'text'
278
- }])
279
- }]
280
- }, _extends2[BLOCKS.HEADING_4] = {
281
- nodes: [{
282
- match: /*#__PURE__*/[].concat(inlines, [{
283
- object: 'text'
284
- }])
285
- }]
286
- }, _extends2[BLOCKS.HEADING_5] = {
287
- nodes: [{
288
- match: /*#__PURE__*/[].concat(inlines, [{
289
- object: 'text'
290
- }])
291
- }]
292
- }, _extends2[BLOCKS.HEADING_6] = {
293
- nodes: [{
294
- match: /*#__PURE__*/[].concat(inlines, [{
295
- object: 'text'
296
- }])
297
- }]
298
- }, _extends2), /*#__PURE__*/VOID_BLOCKS.reduce(function (blocks, nodeType) {
299
- var _extends3;
300
-
301
- return _extends({}, blocks, (_extends3 = {}, _extends3[nodeType] = {
302
- isVoid: true
303
- }, _extends3));
304
- }, {}), (_extends4 = {}, _extends4[BLOCKS.QUOTE] = {
305
- nodes: [{
306
- match: [/*#__PURE__*/CONTAINERS[BLOCKS.QUOTE].map(function (type) {
307
- return {
308
- type: type
309
- };
310
- })],
311
- min: 1
312
- }],
313
- normalize: function normalize(editor, error) {
314
- if (error.code === 'child_type_invalid') {
315
- return editor.unwrapBlockByKey(error.node.key, BLOCKS.QUOTE);
316
- }
317
- }
318
- }, _extends4)),
319
- inlines: (_inlines = {}, _inlines[INLINES.HYPERLINK] = {
320
- nodes: [{
321
- match: [{
322
- object: 'text'
323
- }]
324
- }]
325
- }, _inlines[INLINES.ENTRY_HYPERLINK] = {
326
- nodes: [{
327
- match: [{
328
- object: 'text'
329
- }]
330
- }]
331
- }, _inlines[INLINES.ASSET_HYPERLINK] = {
332
- nodes: [{
333
- match: [{
334
- object: 'text'
335
- }]
336
- }]
337
- }, _inlines[INLINES.EMBEDDED_ENTRY] = {
338
- isVoid: true
339
- }, _inlines)
340
- };
341
-
342
242
  function getContentfulEditorId(sdk) {
343
243
  var entry = sdk.entry,
344
244
  field = sdk.field;
345
245
  var sys = entry.getSys();
346
246
  return "rich-text-editor-" + sys.id + "-" + field.id + "-" + field.locale;
347
247
  }
248
+ var editorContext = /*#__PURE__*/createContext('');
249
+ var ContentfulEditorIdProvider = editorContext.Provider;
250
+ function useContentfulEditorId() {
251
+ var id = useContext(editorContext);
348
252
 
349
- function useContentfulEditorHook(_ref) {
350
- var sdk = _ref.sdk;
351
- var editorId = getContentfulEditorId(sdk);
352
- var editor = usePlateEditorRef(editorId);
353
- return editor;
354
- }
355
-
356
- var _constate = /*#__PURE__*/constate(useContentfulEditorHook),
357
- ContentfulEditorProvider = _constate[0],
358
- useContentfulEditor = _constate[1];
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 = [];
253
+ if (!id) {
254
+ throw new Error('could not find editor id. Please ensure the component is wrapped in <ContentfulEditorIdProvider> ');
371
255
  }
372
256
 
373
- return nodes.map(function (node) {
374
- var _node$children;
375
-
376
- if (isTextElement(node)) {
377
- return node;
378
- }
257
+ return id;
258
+ } // This hook re-renders when the value changes
259
+ // Use case: Toolbar icons, for example
379
260
 
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
- }
261
+ function useContentfulEditor() {
262
+ var editorId = useContentfulEditorId();
263
+ var editor = usePlateEditorState(editorId);
264
+ return editor;
265
+ } // This doesn't re-render when the value changes
388
266
 
389
- return _extends({}, node, {
390
- children: sanitizeIncomingSlateDoc(node.children)
391
- });
392
- });
267
+ function useContentfulEditorRef() {
268
+ var editorId = useContentfulEditorId();
269
+ var editor = usePlateEditorRef(editorId);
270
+ return editor;
393
271
  }
394
272
 
395
273
  var createSoftBreakPlugin = function createSoftBreakPlugin() {
@@ -571,6 +449,10 @@ function insertLink(editor, options) {
571
449
  } // TODO: move to hyperlink plugin
572
450
 
573
451
  function isLinkActive(editor) {
452
+ if (!editor) {
453
+ return false;
454
+ }
455
+
574
456
  var _Array$from2 = Array.from(Editor.nodes(editor, {
575
457
  match: function match(node) {
576
458
  return !Editor.isEditor(node) && Element.isElement(node) && LINK_TYPES.includes(node.type);
@@ -730,12 +612,14 @@ var focus = function focus(editor) {
730
612
  }
731
613
  };
732
614
 
733
- function withLinkTracking(tracking, Component) {
615
+ function withLinkTracking(Component) {
734
616
  return function ComponentWithTracking(props) {
617
+ var editor = useContentfulEditorRef();
618
+ var onEntityFetchComplete = React__default.useCallback(function () {
619
+ return editor.tracking.onViewportAction('linkRendered');
620
+ }, [editor]);
735
621
  return /*#__PURE__*/React__default.createElement(Component, Object.assign({}, props, {
736
- onEntityFetchComplete: function onEntityFetchComplete() {
737
- tracking.onViewportAction('linkRendered');
738
- }
622
+ onEntityFetchComplete: onEntityFetchComplete
739
623
  }));
740
624
  };
741
625
  }
@@ -749,9 +633,9 @@ function useSdk(_ref) {
749
633
  return sdkMemo;
750
634
  }
751
635
 
752
- var _constate$1 = /*#__PURE__*/constate(useSdk),
753
- SdkProvider = _constate$1[0],
754
- useSdkContext = _constate$1[1];
636
+ var _constate = /*#__PURE__*/constate(useSdk),
637
+ SdkProvider = _constate[0],
638
+ useSdkContext = _constate[1];
755
639
 
756
640
  var styles = {
757
641
  scheduleIcon: /*#__PURE__*/css({
@@ -2001,12 +1885,11 @@ function _selectEntityAndInsert() {
2001
1885
  config = _extends({}, baseConfig, {
2002
1886
  withCreate: true
2003
1887
  });
2004
- _context.prev = 5;
2005
1888
  selection = editor.selection;
2006
- _context.next = 9;
1889
+ _context.next = 8;
2007
1890
  return selectEntity(config);
2008
1891
 
2009
- case 9:
1892
+ case 8:
2010
1893
  entity = _context.sent;
2011
1894
 
2012
1895
  if (entity) {
@@ -2014,6 +1897,9 @@ function _selectEntityAndInsert() {
2014
1897
  break;
2015
1898
  }
2016
1899
 
1900
+ logAction('cancelCreateEmbedDialog', {
1901
+ nodeType: nodeType
1902
+ });
2017
1903
  return _context.abrupt("return");
2018
1904
 
2019
1905
  case 12:
@@ -2022,31 +1908,13 @@ function _selectEntityAndInsert() {
2022
1908
  logAction('insert', {
2023
1909
  nodeType: nodeType
2024
1910
  });
2025
- _context.next = 24;
2026
- break;
2027
-
2028
- case 17:
2029
- _context.prev = 17;
2030
- _context.t0 = _context["catch"](5);
2031
-
2032
- if (!_context.t0) {
2033
- _context.next = 23;
2034
- break;
2035
- }
2036
-
2037
- throw _context.t0;
2038
-
2039
- case 23:
2040
- logAction('cancelCreateEmbedDialog', {
2041
- nodeType: nodeType
2042
- });
2043
1911
 
2044
- case 24:
1912
+ case 15:
2045
1913
  case "end":
2046
1914
  return _context.stop();
2047
1915
  }
2048
1916
  }
2049
- }, _callee, null, [[5, 17]]);
1917
+ }, _callee);
2050
1918
  }));
2051
1919
  return _selectEntityAndInsert.apply(this, arguments);
2052
1920
  }
@@ -2093,7 +1961,6 @@ var styles$4 = {
2093
1961
  function EmbeddedEntityBlockToolbarIcon(_ref) {
2094
1962
  var isButton = _ref.isButton,
2095
1963
  isDisabled = _ref.isDisabled,
2096
- logAction = _ref.logAction,
2097
1964
  nodeType = _ref.nodeType,
2098
1965
  onClose = _ref.onClose;
2099
1966
  var editor = useContentfulEditor();
@@ -2102,7 +1969,7 @@ function EmbeddedEntityBlockToolbarIcon(_ref) {
2102
1969
  var handleClick = function handleClick(event) {
2103
1970
  event.preventDefault();
2104
1971
  onClose();
2105
- selectEntityAndInsert(nodeType, sdk, editor, logAction || noop);
1972
+ selectEntityAndInsert(nodeType, sdk, editor, editor.tracking.onToolbarAction);
2106
1973
  };
2107
1974
 
2108
1975
  var type = getEntityTypeFromNodeType(nodeType);
@@ -2169,20 +2036,20 @@ function getWithEmbeddedEntityEvents(nodeType, sdk) {
2169
2036
  }
2170
2037
 
2171
2038
  if (hotkey && isHotkey(hotkey, event)) {
2172
- selectEntityAndInsert(nodeType, sdk, editor, noop);
2039
+ selectEntityAndInsert(nodeType, sdk, editor, editor.tracking.onShortcutAction);
2173
2040
  }
2174
2041
  };
2175
2042
  };
2176
2043
  }
2177
2044
 
2178
2045
  var createEmbeddedEntityPlugin = function createEmbeddedEntityPlugin(nodeType, hotkey) {
2179
- return function (sdk, tracking) {
2046
+ return function (sdk) {
2180
2047
  return {
2181
2048
  key: nodeType,
2182
2049
  type: nodeType,
2183
2050
  isElement: true,
2184
2051
  isVoid: true,
2185
- component: withLinkTracking(tracking, LinkedEntityBlock),
2052
+ component: withLinkTracking(LinkedEntityBlock),
2186
2053
  options: {
2187
2054
  hotkey: hotkey
2188
2055
  },
@@ -2400,44 +2267,53 @@ function EmbeddedEntityInline(props) {
2400
2267
  })), props.children);
2401
2268
  }
2402
2269
 
2403
- function selectEntityAndInsert$1(_x, _x2) {
2270
+ function selectEntityAndInsert$1(_x, _x2, _x3) {
2404
2271
  return _selectEntityAndInsert$1.apply(this, arguments);
2405
2272
  }
2406
2273
 
2407
2274
  function _selectEntityAndInsert$1() {
2408
- _selectEntityAndInsert$1 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(editor, sdk) {
2275
+ _selectEntityAndInsert$1 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(editor, sdk, logAction) {
2409
2276
  var config, selection, entry, inlineEntryNode;
2410
2277
  return runtime_1.wrap(function _callee2$(_context2) {
2411
2278
  while (1) {
2412
2279
  switch (_context2.prev = _context2.next) {
2413
2280
  case 0:
2281
+ logAction('openCreateEmbedDialog', {
2282
+ nodeType: INLINES.EMBEDDED_ENTRY
2283
+ });
2414
2284
  config = _extends({}, newEntitySelectorConfigFromRichTextField(sdk.field, INLINES.EMBEDDED_ENTRY), {
2415
2285
  withCreate: true
2416
2286
  });
2417
2287
  selection = editor.selection;
2418
- _context2.next = 4;
2288
+ _context2.next = 5;
2419
2289
  return sdk.dialogs.selectSingleEntry(config);
2420
2290
 
2421
- case 4:
2291
+ case 5:
2422
2292
  entry = _context2.sent;
2423
2293
  focus(editor); // Dialog steals focus from editor, return it.
2424
2294
 
2425
2295
  if (entry) {
2426
- _context2.next = 8;
2296
+ _context2.next = 10;
2427
2297
  break;
2428
2298
  }
2429
2299
 
2300
+ logAction('cancelCreateEmbedDialog', {
2301
+ nodeType: INLINES.EMBEDDED_ENTRY
2302
+ });
2430
2303
  return _context2.abrupt("return");
2431
2304
 
2432
- case 8:
2305
+ case 10:
2433
2306
  inlineEntryNode = createInlineEntryNode(entry.sys.id); // Got to wait until focus is really back on the editor or setSelection() won't work.
2434
2307
 
2435
2308
  setTimeout(function () {
2436
2309
  Transforms.setSelection(editor, selection);
2437
2310
  Transforms.insertNodes(editor, inlineEntryNode);
2438
2311
  }, 0);
2312
+ logAction('insert', {
2313
+ nodeType: INLINES.EMBEDDED_ENTRY
2314
+ });
2439
2315
 
2440
- case 10:
2316
+ case 13:
2441
2317
  case "end":
2442
2318
  return _context2.stop();
2443
2319
  }
@@ -2451,7 +2327,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2451
2327
  var editor = useContentfulEditor();
2452
2328
  var sdk = useSdkContext();
2453
2329
 
2454
- function handleClick(_x3) {
2330
+ function handleClick(_x4) {
2455
2331
  return _handleClick.apply(this, arguments);
2456
2332
  }
2457
2333
 
@@ -2473,7 +2349,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2473
2349
  case 3:
2474
2350
  props.onClose();
2475
2351
  _context.next = 6;
2476
- return selectEntityAndInsert$1(editor, sdk);
2352
+ return selectEntityAndInsert$1(editor, sdk, editor.tracking.onToolbarAction);
2477
2353
 
2478
2354
  case 6:
2479
2355
  case "end":
@@ -2506,7 +2382,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2506
2382
  className: "rich-text__embedded-entry-list-icon " + styles$6.icon
2507
2383
  }), /*#__PURE__*/createElement("span", null, "Inline entry")));
2508
2384
  }
2509
- function createEmbeddedEntityInlinePlugin(sdk, tracking) {
2385
+ function createEmbeddedEntityInlinePlugin(sdk) {
2510
2386
  var htmlAttributeName = 'data-embedded-entity-inline-id';
2511
2387
  return {
2512
2388
  key: INLINES.EMBEDDED_ENTRY,
@@ -2514,7 +2390,7 @@ function createEmbeddedEntityInlinePlugin(sdk, tracking) {
2514
2390
  isElement: true,
2515
2391
  isInline: true,
2516
2392
  isVoid: true,
2517
- component: withLinkTracking(tracking, EmbeddedEntityInline),
2393
+ component: withLinkTracking(EmbeddedEntityInline),
2518
2394
  options: {
2519
2395
  hotkey: 'mod+shift+2'
2520
2396
  },
@@ -2540,7 +2416,7 @@ function getWithEmbeddedEntryInlineEvents(sdk) {
2540
2416
  if (!editor) return;
2541
2417
 
2542
2418
  if (hotkey && isHotkey(hotkey, event)) {
2543
- selectEntityAndInsert$1(editor, sdk);
2419
+ selectEntityAndInsert$1(editor, sdk, editor.tracking.onShortcutAction);
2544
2420
  }
2545
2421
  };
2546
2422
  };
@@ -2643,6 +2519,10 @@ function ToolbarHeadingButton(props) {
2643
2519
  prevOnChange.apply(void 0, arguments);
2644
2520
  };
2645
2521
 
2522
+ var isActive = isBlockSelected(editor, type);
2523
+ editor.tracking.onToolbarAction(isActive ? 'remove' : 'insert', {
2524
+ nodeType: type
2525
+ });
2646
2526
  toggleNodeType(editor, {
2647
2527
  activeType: type,
2648
2528
  inactiveType: type
@@ -2684,7 +2564,7 @@ function extractNodes(editor, path, match) {
2684
2564
  return Array.from(getNodes(editor, {
2685
2565
  match: match,
2686
2566
  at: path,
2687
- mode: 'all'
2567
+ mode: 'lowest'
2688
2568
  })).map(function (_ref) {
2689
2569
  var node = _ref[0];
2690
2570
  return node;
@@ -2764,6 +2644,24 @@ function createHeading(Tag, block) {
2764
2644
 
2765
2645
  var HeadingComponents = (_HeadingComponents = {}, _HeadingComponents[BLOCKS.HEADING_1] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h1', BLOCKS.HEADING_1)), _HeadingComponents[BLOCKS.HEADING_2] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h2', BLOCKS.HEADING_2)), _HeadingComponents[BLOCKS.HEADING_3] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h3', BLOCKS.HEADING_3)), _HeadingComponents[BLOCKS.HEADING_4] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h4', BLOCKS.HEADING_4)), _HeadingComponents[BLOCKS.HEADING_5] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h5', BLOCKS.HEADING_5)), _HeadingComponents[BLOCKS.HEADING_6] = /*#__PURE__*/memo( /*#__PURE__*/createHeading('h6', BLOCKS.HEADING_6)), _HeadingComponents);
2766
2646
 
2647
+ var buildHeadingEventHandler = function buildHeadingEventHandler(type) {
2648
+ return function (editor, _ref) {
2649
+ var hotkey = _ref.options.hotkey;
2650
+ return function (event) {
2651
+ if (editor.selection && hotkey && isHotkey(hotkey, event)) {
2652
+ var isActive = isBlockSelected(editor, type);
2653
+ editor.tracking.onShortcutAction(isActive ? 'remove' : 'insert', {
2654
+ nodeType: type
2655
+ });
2656
+ toggleNodeType(editor, {
2657
+ activeType: type,
2658
+ inactiveType: BLOCKS.PARAGRAPH
2659
+ });
2660
+ }
2661
+ };
2662
+ };
2663
+ };
2664
+
2767
2665
  var createHeadingPlugin = function createHeadingPlugin() {
2768
2666
  var _transform;
2769
2667
 
@@ -2780,8 +2678,8 @@ var createHeadingPlugin = function createHeadingPlugin() {
2780
2678
  match: {
2781
2679
  type: HEADINGS
2782
2680
  },
2783
- validChildren: function validChildren(_, _ref) {
2784
- var node = _ref[0];
2681
+ validChildren: function validChildren(_, _ref2) {
2682
+ var node = _ref2[0];
2785
2683
  return isInlineOrText(node);
2786
2684
  },
2787
2685
  transform: (_transform = {}, _transform[BLOCKS.PARAGRAPH] = transformUnwrap, _transform["default"] = transformLift, _transform)
@@ -2798,8 +2696,8 @@ var createHeadingPlugin = function createHeadingPlugin() {
2798
2696
  start: true,
2799
2697
  // Exclude headings inside lists as it interferes with the list's
2800
2698
  // insertBreak implementation
2801
- filter: function filter(_ref2) {
2802
- var path = _ref2[1];
2699
+ filter: function filter(_ref3) {
2700
+ var path = _ref3[1];
2803
2701
  return !getAbove(editor, {
2804
2702
  at: path,
2805
2703
  match: {
@@ -2823,7 +2721,7 @@ var createHeadingPlugin = function createHeadingPlugin() {
2823
2721
  hotkey: ["mod+alt+" + level]
2824
2722
  },
2825
2723
  handlers: {
2826
- onKeyDown: onKeyDownToggleElement
2724
+ onKeyDown: buildHeadingEventHandler(nodeType)
2827
2725
  },
2828
2726
  deserializeHtml: {
2829
2727
  rules: [{
@@ -3353,13 +3251,15 @@ function HyperlinkModal(props) {
3353
3251
  testId: "confirm-cta"
3354
3252
  }, props.linkType ? 'Update' : 'Insert'))));
3355
3253
  }
3356
- function addOrEditLink(_x, _x2) {
3254
+ function addOrEditLink(_x, _x2, _x3) {
3357
3255
  return _addOrEditLink.apply(this, arguments);
3358
3256
  }
3359
3257
 
3360
3258
  function _addOrEditLink() {
3361
- _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk) {
3362
- var linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionBeforeBlur, currentLinkText, data, text, url, type, target;
3259
+ _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk, logAction) {
3260
+ var _target$sys$linkType;
3261
+
3262
+ var linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionBeforeBlur, currentLinkText, isEditing, data, text, url, type, target;
3363
3263
 
3364
3264
  return runtime_1.wrap(function _callee3$(_context3) {
3365
3265
  while (1) {
@@ -3384,9 +3284,11 @@ function _addOrEditLink() {
3384
3284
 
3385
3285
  selectionBeforeBlur = _extends({}, editor.selection);
3386
3286
  currentLinkText = linkText || Editor.string(editor, editor.selection);
3387
- _context3.next = 8;
3287
+ isEditing = Boolean(node && path);
3288
+ logAction(isEditing ? 'openEditHyperlinkDialog' : 'openCreateHyperlinkDialog');
3289
+ _context3.next = 10;
3388
3290
  return ModalDialogLauncher.openDialog({
3389
- title: linkType ? 'Edit hyperlink' : 'Insert hyperlink',
3291
+ title: isEditing ? 'Edit hyperlink' : 'Insert hyperlink',
3390
3292
  width: 'large',
3391
3293
  shouldCloseOnEscapePress: true,
3392
3294
  shouldCloseOnOverlayClick: true,
@@ -3403,17 +3305,18 @@ function _addOrEditLink() {
3403
3305
  });
3404
3306
  });
3405
3307
 
3406
- case 8:
3308
+ case 10:
3407
3309
  data = _context3.sent;
3408
3310
 
3409
3311
  if (data) {
3410
- _context3.next = 11;
3312
+ _context3.next = 14;
3411
3313
  break;
3412
3314
  }
3413
3315
 
3316
+ logAction(isEditing ? 'cancelEditHyperlinkDialog' : 'cancelCreateHyperlinkDialog');
3414
3317
  return _context3.abrupt("return");
3415
3318
 
3416
- case 11:
3319
+ case 14:
3417
3320
  text = data.linkText, url = data.linkTarget, type = data.linkType, target = data.linkEntity;
3418
3321
  Transforms.select(editor, selectionBeforeBlur);
3419
3322
  Editor.withoutNormalizing(editor, function () {
@@ -3425,9 +3328,13 @@ function _addOrEditLink() {
3425
3328
  path: path
3426
3329
  });
3427
3330
  });
3331
+ logAction(isEditing ? 'edit' : 'insert', {
3332
+ nodeType: type,
3333
+ linkType: (_target$sys$linkType = target == null ? void 0 : target.sys.linkType) != null ? _target$sys$linkType : 'uri'
3334
+ });
3428
3335
  focus(editor);
3429
3336
 
3430
- case 15:
3337
+ case 19:
3431
3338
  case "end":
3432
3339
  return _context3.stop();
3433
3340
  }
@@ -3491,7 +3398,7 @@ function UrlHyperlink(props) {
3491
3398
  event.preventDefault();
3492
3399
  event.stopPropagation();
3493
3400
  if (!editor) return;
3494
- addOrEditLink(editor, sdk);
3401
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3495
3402
  }
3496
3403
 
3497
3404
  return /*#__PURE__*/createElement(Tooltip, {
@@ -3527,7 +3434,7 @@ function EntityHyperlink(props) {
3527
3434
  event.preventDefault();
3528
3435
  event.stopPropagation();
3529
3436
  if (!editor) return;
3530
- addOrEditLink(editor, sdk);
3437
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3531
3438
  }
3532
3439
 
3533
3440
  return /*#__PURE__*/createElement(Tooltip, {
@@ -3574,8 +3481,9 @@ function ToolbarHyperlinkButton(props) {
3574
3481
  case 2:
3575
3482
  if (isActive) {
3576
3483
  unwrapLink(editor);
3484
+ editor.tracking.onToolbarAction('unlinkHyperlinks');
3577
3485
  } else {
3578
- addOrEditLink(editor, sdk);
3486
+ addOrEditLink(editor, sdk, editor.tracking.onToolbarAction);
3579
3487
  }
3580
3488
 
3581
3489
  case 3:
@@ -3624,8 +3532,9 @@ var buildHyperlinkEventHandler = function buildHyperlinkEventHandler(sdk) {
3624
3532
 
3625
3533
  if (isLinkActive(editor)) {
3626
3534
  unwrapLink(editor);
3535
+ editor.tracking.onShortcutAction('unlinkHyperlinks');
3627
3536
  } else {
3628
- addOrEditLink(editor, sdk);
3537
+ addOrEditLink(editor, sdk, editor.tracking.onShortcutAction);
3629
3538
  }
3630
3539
  };
3631
3540
  };
@@ -3651,7 +3560,7 @@ var getNodeOfType = function getNodeOfType(type) {
3651
3560
  };
3652
3561
  };
3653
3562
 
3654
- var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3563
+ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk) {
3655
3564
  var common = {
3656
3565
  isElement: true,
3657
3566
  isInline: true
@@ -3682,7 +3591,7 @@ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3682
3591
  _extends({}, common, {
3683
3592
  key: INLINES.ENTRY_HYPERLINK,
3684
3593
  type: INLINES.ENTRY_HYPERLINK,
3685
- component: withLinkTracking(tracking, EntityHyperlink),
3594
+ component: withLinkTracking(EntityHyperlink),
3686
3595
  deserializeHtml: {
3687
3596
  rules: [{
3688
3597
  validNodeName: ['A']
@@ -3696,7 +3605,7 @@ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3696
3605
  _extends({}, common, {
3697
3606
  key: INLINES.ASSET_HYPERLINK,
3698
3607
  type: INLINES.ASSET_HYPERLINK,
3699
- component: withLinkTracking(tracking, EntityHyperlink),
3608
+ component: withLinkTracking(EntityHyperlink),
3700
3609
  deserializeHtml: {
3701
3610
  rules: [{
3702
3611
  validNodeName: ['A']
@@ -4170,6 +4079,7 @@ var createListPlugin = function createListPlugin() {
4170
4079
  }, _overrideByKey[ELEMENT_LI] = {
4171
4080
  type: BLOCKS.LIST_ITEM,
4172
4081
  component: ListItem,
4082
+ // @ts-expect-error
4173
4083
  normalizer: [{
4174
4084
  validNode: hasListAsDirectParent,
4175
4085
  transform: normalizeOrphanedListItem
@@ -4222,26 +4132,62 @@ function ToolbarListButton(props) {
4222
4132
  }, /*#__PURE__*/createElement(ListNumberedIcon, null)));
4223
4133
  }
4224
4134
 
4225
- function ToolbarBoldButton(props) {
4226
- var editor = useContentfulEditor();
4135
+ var createMarkToolbarButton = function createMarkToolbarButton(_ref) {
4136
+ var mark = _ref.mark,
4137
+ title = _ref.title,
4138
+ icon = _ref.icon;
4227
4139
 
4228
- function handleClick() {
4229
- if (!(editor != null && editor.selection)) return;
4230
- toggleMark(editor, {
4231
- key: MARKS.BOLD
4232
- });
4233
- focus(editor);
4234
- }
4140
+ var Mark = function Mark(_ref2) {
4141
+ var isDisabled = _ref2.isDisabled;
4142
+ var editor = useContentfulEditor();
4143
+ var handleClick = useCallback(function () {
4144
+ if (!(editor != null && editor.selection)) return;
4145
+ var isActive = isMarkActive(editor, mark);
4146
+ editor.tracking.onToolbarAction(isActive ? 'unmark' : 'mark', {
4147
+ markType: mark
4148
+ });
4149
+ toggleMark(editor, {
4150
+ key: mark
4151
+ });
4152
+ focus(editor);
4153
+ }, [editor]);
4154
+ if (!editor) return null;
4155
+ return /*#__PURE__*/createElement(ToolbarButton, {
4156
+ title: title,
4157
+ testId: mark + "-toolbar-button",
4158
+ onClick: handleClick,
4159
+ isActive: isMarkActive(editor, mark),
4160
+ isDisabled: isDisabled
4161
+ }, icon);
4162
+ };
4235
4163
 
4236
- if (!editor) return null;
4237
- return /*#__PURE__*/createElement(ToolbarButton, {
4238
- title: "Bold",
4239
- testId: "bold-toolbar-button",
4240
- onClick: handleClick,
4241
- isActive: isMarkActive(editor, MARKS.BOLD),
4242
- isDisabled: props.isDisabled
4243
- }, /*#__PURE__*/createElement(FormatBoldIcon, null));
4244
- }
4164
+ Mark.displayName = mark;
4165
+ return Mark;
4166
+ };
4167
+
4168
+ var buildMarkEventHandler = function buildMarkEventHandler(type) {
4169
+ return function (editor, _ref) {
4170
+ var hotkey = _ref.options.hotkey;
4171
+ return function (event) {
4172
+ if (editor.selection && hotkey && isHotkey(hotkey, event)) {
4173
+ event.preventDefault();
4174
+ var isActive = isMarkActive(editor, type);
4175
+ editor.tracking.onShortcutAction(isActive ? 'unmark' : 'mark', {
4176
+ markType: type
4177
+ });
4178
+ toggleMark(editor, {
4179
+ key: type
4180
+ });
4181
+ }
4182
+ };
4183
+ };
4184
+ };
4185
+
4186
+ var ToolbarBoldButton = /*#__PURE__*/createMarkToolbarButton({
4187
+ title: 'Bold',
4188
+ mark: MARKS.BOLD,
4189
+ icon: /*#__PURE__*/createElement(FormatBoldIcon, null)
4190
+ });
4245
4191
  var styles$e = {
4246
4192
  bold: /*#__PURE__*/css({
4247
4193
  fontWeight: 600
@@ -4264,6 +4210,9 @@ var createBoldPlugin = function createBoldPlugin() {
4264
4210
  options: {
4265
4211
  hotkey: ['mod+b']
4266
4212
  },
4213
+ handlers: {
4214
+ onKeyDown: buildMarkEventHandler(MARKS.BOLD)
4215
+ },
4267
4216
  deserializeHtml: {
4268
4217
  rules: [{
4269
4218
  validNodeName: ['STRONG', 'B']
@@ -4281,26 +4230,11 @@ var createBoldPlugin = function createBoldPlugin() {
4281
4230
  });
4282
4231
  };
4283
4232
 
4284
- function ToolbarCodeButton(props) {
4285
- var editor = useContentfulEditor();
4286
-
4287
- function handleClick() {
4288
- if (!(editor != null && editor.selection)) return;
4289
- toggleMark(editor, {
4290
- key: MARKS.CODE
4291
- });
4292
- focus(editor);
4293
- }
4294
-
4295
- if (!editor) return null;
4296
- return /*#__PURE__*/createElement(ToolbarButton, {
4297
- title: "Code",
4298
- testId: "code-toolbar-button",
4299
- onClick: handleClick,
4300
- isActive: isMarkActive(editor, MARKS.CODE),
4301
- isDisabled: props.isDisabled
4302
- }, /*#__PURE__*/createElement(CodeIcon, null));
4303
- }
4233
+ var ToolbarCodeButton = /*#__PURE__*/createMarkToolbarButton({
4234
+ title: 'Code',
4235
+ mark: MARKS.CODE,
4236
+ icon: /*#__PURE__*/createElement(CodeIcon, null)
4237
+ });
4304
4238
  var styles$f = {
4305
4239
  code: /*#__PURE__*/css({
4306
4240
  fontFamily: 'monospace',
@@ -4319,6 +4253,9 @@ var createCodePlugin = function createCodePlugin() {
4319
4253
  options: {
4320
4254
  hotkey: ['mod+/']
4321
4255
  },
4256
+ handlers: {
4257
+ onKeyDown: buildMarkEventHandler(MARKS.CODE)
4258
+ },
4322
4259
  deserializeHtml: {
4323
4260
  rules: [{
4324
4261
  validNodeName: ['CODE', 'PRE']
@@ -4331,26 +4268,11 @@ var createCodePlugin = function createCodePlugin() {
4331
4268
  });
4332
4269
  };
4333
4270
 
4334
- function ToolbarItalicButton(props) {
4335
- var editor = useContentfulEditor();
4336
-
4337
- function handleClick() {
4338
- if (!(editor != null && editor.selection)) return;
4339
- toggleMark(editor, {
4340
- key: MARKS.ITALIC
4341
- });
4342
- focus(editor);
4343
- }
4344
-
4345
- if (!editor) return null;
4346
- return /*#__PURE__*/createElement(ToolbarButton, {
4347
- title: "Italic",
4348
- testId: "italic-toolbar-button",
4349
- onClick: handleClick,
4350
- isActive: isMarkActive(editor, MARKS.ITALIC),
4351
- isDisabled: props.isDisabled
4352
- }, /*#__PURE__*/createElement(FormatItalicIcon, null));
4353
- }
4271
+ var ToolbarItalicButton = /*#__PURE__*/createMarkToolbarButton({
4272
+ title: 'Italic',
4273
+ mark: MARKS.ITALIC,
4274
+ icon: /*#__PURE__*/createElement(FormatItalicIcon, null)
4275
+ });
4354
4276
  var styles$g = {
4355
4277
  italic: /*#__PURE__*/css({
4356
4278
  fontStyle: 'italic'
@@ -4368,6 +4290,9 @@ var createItalicPlugin = function createItalicPlugin() {
4368
4290
  options: {
4369
4291
  hotkey: ['mod+i']
4370
4292
  },
4293
+ handlers: {
4294
+ onKeyDown: buildMarkEventHandler(MARKS.ITALIC)
4295
+ },
4371
4296
  deserializeHtml: {
4372
4297
  rules: [{
4373
4298
  validNodeName: ['I', 'EM']
@@ -4385,26 +4310,11 @@ var createItalicPlugin = function createItalicPlugin() {
4385
4310
  });
4386
4311
  };
4387
4312
 
4388
- function ToolbarUnderlineButton(props) {
4389
- var editor = useContentfulEditor();
4390
-
4391
- function handleClick() {
4392
- if (!(editor != null && editor.selection)) return;
4393
- toggleMark(editor, {
4394
- key: MARKS.UNDERLINE
4395
- });
4396
- focus(editor);
4397
- }
4398
-
4399
- if (!editor) return null;
4400
- return /*#__PURE__*/createElement(ToolbarButton, {
4401
- title: "Underline",
4402
- testId: "underline-toolbar-button",
4403
- onClick: handleClick,
4404
- isActive: isMarkActive(editor, MARKS.UNDERLINE),
4405
- isDisabled: props.isDisabled
4406
- }, /*#__PURE__*/createElement(FormatUnderlinedIcon, null));
4407
- }
4313
+ var ToolbarUnderlineButton = /*#__PURE__*/createMarkToolbarButton({
4314
+ title: 'Underline',
4315
+ mark: MARKS.UNDERLINE,
4316
+ icon: /*#__PURE__*/createElement(FormatUnderlinedIcon, null)
4317
+ });
4408
4318
  function Underline(props) {
4409
4319
  return /*#__PURE__*/createElement("u", Object.assign({}, props.attributes), props.children);
4410
4320
  }
@@ -4415,6 +4325,9 @@ var createUnderlinePlugin = function createUnderlinePlugin() {
4415
4325
  options: {
4416
4326
  hotkey: ['mod+u']
4417
4327
  },
4328
+ handlers: {
4329
+ onKeyDown: buildMarkEventHandler(MARKS.UNDERLINE)
4330
+ },
4418
4331
  deserializeHtml: {
4419
4332
  rules: [{
4420
4333
  validNodeName: ['U']
@@ -4637,6 +4550,7 @@ var withNormalizer = function withNormalizer(editor) {
4637
4550
  var createNormalizerPlugin = function createNormalizerPlugin() {
4638
4551
  return {
4639
4552
  key: 'NormalizerPlugin',
4553
+ // @ts-expect-error
4640
4554
  withOverrides: withNormalizer
4641
4555
  };
4642
4556
  };
@@ -4814,9 +4728,12 @@ function Quote(props) {
4814
4728
  }), props.children);
4815
4729
  }
4816
4730
 
4817
- function toggleQuote(editor) {
4731
+ function toggleQuote(editor, logAction) {
4818
4732
  if (!editor.selection) return;
4819
4733
  var isActive = isBlockSelected(editor, BLOCKS.QUOTE);
4734
+ logAction(isActive ? 'remove' : 'insert', {
4735
+ nodeType: BLOCKS.QUOTE
4736
+ });
4820
4737
  Editor.withoutNormalizing(editor, function () {
4821
4738
  if (!editor.selection) return;
4822
4739
  Transforms.unwrapNodes(editor, {
@@ -4848,7 +4765,7 @@ var onKeyDownToggleQuote = function onKeyDownToggleQuote(editor, plugin) {
4848
4765
 
4849
4766
  if (hotkey && isHotkey(hotkey, event)) {
4850
4767
  event.preventDefault();
4851
- toggleQuote(editor);
4768
+ toggleQuote(editor, editor.tracking.onShortcutAction);
4852
4769
  }
4853
4770
  };
4854
4771
  };
@@ -4875,7 +4792,54 @@ function createQuotePlugin() {
4875
4792
  normalizer: [{
4876
4793
  validChildren: CONTAINERS[BLOCKS.QUOTE],
4877
4794
  transform: (_transform = {}, _transform[BLOCKS.QUOTE] = transformUnwrap, _transform[BLOCKS.HEADING_1] = transformUnwrap, _transform[BLOCKS.HEADING_2] = transformUnwrap, _transform[BLOCKS.HEADING_3] = transformUnwrap, _transform[BLOCKS.HEADING_4] = transformUnwrap, _transform[BLOCKS.HEADING_5] = transformUnwrap, _transform[BLOCKS.HEADING_6] = transformUnwrap, _transform["default"] = transformLift, _transform)
4878
- }]
4795
+ }],
4796
+ withOverrides: function withOverrides(editor) {
4797
+ var insertFragment = editor.insertFragment;
4798
+
4799
+ editor.insertFragment = function (fragment) {
4800
+ var startingNode = fragment.length && fragment[0];
4801
+ var startsWithBlockquote = Element.isElement(startingNode) && startingNode.type === BLOCKS.QUOTE;
4802
+ var containerEntry = getAbove(editor, {
4803
+ match: {
4804
+ type: TEXT_CONTAINERS
4805
+ }
4806
+ });
4807
+ var containerIsNotEmpty = containerEntry && Node.string(containerEntry[0]) !== '';
4808
+
4809
+ if (startsWithBlockquote && containerIsNotEmpty) {
4810
+ var selection = editor.selection;
4811
+
4812
+ var isContentSelected = function isContentSelected(selection) {
4813
+ return !!selection && Point.compare(selection.anchor, selection.focus) !== 0;
4814
+ }; // if something is selected (highlighted) we replace the selection
4815
+
4816
+
4817
+ if (isContentSelected(selection)) {
4818
+ Transforms["delete"](editor, {
4819
+ at: selection
4820
+ });
4821
+ } // get the cursor entry again, it may be different after deletion
4822
+
4823
+
4824
+ var _containerEntry = getAbove(editor, {
4825
+ match: {
4826
+ type: TEXT_CONTAINERS
4827
+ }
4828
+ });
4829
+
4830
+ var _containerIsNotEmpty = _containerEntry && Node.string(_containerEntry[0]) !== '';
4831
+
4832
+ if (_containerIsNotEmpty) {
4833
+ Transforms.insertNodes(editor, fragment);
4834
+ return;
4835
+ }
4836
+ }
4837
+
4838
+ insertFragment(fragment);
4839
+ };
4840
+
4841
+ return editor;
4842
+ }
4879
4843
  };
4880
4844
  }
4881
4845
 
@@ -4884,7 +4848,7 @@ function ToolbarQuoteButton(props) {
4884
4848
 
4885
4849
  function handleOnClick() {
4886
4850
  if (!editor) return;
4887
- toggleQuote(editor);
4851
+ toggleQuote(editor, editor.tracking.onToolbarAction);
4888
4852
  focus(editor);
4889
4853
  }
4890
4854
 
@@ -4933,8 +4897,7 @@ function hasHeadersOutsideFirstRow(nodes) {
4933
4897
  });
4934
4898
  }
4935
4899
 
4936
- function addTableTrackingEvents(editor, _ref6) {
4937
- var onViewportAction = _ref6.onViewportAction;
4900
+ function addTableTrackingEvents(editor) {
4938
4901
  var insertData = editor.insertData;
4939
4902
 
4940
4903
  editor.insertData = function (data) {
@@ -4948,7 +4911,7 @@ function addTableTrackingEvents(editor, _ref6) {
4948
4911
  if (hasTables(markupBefore)) return;
4949
4912
 
4950
4913
  if (hasTables(markupAfter)) {
4951
- onViewportAction('paste', {
4914
+ editor.tracking.onViewportAction('paste', {
4952
4915
  tablePasted: true,
4953
4916
  hasHeadersOutsideFirstRow: hasHeadersOutsideFirstRow(markupAfter)
4954
4917
  });
@@ -4960,29 +4923,6 @@ function addTableTrackingEvents(editor, _ref6) {
4960
4923
  };
4961
4924
  }
4962
4925
 
4963
- function useTracking(_ref) {
4964
- var onAction = _ref.onAction;
4965
- var trackingMemo = useMemo(function () {
4966
- return {
4967
- onViewportAction: function onViewportAction(actionName, data) {
4968
- if (data === void 0) {
4969
- data = {};
4970
- }
4971
-
4972
- return onAction(actionName, _extends({
4973
- origin: 'viewport-interaction'
4974
- }, data));
4975
- }
4976
- };
4977
- }, [] // eslint-disable-line
4978
- );
4979
- return trackingMemo;
4980
- }
4981
-
4982
- var _constate$2 = /*#__PURE__*/constate(useTracking),
4983
- TrackingProvider = _constate$2[0],
4984
- useTrackingContext = _constate$2[1];
4985
-
4986
4926
  var addRow = function addRow(editor, getNextRowPath) {
4987
4927
  if (someNode(editor, {
4988
4928
  match: {
@@ -5228,9 +5168,6 @@ var TableActions = function TableActions() {
5228
5168
  var editor = useContentfulEditor();
5229
5169
  var isDisabled = useReadOnly();
5230
5170
 
5231
- var _useTrackingContext = useTrackingContext(),
5232
- onViewportAction = _useTrackingContext.onViewportAction;
5233
-
5234
5171
  var _React$useState = React__default.useState(false),
5235
5172
  isOpen = _React$useState[0],
5236
5173
  setOpen = _React$useState[1];
@@ -5280,11 +5217,11 @@ var TableActions = function TableActions() {
5280
5217
  }); // Tracking
5281
5218
 
5282
5219
  var actionName = type + "Table" + (element === 'Table' ? '' : element);
5283
- onViewportAction(actionName, {
5220
+ editor.tracking.onViewportAction(actionName, {
5284
5221
  tableSize: tableSize
5285
5222
  });
5286
5223
  };
5287
- }, [editor, isHeaderEnabled, close, onViewportAction]);
5224
+ }, [editor, isHeaderEnabled, close]);
5288
5225
 
5289
5226
  if (isDisabled) {
5290
5227
  return null;
@@ -5375,7 +5312,7 @@ var createTableOnKeyDown = function createTableOnKeyDown(editor, plugin) {
5375
5312
  };
5376
5313
  };
5377
5314
 
5378
- var createTablePlugin = function createTablePlugin(tracking) {
5315
+ var createTablePlugin = function createTablePlugin() {
5379
5316
  var _overrideByKey;
5380
5317
 
5381
5318
  return createTablePlugin$1({
@@ -5384,7 +5321,7 @@ var createTablePlugin = function createTablePlugin(tracking) {
5384
5321
  onKeyDown: createTableOnKeyDown
5385
5322
  },
5386
5323
  withOverrides: function withOverrides(editor) {
5387
- addTableTrackingEvents(editor, tracking);
5324
+ addTableTrackingEvents(editor);
5388
5325
  var insertFragment = editor.insertFragment;
5389
5326
 
5390
5327
  editor.insertFragment = function (fragments) {
@@ -5484,10 +5421,6 @@ var createTablePlugin = function createTablePlugin(tracking) {
5484
5421
 
5485
5422
  function ToolbarTableButton(props) {
5486
5423
  var editor = useContentfulEditor();
5487
-
5488
- var _useTrackingContext = useTrackingContext(),
5489
- onViewportAction = _useTrackingContext.onViewportAction;
5490
-
5491
5424
  var isActive = editor && isTableActive(editor);
5492
5425
 
5493
5426
  function handleClick() {
@@ -5508,7 +5441,7 @@ function ToolbarTableButton(props) {
5508
5441
  return _context.abrupt("return");
5509
5442
 
5510
5443
  case 2:
5511
- onViewportAction('insertTable');
5444
+ editor.tracking.onToolbarAction('insertTable');
5512
5445
  insertTableAndFocusFirstCell(editor);
5513
5446
  focus(editor);
5514
5447
 
@@ -5613,35 +5546,199 @@ function deleteEmptyParagraph(unit, editor, deleteFunction) {
5613
5546
  }
5614
5547
  }
5615
5548
 
5616
- var createTrailingParagraphPlugin = function createTrailingParagraphPlugin() {
5617
- return createTrailingBlockPlugin({
5618
- options: {
5619
- type: BLOCKS.PARAGRAPH,
5620
- level: 0
5549
+ var _extends2, _extends4, _inlines;
5550
+ var inlines = /*#__PURE__*/Object.values(INLINES).map(function (type) {
5551
+ return {
5552
+ type: type
5553
+ };
5554
+ });
5555
+ var schema = {
5556
+ document: {
5557
+ nodes: [{
5558
+ types: /*#__PURE__*/TOP_LEVEL_BLOCKS.map(function (type) {
5559
+ return {
5560
+ type: type
5561
+ };
5562
+ })
5563
+ }]
5564
+ },
5565
+ blocks: /*#__PURE__*/_extends((_extends2 = {}, _extends2[BLOCKS.PARAGRAPH] = {
5566
+ nodes: [{
5567
+ match: /*#__PURE__*/[].concat(inlines, [{
5568
+ object: 'text'
5569
+ }])
5570
+ }]
5571
+ }, _extends2[BLOCKS.HEADING_1] = {
5572
+ nodes: [{
5573
+ match: /*#__PURE__*/[].concat(inlines, [{
5574
+ object: 'text'
5575
+ }])
5576
+ }]
5577
+ }, _extends2[BLOCKS.HEADING_2] = {
5578
+ nodes: [{
5579
+ match: /*#__PURE__*/[].concat(inlines, [{
5580
+ object: 'text'
5581
+ }])
5582
+ }]
5583
+ }, _extends2[BLOCKS.HEADING_3] = {
5584
+ nodes: [{
5585
+ match: /*#__PURE__*/[].concat(inlines, [{
5586
+ object: 'text'
5587
+ }])
5588
+ }]
5589
+ }, _extends2[BLOCKS.HEADING_4] = {
5590
+ nodes: [{
5591
+ match: /*#__PURE__*/[].concat(inlines, [{
5592
+ object: 'text'
5593
+ }])
5594
+ }]
5595
+ }, _extends2[BLOCKS.HEADING_5] = {
5596
+ nodes: [{
5597
+ match: /*#__PURE__*/[].concat(inlines, [{
5598
+ object: 'text'
5599
+ }])
5600
+ }]
5601
+ }, _extends2[BLOCKS.HEADING_6] = {
5602
+ nodes: [{
5603
+ match: /*#__PURE__*/[].concat(inlines, [{
5604
+ object: 'text'
5605
+ }])
5606
+ }]
5607
+ }, _extends2), /*#__PURE__*/VOID_BLOCKS.reduce(function (blocks, nodeType) {
5608
+ var _extends3;
5609
+
5610
+ return _extends({}, blocks, (_extends3 = {}, _extends3[nodeType] = {
5611
+ isVoid: true
5612
+ }, _extends3));
5613
+ }, {}), (_extends4 = {}, _extends4[BLOCKS.QUOTE] = {
5614
+ nodes: [{
5615
+ match: [/*#__PURE__*/CONTAINERS[BLOCKS.QUOTE].map(function (type) {
5616
+ return {
5617
+ type: type
5618
+ };
5619
+ })],
5620
+ min: 1
5621
+ }],
5622
+ normalize: function normalize(editor, error) {
5623
+ if (error.code === 'child_type_invalid') {
5624
+ return editor.unwrapBlockByKey(error.node.key, BLOCKS.QUOTE);
5625
+ }
5621
5626
  }
5627
+ }, _extends4)),
5628
+ inlines: (_inlines = {}, _inlines[INLINES.HYPERLINK] = {
5629
+ nodes: [{
5630
+ match: [{
5631
+ object: 'text'
5632
+ }]
5633
+ }]
5634
+ }, _inlines[INLINES.ENTRY_HYPERLINK] = {
5635
+ nodes: [{
5636
+ match: [{
5637
+ object: 'text'
5638
+ }]
5639
+ }]
5640
+ }, _inlines[INLINES.ASSET_HYPERLINK] = {
5641
+ nodes: [{
5642
+ match: [{
5643
+ object: 'text'
5644
+ }]
5645
+ }]
5646
+ }, _inlines[INLINES.EMBEDDED_ENTRY] = {
5647
+ isVoid: true
5648
+ }, _inlines)
5649
+ };
5650
+
5651
+ function getCharacterCount(editor) {
5652
+ var document = toContentfulDocument({
5653
+ document: editor.children,
5654
+ schema: schema
5622
5655
  });
5656
+ return documentToPlainTextString(document).length;
5657
+ }
5658
+
5659
+ var actionOrigin = {
5660
+ TOOLBAR: 'toolbar-icon',
5661
+ SHORTCUT: 'shortcut',
5662
+ VIEWPORT: 'viewport-interaction',
5663
+ COMMAND_PALETTE: 'command-palette'
5623
5664
  };
5665
+ var createTrackingPlugin = function createTrackingPlugin(onAction) {
5666
+ var trackingActions = {
5667
+ onViewportAction: function onViewportAction(actionName, data) {
5668
+ if (data === void 0) {
5669
+ data = {};
5670
+ }
5624
5671
 
5625
- /**
5626
- * Re-creates a void node with valid children.
5627
- */
5672
+ return onAction(actionName, _extends({
5673
+ origin: actionOrigin.VIEWPORT
5674
+ }, data));
5675
+ },
5676
+ onShortcutAction: function onShortcutAction(actionName, data) {
5677
+ if (data === void 0) {
5678
+ data = {};
5679
+ }
5680
+
5681
+ return onAction(actionName, _extends({
5682
+ origin: actionOrigin.SHORTCUT
5683
+ }, data));
5684
+ },
5685
+ onToolbarAction: function onToolbarAction(actionName, data) {
5686
+ if (data === void 0) {
5687
+ data = {};
5688
+ }
5628
5689
 
5629
- var transformVoid = function transformVoid(editor, _ref) {
5630
- var node = _ref[0],
5631
- path = _ref[1];
5690
+ return onAction(actionName, _extends({
5691
+ origin: actionOrigin.TOOLBAR
5692
+ }, data));
5693
+ },
5694
+ onCommandPaletteAction: function onCommandPaletteAction(actionName, data) {
5695
+ if (data === void 0) {
5696
+ data = {};
5697
+ }
5632
5698
 
5633
- var validVoid = _extends({}, node, {
5634
- children: [{
5635
- text: ''
5636
- }]
5637
- }); // A workaround because Slate doesn't allow adjusting void nodes children
5699
+ return onAction(actionName, _extends({
5700
+ origin: actionOrigin.COMMAND_PALETTE
5701
+ }, data));
5702
+ }
5703
+ };
5704
+ return {
5705
+ key: 'TrackingPlugin',
5706
+ withOverrides: function withOverrides(editor) {
5707
+ var insertData = editor.insertData;
5708
+ editor.tracking = trackingActions;
5709
+
5710
+ editor.insertData = function (data) {
5711
+ var isCopyAndPaste = data.types.length !== 0;
5712
+
5713
+ if (isCopyAndPaste) {
5714
+ var _window$getSelection;
5715
+
5716
+ var characterCountSelection = (_window$getSelection = window.getSelection()) == null ? void 0 : _window$getSelection.toString().length;
5717
+ var characterCountBefore = getCharacterCount(editor);
5718
+ setTimeout(function () {
5719
+ var characterCountAfter = getCharacterCount(editor);
5720
+ trackingActions.onShortcutAction('paste', {
5721
+ characterCountAfter: characterCountAfter,
5722
+ characterCountBefore: characterCountBefore,
5723
+ characterCountSelection: characterCountSelection
5724
+ });
5725
+ });
5726
+ }
5638
5727
 
5728
+ insertData(data);
5729
+ };
5639
5730
 
5640
- Transforms.removeNodes(editor, {
5641
- at: path
5642
- });
5643
- Transforms.insertNodes(editor, [validVoid], {
5644
- at: path
5731
+ return editor;
5732
+ }
5733
+ };
5734
+ };
5735
+
5736
+ var createTrailingParagraphPlugin = function createTrailingParagraphPlugin() {
5737
+ return createTrailingBlockPlugin({
5738
+ options: {
5739
+ type: BLOCKS.PARAGRAPH,
5740
+ level: 0
5741
+ }
5645
5742
  });
5646
5743
  };
5647
5744
 
@@ -5673,34 +5770,17 @@ var createVoidsPlugin = function createVoidsPlugin() {
5673
5770
  return !(isRootLevel(path) && isFirstChild(path)) && !!node.isVoid;
5674
5771
  }
5675
5772
  }
5676
- }],
5677
- normalizer: [{
5678
- match: {
5679
- isVoid: true
5680
- },
5681
- validNode: function validNode(editor, _ref3) {
5682
- var path = _ref3[1];
5683
- var children = Array.from(Node.children(editor, path));
5684
-
5685
- if (children.length !== 1) {
5686
- return false;
5687
- }
5688
-
5689
- var _children$ = children[0],
5690
- textNode = _children$[0];
5691
- return Text.isText(textNode) && textNode.text === '';
5692
- },
5693
- transform: transformVoid
5694
5773
  }]
5695
5774
  };
5696
5775
  };
5697
5776
 
5698
- var getPlugins = function getPlugins(sdk, tracking) {
5777
+ var getPlugins = function getPlugins(sdk, onAction) {
5699
5778
  return [// AST must come after the HTML deserializer
5700
- createDeserializeHtmlPlugin(), createDeserializeAstPlugin(), createDeserializeDocxPlugin(), // Global shortcuts
5779
+ createDeserializeHtmlPlugin(), createDeserializeAstPlugin(), createDeserializeDocxPlugin(), // Tracking - This should come first so all plugins below will have access to `editor.tracking`
5780
+ createTrackingPlugin(onAction), // Global / Global shortcuts
5701
5781
  createDragAndDropPlugin(), // Block Elements
5702
- createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(tracking), createEmbeddedEntryBlockPlugin(sdk, tracking), createEmbeddedAssetBlockPlugin(sdk, tracking), // Inline elements
5703
- createHyperlinkPlugin(sdk, tracking), createEmbeddedEntityInlinePlugin(sdk, tracking), // Marks
5782
+ createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(), createEmbeddedEntryBlockPlugin(sdk), createEmbeddedAssetBlockPlugin(sdk), // Inline elements
5783
+ createHyperlinkPlugin(sdk), createEmbeddedEntityInlinePlugin(sdk), // Marks
5704
5784
  createMarksPlugin(), // Other
5705
5785
  createTrailingParagraphPlugin(), createTextPlugin(), createVoidsPlugin(), createSelectOnBackspacePlugin(), // Pasting content from other sources
5706
5786
  createPasteHTMLPlugin(), // These plugins drive their configurations from the list of plugins
@@ -5922,10 +6002,10 @@ var Toolbar = function Toolbar(_ref) {
5922
6002
  isDisabled: isDisabled
5923
6003
  })), validationInfo.isAnyBlockFormattingEnabled && /*#__PURE__*/React__default.createElement("span", {
5924
6004
  className: styles$k.divider
5925
- }), isNodeTypeEnabled(sdk.field, BLOCKS.QUOTE) && /*#__PURE__*/React__default.createElement(ToolbarQuoteButton, {
5926
- isDisabled: isDisabled || !canInsertBlocks
5927
6005
  }), /*#__PURE__*/React__default.createElement(ToolbarListButton, {
5928
6006
  isDisabled: isDisabled || !canInsertBlocks
6007
+ }), isNodeTypeEnabled(sdk.field, BLOCKS.QUOTE) && /*#__PURE__*/React__default.createElement(ToolbarQuoteButton, {
6008
+ isDisabled: isDisabled || !canInsertBlocks
5929
6009
  }), isNodeTypeEnabled(sdk.field, BLOCKS.HR) && /*#__PURE__*/React__default.createElement(ToolbarHrButton, {
5930
6010
  isDisabled: isDisabled || !canInsertBlocks
5931
6011
  }), isNodeTypeEnabled(sdk.field, BLOCKS.TABLE) && /*#__PURE__*/React__default.createElement(ToolbarTableButton, {
@@ -5968,62 +6048,113 @@ var StickyToolbarWrapper = function StickyToolbarWrapper(_ref) {
5968
6048
  }, children);
5969
6049
  };
5970
6050
 
6051
+ /**
6052
+ * For legacy reasons, a document may not have any content at all
6053
+ * e.g:
6054
+ *
6055
+ * {nodeType: document, data: {}, content: []}
6056
+ *
6057
+ * Rendering such document will break the Slate editor
6058
+ */
6059
+
6060
+ var hasContent = function hasContent(doc) {
6061
+ if (!doc) {
6062
+ return false;
6063
+ }
6064
+
6065
+ return doc.content.length > 0;
6066
+ };
6067
+
6068
+ var useNormalizedSlateValue = function useNormalizedSlateValue(_ref) {
6069
+ var id = _ref.id,
6070
+ incomingDoc = _ref.incomingDoc,
6071
+ plugins = _ref.plugins;
6072
+ return useMemo(function () {
6073
+ var editor = createPlateEditor({
6074
+ id: id,
6075
+ plugins: plugins,
6076
+ disableCorePlugins: disableCorePlugins
6077
+ });
6078
+ var doc = toSlatejsDocument({
6079
+ document: hasContent(incomingDoc) ? incomingDoc : EMPTY_DOCUMENT,
6080
+ schema: schema
6081
+ }); // Sets editor value & kicks normalization
6082
+
6083
+ Transforms.insertNodes(editor, doc); // TODO: return the editor itself to avoid recompiling & initializing all
6084
+ // of the plugins again. It's currently not possible due to a bug in Plate
6085
+ // with initialValues
6086
+ // See: https://slate-js.slack.com/archives/C013QHXSCG1/p1645112799942819
6087
+
6088
+ return editor.children;
6089
+ }, [id, plugins, incomingDoc]);
6090
+ };
6091
+
6092
+ /**
6093
+ * Returns whether a given operation is relevant enough to trigger a save.
6094
+ */
6095
+
6096
+ var isRelevantOperation = function isRelevantOperation(op) {
6097
+ if (op.type === 'set_selection') {
6098
+ return false;
6099
+ }
6100
+
6101
+ return true;
6102
+ };
6103
+
6104
+ var useOnValueChanged = function useOnValueChanged(_ref) {
6105
+ var editor = _ref.editor,
6106
+ handler = _ref.handler;
6107
+ var onChange = useMemo(function () {
6108
+ return debounce(function (document) {
6109
+ handler == null ? void 0 : handler(toContentfulDocument({
6110
+ document: document,
6111
+ schema: schema
6112
+ }));
6113
+ }, 500);
6114
+ }, [handler]);
6115
+ return useCallback(function (value) {
6116
+ var operations = editor.operations.filter(isRelevantOperation);
6117
+
6118
+ if (operations.length > 0) {
6119
+ onChange(value);
6120
+ }
6121
+ }, [editor, onChange]);
6122
+ };
6123
+
5971
6124
  var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
5972
6125
  var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
5973
- var tracking = useTrackingContext();
6126
+ var id = useContentfulEditorId();
5974
6127
  var editor = useContentfulEditor();
5975
-
5976
- var _useState = useState([]),
5977
- value = _useState[0],
5978
- setValue = _useState[1];
5979
-
6128
+ var plugins = React__default.useMemo(function () {
6129
+ var _props$onAction;
6130
+
6131
+ return getPlugins(props.sdk, (_props$onAction = props.onAction) != null ? _props$onAction : noop);
6132
+ }, [props.sdk, props.onAction]);
6133
+ var initialValue = useNormalizedSlateValue({
6134
+ id: id,
6135
+ incomingDoc: props.value,
6136
+ plugins: plugins
6137
+ });
6138
+ var onValueChanged = useOnValueChanged({
6139
+ editor: editor,
6140
+ handler: props.onChange
6141
+ });
5980
6142
  var classNames = cx(styles$j.editor, props.minHeight !== undefined ? css({
5981
6143
  minHeight: props.minHeight
5982
6144
  }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
5983
- var plugins = React__default.useMemo(function () {
5984
- return getPlugins(props.sdk, tracking);
5985
- }, [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]);
6007
6145
  return /*#__PURE__*/React__default.createElement("div", {
6008
6146
  className: styles$j.root,
6009
6147
  "data-test-id": "rich-text-editor"
6010
6148
  }, /*#__PURE__*/React__default.createElement(Plate, {
6011
- id: getContentfulEditorId(props.sdk),
6012
- value: value,
6149
+ id: id,
6150
+ initialValue: initialValue,
6013
6151
  plugins: plugins,
6014
6152
  disableCorePlugins: disableCorePlugins,
6015
6153
  editableProps: {
6016
6154
  className: classNames,
6017
6155
  readOnly: props.isDisabled
6018
6156
  },
6019
- onChange: function onChange(slateDoc) {
6020
- setValue(slateDoc);
6021
- var contentfulDoc = toContentfulDocument({
6022
- document: slateDoc,
6023
- schema: schema
6024
- });
6025
- props.onChange == null ? void 0 : props.onChange(contentfulDoc);
6026
- }
6157
+ onChange: onValueChanged
6027
6158
  }, !props.isToolbarHidden && /*#__PURE__*/React__default.createElement(StickyToolbarWrapper, {
6028
6159
  isDisabled: props.isDisabled
6029
6160
  }, /*#__PURE__*/React__default.createElement(Toolbar, {
@@ -6040,12 +6171,11 @@ var RichTextEditor = function RichTextEditor(props) {
6040
6171
  var isEmptyValue = useCallback(function (value) {
6041
6172
  return !value || deepEquals(value, EMPTY_DOCUMENT);
6042
6173
  }, []);
6174
+ var editorId = getContentfulEditorId(sdk);
6043
6175
  return /*#__PURE__*/React__default.createElement(EntityProvider, {
6044
6176
  sdk: sdk
6045
6177
  }, /*#__PURE__*/React__default.createElement(SdkProvider, {
6046
6178
  sdk: sdk
6047
- }, /*#__PURE__*/React__default.createElement(TrackingProvider, {
6048
- onAction: onAction || noop
6049
6179
  }, /*#__PURE__*/React__default.createElement(FieldConnector, {
6050
6180
  throttle: 0,
6051
6181
  field: sdk.field,
@@ -6057,17 +6187,17 @@ var RichTextEditor = function RichTextEditor(props) {
6057
6187
  disabled = _ref.disabled,
6058
6188
  setValue = _ref.setValue,
6059
6189
  externalReset = _ref.externalReset;
6060
- return /*#__PURE__*/React__default.createElement(ContentfulEditorProvider, {
6061
- sdk: sdk
6190
+ return /*#__PURE__*/React__default.createElement(ContentfulEditorIdProvider, {
6191
+ value: editorId
6062
6192
  }, /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
6063
6193
  key: "rich-text-editor-" + externalReset,
6064
6194
  value: lastRemoteValue,
6065
6195
  sdk: sdk,
6066
- onAction: onAction || noop,
6196
+ onAction: onAction,
6067
6197
  isDisabled: disabled,
6068
6198
  onChange: setValue
6069
6199
  })));
6070
- }))));
6200
+ })));
6071
6201
  };
6072
6202
 
6073
6203
  var LINK_TYPES$1 = {