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

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 +551 -370
  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 +554 -373
  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/PasteHTML/createPasteHTMLPlugin.d.ts +6 -0
  35. package/dist/plugins/Quote/toggleQuote.d.ts +5 -3
  36. package/dist/plugins/Table/actions/addColumn.d.ts +3 -3
  37. package/dist/plugins/Table/actions/addRow.d.ts +3 -3
  38. package/dist/plugins/Table/actions/setHeader.d.ts +2 -2
  39. package/dist/plugins/Table/addTableTrackingEvents.d.ts +2 -3
  40. package/dist/plugins/Table/createTablePlugin.d.ts +1 -2
  41. package/dist/plugins/Table/helpers.d.ts +7 -7
  42. package/dist/plugins/Tracking/createTrackingPlugin.d.ts +10 -0
  43. package/dist/plugins/Tracking/index.d.ts +1 -0
  44. package/dist/plugins/Tracking/utils.d.ts +2 -0
  45. package/dist/plugins/TrailingParagraph/index.d.ts +2 -1
  46. package/dist/plugins/Voids/transformVoid.d.ts +2 -2
  47. package/dist/plugins/index.d.ts +2 -2
  48. package/dist/plugins/links-tracking.d.ts +1 -2
  49. package/dist/test-utils/assertOutput.d.ts +2 -2
  50. package/dist/test-utils/createEditor.d.ts +5 -6
  51. package/dist/test-utils/jsx.d.ts +1 -1
  52. package/dist/test-utils/mockPlugin.d.ts +1 -1
  53. package/dist/test-utils/setEmptyDataAttribute.d.ts +2 -2
  54. package/dist/types.d.ts +6 -2
  55. package/dist/useOnValueChanged.d.ts +7 -0
  56. package/package.json +1 -1
  57. package/CHANGELOG.md +0 -410
  58. package/dist/TrackingProvider.d.ts +0 -11
@@ -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, createPlateEditor, 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 constate from 'constate';
11
9
  import { createDeserializeDocxPlugin } from '@udecode/plate-serializer-docx';
12
10
  import { createSoftBreakPlugin as createSoftBreakPlugin$1, createExitBreakPlugin as createExitBreakPlugin$1 } from '@udecode/plate-break';
13
11
  import isHotkey from 'is-hotkey';
14
- import { Text, Element, Editor, Transforms, Range, Path, Node } from 'slate';
12
+ import { Text, Element, Editor, Transforms, Range, Node, Path, 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,126 +239,37 @@ 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);
253
+ if (!id) {
254
+ throw new Error('could not find editor id. Please ensure the component is wrapped in <ContentfulEditorIdProvider> ');
255
+ }
256
+
257
+ return id;
258
+ } // This hook re-renders when the value changes
259
+ // Use case: Toolbar icons, for example
260
+
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
266
+
267
+ function useContentfulEditorRef() {
268
+ var editorId = useContentfulEditorId();
352
269
  var editor = usePlateEditorRef(editorId);
353
270
  return editor;
354
271
  }
355
272
 
356
- var _constate = /*#__PURE__*/constate(useContentfulEditorHook),
357
- ContentfulEditorProvider = _constate[0],
358
- useContentfulEditor = _constate[1];
359
-
360
273
  var createSoftBreakPlugin = function createSoftBreakPlugin() {
361
274
  return createSoftBreakPlugin$1({
362
275
  then: function then(editor) {
@@ -536,6 +449,10 @@ function insertLink(editor, options) {
536
449
  } // TODO: move to hyperlink plugin
537
450
 
538
451
  function isLinkActive(editor) {
452
+ if (!editor) {
453
+ return false;
454
+ }
455
+
539
456
  var _Array$from2 = Array.from(Editor.nodes(editor, {
540
457
  match: function match(node) {
541
458
  return !Editor.isEditor(node) && Element.isElement(node) && LINK_TYPES.includes(node.type);
@@ -695,12 +612,14 @@ var focus = function focus(editor) {
695
612
  }
696
613
  };
697
614
 
698
- function withLinkTracking(tracking, Component) {
615
+ function withLinkTracking(Component) {
699
616
  return function ComponentWithTracking(props) {
617
+ var editor = useContentfulEditorRef();
618
+ var onEntityFetchComplete = React__default.useCallback(function () {
619
+ return editor.tracking.onViewportAction('linkRendered');
620
+ }, [editor]);
700
621
  return /*#__PURE__*/React__default.createElement(Component, Object.assign({}, props, {
701
- onEntityFetchComplete: function onEntityFetchComplete() {
702
- tracking.onViewportAction('linkRendered');
703
- }
622
+ onEntityFetchComplete: onEntityFetchComplete
704
623
  }));
705
624
  };
706
625
  }
@@ -714,9 +633,9 @@ function useSdk(_ref) {
714
633
  return sdkMemo;
715
634
  }
716
635
 
717
- var _constate$1 = /*#__PURE__*/constate(useSdk),
718
- SdkProvider = _constate$1[0],
719
- useSdkContext = _constate$1[1];
636
+ var _constate = /*#__PURE__*/constate(useSdk),
637
+ SdkProvider = _constate[0],
638
+ useSdkContext = _constate[1];
720
639
 
721
640
  var styles = {
722
641
  scheduleIcon: /*#__PURE__*/css({
@@ -1966,12 +1885,11 @@ function _selectEntityAndInsert() {
1966
1885
  config = _extends({}, baseConfig, {
1967
1886
  withCreate: true
1968
1887
  });
1969
- _context.prev = 5;
1970
1888
  selection = editor.selection;
1971
- _context.next = 9;
1889
+ _context.next = 8;
1972
1890
  return selectEntity(config);
1973
1891
 
1974
- case 9:
1892
+ case 8:
1975
1893
  entity = _context.sent;
1976
1894
 
1977
1895
  if (entity) {
@@ -1979,6 +1897,9 @@ function _selectEntityAndInsert() {
1979
1897
  break;
1980
1898
  }
1981
1899
 
1900
+ logAction('cancelCreateEmbedDialog', {
1901
+ nodeType: nodeType
1902
+ });
1982
1903
  return _context.abrupt("return");
1983
1904
 
1984
1905
  case 12:
@@ -1987,31 +1908,13 @@ function _selectEntityAndInsert() {
1987
1908
  logAction('insert', {
1988
1909
  nodeType: nodeType
1989
1910
  });
1990
- _context.next = 24;
1991
- break;
1992
-
1993
- case 17:
1994
- _context.prev = 17;
1995
- _context.t0 = _context["catch"](5);
1996
1911
 
1997
- if (!_context.t0) {
1998
- _context.next = 23;
1999
- break;
2000
- }
2001
-
2002
- throw _context.t0;
2003
-
2004
- case 23:
2005
- logAction('cancelCreateEmbedDialog', {
2006
- nodeType: nodeType
2007
- });
2008
-
2009
- case 24:
1912
+ case 15:
2010
1913
  case "end":
2011
1914
  return _context.stop();
2012
1915
  }
2013
1916
  }
2014
- }, _callee, null, [[5, 17]]);
1917
+ }, _callee);
2015
1918
  }));
2016
1919
  return _selectEntityAndInsert.apply(this, arguments);
2017
1920
  }
@@ -2058,7 +1961,6 @@ var styles$4 = {
2058
1961
  function EmbeddedEntityBlockToolbarIcon(_ref) {
2059
1962
  var isButton = _ref.isButton,
2060
1963
  isDisabled = _ref.isDisabled,
2061
- logAction = _ref.logAction,
2062
1964
  nodeType = _ref.nodeType,
2063
1965
  onClose = _ref.onClose;
2064
1966
  var editor = useContentfulEditor();
@@ -2067,7 +1969,7 @@ function EmbeddedEntityBlockToolbarIcon(_ref) {
2067
1969
  var handleClick = function handleClick(event) {
2068
1970
  event.preventDefault();
2069
1971
  onClose();
2070
- selectEntityAndInsert(nodeType, sdk, editor, logAction || noop);
1972
+ selectEntityAndInsert(nodeType, sdk, editor, editor.tracking.onToolbarAction);
2071
1973
  };
2072
1974
 
2073
1975
  var type = getEntityTypeFromNodeType(nodeType);
@@ -2134,20 +2036,20 @@ function getWithEmbeddedEntityEvents(nodeType, sdk) {
2134
2036
  }
2135
2037
 
2136
2038
  if (hotkey && isHotkey(hotkey, event)) {
2137
- selectEntityAndInsert(nodeType, sdk, editor, noop);
2039
+ selectEntityAndInsert(nodeType, sdk, editor, editor.tracking.onShortcutAction);
2138
2040
  }
2139
2041
  };
2140
2042
  };
2141
2043
  }
2142
2044
 
2143
2045
  var createEmbeddedEntityPlugin = function createEmbeddedEntityPlugin(nodeType, hotkey) {
2144
- return function (sdk, tracking) {
2046
+ return function (sdk) {
2145
2047
  return {
2146
2048
  key: nodeType,
2147
2049
  type: nodeType,
2148
2050
  isElement: true,
2149
2051
  isVoid: true,
2150
- component: withLinkTracking(tracking, LinkedEntityBlock),
2052
+ component: withLinkTracking(LinkedEntityBlock),
2151
2053
  options: {
2152
2054
  hotkey: hotkey
2153
2055
  },
@@ -2365,44 +2267,53 @@ function EmbeddedEntityInline(props) {
2365
2267
  })), props.children);
2366
2268
  }
2367
2269
 
2368
- function selectEntityAndInsert$1(_x, _x2) {
2270
+ function selectEntityAndInsert$1(_x, _x2, _x3) {
2369
2271
  return _selectEntityAndInsert$1.apply(this, arguments);
2370
2272
  }
2371
2273
 
2372
2274
  function _selectEntityAndInsert$1() {
2373
- _selectEntityAndInsert$1 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(editor, sdk) {
2275
+ _selectEntityAndInsert$1 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(editor, sdk, logAction) {
2374
2276
  var config, selection, entry, inlineEntryNode;
2375
2277
  return runtime_1.wrap(function _callee2$(_context2) {
2376
2278
  while (1) {
2377
2279
  switch (_context2.prev = _context2.next) {
2378
2280
  case 0:
2281
+ logAction('openCreateEmbedDialog', {
2282
+ nodeType: INLINES.EMBEDDED_ENTRY
2283
+ });
2379
2284
  config = _extends({}, newEntitySelectorConfigFromRichTextField(sdk.field, INLINES.EMBEDDED_ENTRY), {
2380
2285
  withCreate: true
2381
2286
  });
2382
2287
  selection = editor.selection;
2383
- _context2.next = 4;
2288
+ _context2.next = 5;
2384
2289
  return sdk.dialogs.selectSingleEntry(config);
2385
2290
 
2386
- case 4:
2291
+ case 5:
2387
2292
  entry = _context2.sent;
2388
2293
  focus(editor); // Dialog steals focus from editor, return it.
2389
2294
 
2390
2295
  if (entry) {
2391
- _context2.next = 8;
2296
+ _context2.next = 10;
2392
2297
  break;
2393
2298
  }
2394
2299
 
2300
+ logAction('cancelCreateEmbedDialog', {
2301
+ nodeType: INLINES.EMBEDDED_ENTRY
2302
+ });
2395
2303
  return _context2.abrupt("return");
2396
2304
 
2397
- case 8:
2305
+ case 10:
2398
2306
  inlineEntryNode = createInlineEntryNode(entry.sys.id); // Got to wait until focus is really back on the editor or setSelection() won't work.
2399
2307
 
2400
2308
  setTimeout(function () {
2401
2309
  Transforms.setSelection(editor, selection);
2402
2310
  Transforms.insertNodes(editor, inlineEntryNode);
2403
2311
  }, 0);
2312
+ logAction('insert', {
2313
+ nodeType: INLINES.EMBEDDED_ENTRY
2314
+ });
2404
2315
 
2405
- case 10:
2316
+ case 13:
2406
2317
  case "end":
2407
2318
  return _context2.stop();
2408
2319
  }
@@ -2416,7 +2327,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2416
2327
  var editor = useContentfulEditor();
2417
2328
  var sdk = useSdkContext();
2418
2329
 
2419
- function handleClick(_x3) {
2330
+ function handleClick(_x4) {
2420
2331
  return _handleClick.apply(this, arguments);
2421
2332
  }
2422
2333
 
@@ -2438,7 +2349,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2438
2349
  case 3:
2439
2350
  props.onClose();
2440
2351
  _context.next = 6;
2441
- return selectEntityAndInsert$1(editor, sdk);
2352
+ return selectEntityAndInsert$1(editor, sdk, editor.tracking.onToolbarAction);
2442
2353
 
2443
2354
  case 6:
2444
2355
  case "end":
@@ -2471,7 +2382,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
2471
2382
  className: "rich-text__embedded-entry-list-icon " + styles$6.icon
2472
2383
  }), /*#__PURE__*/createElement("span", null, "Inline entry")));
2473
2384
  }
2474
- function createEmbeddedEntityInlinePlugin(sdk, tracking) {
2385
+ function createEmbeddedEntityInlinePlugin(sdk) {
2475
2386
  var htmlAttributeName = 'data-embedded-entity-inline-id';
2476
2387
  return {
2477
2388
  key: INLINES.EMBEDDED_ENTRY,
@@ -2479,7 +2390,7 @@ function createEmbeddedEntityInlinePlugin(sdk, tracking) {
2479
2390
  isElement: true,
2480
2391
  isInline: true,
2481
2392
  isVoid: true,
2482
- component: withLinkTracking(tracking, EmbeddedEntityInline),
2393
+ component: withLinkTracking(EmbeddedEntityInline),
2483
2394
  options: {
2484
2395
  hotkey: 'mod+shift+2'
2485
2396
  },
@@ -2505,7 +2416,7 @@ function getWithEmbeddedEntryInlineEvents(sdk) {
2505
2416
  if (!editor) return;
2506
2417
 
2507
2418
  if (hotkey && isHotkey(hotkey, event)) {
2508
- selectEntityAndInsert$1(editor, sdk);
2419
+ selectEntityAndInsert$1(editor, sdk, editor.tracking.onShortcutAction);
2509
2420
  }
2510
2421
  };
2511
2422
  };
@@ -2608,6 +2519,10 @@ function ToolbarHeadingButton(props) {
2608
2519
  prevOnChange.apply(void 0, arguments);
2609
2520
  };
2610
2521
 
2522
+ var isActive = isBlockSelected(editor, type);
2523
+ editor.tracking.onToolbarAction(isActive ? 'remove' : 'insert', {
2524
+ nodeType: type
2525
+ });
2611
2526
  toggleNodeType(editor, {
2612
2527
  activeType: type,
2613
2528
  inactiveType: type
@@ -2729,6 +2644,24 @@ function createHeading(Tag, block) {
2729
2644
 
2730
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);
2731
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
+
2732
2665
  var createHeadingPlugin = function createHeadingPlugin() {
2733
2666
  var _transform;
2734
2667
 
@@ -2745,8 +2678,8 @@ var createHeadingPlugin = function createHeadingPlugin() {
2745
2678
  match: {
2746
2679
  type: HEADINGS
2747
2680
  },
2748
- validChildren: function validChildren(_, _ref) {
2749
- var node = _ref[0];
2681
+ validChildren: function validChildren(_, _ref2) {
2682
+ var node = _ref2[0];
2750
2683
  return isInlineOrText(node);
2751
2684
  },
2752
2685
  transform: (_transform = {}, _transform[BLOCKS.PARAGRAPH] = transformUnwrap, _transform["default"] = transformLift, _transform)
@@ -2763,8 +2696,8 @@ var createHeadingPlugin = function createHeadingPlugin() {
2763
2696
  start: true,
2764
2697
  // Exclude headings inside lists as it interferes with the list's
2765
2698
  // insertBreak implementation
2766
- filter: function filter(_ref2) {
2767
- var path = _ref2[1];
2699
+ filter: function filter(_ref3) {
2700
+ var path = _ref3[1];
2768
2701
  return !getAbove(editor, {
2769
2702
  at: path,
2770
2703
  match: {
@@ -2788,7 +2721,7 @@ var createHeadingPlugin = function createHeadingPlugin() {
2788
2721
  hotkey: ["mod+alt+" + level]
2789
2722
  },
2790
2723
  handlers: {
2791
- onKeyDown: onKeyDownToggleElement
2724
+ onKeyDown: buildHeadingEventHandler(nodeType)
2792
2725
  },
2793
2726
  deserializeHtml: {
2794
2727
  rules: [{
@@ -2860,10 +2793,6 @@ function withHrEvents(editor) {
2860
2793
  pathToSelectedHr = _getNodeEntryFromSele[1];
2861
2794
 
2862
2795
  if (pathToSelectedHr) {
2863
- if (shouldUnwrapBlockquote(editor, BLOCKS.HR)) {
2864
- unwrapFromRoot(editor);
2865
- }
2866
-
2867
2796
  var isBackspace = event.key === 'Backspace';
2868
2797
  var isDelete = event.key === 'Delete';
2869
2798
 
@@ -2881,11 +2810,6 @@ function ToolbarHrButton(props) {
2881
2810
 
2882
2811
  function handleOnClick() {
2883
2812
  if (!(editor != null && editor.selection)) return;
2884
-
2885
- if (shouldUnwrapBlockquote(editor, BLOCKS.HR)) {
2886
- unwrapFromRoot(editor);
2887
- }
2888
-
2889
2813
  var hr = {
2890
2814
  type: BLOCKS.HR,
2891
2815
  data: {},
@@ -3318,13 +3242,15 @@ function HyperlinkModal(props) {
3318
3242
  testId: "confirm-cta"
3319
3243
  }, props.linkType ? 'Update' : 'Insert'))));
3320
3244
  }
3321
- function addOrEditLink(_x, _x2) {
3245
+ function addOrEditLink(_x, _x2, _x3) {
3322
3246
  return _addOrEditLink.apply(this, arguments);
3323
3247
  }
3324
3248
 
3325
3249
  function _addOrEditLink() {
3326
- _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk) {
3327
- var linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionBeforeBlur, currentLinkText, data, text, url, type, target;
3250
+ _addOrEditLink = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(editor, sdk, logAction) {
3251
+ var _target$sys$linkType;
3252
+
3253
+ var linkType, linkText, linkTarget, linkEntity, _getNodeEntryFromSele, node, path, selectionBeforeBlur, currentLinkText, isEditing, data, text, url, type, target;
3328
3254
 
3329
3255
  return runtime_1.wrap(function _callee3$(_context3) {
3330
3256
  while (1) {
@@ -3349,9 +3275,11 @@ function _addOrEditLink() {
3349
3275
 
3350
3276
  selectionBeforeBlur = _extends({}, editor.selection);
3351
3277
  currentLinkText = linkText || Editor.string(editor, editor.selection);
3352
- _context3.next = 8;
3278
+ isEditing = Boolean(node && path);
3279
+ logAction(isEditing ? 'openEditHyperlinkDialog' : 'openCreateHyperlinkDialog');
3280
+ _context3.next = 10;
3353
3281
  return ModalDialogLauncher.openDialog({
3354
- title: linkType ? 'Edit hyperlink' : 'Insert hyperlink',
3282
+ title: isEditing ? 'Edit hyperlink' : 'Insert hyperlink',
3355
3283
  width: 'large',
3356
3284
  shouldCloseOnEscapePress: true,
3357
3285
  shouldCloseOnOverlayClick: true,
@@ -3368,17 +3296,18 @@ function _addOrEditLink() {
3368
3296
  });
3369
3297
  });
3370
3298
 
3371
- case 8:
3299
+ case 10:
3372
3300
  data = _context3.sent;
3373
3301
 
3374
3302
  if (data) {
3375
- _context3.next = 11;
3303
+ _context3.next = 14;
3376
3304
  break;
3377
3305
  }
3378
3306
 
3307
+ logAction(isEditing ? 'cancelEditHyperlinkDialog' : 'cancelCreateHyperlinkDialog');
3379
3308
  return _context3.abrupt("return");
3380
3309
 
3381
- case 11:
3310
+ case 14:
3382
3311
  text = data.linkText, url = data.linkTarget, type = data.linkType, target = data.linkEntity;
3383
3312
  Transforms.select(editor, selectionBeforeBlur);
3384
3313
  Editor.withoutNormalizing(editor, function () {
@@ -3390,9 +3319,13 @@ function _addOrEditLink() {
3390
3319
  path: path
3391
3320
  });
3392
3321
  });
3322
+ logAction(isEditing ? 'edit' : 'insert', {
3323
+ nodeType: type,
3324
+ linkType: (_target$sys$linkType = target == null ? void 0 : target.sys.linkType) != null ? _target$sys$linkType : 'uri'
3325
+ });
3393
3326
  focus(editor);
3394
3327
 
3395
- case 15:
3328
+ case 19:
3396
3329
  case "end":
3397
3330
  return _context3.stop();
3398
3331
  }
@@ -3456,7 +3389,7 @@ function UrlHyperlink(props) {
3456
3389
  event.preventDefault();
3457
3390
  event.stopPropagation();
3458
3391
  if (!editor) return;
3459
- addOrEditLink(editor, sdk);
3392
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3460
3393
  }
3461
3394
 
3462
3395
  return /*#__PURE__*/createElement(Tooltip, {
@@ -3492,7 +3425,7 @@ function EntityHyperlink(props) {
3492
3425
  event.preventDefault();
3493
3426
  event.stopPropagation();
3494
3427
  if (!editor) return;
3495
- addOrEditLink(editor, sdk);
3428
+ addOrEditLink(editor, sdk, editor.tracking.onViewportAction);
3496
3429
  }
3497
3430
 
3498
3431
  return /*#__PURE__*/createElement(Tooltip, {
@@ -3539,8 +3472,9 @@ function ToolbarHyperlinkButton(props) {
3539
3472
  case 2:
3540
3473
  if (isActive) {
3541
3474
  unwrapLink(editor);
3475
+ editor.tracking.onToolbarAction('unlinkHyperlinks');
3542
3476
  } else {
3543
- addOrEditLink(editor, sdk);
3477
+ addOrEditLink(editor, sdk, editor.tracking.onToolbarAction);
3544
3478
  }
3545
3479
 
3546
3480
  case 3:
@@ -3589,8 +3523,9 @@ var buildHyperlinkEventHandler = function buildHyperlinkEventHandler(sdk) {
3589
3523
 
3590
3524
  if (isLinkActive(editor)) {
3591
3525
  unwrapLink(editor);
3526
+ editor.tracking.onShortcutAction('unlinkHyperlinks');
3592
3527
  } else {
3593
- addOrEditLink(editor, sdk);
3528
+ addOrEditLink(editor, sdk, editor.tracking.onShortcutAction);
3594
3529
  }
3595
3530
  };
3596
3531
  };
@@ -3616,7 +3551,7 @@ var getNodeOfType = function getNodeOfType(type) {
3616
3551
  };
3617
3552
  };
3618
3553
 
3619
- var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3554
+ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk) {
3620
3555
  var common = {
3621
3556
  isElement: true,
3622
3557
  isInline: true
@@ -3647,7 +3582,7 @@ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3647
3582
  _extends({}, common, {
3648
3583
  key: INLINES.ENTRY_HYPERLINK,
3649
3584
  type: INLINES.ENTRY_HYPERLINK,
3650
- component: withLinkTracking(tracking, EntityHyperlink),
3585
+ component: withLinkTracking(EntityHyperlink),
3651
3586
  deserializeHtml: {
3652
3587
  rules: [{
3653
3588
  validNodeName: ['A']
@@ -3661,7 +3596,7 @@ var createHyperlinkPlugin = function createHyperlinkPlugin(sdk, tracking) {
3661
3596
  _extends({}, common, {
3662
3597
  key: INLINES.ASSET_HYPERLINK,
3663
3598
  type: INLINES.ASSET_HYPERLINK,
3664
- component: withLinkTracking(tracking, EntityHyperlink),
3599
+ component: withLinkTracking(EntityHyperlink),
3665
3600
  deserializeHtml: {
3666
3601
  rules: [{
3667
3602
  validNodeName: ['A']
@@ -4135,6 +4070,7 @@ var createListPlugin = function createListPlugin() {
4135
4070
  }, _overrideByKey[ELEMENT_LI] = {
4136
4071
  type: BLOCKS.LIST_ITEM,
4137
4072
  component: ListItem,
4073
+ // @ts-expect-error
4138
4074
  normalizer: [{
4139
4075
  validNode: hasListAsDirectParent,
4140
4076
  transform: normalizeOrphanedListItem
@@ -4187,26 +4123,62 @@ function ToolbarListButton(props) {
4187
4123
  }, /*#__PURE__*/createElement(ListNumberedIcon, null)));
4188
4124
  }
4189
4125
 
4190
- function ToolbarBoldButton(props) {
4191
- var editor = useContentfulEditor();
4126
+ var createMarkToolbarButton = function createMarkToolbarButton(_ref) {
4127
+ var mark = _ref.mark,
4128
+ title = _ref.title,
4129
+ icon = _ref.icon;
4192
4130
 
4193
- function handleClick() {
4194
- if (!(editor != null && editor.selection)) return;
4195
- toggleMark(editor, {
4196
- key: MARKS.BOLD
4197
- });
4198
- focus(editor);
4199
- }
4131
+ var Mark = function Mark(_ref2) {
4132
+ var isDisabled = _ref2.isDisabled;
4133
+ var editor = useContentfulEditor();
4134
+ var handleClick = useCallback(function () {
4135
+ if (!(editor != null && editor.selection)) return;
4136
+ var isActive = isMarkActive(editor, mark);
4137
+ editor.tracking.onToolbarAction(isActive ? 'unmark' : 'mark', {
4138
+ markType: mark
4139
+ });
4140
+ toggleMark(editor, {
4141
+ key: mark
4142
+ });
4143
+ focus(editor);
4144
+ }, [editor]);
4145
+ if (!editor) return null;
4146
+ return /*#__PURE__*/createElement(ToolbarButton, {
4147
+ title: title,
4148
+ testId: mark + "-toolbar-button",
4149
+ onClick: handleClick,
4150
+ isActive: isMarkActive(editor, mark),
4151
+ isDisabled: isDisabled
4152
+ }, icon);
4153
+ };
4200
4154
 
4201
- if (!editor) return null;
4202
- return /*#__PURE__*/createElement(ToolbarButton, {
4203
- title: "Bold",
4204
- testId: "bold-toolbar-button",
4205
- onClick: handleClick,
4206
- isActive: isMarkActive(editor, MARKS.BOLD),
4207
- isDisabled: props.isDisabled
4208
- }, /*#__PURE__*/createElement(FormatBoldIcon, null));
4209
- }
4155
+ Mark.displayName = mark;
4156
+ return Mark;
4157
+ };
4158
+
4159
+ var buildMarkEventHandler = function buildMarkEventHandler(type) {
4160
+ return function (editor, _ref) {
4161
+ var hotkey = _ref.options.hotkey;
4162
+ return function (event) {
4163
+ if (editor.selection && hotkey && isHotkey(hotkey, event)) {
4164
+ event.preventDefault();
4165
+ var isActive = isMarkActive(editor, type);
4166
+ editor.tracking.onShortcutAction(isActive ? 'unmark' : 'mark', {
4167
+ markType: type
4168
+ });
4169
+ toggleMark(editor, {
4170
+ key: type
4171
+ });
4172
+ }
4173
+ };
4174
+ };
4175
+ };
4176
+
4177
+ var ToolbarBoldButton = /*#__PURE__*/createMarkToolbarButton({
4178
+ title: 'Bold',
4179
+ mark: MARKS.BOLD,
4180
+ icon: /*#__PURE__*/createElement(FormatBoldIcon, null)
4181
+ });
4210
4182
  var styles$e = {
4211
4183
  bold: /*#__PURE__*/css({
4212
4184
  fontWeight: 600
@@ -4229,6 +4201,9 @@ var createBoldPlugin = function createBoldPlugin() {
4229
4201
  options: {
4230
4202
  hotkey: ['mod+b']
4231
4203
  },
4204
+ handlers: {
4205
+ onKeyDown: buildMarkEventHandler(MARKS.BOLD)
4206
+ },
4232
4207
  deserializeHtml: {
4233
4208
  rules: [{
4234
4209
  validNodeName: ['STRONG', 'B']
@@ -4246,26 +4221,11 @@ var createBoldPlugin = function createBoldPlugin() {
4246
4221
  });
4247
4222
  };
4248
4223
 
4249
- function ToolbarCodeButton(props) {
4250
- var editor = useContentfulEditor();
4251
-
4252
- function handleClick() {
4253
- if (!(editor != null && editor.selection)) return;
4254
- toggleMark(editor, {
4255
- key: MARKS.CODE
4256
- });
4257
- focus(editor);
4258
- }
4259
-
4260
- if (!editor) return null;
4261
- return /*#__PURE__*/createElement(ToolbarButton, {
4262
- title: "Code",
4263
- testId: "code-toolbar-button",
4264
- onClick: handleClick,
4265
- isActive: isMarkActive(editor, MARKS.CODE),
4266
- isDisabled: props.isDisabled
4267
- }, /*#__PURE__*/createElement(CodeIcon, null));
4268
- }
4224
+ var ToolbarCodeButton = /*#__PURE__*/createMarkToolbarButton({
4225
+ title: 'Code',
4226
+ mark: MARKS.CODE,
4227
+ icon: /*#__PURE__*/createElement(CodeIcon, null)
4228
+ });
4269
4229
  var styles$f = {
4270
4230
  code: /*#__PURE__*/css({
4271
4231
  fontFamily: 'monospace',
@@ -4284,6 +4244,9 @@ var createCodePlugin = function createCodePlugin() {
4284
4244
  options: {
4285
4245
  hotkey: ['mod+/']
4286
4246
  },
4247
+ handlers: {
4248
+ onKeyDown: buildMarkEventHandler(MARKS.CODE)
4249
+ },
4287
4250
  deserializeHtml: {
4288
4251
  rules: [{
4289
4252
  validNodeName: ['CODE', 'PRE']
@@ -4296,26 +4259,11 @@ var createCodePlugin = function createCodePlugin() {
4296
4259
  });
4297
4260
  };
4298
4261
 
4299
- function ToolbarItalicButton(props) {
4300
- var editor = useContentfulEditor();
4301
-
4302
- function handleClick() {
4303
- if (!(editor != null && editor.selection)) return;
4304
- toggleMark(editor, {
4305
- key: MARKS.ITALIC
4306
- });
4307
- focus(editor);
4308
- }
4309
-
4310
- if (!editor) return null;
4311
- return /*#__PURE__*/createElement(ToolbarButton, {
4312
- title: "Italic",
4313
- testId: "italic-toolbar-button",
4314
- onClick: handleClick,
4315
- isActive: isMarkActive(editor, MARKS.ITALIC),
4316
- isDisabled: props.isDisabled
4317
- }, /*#__PURE__*/createElement(FormatItalicIcon, null));
4318
- }
4262
+ var ToolbarItalicButton = /*#__PURE__*/createMarkToolbarButton({
4263
+ title: 'Italic',
4264
+ mark: MARKS.ITALIC,
4265
+ icon: /*#__PURE__*/createElement(FormatItalicIcon, null)
4266
+ });
4319
4267
  var styles$g = {
4320
4268
  italic: /*#__PURE__*/css({
4321
4269
  fontStyle: 'italic'
@@ -4333,6 +4281,9 @@ var createItalicPlugin = function createItalicPlugin() {
4333
4281
  options: {
4334
4282
  hotkey: ['mod+i']
4335
4283
  },
4284
+ handlers: {
4285
+ onKeyDown: buildMarkEventHandler(MARKS.ITALIC)
4286
+ },
4336
4287
  deserializeHtml: {
4337
4288
  rules: [{
4338
4289
  validNodeName: ['I', 'EM']
@@ -4350,26 +4301,11 @@ var createItalicPlugin = function createItalicPlugin() {
4350
4301
  });
4351
4302
  };
4352
4303
 
4353
- function ToolbarUnderlineButton(props) {
4354
- var editor = useContentfulEditor();
4355
-
4356
- function handleClick() {
4357
- if (!(editor != null && editor.selection)) return;
4358
- toggleMark(editor, {
4359
- key: MARKS.UNDERLINE
4360
- });
4361
- focus(editor);
4362
- }
4363
-
4364
- if (!editor) return null;
4365
- return /*#__PURE__*/createElement(ToolbarButton, {
4366
- title: "Underline",
4367
- testId: "underline-toolbar-button",
4368
- onClick: handleClick,
4369
- isActive: isMarkActive(editor, MARKS.UNDERLINE),
4370
- isDisabled: props.isDisabled
4371
- }, /*#__PURE__*/createElement(FormatUnderlinedIcon, null));
4372
- }
4304
+ var ToolbarUnderlineButton = /*#__PURE__*/createMarkToolbarButton({
4305
+ title: 'Underline',
4306
+ mark: MARKS.UNDERLINE,
4307
+ icon: /*#__PURE__*/createElement(FormatUnderlinedIcon, null)
4308
+ });
4373
4309
  function Underline(props) {
4374
4310
  return /*#__PURE__*/createElement("u", Object.assign({}, props.attributes), props.children);
4375
4311
  }
@@ -4380,6 +4316,9 @@ var createUnderlinePlugin = function createUnderlinePlugin() {
4380
4316
  options: {
4381
4317
  hotkey: ['mod+u']
4382
4318
  },
4319
+ handlers: {
4320
+ onKeyDown: buildMarkEventHandler(MARKS.UNDERLINE)
4321
+ },
4383
4322
  deserializeHtml: {
4384
4323
  rules: [{
4385
4324
  validNodeName: ['U']
@@ -4602,6 +4541,7 @@ var withNormalizer = function withNormalizer(editor) {
4602
4541
  var createNormalizerPlugin = function createNormalizerPlugin() {
4603
4542
  return {
4604
4543
  key: 'NormalizerPlugin',
4544
+ // @ts-expect-error
4605
4545
  withOverrides: withNormalizer
4606
4546
  };
4607
4547
  };
@@ -4745,11 +4685,54 @@ var sanitizeHTML = function sanitizeHTML(html) {
4745
4685
  return doc.body.innerHTML.replace(/>\s+</g, '><');
4746
4686
  };
4747
4687
 
4688
+ /**
4689
+ * Get x-slate-fragment attribute from data-slate-fragment
4690
+ */
4691
+
4692
+ var catchSlateFragment = /data-slate-fragment="(.+?)"/m;
4693
+ var getSlateFragmentAttribute = function getSlateFragmentAttribute(dataTransfer) {
4694
+ var htmlData = dataTransfer.getData('text/html');
4695
+
4696
+ var _ref = htmlData.match(catchSlateFragment) || [],
4697
+ fragment = _ref[1];
4698
+
4699
+ return fragment;
4700
+ };
4701
+ /**
4702
+ * Get the x-slate-fragment attribute that exist in text/html data
4703
+ * and append it to the DataTransfer object
4704
+ */
4705
+
4706
+ var ensureXSlateFragment = function ensureXSlateFragment(dataTransfer) {
4707
+ if (!dataTransfer.getData('application/x-slate-fragment')) {
4708
+ var fragment = getSlateFragmentAttribute(dataTransfer);
4709
+
4710
+ if (fragment) {
4711
+ var clipboardData = new DataTransfer();
4712
+ dataTransfer.types.forEach(function (type) {
4713
+ clipboardData.setData(type, dataTransfer.getData(type));
4714
+ });
4715
+ clipboardData.setData('application/x-slate-fragment', fragment);
4716
+ return clipboardData;
4717
+ }
4718
+ }
4719
+
4720
+ return dataTransfer;
4721
+ };
4748
4722
  var createPasteHTMLPlugin = function createPasteHTMLPlugin() {
4749
4723
  var _pluginsByKey;
4750
4724
 
4751
4725
  return {
4752
4726
  key: 'PasteHTMLPlugin',
4727
+ withOverrides: function withOverrides(editor) {
4728
+ var insertData = editor.insertData;
4729
+
4730
+ editor.insertData = function (data) {
4731
+ return insertData(ensureXSlateFragment(data));
4732
+ };
4733
+
4734
+ return editor;
4735
+ },
4753
4736
  inject: {
4754
4737
  pluginsByKey: (_pluginsByKey = {}, _pluginsByKey[KEY_DESERIALIZE_HTML] = {
4755
4738
  editor: {
@@ -4779,9 +4762,12 @@ function Quote(props) {
4779
4762
  }), props.children);
4780
4763
  }
4781
4764
 
4782
- function toggleQuote(editor) {
4765
+ function toggleQuote(editor, logAction) {
4783
4766
  if (!editor.selection) return;
4784
4767
  var isActive = isBlockSelected(editor, BLOCKS.QUOTE);
4768
+ logAction(isActive ? 'remove' : 'insert', {
4769
+ nodeType: BLOCKS.QUOTE
4770
+ });
4785
4771
  Editor.withoutNormalizing(editor, function () {
4786
4772
  if (!editor.selection) return;
4787
4773
  Transforms.unwrapNodes(editor, {
@@ -4813,7 +4799,7 @@ var onKeyDownToggleQuote = function onKeyDownToggleQuote(editor, plugin) {
4813
4799
 
4814
4800
  if (hotkey && isHotkey(hotkey, event)) {
4815
4801
  event.preventDefault();
4816
- toggleQuote(editor);
4802
+ toggleQuote(editor, editor.tracking.onShortcutAction);
4817
4803
  }
4818
4804
  };
4819
4805
  };
@@ -4840,7 +4826,54 @@ function createQuotePlugin() {
4840
4826
  normalizer: [{
4841
4827
  validChildren: CONTAINERS[BLOCKS.QUOTE],
4842
4828
  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)
4843
- }]
4829
+ }],
4830
+ withOverrides: function withOverrides(editor) {
4831
+ var insertFragment = editor.insertFragment;
4832
+
4833
+ editor.insertFragment = function (fragment) {
4834
+ var startingNode = fragment.length && fragment[0];
4835
+ var startsWithBlockquote = Element.isElement(startingNode) && startingNode.type === BLOCKS.QUOTE;
4836
+ var containerEntry = getAbove(editor, {
4837
+ match: {
4838
+ type: TEXT_CONTAINERS
4839
+ }
4840
+ });
4841
+ var containerIsNotEmpty = containerEntry && Node.string(containerEntry[0]) !== '';
4842
+
4843
+ if (startsWithBlockquote && containerIsNotEmpty) {
4844
+ var selection = editor.selection;
4845
+
4846
+ var isContentSelected = function isContentSelected(selection) {
4847
+ return !!selection && Point.compare(selection.anchor, selection.focus) !== 0;
4848
+ }; // if something is selected (highlighted) we replace the selection
4849
+
4850
+
4851
+ if (isContentSelected(selection)) {
4852
+ Transforms["delete"](editor, {
4853
+ at: selection
4854
+ });
4855
+ } // get the cursor entry again, it may be different after deletion
4856
+
4857
+
4858
+ var _containerEntry = getAbove(editor, {
4859
+ match: {
4860
+ type: TEXT_CONTAINERS
4861
+ }
4862
+ });
4863
+
4864
+ var _containerIsNotEmpty = _containerEntry && Node.string(_containerEntry[0]) !== '';
4865
+
4866
+ if (_containerIsNotEmpty) {
4867
+ Transforms.insertNodes(editor, fragment);
4868
+ return;
4869
+ }
4870
+ }
4871
+
4872
+ insertFragment(fragment);
4873
+ };
4874
+
4875
+ return editor;
4876
+ }
4844
4877
  };
4845
4878
  }
4846
4879
 
@@ -4849,7 +4882,7 @@ function ToolbarQuoteButton(props) {
4849
4882
 
4850
4883
  function handleOnClick() {
4851
4884
  if (!editor) return;
4852
- toggleQuote(editor);
4885
+ toggleQuote(editor, editor.tracking.onToolbarAction);
4853
4886
  focus(editor);
4854
4887
  }
4855
4888
 
@@ -4898,8 +4931,7 @@ function hasHeadersOutsideFirstRow(nodes) {
4898
4931
  });
4899
4932
  }
4900
4933
 
4901
- function addTableTrackingEvents(editor, _ref6) {
4902
- var onViewportAction = _ref6.onViewportAction;
4934
+ function addTableTrackingEvents(editor) {
4903
4935
  var insertData = editor.insertData;
4904
4936
 
4905
4937
  editor.insertData = function (data) {
@@ -4913,7 +4945,7 @@ function addTableTrackingEvents(editor, _ref6) {
4913
4945
  if (hasTables(markupBefore)) return;
4914
4946
 
4915
4947
  if (hasTables(markupAfter)) {
4916
- onViewportAction('paste', {
4948
+ editor.tracking.onViewportAction('paste', {
4917
4949
  tablePasted: true,
4918
4950
  hasHeadersOutsideFirstRow: hasHeadersOutsideFirstRow(markupAfter)
4919
4951
  });
@@ -4925,29 +4957,6 @@ function addTableTrackingEvents(editor, _ref6) {
4925
4957
  };
4926
4958
  }
4927
4959
 
4928
- function useTracking(_ref) {
4929
- var onAction = _ref.onAction;
4930
- var trackingMemo = useMemo(function () {
4931
- return {
4932
- onViewportAction: function onViewportAction(actionName, data) {
4933
- if (data === void 0) {
4934
- data = {};
4935
- }
4936
-
4937
- return onAction(actionName, _extends({
4938
- origin: 'viewport-interaction'
4939
- }, data));
4940
- }
4941
- };
4942
- }, [] // eslint-disable-line
4943
- );
4944
- return trackingMemo;
4945
- }
4946
-
4947
- var _constate$2 = /*#__PURE__*/constate(useTracking),
4948
- TrackingProvider = _constate$2[0],
4949
- useTrackingContext = _constate$2[1];
4950
-
4951
4960
  var addRow = function addRow(editor, getNextRowPath) {
4952
4961
  if (someNode(editor, {
4953
4962
  match: {
@@ -5193,9 +5202,6 @@ var TableActions = function TableActions() {
5193
5202
  var editor = useContentfulEditor();
5194
5203
  var isDisabled = useReadOnly();
5195
5204
 
5196
- var _useTrackingContext = useTrackingContext(),
5197
- onViewportAction = _useTrackingContext.onViewportAction;
5198
-
5199
5205
  var _React$useState = React__default.useState(false),
5200
5206
  isOpen = _React$useState[0],
5201
5207
  setOpen = _React$useState[1];
@@ -5245,11 +5251,11 @@ var TableActions = function TableActions() {
5245
5251
  }); // Tracking
5246
5252
 
5247
5253
  var actionName = type + "Table" + (element === 'Table' ? '' : element);
5248
- onViewportAction(actionName, {
5254
+ editor.tracking.onViewportAction(actionName, {
5249
5255
  tableSize: tableSize
5250
5256
  });
5251
5257
  };
5252
- }, [editor, isHeaderEnabled, close, onViewportAction]);
5258
+ }, [editor, isHeaderEnabled, close]);
5253
5259
 
5254
5260
  if (isDisabled) {
5255
5261
  return null;
@@ -5340,7 +5346,7 @@ var createTableOnKeyDown = function createTableOnKeyDown(editor, plugin) {
5340
5346
  };
5341
5347
  };
5342
5348
 
5343
- var createTablePlugin = function createTablePlugin(tracking) {
5349
+ var createTablePlugin = function createTablePlugin() {
5344
5350
  var _overrideByKey;
5345
5351
 
5346
5352
  return createTablePlugin$1({
@@ -5349,7 +5355,7 @@ var createTablePlugin = function createTablePlugin(tracking) {
5349
5355
  onKeyDown: createTableOnKeyDown
5350
5356
  },
5351
5357
  withOverrides: function withOverrides(editor) {
5352
- addTableTrackingEvents(editor, tracking);
5358
+ addTableTrackingEvents(editor);
5353
5359
  var insertFragment = editor.insertFragment;
5354
5360
 
5355
5361
  editor.insertFragment = function (fragments) {
@@ -5449,10 +5455,6 @@ var createTablePlugin = function createTablePlugin(tracking) {
5449
5455
 
5450
5456
  function ToolbarTableButton(props) {
5451
5457
  var editor = useContentfulEditor();
5452
-
5453
- var _useTrackingContext = useTrackingContext(),
5454
- onViewportAction = _useTrackingContext.onViewportAction;
5455
-
5456
5458
  var isActive = editor && isTableActive(editor);
5457
5459
 
5458
5460
  function handleClick() {
@@ -5473,7 +5475,7 @@ function ToolbarTableButton(props) {
5473
5475
  return _context.abrupt("return");
5474
5476
 
5475
5477
  case 2:
5476
- onViewportAction('insertTable');
5478
+ editor.tracking.onToolbarAction('insertTable');
5477
5479
  insertTableAndFocusFirstCell(editor);
5478
5480
  focus(editor);
5479
5481
 
@@ -5578,35 +5580,199 @@ function deleteEmptyParagraph(unit, editor, deleteFunction) {
5578
5580
  }
5579
5581
  }
5580
5582
 
5581
- var createTrailingParagraphPlugin = function createTrailingParagraphPlugin() {
5582
- return createTrailingBlockPlugin({
5583
- options: {
5584
- type: BLOCKS.PARAGRAPH,
5585
- level: 0
5583
+ var _extends2, _extends4, _inlines;
5584
+ var inlines = /*#__PURE__*/Object.values(INLINES).map(function (type) {
5585
+ return {
5586
+ type: type
5587
+ };
5588
+ });
5589
+ var schema = {
5590
+ document: {
5591
+ nodes: [{
5592
+ types: /*#__PURE__*/TOP_LEVEL_BLOCKS.map(function (type) {
5593
+ return {
5594
+ type: type
5595
+ };
5596
+ })
5597
+ }]
5598
+ },
5599
+ blocks: /*#__PURE__*/_extends((_extends2 = {}, _extends2[BLOCKS.PARAGRAPH] = {
5600
+ nodes: [{
5601
+ match: /*#__PURE__*/[].concat(inlines, [{
5602
+ object: 'text'
5603
+ }])
5604
+ }]
5605
+ }, _extends2[BLOCKS.HEADING_1] = {
5606
+ nodes: [{
5607
+ match: /*#__PURE__*/[].concat(inlines, [{
5608
+ object: 'text'
5609
+ }])
5610
+ }]
5611
+ }, _extends2[BLOCKS.HEADING_2] = {
5612
+ nodes: [{
5613
+ match: /*#__PURE__*/[].concat(inlines, [{
5614
+ object: 'text'
5615
+ }])
5616
+ }]
5617
+ }, _extends2[BLOCKS.HEADING_3] = {
5618
+ nodes: [{
5619
+ match: /*#__PURE__*/[].concat(inlines, [{
5620
+ object: 'text'
5621
+ }])
5622
+ }]
5623
+ }, _extends2[BLOCKS.HEADING_4] = {
5624
+ nodes: [{
5625
+ match: /*#__PURE__*/[].concat(inlines, [{
5626
+ object: 'text'
5627
+ }])
5628
+ }]
5629
+ }, _extends2[BLOCKS.HEADING_5] = {
5630
+ nodes: [{
5631
+ match: /*#__PURE__*/[].concat(inlines, [{
5632
+ object: 'text'
5633
+ }])
5634
+ }]
5635
+ }, _extends2[BLOCKS.HEADING_6] = {
5636
+ nodes: [{
5637
+ match: /*#__PURE__*/[].concat(inlines, [{
5638
+ object: 'text'
5639
+ }])
5640
+ }]
5641
+ }, _extends2), /*#__PURE__*/VOID_BLOCKS.reduce(function (blocks, nodeType) {
5642
+ var _extends3;
5643
+
5644
+ return _extends({}, blocks, (_extends3 = {}, _extends3[nodeType] = {
5645
+ isVoid: true
5646
+ }, _extends3));
5647
+ }, {}), (_extends4 = {}, _extends4[BLOCKS.QUOTE] = {
5648
+ nodes: [{
5649
+ match: [/*#__PURE__*/CONTAINERS[BLOCKS.QUOTE].map(function (type) {
5650
+ return {
5651
+ type: type
5652
+ };
5653
+ })],
5654
+ min: 1
5655
+ }],
5656
+ normalize: function normalize(editor, error) {
5657
+ if (error.code === 'child_type_invalid') {
5658
+ return editor.unwrapBlockByKey(error.node.key, BLOCKS.QUOTE);
5659
+ }
5586
5660
  }
5661
+ }, _extends4)),
5662
+ inlines: (_inlines = {}, _inlines[INLINES.HYPERLINK] = {
5663
+ nodes: [{
5664
+ match: [{
5665
+ object: 'text'
5666
+ }]
5667
+ }]
5668
+ }, _inlines[INLINES.ENTRY_HYPERLINK] = {
5669
+ nodes: [{
5670
+ match: [{
5671
+ object: 'text'
5672
+ }]
5673
+ }]
5674
+ }, _inlines[INLINES.ASSET_HYPERLINK] = {
5675
+ nodes: [{
5676
+ match: [{
5677
+ object: 'text'
5678
+ }]
5679
+ }]
5680
+ }, _inlines[INLINES.EMBEDDED_ENTRY] = {
5681
+ isVoid: true
5682
+ }, _inlines)
5683
+ };
5684
+
5685
+ function getCharacterCount(editor) {
5686
+ var document = toContentfulDocument({
5687
+ document: editor.children,
5688
+ schema: schema
5587
5689
  });
5690
+ return documentToPlainTextString(document).length;
5691
+ }
5692
+
5693
+ var actionOrigin = {
5694
+ TOOLBAR: 'toolbar-icon',
5695
+ SHORTCUT: 'shortcut',
5696
+ VIEWPORT: 'viewport-interaction',
5697
+ COMMAND_PALETTE: 'command-palette'
5588
5698
  };
5699
+ var createTrackingPlugin = function createTrackingPlugin(onAction) {
5700
+ var trackingActions = {
5701
+ onViewportAction: function onViewportAction(actionName, data) {
5702
+ if (data === void 0) {
5703
+ data = {};
5704
+ }
5589
5705
 
5590
- /**
5591
- * Re-creates a void node with valid children.
5592
- */
5706
+ return onAction(actionName, _extends({
5707
+ origin: actionOrigin.VIEWPORT
5708
+ }, data));
5709
+ },
5710
+ onShortcutAction: function onShortcutAction(actionName, data) {
5711
+ if (data === void 0) {
5712
+ data = {};
5713
+ }
5593
5714
 
5594
- var transformVoid = function transformVoid(editor, _ref) {
5595
- var node = _ref[0],
5596
- path = _ref[1];
5715
+ return onAction(actionName, _extends({
5716
+ origin: actionOrigin.SHORTCUT
5717
+ }, data));
5718
+ },
5719
+ onToolbarAction: function onToolbarAction(actionName, data) {
5720
+ if (data === void 0) {
5721
+ data = {};
5722
+ }
5597
5723
 
5598
- var validVoid = _extends({}, node, {
5599
- children: [{
5600
- text: ''
5601
- }]
5602
- }); // A workaround because Slate doesn't allow adjusting void nodes children
5724
+ return onAction(actionName, _extends({
5725
+ origin: actionOrigin.TOOLBAR
5726
+ }, data));
5727
+ },
5728
+ onCommandPaletteAction: function onCommandPaletteAction(actionName, data) {
5729
+ if (data === void 0) {
5730
+ data = {};
5731
+ }
5603
5732
 
5733
+ return onAction(actionName, _extends({
5734
+ origin: actionOrigin.COMMAND_PALETTE
5735
+ }, data));
5736
+ }
5737
+ };
5738
+ return {
5739
+ key: 'TrackingPlugin',
5740
+ withOverrides: function withOverrides(editor) {
5741
+ var insertData = editor.insertData;
5742
+ editor.tracking = trackingActions;
5743
+
5744
+ editor.insertData = function (data) {
5745
+ var isCopyAndPaste = data.types.length !== 0;
5746
+
5747
+ if (isCopyAndPaste) {
5748
+ var _window$getSelection;
5749
+
5750
+ var characterCountSelection = (_window$getSelection = window.getSelection()) == null ? void 0 : _window$getSelection.toString().length;
5751
+ var characterCountBefore = getCharacterCount(editor);
5752
+ setTimeout(function () {
5753
+ var characterCountAfter = getCharacterCount(editor);
5754
+ trackingActions.onShortcutAction('paste', {
5755
+ characterCountAfter: characterCountAfter,
5756
+ characterCountBefore: characterCountBefore,
5757
+ characterCountSelection: characterCountSelection
5758
+ });
5759
+ });
5760
+ }
5604
5761
 
5605
- Transforms.removeNodes(editor, {
5606
- at: path
5607
- });
5608
- Transforms.insertNodes(editor, [validVoid], {
5609
- at: path
5762
+ insertData(data);
5763
+ };
5764
+
5765
+ return editor;
5766
+ }
5767
+ };
5768
+ };
5769
+
5770
+ var createTrailingParagraphPlugin = function createTrailingParagraphPlugin() {
5771
+ return createTrailingBlockPlugin({
5772
+ options: {
5773
+ type: BLOCKS.PARAGRAPH,
5774
+ level: 0
5775
+ }
5610
5776
  });
5611
5777
  };
5612
5778
 
@@ -5638,34 +5804,17 @@ var createVoidsPlugin = function createVoidsPlugin() {
5638
5804
  return !(isRootLevel(path) && isFirstChild(path)) && !!node.isVoid;
5639
5805
  }
5640
5806
  }
5641
- }],
5642
- normalizer: [{
5643
- match: {
5644
- isVoid: true
5645
- },
5646
- validNode: function validNode(editor, _ref3) {
5647
- var path = _ref3[1];
5648
- var children = Array.from(Node.children(editor, path));
5649
-
5650
- if (children.length !== 1) {
5651
- return false;
5652
- }
5653
-
5654
- var _children$ = children[0],
5655
- textNode = _children$[0];
5656
- return Text.isText(textNode) && textNode.text === '';
5657
- },
5658
- transform: transformVoid
5659
5807
  }]
5660
5808
  };
5661
5809
  };
5662
5810
 
5663
- var getPlugins = function getPlugins(sdk, tracking) {
5811
+ var getPlugins = function getPlugins(sdk, onAction) {
5664
5812
  return [// AST must come after the HTML deserializer
5665
- createDeserializeHtmlPlugin(), createDeserializeAstPlugin(), createDeserializeDocxPlugin(), // Global shortcuts
5813
+ createDeserializeHtmlPlugin(), createDeserializeAstPlugin(), createDeserializeDocxPlugin(), // Tracking - This should come first so all plugins below will have access to `editor.tracking`
5814
+ createTrackingPlugin(onAction), // Global / Global shortcuts
5666
5815
  createDragAndDropPlugin(), // Block Elements
5667
- createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(tracking), createEmbeddedEntryBlockPlugin(sdk, tracking), createEmbeddedAssetBlockPlugin(sdk, tracking), // Inline elements
5668
- createHyperlinkPlugin(sdk, tracking), createEmbeddedEntityInlinePlugin(sdk, tracking), // Marks
5816
+ createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(), createEmbeddedEntryBlockPlugin(sdk), createEmbeddedAssetBlockPlugin(sdk), // Inline elements
5817
+ createHyperlinkPlugin(sdk), createEmbeddedEntityInlinePlugin(sdk), // Marks
5669
5818
  createMarksPlugin(), // Other
5670
5819
  createTrailingParagraphPlugin(), createTextPlugin(), createVoidsPlugin(), createSelectOnBackspacePlugin(), // Pasting content from other sources
5671
5820
  createPasteHTMLPlugin(), // These plugins drive their configurations from the list of plugins
@@ -5887,10 +6036,10 @@ var Toolbar = function Toolbar(_ref) {
5887
6036
  isDisabled: isDisabled
5888
6037
  })), validationInfo.isAnyBlockFormattingEnabled && /*#__PURE__*/React__default.createElement("span", {
5889
6038
  className: styles$k.divider
5890
- }), isNodeTypeEnabled(sdk.field, BLOCKS.QUOTE) && /*#__PURE__*/React__default.createElement(ToolbarQuoteButton, {
5891
- isDisabled: isDisabled || !canInsertBlocks
5892
6039
  }), /*#__PURE__*/React__default.createElement(ToolbarListButton, {
5893
6040
  isDisabled: isDisabled || !canInsertBlocks
6041
+ }), isNodeTypeEnabled(sdk.field, BLOCKS.QUOTE) && /*#__PURE__*/React__default.createElement(ToolbarQuoteButton, {
6042
+ isDisabled: isDisabled || !canInsertBlocks
5894
6043
  }), isNodeTypeEnabled(sdk.field, BLOCKS.HR) && /*#__PURE__*/React__default.createElement(ToolbarHrButton, {
5895
6044
  isDisabled: isDisabled || !canInsertBlocks
5896
6045
  }), isNodeTypeEnabled(sdk.field, BLOCKS.TABLE) && /*#__PURE__*/React__default.createElement(ToolbarTableButton, {
@@ -5974,18 +6123,56 @@ var useNormalizedSlateValue = function useNormalizedSlateValue(_ref) {
5974
6123
  }, [id, plugins, incomingDoc]);
5975
6124
  };
5976
6125
 
6126
+ /**
6127
+ * Returns whether a given operation is relevant enough to trigger a save.
6128
+ */
6129
+
6130
+ var isRelevantOperation = function isRelevantOperation(op) {
6131
+ if (op.type === 'set_selection') {
6132
+ return false;
6133
+ }
6134
+
6135
+ return true;
6136
+ };
6137
+
6138
+ var useOnValueChanged = function useOnValueChanged(_ref) {
6139
+ var editor = _ref.editor,
6140
+ handler = _ref.handler;
6141
+ var onChange = useMemo(function () {
6142
+ return debounce(function (document) {
6143
+ handler == null ? void 0 : handler(toContentfulDocument({
6144
+ document: document,
6145
+ schema: schema
6146
+ }));
6147
+ }, 500);
6148
+ }, [handler]);
6149
+ return useCallback(function (value) {
6150
+ var operations = editor.operations.filter(isRelevantOperation);
6151
+
6152
+ if (operations.length > 0) {
6153
+ onChange(value);
6154
+ }
6155
+ }, [editor, onChange]);
6156
+ };
6157
+
5977
6158
  var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
5978
6159
  var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
5979
- var id = getContentfulEditorId(props.sdk);
5980
- var tracking = useTrackingContext();
6160
+ var id = useContentfulEditorId();
6161
+ var editor = useContentfulEditor();
5981
6162
  var plugins = React__default.useMemo(function () {
5982
- return getPlugins(props.sdk, tracking);
5983
- }, [props.sdk, tracking]);
6163
+ var _props$onAction;
6164
+
6165
+ return getPlugins(props.sdk, (_props$onAction = props.onAction) != null ? _props$onAction : noop);
6166
+ }, [props.sdk, props.onAction]);
5984
6167
  var initialValue = useNormalizedSlateValue({
5985
6168
  id: id,
5986
6169
  incomingDoc: props.value,
5987
6170
  plugins: plugins
5988
6171
  });
6172
+ var onValueChanged = useOnValueChanged({
6173
+ editor: editor,
6174
+ handler: props.onChange
6175
+ });
5989
6176
  var classNames = cx(styles$j.editor, props.minHeight !== undefined ? css({
5990
6177
  minHeight: props.minHeight
5991
6178
  }) : undefined, props.isDisabled ? styles$j.disabled : styles$j.enabled, props.isToolbarHidden && styles$j.hiddenToolbar);
@@ -6001,12 +6188,7 @@ var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
6001
6188
  className: classNames,
6002
6189
  readOnly: props.isDisabled
6003
6190
  },
6004
- onChange: function onChange(document) {
6005
- props.onChange == null ? void 0 : props.onChange(toContentfulDocument({
6006
- document: document,
6007
- schema: schema
6008
- }));
6009
- }
6191
+ onChange: onValueChanged
6010
6192
  }, !props.isToolbarHidden && /*#__PURE__*/React__default.createElement(StickyToolbarWrapper, {
6011
6193
  isDisabled: props.isDisabled
6012
6194
  }, /*#__PURE__*/React__default.createElement(Toolbar, {
@@ -6023,12 +6205,11 @@ var RichTextEditor = function RichTextEditor(props) {
6023
6205
  var isEmptyValue = useCallback(function (value) {
6024
6206
  return !value || deepEquals(value, EMPTY_DOCUMENT);
6025
6207
  }, []);
6208
+ var editorId = getContentfulEditorId(sdk);
6026
6209
  return /*#__PURE__*/React__default.createElement(EntityProvider, {
6027
6210
  sdk: sdk
6028
6211
  }, /*#__PURE__*/React__default.createElement(SdkProvider, {
6029
6212
  sdk: sdk
6030
- }, /*#__PURE__*/React__default.createElement(TrackingProvider, {
6031
- onAction: onAction || noop
6032
6213
  }, /*#__PURE__*/React__default.createElement(FieldConnector, {
6033
6214
  throttle: 0,
6034
6215
  field: sdk.field,
@@ -6040,17 +6221,17 @@ var RichTextEditor = function RichTextEditor(props) {
6040
6221
  disabled = _ref.disabled,
6041
6222
  setValue = _ref.setValue,
6042
6223
  externalReset = _ref.externalReset;
6043
- return /*#__PURE__*/React__default.createElement(ContentfulEditorProvider, {
6044
- sdk: sdk
6224
+ return /*#__PURE__*/React__default.createElement(ContentfulEditorIdProvider, {
6225
+ value: editorId
6045
6226
  }, /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
6046
6227
  key: "rich-text-editor-" + externalReset,
6047
6228
  value: lastRemoteValue,
6048
6229
  sdk: sdk,
6049
- onAction: onAction || noop,
6230
+ onAction: onAction,
6050
6231
  isDisabled: disabled,
6051
6232
  onChange: setValue
6052
6233
  })));
6053
- }))));
6234
+ })));
6054
6235
  };
6055
6236
 
6056
6237
  var LINK_TYPES$1 = {