@contentful/field-editor-rich-text 0.23.1-next → 0.25.0-next

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.
@@ -1,24 +1,26 @@
1
- import React__default, { createElement, useMemo, useState, useEffect, Fragment, useCallback } from 'react';
1
+ import React__default, { useState, useEffect, createElement, useMemo, Fragment, useCallback } from 'react';
2
2
  import noop from 'lodash-es/noop';
3
- import { toSlatejsDocument, toContentfulDocument } from '@contentful/contentful-slatejs-adapter';
4
- import { TOP_LEVEL_BLOCKS, BLOCKS, CONTAINERS, VOID_BLOCKS, INLINES, MARKS, EMPTY_DOCUMENT } from '@contentful/rich-text-types';
5
- import { useEntities, MissingEntityCard, WrappedEntryCard, WrappedAssetCard, EntityProvider, ScheduledIconWithTooltip } from '@contentful/field-editor-reference';
3
+ import { toContentfulDocument, toSlatejsDocument } from '@contentful/contentful-slatejs-adapter';
4
+ import { TOP_LEVEL_BLOCKS, BLOCKS, CONTAINERS, VOID_BLOCKS, INLINES, LIST_ITEM_BLOCKS, MARKS, EMPTY_DOCUMENT } from '@contentful/rich-text-types';
5
+ import { useEntities, ScheduledIconWithTooltip, MissingEntityCard, AssetThumbnail, EntityProvider } from '@contentful/field-editor-reference';
6
6
  import { css, cx } from 'emotion';
7
7
  import tokens from '@contentful/forma-36-tokens';
8
8
  import deepEquals from 'fast-deep-equal';
9
- import { EditorToolbarButton, Dropdown, Button, DropdownList, DropdownListItem, Tag, Paragraph as Paragraph$1, EntryCard, AssetCard, Modal, Form, TextField, SelectField, Option, FormLabel, TextLink, Tooltip, IconButton, Flex, Icon, InlineEntryCard, EditorToolbar, EditorToolbarDivider } from '@contentful/forma-36-react-components';
9
+ import { EditorToolbarButton, Dropdown, Button, DropdownList, DropdownListItem, Tag, Paragraph as Paragraph$1, Icon, EntryCard, AssetCard, Modal, Form, TextField, SelectField, Option, FormLabel, TextLink, Tooltip, IconButton, Flex, InlineEntryCard, EditorToolbar, EditorToolbarDivider } from '@contentful/forma-36-react-components';
10
10
  import { useSelected, useFocused, ReactEditor, useReadOnly } from 'slate-react';
11
- import { Editor, Transforms, Element, Text, Range, Path, Node } from 'slate';
11
+ import { Editor, Transforms, Element, Text, Range, Path, Node as Node$1 } from 'slate';
12
12
  import { getPlatePluginOptions, useStoreEditorRef, getRenderElement, getPlatePluginTypes, getRenderLeaf, getPlatePluginType, Plate, createReactPlugin, createHistoryPlugin } from '@udecode/plate-core';
13
13
  import { getElementDeserializer, getLeafDeserializer, getText, setNodes, insertNodes, toggleNodeType, getToggleMarkOnKeyDown, isMarkActive, toggleMark, getAbove, getChildren, someNode, getToggleElementOnKeyDown } from '@udecode/plate-common';
14
14
  import constate from 'constate';
15
15
  import find from 'lodash-es/find';
16
16
  import flow from 'lodash-es/flow';
17
17
  import get from 'lodash-es/get';
18
- import { ELEMENT_LIC, ELEMENT_LI, ELEMENT_UL, ELEMENT_OL, toggleList, createListPlugin } from '@udecode/plate-list';
19
- import { entityHelpers, ModalDialogLauncher, FieldConnector } from '@contentful/field-editor-shared';
18
+ import { ELEMENT_LIC, ELEMENT_LI, ELEMENT_UL, ELEMENT_OL, createListPlugin as createListPlugin$1, toggleList } from '@udecode/plate-list';
19
+ import { entityHelpers, isValidImage, shortenStorageUnit, ModalDialogLauncher, FieldConnector } from '@contentful/field-editor-shared';
20
20
  import moment from 'moment';
21
+ import mimetype from '@contentful/mimetype';
21
22
  import { ELEMENT_TABLE, ELEMENT_TH, ELEMENT_TR, ELEMENT_TD, insertTable, getEmptyRowNode, getEmptyCellNode, deleteRow, deleteColumn, deleteTable, createTablePlugin as createTablePlugin$1, getTableOnKeyDown } from '@udecode/plate-table';
23
+ import { documentToPlainTextString } from '@contentful/rich-text-plain-text-renderer';
22
24
  import { createDeserializeHTMLPlugin } from '@udecode/plate-html-serializer';
23
25
  import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph';
24
26
  import { createExitBreakPlugin } from '@udecode/plate-break';
@@ -120,6 +122,44 @@ function _taggedTemplateLiteralLoose(strings, raw) {
120
122
  return strings;
121
123
  }
122
124
 
125
+ function _unsupportedIterableToArray(o, minLen) {
126
+ if (!o) return;
127
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
128
+ var n = Object.prototype.toString.call(o).slice(8, -1);
129
+ if (n === "Object" && o.constructor) n = o.constructor.name;
130
+ if (n === "Map" || n === "Set") return Array.from(o);
131
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
132
+ }
133
+
134
+ function _arrayLikeToArray(arr, len) {
135
+ if (len == null || len > arr.length) len = arr.length;
136
+
137
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
138
+
139
+ return arr2;
140
+ }
141
+
142
+ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
143
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
144
+ if (it) return (it = it.call(o)).next.bind(it);
145
+
146
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
147
+ if (it) o = it;
148
+ var i = 0;
149
+ return function () {
150
+ if (i >= o.length) return {
151
+ done: true
152
+ };
153
+ return {
154
+ done: false,
155
+ value: o[i++]
156
+ };
157
+ };
158
+ }
159
+
160
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
161
+ }
162
+
123
163
  var STYLE_EDITOR_BORDER = "1px solid " + tokens.gray400;
124
164
  var styles = {
125
165
  root: /*#__PURE__*/css({
@@ -504,9 +544,25 @@ function getContentfulEditorId(sdk) {
504
544
  }
505
545
 
506
546
  function useContentfulEditorHook(_ref) {
547
+ var _editor$selection;
548
+
507
549
  var sdk = _ref.sdk;
508
550
  var editorId = getContentfulEditorId(sdk);
509
551
  var editor = useStoreEditorRef(editorId);
552
+
553
+ var _React$useState = useState((_editor$selection = editor == null ? void 0 : editor.selection) != null ? _editor$selection : null),
554
+ selection = _React$useState[0],
555
+ setSelection = _React$useState[1];
556
+
557
+ useEffect(function () {
558
+ if (!(editor != null && editor.selection)) return;
559
+ setSelection(editor.selection);
560
+ }, [editor == null ? void 0 : editor.selection]);
561
+
562
+ if (editor && !(editor != null && editor.selection) && selection) {
563
+ editor.selection = selection;
564
+ }
565
+
510
566
  return editor;
511
567
  }
512
568
 
@@ -548,7 +604,8 @@ function withHrEvents(editor) {
548
604
  function ToolbarHrButton(props) {
549
605
  var editor = useContentfulEditor();
550
606
 
551
- function handleOnClick() {
607
+ function handleOnClick(event) {
608
+ event.preventDefault();
552
609
  if (!(editor != null && editor.selection)) return;
553
610
 
554
611
  if (shouldUnwrapBlockquote(editor, BLOCKS.HR)) {
@@ -577,7 +634,8 @@ function ToolbarHrButton(props) {
577
634
  tooltipPlace: "bottom",
578
635
  label: "HR",
579
636
  disabled: props.isDisabled,
580
- onClick: handleOnClick,
637
+ // @ts-expect-error
638
+ onMouseDown: handleOnClick,
581
639
  testId: "hr-toolbar-button",
582
640
  isActive: isBlockSelected(editor, BLOCKS.HR)
583
641
  });
@@ -693,7 +751,7 @@ function withHeadingEvents(editor) {
693
751
 
694
752
  if (hasSelectionText(editor)) {
695
753
  var currentOffset = editor.selection.focus.offset;
696
- var currentTextLength = Node.string(currentFragment).length;
754
+ var currentTextLength = Node$1.string(currentFragment).length;
697
755
  var cursorIsAtTheBeginning = currentOffset === 0;
698
756
  var cursorIsAtTheEnd = currentTextLength === currentOffset;
699
757
 
@@ -775,19 +833,22 @@ function ToolbarHeadingButton(props) {
775
833
  someHeadingsEnabled = _React$useMemo[1];
776
834
 
777
835
  function handleOnSelectItem(type) {
778
- if (!(editor != null && editor.selection)) return;
779
- setSelected(type);
780
- setOpen(false);
836
+ return function (event) {
837
+ event.preventDefault();
838
+ if (!(editor != null && editor.selection)) return;
839
+ setSelected(type);
840
+ setOpen(false);
781
841
 
782
- if (shouldUnwrapBlockquote(editor, type)) {
783
- unwrapFromRoot(editor);
784
- }
842
+ if (shouldUnwrapBlockquote(editor, type)) {
843
+ unwrapFromRoot(editor);
844
+ }
785
845
 
786
- toggleNodeType(editor, {
787
- activeType: type,
788
- inactiveType: type
789
- });
790
- ReactEditor.focus(editor);
846
+ toggleNodeType(editor, {
847
+ activeType: type,
848
+ inactiveType: type
849
+ });
850
+ ReactEditor.focus(editor);
851
+ };
791
852
  }
792
853
 
793
854
  if (!editor) return null;
@@ -811,9 +872,7 @@ function ToolbarHeadingButton(props) {
811
872
  return nodeTypesByEnablement[nodeType] && /*#__PURE__*/createElement(DropdownListItem, {
812
873
  key: nodeType,
813
874
  isActive: selected === nodeType,
814
- onClick: function onClick() {
815
- return handleOnSelectItem(nodeType);
816
- },
875
+ onMouseDown: handleOnSelectItem(nodeType),
817
876
  testId: "dropdown-option-" + nodeType,
818
877
  isDisabled: props.isDisabled
819
878
  }, /*#__PURE__*/createElement("span", {
@@ -919,7 +978,7 @@ function withQuoteEvents(editor) {
919
978
 
920
979
  if (hasSelectionText(editor)) {
921
980
  var currentOffset = editor.selection.focus.offset;
922
- var currentTextLength = Node.string(currentFragment).length;
981
+ var currentTextLength = Node$1.string(currentFragment).length;
923
982
  var cursorIsAtTheBeginning = currentOffset === 0;
924
983
  var cursorIsAtTheEnd = currentTextLength === currentOffset;
925
984
 
@@ -962,7 +1021,8 @@ function withQuoteEvents(editor) {
962
1021
  function ToolbarQuoteButton(props) {
963
1022
  var editor = useContentfulEditor();
964
1023
 
965
- function handleOnClick() {
1024
+ function handleOnClick(event) {
1025
+ event.preventDefault();
966
1026
  if (!editor) return;
967
1027
  createBlockQuote(editor);
968
1028
  ReactEditor.focus(editor);
@@ -974,7 +1034,8 @@ function ToolbarQuoteButton(props) {
974
1034
  tooltip: "Blockquote",
975
1035
  tooltipPlace: "bottom",
976
1036
  label: "Blockquote",
977
- onClick: handleOnClick,
1037
+ // @ts-expect-error
1038
+ onMouseDown: handleOnClick,
978
1039
  testId: "quote-toolbar-button",
979
1040
  disabled: props.isDisabled,
980
1041
  isActive: isBlockSelected(editor, BLOCKS.QUOTE)
@@ -1006,16 +1067,19 @@ function ToolbarListButton(props) {
1006
1067
  var editor = useContentfulEditor();
1007
1068
 
1008
1069
  function handleClick(type) {
1009
- if (!(editor != null && editor.selection)) return;
1070
+ return function (event) {
1071
+ event.preventDefault();
1072
+ if (!(editor != null && editor.selection)) return;
1010
1073
 
1011
- if (shouldUnwrapBlockquote(editor, type)) {
1012
- unwrapFromRoot(editor);
1013
- }
1074
+ if (shouldUnwrapBlockquote(editor, type)) {
1075
+ unwrapFromRoot(editor);
1076
+ }
1014
1077
 
1015
- toggleList(editor, {
1016
- type: type
1017
- });
1018
- ReactEditor.focus(editor);
1078
+ toggleList(editor, {
1079
+ type: type
1080
+ });
1081
+ ReactEditor.focus(editor);
1082
+ };
1019
1083
  }
1020
1084
 
1021
1085
  if (!editor) return null;
@@ -1025,9 +1089,8 @@ function ToolbarListButton(props) {
1025
1089
  tooltipPlace: "bottom",
1026
1090
  label: "UL",
1027
1091
  testId: "ul-toolbar-button",
1028
- onClick: function onClick() {
1029
- return handleClick(BLOCKS.UL_LIST);
1030
- },
1092
+ // @ts-expect-error
1093
+ onMouseDown: handleClick(BLOCKS.UL_LIST),
1031
1094
  isActive: isBlockSelected(editor, BLOCKS.UL_LIST),
1032
1095
  disabled: props.isDisabled
1033
1096
  }), isNodeTypeEnabled(sdk.field, BLOCKS.OL_LIST) && /*#__PURE__*/createElement(EditorToolbarButton, {
@@ -1036,9 +1099,8 @@ function ToolbarListButton(props) {
1036
1099
  tooltipPlace: "bottom",
1037
1100
  label: "OL",
1038
1101
  testId: "ol-toolbar-button",
1039
- onClick: function onClick() {
1040
- return handleClick(BLOCKS.OL_LIST);
1041
- },
1102
+ // @ts-expect-error
1103
+ onMouseDown: handleClick(BLOCKS.OL_LIST),
1042
1104
  isActive: isBlockSelected(editor, BLOCKS.OL_LIST),
1043
1105
  disabled: props.isDisabled
1044
1106
  }));
@@ -1067,12 +1129,18 @@ var withListOptions = (_withListOptions = {}, _withListOptions[ELEMENT_LIC] = {
1067
1129
  type: BLOCKS.OL_LIST,
1068
1130
  component: OL
1069
1131
  }, _withListOptions);
1132
+ var createListPlugin = function createListPlugin() {
1133
+ return createListPlugin$1({
1134
+ validLiChildrenTypes: LIST_ITEM_BLOCKS
1135
+ });
1136
+ };
1070
1137
 
1071
1138
  var _withBoldOptions;
1072
1139
  function ToolbarBoldButton(props) {
1073
1140
  var editor = useContentfulEditor();
1074
1141
 
1075
- function handleClick() {
1142
+ function handleClick(event) {
1143
+ event.preventDefault();
1076
1144
  if (!(editor != null && editor.selection)) return;
1077
1145
  toggleMark(editor, MARKS.BOLD);
1078
1146
  ReactEditor.focus(editor);
@@ -1085,7 +1153,8 @@ function ToolbarBoldButton(props) {
1085
1153
  tooltipPlace: "bottom",
1086
1154
  label: "Bold",
1087
1155
  testId: "bold-toolbar-button",
1088
- onClick: handleClick,
1156
+ // @ts-expect-error
1157
+ onMouseDown: handleClick,
1089
1158
  isActive: isMarkActive(editor, MARKS.BOLD),
1090
1159
  disabled: props.isDisabled
1091
1160
  });
@@ -1133,7 +1202,8 @@ var _withCodeOptions;
1133
1202
  function ToolbarCodeButton(props) {
1134
1203
  var editor = useContentfulEditor();
1135
1204
 
1136
- function handleClick() {
1205
+ function handleClick(event) {
1206
+ event.preventDefault();
1137
1207
  if (!(editor != null && editor.selection)) return;
1138
1208
  toggleMark(editor, MARKS.CODE);
1139
1209
  ReactEditor.focus(editor);
@@ -1146,7 +1216,8 @@ function ToolbarCodeButton(props) {
1146
1216
  tooltipPlace: "bottom",
1147
1217
  label: "Code",
1148
1218
  testId: "code-toolbar-button",
1149
- onClick: handleClick,
1219
+ // @ts-expect-error
1220
+ onMouseDown: handleClick,
1150
1221
  isActive: isMarkActive(editor, MARKS.CODE),
1151
1222
  disabled: props.isDisabled
1152
1223
  });
@@ -1187,7 +1258,8 @@ var _withItalicOptions;
1187
1258
  function ToolbarItalicButton(props) {
1188
1259
  var editor = useContentfulEditor();
1189
1260
 
1190
- function handleClick() {
1261
+ function handleClick(event) {
1262
+ event.preventDefault();
1191
1263
  if (!(editor != null && editor.selection)) return;
1192
1264
  toggleMark(editor, MARKS.ITALIC);
1193
1265
  ReactEditor.focus(editor);
@@ -1200,7 +1272,8 @@ function ToolbarItalicButton(props) {
1200
1272
  tooltipPlace: "bottom",
1201
1273
  label: "Italic",
1202
1274
  testId: "italic-toolbar-button",
1203
- onClick: handleClick,
1275
+ // @ts-expect-error
1276
+ onMouseDown: handleClick,
1204
1277
  isActive: isMarkActive(editor, MARKS.ITALIC),
1205
1278
  disabled: props.isDisabled
1206
1279
  });
@@ -1240,7 +1313,8 @@ var _withUnderlineOptions;
1240
1313
  function ToolbarUnderlineButton(props) {
1241
1314
  var editor = useContentfulEditor();
1242
1315
 
1243
- function handleClick() {
1316
+ function handleClick(event) {
1317
+ event.preventDefault();
1244
1318
  if (!(editor != null && editor.selection)) return;
1245
1319
  toggleMark(editor, MARKS.UNDERLINE);
1246
1320
  ReactEditor.focus(editor);
@@ -1253,7 +1327,8 @@ function ToolbarUnderlineButton(props) {
1253
1327
  tooltipPlace: "bottom",
1254
1328
  label: "Underline",
1255
1329
  testId: "underline-toolbar-button",
1256
- onClick: handleClick,
1330
+ // @ts-expect-error
1331
+ onMouseDown: handleClick,
1257
1332
  isActive: isMarkActive(editor, MARKS.UNDERLINE),
1258
1333
  disabled: props.isDisabled
1259
1334
  });
@@ -2278,26 +2353,97 @@ function EntryAssetTooltip(_ref) {
2278
2353
  })));
2279
2354
  }
2280
2355
 
2356
+ var styles$a = {
2357
+ scheduleIcon: /*#__PURE__*/css({
2358
+ marginRight: tokens.spacing2Xs
2359
+ })
2360
+ };
2361
+ function EntityStatusIcon(_ref) {
2362
+ var entity = _ref.entity,
2363
+ entityType = _ref.entityType;
2364
+
2365
+ var _useEntities = useEntities(),
2366
+ loadEntityScheduledActions = _useEntities.loadEntityScheduledActions;
2367
+
2368
+ return /*#__PURE__*/createElement(ScheduledIconWithTooltip, {
2369
+ getEntityScheduledActions: loadEntityScheduledActions,
2370
+ entityType: entityType,
2371
+ entityId: entity.sys.id
2372
+ }, /*#__PURE__*/createElement(Icon, {
2373
+ className: styles$a.scheduleIcon,
2374
+ icon: "Clock",
2375
+ size: "small",
2376
+ color: "muted",
2377
+ testId: "schedule-icon"
2378
+ }));
2379
+ }
2380
+
2381
+ var styles$b = {
2382
+ entryCard: /*#__PURE__*/css({
2383
+ cursor: 'pointer'
2384
+ })
2385
+ };
2386
+
2387
+ function EntryThumbnail(_ref) {
2388
+ var file = _ref.file;
2389
+ if (!isValidImage(file)) return null;
2390
+ return /*#__PURE__*/createElement(AssetThumbnail, {
2391
+ file: file
2392
+ });
2393
+ }
2394
+
2395
+ function EntryDropdownMenu(_ref2) {
2396
+ var onEdit = _ref2.onEdit,
2397
+ onRemove = _ref2.onRemove,
2398
+ isDisabled = _ref2.isDisabled;
2399
+ return /*#__PURE__*/createElement(DropdownList, null, /*#__PURE__*/createElement(DropdownListItem, {
2400
+ isTitle: true
2401
+ }, "Actions"), /*#__PURE__*/createElement(DropdownListItem, {
2402
+ onClick: onEdit,
2403
+ testId: "card-action-edit"
2404
+ }, "Edit"), /*#__PURE__*/createElement(DropdownListItem, {
2405
+ onClick: onRemove,
2406
+ isDisabled: isDisabled,
2407
+ testId: "card-action-remove"
2408
+ }, "Remove"));
2409
+ }
2410
+
2281
2411
  function FetchingWrappedEntryCard(props) {
2282
2412
  var _useEntities = useEntities(),
2283
2413
  getOrLoadEntry = _useEntities.getOrLoadEntry,
2284
- loadEntityScheduledActions = _useEntities.loadEntityScheduledActions,
2285
2414
  entries = _useEntities.entries;
2286
2415
 
2287
- useEffect(function () {
2288
- getOrLoadEntry(props.entryId);
2289
- }, [props.entryId]); // eslint-disable-line
2416
+ var _React$useState = useState(null),
2417
+ file = _React$useState[0],
2418
+ setFile = _React$useState[1];
2290
2419
 
2291
2420
  var entry = entries[props.entryId];
2421
+ var contentType = useMemo(function () {
2422
+ return props.sdk.space.getCachedContentTypes().find(function (contentType) {
2423
+ return contentType.sys.id === (entry == null ? void 0 : entry.sys.contentType.sys.id);
2424
+ });
2425
+ }, [props.sdk, entry]);
2426
+ var defaultLocaleCode = props.sdk.locales["default"];
2292
2427
  useEffect(function () {
2293
2428
  if (!entry) return;
2294
- props.onEntityFetchComplete && props.onEntityFetchComplete();
2295
- }, [entry]); // eslint-disable-line
2429
+ entityHelpers.getEntryImage({
2430
+ entry: entry,
2431
+ contentType: contentType,
2432
+ localeCode: props.locale,
2433
+ defaultLocaleCode: defaultLocaleCode
2434
+ }, props.sdk.space.getAsset).then(setFile)["catch"](function () {
2435
+ return setFile(null);
2436
+ });
2437
+ }, [entry, contentType, props.locale, defaultLocaleCode, props.sdk, file]);
2438
+ useEffect(function () {
2439
+ getOrLoadEntry(props.entryId);
2440
+ }, [props.entryId]); // eslint-disable-line
2296
2441
 
2297
- if (entry === 'failed') {
2298
- return /*#__PURE__*/createElement(MissingEntityCard, {
2299
- entityType: "Entry",
2442
+ function renderDropdown() {
2443
+ if (!props.onEdit || !props.onRemove) return undefined;
2444
+ return /*#__PURE__*/createElement(EntryDropdownMenu, {
2300
2445
  isDisabled: props.isDisabled,
2446
+ onEdit: props.onEdit,
2301
2447
  onRemove: props.onRemove
2302
2448
  });
2303
2449
  }
@@ -2309,49 +2455,149 @@ function FetchingWrappedEntryCard(props) {
2309
2455
  });
2310
2456
  }
2311
2457
 
2312
- var contentType = props.sdk.space.getCachedContentTypes().find(function (contentType) {
2313
- return contentType.sys.id === entry.sys.contentType.sys.id;
2458
+ if (entry === 'failed') {
2459
+ return /*#__PURE__*/createElement(MissingEntityCard, {
2460
+ entityType: "Entry",
2461
+ isDisabled: props.isDisabled,
2462
+ onRemove: props.onRemove
2463
+ });
2464
+ }
2465
+
2466
+ var entryStatus = entry ? entityHelpers.getEntryStatus(entry.sys) : undefined;
2467
+
2468
+ if (entryStatus === 'deleted') {
2469
+ return /*#__PURE__*/createElement(MissingEntityCard, {
2470
+ entityType: "Entry",
2471
+ isDisabled: props.isDisabled,
2472
+ onRemove: props.onRemove
2473
+ });
2474
+ }
2475
+
2476
+ var title = entityHelpers.getEntryTitle({
2477
+ entry: entry,
2478
+ contentType: contentType,
2479
+ localeCode: props.locale,
2480
+ defaultLocaleCode: defaultLocaleCode,
2481
+ defaultTitle: 'Untitled'
2314
2482
  });
2315
- return /*#__PURE__*/createElement(WrappedEntryCard, {
2483
+ var description = entityHelpers.getEntityDescription({
2484
+ entity: entry,
2316
2485
  contentType: contentType,
2317
- defaultLocaleCode: props.sdk.locales["default"],
2318
- entry: entry,
2319
- entryUrl: props.getEntryUrl && props.getEntryUrl(entry.sys.id),
2320
- getAsset: props.sdk.space.getAsset,
2321
- getEntityScheduledActions: loadEntityScheduledActions,
2322
- isClickable: false,
2323
- isDisabled: props.isDisabled,
2324
- isSelected: props.isSelected,
2325
2486
  localeCode: props.locale,
2326
- onEdit: props.onEdit,
2327
- onRemove: props.onRemove,
2487
+ defaultLocaleCode: defaultLocaleCode
2488
+ });
2489
+ return /*#__PURE__*/createElement(EntryCard, {
2490
+ contentType: contentType == null ? void 0 : contentType.name,
2491
+ title: title,
2492
+ description: description,
2328
2493
  size: "default",
2329
- hasMoveOptions: false
2494
+ selected: props.isSelected,
2495
+ status: entryStatus,
2496
+ className: styles$b.entryCard,
2497
+ thumbnailElement: file ? /*#__PURE__*/createElement(EntryThumbnail, {
2498
+ file: file
2499
+ }) : null,
2500
+ statusIcon: /*#__PURE__*/createElement(EntityStatusIcon, {
2501
+ entityType: "Entry",
2502
+ entity: entry
2503
+ }),
2504
+ dropdownListElements: renderDropdown()
2330
2505
  });
2331
2506
  }
2332
2507
 
2508
+ var styles$c = {
2509
+ assetCard: /*#__PURE__*/css({
2510
+ cursor: 'pointer'
2511
+ }),
2512
+ cardDropdown: /*#__PURE__*/css({
2513
+ width: '300px'
2514
+ }),
2515
+ truncated: /*#__PURE__*/css({
2516
+ overflow: 'hidden',
2517
+ whiteSpace: 'nowrap',
2518
+ textOverflow: 'ellipsis'
2519
+ })
2520
+ };
2521
+
2522
+ function AssetDropdownMenu(_ref) {
2523
+ var onEdit = _ref.onEdit,
2524
+ onRemove = _ref.onRemove,
2525
+ isDisabled = _ref.isDisabled,
2526
+ entityFile = _ref.entityFile;
2527
+ var fileName = entityFile.fileName,
2528
+ mimeType = entityFile.contentType,
2529
+ details = entityFile.details;
2530
+ var fileSize = details.size,
2531
+ image = details.image;
2532
+
2533
+ function downloadAsset() {
2534
+ if (!entityFile) return;
2535
+ window.open(entityFile.url, '_blank', 'noopener,noreferrer');
2536
+ }
2537
+
2538
+ return /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement(DropdownList, null, /*#__PURE__*/createElement(DropdownListItem, {
2539
+ isTitle: true
2540
+ }, "Actions"), onEdit && /*#__PURE__*/createElement(DropdownListItem, {
2541
+ onClick: onEdit,
2542
+ testId: "card-action-edit"
2543
+ }, "Edit"), entityFile && /*#__PURE__*/createElement(DropdownListItem, {
2544
+ onClick: downloadAsset,
2545
+ testId: "card-action-download"
2546
+ }, "Download"), onRemove && /*#__PURE__*/createElement(DropdownListItem, {
2547
+ onClick: onRemove,
2548
+ isDisabled: isDisabled,
2549
+ testId: "card-action-remove"
2550
+ }, "Remove")), /*#__PURE__*/createElement(DropdownList, {
2551
+ border: "top"
2552
+ }, /*#__PURE__*/createElement(DropdownListItem, {
2553
+ isTitle: true
2554
+ }, "File info"), fileName && /*#__PURE__*/createElement(DropdownListItem, null, /*#__PURE__*/createElement("div", {
2555
+ className: styles$c.truncated
2556
+ }, fileName)), mimeType && /*#__PURE__*/createElement(DropdownListItem, null, /*#__PURE__*/createElement("div", null, mimeType)), fileSize && /*#__PURE__*/createElement(DropdownListItem, null, shortenStorageUnit(fileSize, 'B')), image && /*#__PURE__*/createElement(DropdownListItem, null, image.width + " \xD7 " + image.height)));
2557
+ }
2558
+
2333
2559
  function FetchingWrappedAssetCard(props) {
2334
2560
  var _useEntities = useEntities(),
2335
2561
  getOrLoadAsset = _useEntities.getOrLoadAsset,
2336
- loadEntityScheduledActions = _useEntities.loadEntityScheduledActions,
2337
2562
  assets = _useEntities.assets;
2338
2563
 
2564
+ var asset = assets[props.assetId];
2565
+ var defaultLocaleCode = props.sdk.locales["default"];
2566
+ var entityFile = asset != null && asset.fields.file ? asset.fields.file[props.locale] || asset.fields.file[defaultLocaleCode] : undefined;
2339
2567
  useEffect(function () {
2340
2568
  getOrLoadAsset(props.assetId);
2341
2569
  }, [props.assetId]); // eslint-disable-line
2342
2570
 
2343
- var asset = assets[props.assetId];
2344
- useEffect(function () {
2345
- if (!asset) return;
2346
- props.onEntityFetchComplete && props.onEntityFetchComplete();
2347
- }, [asset]); // eslint-disable-line
2571
+ function getAssetSrc() {
2572
+ if (!(entityFile != null && entityFile.url)) return '';
2573
+ return entityFile.url + "?h=300";
2574
+ }
2348
2575
 
2349
- if (asset === 'failed') {
2350
- return /*#__PURE__*/createElement(MissingEntityCard, {
2351
- entityType: "Asset",
2352
- isDisabled: props.isDisabled,
2353
- onRemove: props.onRemove
2576
+ function getFileType() {
2577
+ var groupToIconMap = {
2578
+ image: 'image',
2579
+ video: 'video',
2580
+ audio: 'audio',
2581
+ richtext: 'richtext',
2582
+ presentation: 'presentation',
2583
+ spreadsheet: 'spreadsheet',
2584
+ pdfdocument: 'pdf',
2585
+ archive: 'archive',
2586
+ plaintext: 'plaintext',
2587
+ code: 'code',
2588
+ markup: 'markup'
2589
+ };
2590
+ var archive = groupToIconMap['archive'];
2591
+
2592
+ if (!entityFile) {
2593
+ return archive;
2594
+ }
2595
+
2596
+ var groupName = mimetype.getGroupLabel({
2597
+ type: entityFile.contentType,
2598
+ fallbackFileName: entityFile.fileName
2354
2599
  });
2600
+ return groupToIconMap[groupName] || archive;
2355
2601
  }
2356
2602
 
2357
2603
  if (asset === undefined) {
@@ -2364,20 +2610,49 @@ function FetchingWrappedAssetCard(props) {
2364
2610
  });
2365
2611
  }
2366
2612
 
2367
- return /*#__PURE__*/createElement(WrappedAssetCard, {
2613
+ if (asset === 'failed') {
2614
+ return /*#__PURE__*/createElement(MissingEntityCard, {
2615
+ entityType: "Asset",
2616
+ isDisabled: props.isDisabled,
2617
+ onRemove: props.onRemove
2618
+ });
2619
+ }
2620
+
2621
+ var status = asset ? entityHelpers.getEntryStatus(asset.sys) : undefined;
2622
+
2623
+ if (status === 'deleted') {
2624
+ return /*#__PURE__*/createElement(MissingEntityCard, {
2625
+ entityType: "Asset",
2626
+ asSquare: true,
2627
+ isDisabled: props.isDisabled,
2628
+ onRemove: props.onRemove
2629
+ });
2630
+ }
2631
+
2632
+ var entityTitle = entityHelpers.getAssetTitle({
2368
2633
  asset: asset,
2369
- defaultLocaleCode: props.sdk.locales["default"],
2370
- // @ts-expect-error
2371
- getAsset: props.sdk.space.getAsset,
2372
- getAssetUrl: props.getAssetUrl,
2373
- getEntityScheduledActions: loadEntityScheduledActions,
2374
- isClickable: false,
2375
- isDisabled: props.isDisabled,
2376
- isSelected: props.isSelected,
2377
2634
  localeCode: props.locale,
2378
- onEdit: props.onEdit,
2379
- onRemove: props.onRemove,
2380
- size: "default"
2635
+ defaultLocaleCode: defaultLocaleCode,
2636
+ defaultTitle: 'Untitled'
2637
+ });
2638
+ return /*#__PURE__*/createElement(AssetCard, {
2639
+ title: entityTitle,
2640
+ selected: props.isSelected,
2641
+ size: "default",
2642
+ src: getAssetSrc(),
2643
+ type: getFileType(),
2644
+ status: status,
2645
+ statusIcon: /*#__PURE__*/createElement(EntityStatusIcon, {
2646
+ entityType: "Asset",
2647
+ entity: asset
2648
+ }),
2649
+ className: styles$c.assetCard,
2650
+ dropdownListElements: entityFile && /*#__PURE__*/createElement(AssetDropdownMenu, {
2651
+ onEdit: props.onEdit,
2652
+ onRemove: props.onRemove,
2653
+ isDisabled: props.isDisabled,
2654
+ entityFile: entityFile
2655
+ })
2381
2656
  });
2382
2657
  }
2383
2658
 
@@ -2421,7 +2696,7 @@ function getLinkedContentTypeIdsForNodeType(field, nodeType) {
2421
2696
  }
2422
2697
 
2423
2698
  var _templateObject$3, _SYS_LINK_TYPES, _LINK_TYPE_SELECTION_;
2424
- var styles$a = {
2699
+ var styles$d = {
2425
2700
  removeSelectionLabel: /*#__PURE__*/css(_templateObject$3 || (_templateObject$3 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n margin-left: ", ";\n "])), tokens.spacingS)
2426
2701
  };
2427
2702
  var SYS_LINK_TYPES = (_SYS_LINK_TYPES = {}, _SYS_LINK_TYPES[INLINES.ENTRY_HYPERLINK] = 'Entry', _SYS_LINK_TYPES[INLINES.ASSET_HYPERLINK] = 'Asset', _SYS_LINK_TYPES);
@@ -2609,7 +2884,7 @@ function HyperlinkModal(props) {
2609
2884
  htmlFor: ""
2610
2885
  }, "Link target", ' '), linkEntity && linkEntity.sys.linkType === SYS_LINK_TYPES[linkType] ? /*#__PURE__*/createElement(Fragment, null, /*#__PURE__*/createElement(TextLink, {
2611
2886
  onClick: resetLinkEntity,
2612
- className: styles$a.removeSelectionLabel
2887
+ className: styles$d.removeSelectionLabel
2613
2888
  }, "Remove selection"), /*#__PURE__*/createElement("div", null, linkType === INLINES.ENTRY_HYPERLINK && /*#__PURE__*/createElement(FetchingWrappedEntryCard, {
2614
2889
  sdk: props.sdk,
2615
2890
  locale: props.sdk.field.locale,
@@ -2724,7 +2999,7 @@ function _addOrEditLink() {
2724
2999
  }
2725
3000
 
2726
3001
  var _withHyperlinkOptions;
2727
- var styles$b = {
3002
+ var styles$e = {
2728
3003
  hyperlinkWrapper: /*#__PURE__*/css({
2729
3004
  display: 'inline',
2730
3005
  position: 'static',
@@ -2903,14 +3178,14 @@ function UrlHyperlink(props) {
2903
3178
 
2904
3179
  return /*#__PURE__*/createElement(Tooltip, {
2905
3180
  content: uri,
2906
- targetWrapperClassName: styles$b.hyperlinkWrapper,
3181
+ targetWrapperClassName: styles$e.hyperlinkWrapper,
2907
3182
  place: "bottom",
2908
3183
  maxWidth: "auto"
2909
3184
  }, /*#__PURE__*/createElement(TextLink, {
2910
3185
  href: uri,
2911
3186
  rel: "noopener noreferrer",
2912
3187
  onClick: handleClick,
2913
- className: styles$b.hyperlink
3188
+ className: styles$e.hyperlink
2914
3189
  }, props.children));
2915
3190
  }
2916
3191
 
@@ -2959,14 +3234,14 @@ function EntityHyperlink(props) {
2959
3234
  type: target.sys.linkType,
2960
3235
  sdk: sdk
2961
3236
  }),
2962
- targetWrapperClassName: styles$b.hyperlinkWrapper,
3237
+ targetWrapperClassName: styles$e.hyperlinkWrapper,
2963
3238
  place: "bottom",
2964
3239
  maxWidth: "auto"
2965
3240
  }, /*#__PURE__*/createElement(TextLink, {
2966
3241
  href: "javascript:void(0)",
2967
3242
  rel: "noopener noreferrer",
2968
3243
  onClick: handleClick,
2969
- className: styles$b.hyperlink,
3244
+ className: styles$e.hyperlink,
2970
3245
  "data-link-type": target.sys.linkType,
2971
3246
  "data-link-id": target.sys.id
2972
3247
  }, props.children));
@@ -3020,7 +3295,8 @@ function ToolbarHyperlinkButton(props) {
3020
3295
  tooltipPlace: "bottom",
3021
3296
  label: "Hyperlink",
3022
3297
  testId: "hyperlink-toolbar-button",
3023
- onClick: handleClick,
3298
+ // @ts-expect-error
3299
+ onMouseDown: handleClick,
3024
3300
  isActive: isActive,
3025
3301
  disabled: props.isDisabled
3026
3302
  });
@@ -3238,7 +3514,7 @@ var setHeader = function setHeader(editor, enable) {
3238
3514
  });
3239
3515
  };
3240
3516
 
3241
- var styles$c = {
3517
+ var styles$f = {
3242
3518
  topRight: /*#__PURE__*/css({
3243
3519
  position: 'absolute',
3244
3520
  top: tokens.spacingXs,
@@ -3316,7 +3592,7 @@ var TableActions = function TableActions() {
3316
3592
  };
3317
3593
  }, [editor, isHeaderEnabled, close, onViewportAction]);
3318
3594
  return /*#__PURE__*/React__default.createElement(Dropdown, {
3319
- className: styles$c.topRight,
3595
+ className: styles$f.topRight,
3320
3596
  position: "left",
3321
3597
  isOpen: isOpen,
3322
3598
  onClose: close,
@@ -3356,27 +3632,36 @@ var TableActions = function TableActions() {
3356
3632
  };
3357
3633
 
3358
3634
  var _templateObject$4, _templateObject2$3, _templateObject3$3, _templateObject4$1, _styles$1, _withTableOptions;
3359
- var styles$d = (_styles$1 = {}, _styles$1[BLOCKS.TABLE] = /*#__PURE__*/css(_templateObject$4 || (_templateObject$4 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n margin-bottom: 1.5em;\n border-collapse: collapse;\n border-radius: 5px;\n border-style: hidden;\n box-shadow: 0 0 0 1px ", ";\n width: 100%;\n table-layout: fixed;\n overflow: hidden;\n "])), tokens.gray400), _styles$1[BLOCKS.TABLE_ROW] = /*#__PURE__*/css(_templateObject2$3 || (_templateObject2$3 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n &:hover td {\n background-color: transparent !important;\n }\n "])), tokens.gray400), _styles$1[BLOCKS.TABLE_HEADER_CELL] = /*#__PURE__*/css(_templateObject3$3 || (_templateObject3$3 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n background-color: ", ";\n border: 1px solid ", ";\n padding: 10px 12px;\n font-weight: ", ";\n text-align: left;\n min-width: 48px;\n position: relative;\n div:last-child {\n margin-bottom: 0;\n }\n "])), tokens.gray200, tokens.gray400, tokens.fontWeightMedium), _styles$1[BLOCKS.TABLE_CELL] = /*#__PURE__*/css(_templateObject4$1 || (_templateObject4$1 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n padding: 10px 12px;\n min-width: 48px;\n position: relative;\n div:last-child {\n margin-bottom: 0;\n }\n "])), tokens.gray400), _styles$1);
3635
+ var styles$g = (_styles$1 = {}, _styles$1[BLOCKS.TABLE] = /*#__PURE__*/css(_templateObject$4 || (_templateObject$4 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n margin-bottom: 1.5em;\n border-collapse: collapse;\n border-radius: 5px;\n border-style: hidden;\n box-shadow: 0 0 0 1px ", ";\n width: 100%;\n table-layout: fixed;\n overflow: hidden;\n "])), tokens.gray400), _styles$1[BLOCKS.TABLE_ROW] = /*#__PURE__*/css(_templateObject2$3 || (_templateObject2$3 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n &:hover td {\n background-color: transparent !important;\n }\n "])), tokens.gray400), _styles$1[BLOCKS.TABLE_HEADER_CELL] = /*#__PURE__*/css(_templateObject3$3 || (_templateObject3$3 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n background-color: ", ";\n border: 1px solid ", ";\n padding: 10px 12px;\n font-weight: ", ";\n text-align: left;\n min-width: 48px;\n position: relative;\n div:last-child {\n margin-bottom: 0;\n }\n "])), tokens.gray200, tokens.gray400, tokens.fontWeightMedium), _styles$1[BLOCKS.TABLE_CELL] = /*#__PURE__*/css(_templateObject4$1 || (_templateObject4$1 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n padding: 10px 12px;\n min-width: 48px;\n position: relative;\n div:last-child {\n margin-bottom: 0;\n }\n "])), tokens.gray400), _styles$1);
3636
+
3637
+ var slateNodeToText = function slateNodeToText(node) {
3638
+ var contentfulNode = toContentfulDocument({
3639
+ document: [node],
3640
+ schema: schema
3641
+ });
3642
+ return documentToPlainTextString(contentfulNode);
3643
+ };
3644
+
3360
3645
  var Table = function Table(props) {
3361
3646
  return /*#__PURE__*/createElement("table", Object.assign({}, props.attributes, {
3362
- className: styles$d[BLOCKS.TABLE]
3647
+ className: styles$g[BLOCKS.TABLE]
3363
3648
  }), /*#__PURE__*/createElement("tbody", null, props.children));
3364
3649
  };
3365
3650
  var TR = function TR(props) {
3366
3651
  return /*#__PURE__*/createElement("tr", Object.assign({}, props.attributes, {
3367
- className: styles$d[BLOCKS.TABLE_ROW]
3652
+ className: styles$g[BLOCKS.TABLE_ROW]
3368
3653
  }), props.children);
3369
3654
  };
3370
3655
  var TH = function TH(props) {
3371
3656
  var isSelected = useSelected();
3372
3657
  return /*#__PURE__*/createElement("th", Object.assign({}, props.attributes, props.element.data, {
3373
- className: styles$d[BLOCKS.TABLE_HEADER_CELL]
3658
+ className: styles$g[BLOCKS.TABLE_HEADER_CELL]
3374
3659
  }), isSelected && /*#__PURE__*/createElement(TableActions, null), props.children);
3375
3660
  };
3376
3661
  var TD = function TD(props) {
3377
3662
  var isSelected = useSelected();
3378
3663
  return /*#__PURE__*/createElement("td", Object.assign({}, props.attributes, props.element.data, {
3379
- className: styles$d[BLOCKS.TABLE_CELL]
3664
+ className: styles$g[BLOCKS.TABLE_CELL]
3380
3665
  }), isSelected && /*#__PURE__*/createElement(TableActions, null), props.children);
3381
3666
  };
3382
3667
  var withTableOptions = (_withTableOptions = {}, _withTableOptions[ELEMENT_TABLE] = {
@@ -3409,7 +3694,8 @@ function addTableTrackingEvents(editor, _ref) {
3409
3694
 
3410
3695
  if (hasTables(markupAfter)) {
3411
3696
  onViewportAction('paste', {
3412
- tablePasted: true
3697
+ tablePasted: true,
3698
+ hasHeadersOutsideFirstRow: hasHeadersOutsideFirstRow(markupAfter)
3413
3699
  });
3414
3700
  }
3415
3701
  }, 1);
@@ -3417,6 +3703,56 @@ function addTableTrackingEvents(editor, _ref) {
3417
3703
  };
3418
3704
  }
3419
3705
 
3706
+ var paragraph = function paragraph() {
3707
+ return {
3708
+ type: BLOCKS.PARAGRAPH,
3709
+ data: {},
3710
+ children: []
3711
+ };
3712
+ };
3713
+
3714
+ function addTableNormalization(editor) {
3715
+ var normalizeNode = editor.normalizeNode;
3716
+
3717
+ editor.normalizeNode = function (entry) {
3718
+ var node = entry[0],
3719
+ path = entry[1]; // TODO: This should be enforced by sanitizeSlateDoc() but the internal
3720
+ // editor value can be different.
3721
+ // cf. https://github.com/ianstormtaylor/slate/issues/2206
3722
+
3723
+ var cellTypes = [BLOCKS.TABLE_CELL, BLOCKS.TABLE_HEADER_CELL];
3724
+
3725
+ if (Element.isElement(node) && cellTypes.includes(node.type)) {
3726
+ for (var _iterator = _createForOfIteratorHelperLoose(Node$1.children(editor, path)), _step; !(_step = _iterator()).done;) {
3727
+ var _step$value = _step.value,
3728
+ child = _step$value[0],
3729
+ childPath = _step$value[1];
3730
+
3731
+ if (Text.isText(child)) {
3732
+ Transforms.wrapNodes(editor, paragraph(), {
3733
+ at: childPath
3734
+ });
3735
+ } else if (!CONTAINERS[node.type].includes(child.type)) {
3736
+ var paragraphWithTextFromNode = _extends({}, paragraph(), {
3737
+ children: [{
3738
+ text: slateNodeToText(child)
3739
+ }]
3740
+ });
3741
+
3742
+ Transforms.removeNodes(editor, {
3743
+ at: childPath
3744
+ });
3745
+ Transforms.insertNodes(editor, paragraphWithTextFromNode, {
3746
+ at: childPath
3747
+ });
3748
+ }
3749
+ }
3750
+ }
3751
+
3752
+ normalizeNode(entry);
3753
+ };
3754
+ }
3755
+
3420
3756
  function hasTables(nodes) {
3421
3757
  return nodes.some(function (_ref2) {
3422
3758
  var type = _ref2.type;
@@ -3424,16 +3760,62 @@ function hasTables(nodes) {
3424
3760
  });
3425
3761
  }
3426
3762
 
3763
+ var isTableHeaderCell = function isTableHeaderCell(_ref3) {
3764
+ var type = _ref3.type;
3765
+ return type === BLOCKS.TABLE_HEADER_CELL;
3766
+ };
3767
+
3768
+ function hasHeadersOutsideFirstRow(nodes) {
3769
+ return nodes.filter(function (_ref4) {
3770
+ var type = _ref4.type;
3771
+ return type === BLOCKS.TABLE;
3772
+ }).flatMap(function (_ref5) {
3773
+ var children = _ref5.children;
3774
+ return children.slice(1);
3775
+ }).some(function (_ref6) {
3776
+ var children = _ref6.children;
3777
+ return children.some(isTableHeaderCell);
3778
+ });
3779
+ }
3780
+
3427
3781
  function createWithTableEvents(tracking) {
3428
3782
  return function withTableEvents(editor) {
3429
3783
  addTableTrackingEvents(editor, tracking);
3784
+ addTableNormalization(editor);
3430
3785
  return getTableOnKeyDown()(editor);
3431
3786
  };
3432
3787
  }
3433
3788
 
3434
3789
  var createTablePlugin = function createTablePlugin(tracking) {
3435
3790
  return _extends({}, createTablePlugin$1(), {
3436
- onKeyDown: createWithTableEvents(tracking)
3791
+ onKeyDown: createWithTableEvents(tracking),
3792
+ withOverrides: function withOverrides(editor) {
3793
+ var insertFragment = editor.insertFragment;
3794
+
3795
+ editor.insertFragment = function (fragments) {
3796
+ // We need to make sure we have a new, empty and clean paragraph in order to paste tables as-is due to how Slate behaves
3797
+ // More info: https://github.com/ianstormtaylor/slate/pull/4489 and https://github.com/ianstormtaylor/slate/issues/4542
3798
+ var fragmentHasTable = fragments.some(function (fragment) {
3799
+ return fragment.type === BLOCKS.TABLE;
3800
+ });
3801
+
3802
+ if (fragmentHasTable) {
3803
+ var emptyParagraph = {
3804
+ type: BLOCKS.PARAGRAPH,
3805
+ children: [{
3806
+ text: ''
3807
+ }],
3808
+ data: {},
3809
+ isVoid: false
3810
+ };
3811
+ Transforms.insertNodes(editor, emptyParagraph);
3812
+ }
3813
+
3814
+ insertFragment(fragments);
3815
+ };
3816
+
3817
+ return editor;
3818
+ }
3437
3819
  });
3438
3820
  };
3439
3821
  function ToolbarTableButton(props) {
@@ -3485,7 +3867,8 @@ function ToolbarTableButton(props) {
3485
3867
  tooltipPlace: "bottom",
3486
3868
  label: "Table",
3487
3869
  testId: "table-toolbar-button",
3488
- onClick: handleClick,
3870
+ // @ts-expect-error
3871
+ onMouseDown: handleClick,
3489
3872
  // TODO: active state looks off since the button will be disabled. Do we still need it?
3490
3873
  isActive: isActive,
3491
3874
  disabled: props.isDisabled
@@ -3515,7 +3898,7 @@ function EmbeddedEntityDropdownButton(_ref) {
3515
3898
  }, /*#__PURE__*/createElement(DropdownList, null, children));
3516
3899
  }
3517
3900
 
3518
- var styles$e = {
3901
+ var styles$h = {
3519
3902
  root: /*#__PURE__*/css({
3520
3903
  marginBottom: '1.25rem'
3521
3904
  })
@@ -3523,8 +3906,7 @@ var styles$e = {
3523
3906
  function LinkedEntityBlock(props) {
3524
3907
  var attributes = props.attributes,
3525
3908
  children = props.children,
3526
- element = props.element,
3527
- onEntityFetchComplete = props.onEntityFetchComplete;
3909
+ element = props.element;
3528
3910
  var isSelected = useSelected();
3529
3911
  var editor = useContentfulEditor();
3530
3912
  var sdk = useSdkContext();
@@ -3549,7 +3931,7 @@ function LinkedEntityBlock(props) {
3549
3931
  };
3550
3932
 
3551
3933
  return /*#__PURE__*/React__default.createElement("div", Object.assign({}, attributes, {
3552
- className: styles$e.root,
3934
+ className: styles$h.root,
3553
3935
  "data-entity-type": entityType,
3554
3936
  "data-entity-id": entityId
3555
3937
  }), /*#__PURE__*/React__default.createElement("div", {
@@ -3561,12 +3943,7 @@ function LinkedEntityBlock(props) {
3561
3943
  isDisabled: isDisabled,
3562
3944
  isSelected: isSelected,
3563
3945
  onRemove: handleRemoveClick,
3564
- onEdit: handleEditClick,
3565
- getEntryUrl: function getEntryUrl() {
3566
- var getEntryUrl = sdk.parameters.instance.getEntryUrl;
3567
- return typeof getEntryUrl === 'function' ? getEntryUrl(entityId) : '';
3568
- },
3569
- onEntityFetchComplete: onEntityFetchComplete
3946
+ onEdit: handleEditClick
3570
3947
  }), entityType === 'Asset' && /*#__PURE__*/React__default.createElement(FetchingWrappedAssetCard, {
3571
3948
  sdk: sdk,
3572
3949
  assetId: entityId,
@@ -3574,12 +3951,7 @@ function LinkedEntityBlock(props) {
3574
3951
  isDisabled: isDisabled,
3575
3952
  isSelected: isSelected,
3576
3953
  onRemove: handleRemoveClick,
3577
- onEdit: handleEditClick,
3578
- getAssetUrl: function getAssetUrl() {
3579
- var getAssetUrl = sdk.parameters.instance.getAssetUrl;
3580
- return typeof getAssetUrl === 'function' ? getAssetUrl(entityId) : '';
3581
- },
3582
- onEntityFetchComplete: onEntityFetchComplete
3954
+ onEdit: handleEditClick
3583
3955
  })), children);
3584
3956
  }
3585
3957
 
@@ -3719,7 +4091,7 @@ function insertBlock(editor, nodeType, entity) {
3719
4091
  ReactEditor.focus(editor);
3720
4092
  }
3721
4093
 
3722
- var styles$f = {
4094
+ var styles$i = {
3723
4095
  icon: /*#__PURE__*/css({
3724
4096
  marginRight: '10px'
3725
4097
  })
@@ -3734,16 +4106,17 @@ function EmbeddedEntityBlockToolbarIcon(_ref) {
3734
4106
  var sdk = useSdkContext();
3735
4107
 
3736
4108
  var handleClick = /*#__PURE__*/function () {
3737
- var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
4109
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(event) {
3738
4110
  return runtime_1.wrap(function _callee$(_context) {
3739
4111
  while (1) {
3740
4112
  switch (_context.prev = _context.next) {
3741
4113
  case 0:
4114
+ event.preventDefault();
3742
4115
  onClose();
3743
- _context.next = 3;
4116
+ _context.next = 4;
3744
4117
  return selectEntityAndInsert(nodeType, sdk, editor, logAction || noop);
3745
4118
 
3746
- case 3:
4119
+ case 4:
3747
4120
  case "end":
3748
4121
  return _context.stop();
3749
4122
  }
@@ -3751,7 +4124,7 @@ function EmbeddedEntityBlockToolbarIcon(_ref) {
3751
4124
  }, _callee);
3752
4125
  }));
3753
4126
 
3754
- return function handleClick() {
4127
+ return function handleClick(_x) {
3755
4128
  return _ref2.apply(this, arguments);
3756
4129
  };
3757
4130
  }();
@@ -3762,21 +4135,22 @@ function EmbeddedEntityBlockToolbarIcon(_ref) {
3762
4135
  disabled: isDisabled,
3763
4136
  className: baseClass + "-button",
3764
4137
  size: "small",
3765
- onClick: handleClick,
4138
+ // @ts-expect-error
4139
+ onMouseDown: handleClick,
3766
4140
  icon: type === 'Asset' ? 'Asset' : 'EmbeddedEntryBlock',
3767
4141
  buttonType: "muted",
3768
4142
  testId: "toolbar-toggle-" + nodeType
3769
4143
  }, "Embed " + type.toLowerCase()) : /*#__PURE__*/React__default.createElement(DropdownListItem, {
3770
4144
  isDisabled: isDisabled,
3771
4145
  className: baseClass + "-list-item",
3772
- onClick: handleClick,
4146
+ onMouseDown: handleClick,
3773
4147
  testId: "toolbar-toggle-" + nodeType
3774
4148
  }, /*#__PURE__*/React__default.createElement(Flex, {
3775
4149
  alignItems: "center",
3776
4150
  flexDirection: "row"
3777
4151
  }, /*#__PURE__*/React__default.createElement(Icon, {
3778
4152
  icon: type === 'Asset' ? 'Asset' : 'EmbeddedEntryBlock',
3779
- className: "rich-text__embedded-entry-list-icon " + styles$f.icon,
4153
+ className: "rich-text__embedded-entry-list-icon " + styles$i.icon,
3780
4154
  color: "secondary"
3781
4155
  }), /*#__PURE__*/React__default.createElement("span", null, type)));
3782
4156
  }
@@ -3819,6 +4193,7 @@ var createEmbeddedEntityPlugin = function createEmbeddedEntityPlugin(nodeType) {
3819
4193
  if (!isBlock) return;
3820
4194
  return {
3821
4195
  type: nodeType,
4196
+ isVoid: true,
3822
4197
  data: {
3823
4198
  target: {
3824
4199
  sys: {
@@ -3901,7 +4276,7 @@ function getWithEmbeddedEntityEvents(nodeType, sdk) {
3901
4276
 
3902
4277
  var getEntryTitle = entityHelpers.getEntryTitle,
3903
4278
  getEntryStatus = entityHelpers.getEntryStatus;
3904
- var styles$g = {
4279
+ var styles$j = {
3905
4280
  scheduledIcon: /*#__PURE__*/css({
3906
4281
  verticalAlign: 'text-bottom',
3907
4282
  marginRight: tokens.spacing2Xs
@@ -3979,7 +4354,7 @@ function FetchingWrappedInlineEntryCard(props) {
3979
4354
  entityType: "Entry",
3980
4355
  entityId: entry.sys.id
3981
4356
  }, /*#__PURE__*/React__default.createElement(Icon, {
3982
- className: styles$g.scheduledIcon,
4357
+ className: styles$j.scheduledIcon,
3983
4358
  icon: "Clock",
3984
4359
  color: "muted",
3985
4360
  testId: "scheduled-icon"
@@ -4005,7 +4380,7 @@ function createInlineEntryNode(id) {
4005
4380
  }
4006
4381
 
4007
4382
  var _withEmbeddedEntityIn;
4008
- var styles$h = {
4383
+ var styles$k = {
4009
4384
  icon: /*#__PURE__*/css({
4010
4385
  marginRight: '10px'
4011
4386
  }),
@@ -4043,7 +4418,7 @@ function EmbeddedEntityInline(props) {
4043
4418
  }
4044
4419
 
4045
4420
  return /*#__PURE__*/createElement("span", Object.assign({}, props.attributes, {
4046
- className: styles$h.root,
4421
+ className: styles$k.root,
4047
4422
  "data-embedded-entity-inline-id": entryId
4048
4423
  }), /*#__PURE__*/createElement("span", {
4049
4424
  contentEditable: false
@@ -4161,7 +4536,7 @@ function ToolbarEmbeddedEntityInlineButton(props) {
4161
4536
  }, /*#__PURE__*/createElement(Icon, {
4162
4537
  icon: "EmbeddedEntryInline",
4163
4538
  color: "secondary",
4164
- className: "rich-text__embedded-entry-list-icon " + styles$h.icon
4539
+ className: "rich-text__embedded-entry-list-icon " + styles$k.icon
4165
4540
  }), /*#__PURE__*/createElement("span", null, "Inline entry")));
4166
4541
  }
4167
4542
  function createEmbeddedEntityInlinePlugin(sdk) {
@@ -4281,7 +4656,7 @@ var EmbedEntityWidget = function EmbedEntityWidget(_ref) {
4281
4656
  }, actions);
4282
4657
  };
4283
4658
 
4284
- var styles$i = {
4659
+ var styles$l = {
4285
4660
  embedActionsWrapper: /*#__PURE__*/css({
4286
4661
  display: ['-webkit-box', '-ms-flexbox', 'flex'],
4287
4662
  webkitAlignSelf: 'flex-start',
@@ -4311,7 +4686,7 @@ var Toolbar = function Toolbar(_ref) {
4311
4686
  return /*#__PURE__*/React__default.createElement(EditorToolbar, {
4312
4687
  testId: "toolbar"
4313
4688
  }, /*#__PURE__*/React__default.createElement("div", {
4314
- className: styles$i.formattingOptionsWrapper
4689
+ className: styles$l.formattingOptionsWrapper
4315
4690
  }, /*#__PURE__*/React__default.createElement(ToolbarHeadingButton, {
4316
4691
  isDisabled: isDisabled || !canInsertBlocks
4317
4692
  }), validationInfo.isAnyMarkEnabled && /*#__PURE__*/React__default.createElement(EditorToolbarDivider, null), isMarkEnabled(sdk.field, MARKS.BOLD) && /*#__PURE__*/React__default.createElement(ToolbarBoldButton, {
@@ -4333,7 +4708,7 @@ var Toolbar = function Toolbar(_ref) {
4333
4708
  }), isNodeTypeEnabled(sdk.field, BLOCKS.TABLE) && /*#__PURE__*/React__default.createElement(ToolbarTableButton, {
4334
4709
  isDisabled: isDisabled || !canInsertBlocks
4335
4710
  })), /*#__PURE__*/React__default.createElement("div", {
4336
- className: styles$i.embedActionsWrapper
4711
+ className: styles$l.embedActionsWrapper
4337
4712
  }, /*#__PURE__*/React__default.createElement(EmbedEntityWidget, {
4338
4713
  isDisabled: isDisabled,
4339
4714
  canInsertBlocks: canInsertBlocks
@@ -4358,7 +4733,7 @@ function getValidationInfo(field) {
4358
4733
  }
4359
4734
 
4360
4735
  var _templateObject$5;
4361
- var styles$j = {
4736
+ var styles$m = {
4362
4737
  nativeSticky: /*#__PURE__*/css(_templateObject$5 || (_templateObject$5 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n position: -webkit-sticky;\n position: sticky;\n top: -1px;\n z-index: 2;\n "])))
4363
4738
  };
4364
4739
 
@@ -4366,15 +4741,158 @@ var StickyToolbarWrapper = function StickyToolbarWrapper(_ref) {
4366
4741
  var isDisabled = _ref.isDisabled,
4367
4742
  children = _ref.children;
4368
4743
  return /*#__PURE__*/React__default.createElement("div", {
4369
- className: isDisabled ? '' : styles$j.nativeSticky
4744
+ className: isDisabled ? '' : styles$m.nativeSticky
4370
4745
  }, children);
4371
4746
  };
4372
4747
 
4748
+ var removeChildNodes = function removeChildNodes(node, predicate) {
4749
+ return Array.from(node.childNodes).filter(predicate).forEach(function (table) {
4750
+ return node.removeChild(table);
4751
+ });
4752
+ };
4753
+
4754
+ var removeChildNodesUsingPredicate = function removeChildNodesUsingPredicate(predicate) {
4755
+ return function (nodeList) {
4756
+ var nodes = Array.from(nodeList);
4757
+
4758
+ while (nodes.length > 0) {
4759
+ var node = nodes.pop();
4760
+ removeChildNodes(node, predicate);
4761
+
4762
+ for (var _i = 0, _Array$from = Array.from(node.childNodes); _i < _Array$from.length; _i++) {
4763
+ var childNode = _Array$from[_i];
4764
+ nodes.push(childNode);
4765
+ }
4766
+ }
4767
+
4768
+ return nodes;
4769
+ };
4770
+ };
4771
+
4772
+ var isComment = function isComment(node) {
4773
+ return node.nodeType === Node.COMMENT_NODE;
4774
+ };
4775
+
4776
+ var removeCommentChildren = /*#__PURE__*/removeChildNodesUsingPredicate(isComment);
4777
+ var removeComments = function removeComments(_ref) {
4778
+ var doc = _ref[0],
4779
+ editor = _ref[1];
4780
+ removeCommentChildren(doc.childNodes);
4781
+ return [doc, editor];
4782
+ };
4783
+
4784
+ var TAG_NAME_TABLE = 'TABLE';
4785
+ var TAG_NAME_TABLE_CAPTION = 'CAPTION';
4786
+ var DISALLOWED_TABLE_CHILD_ELEMENTS = [TAG_NAME_TABLE_CAPTION];
4787
+
4788
+ var isHTMLElement = function isHTMLElement(node) {
4789
+ return node.nodeType === Node.ELEMENT_NODE;
4790
+ };
4791
+
4792
+ var isTableElement = function isTableElement(node) {
4793
+ return isHTMLElement(node) && node.tagName === TAG_NAME_TABLE;
4794
+ };
4795
+
4796
+ var isDisallowedTableChildElement = function isDisallowedTableChildElement(node) {
4797
+ return isHTMLElement(node) && DISALLOWED_TABLE_CHILD_ELEMENTS.includes(node.tagName);
4798
+ };
4799
+
4800
+ var removeDisallowedTableChildElements = /*#__PURE__*/removeChildNodesUsingPredicate(isDisallowedTableChildElement);
4801
+
4802
+ var removeTableGrandchildren = function removeTableGrandchildren(nodeList) {
4803
+ var nodes = Array.from(nodeList);
4804
+
4805
+ while (nodes.length > 0) {
4806
+ var node = nodes.pop();
4807
+
4808
+ if (isTableElement(node)) {
4809
+ removeDisallowedTableChildElements(node.childNodes);
4810
+ continue;
4811
+ }
4812
+
4813
+ for (var _i = 0, _Array$from = Array.from(node.childNodes); _i < _Array$from.length; _i++) {
4814
+ var childNode = _Array$from[_i];
4815
+ nodes.push(childNode);
4816
+ }
4817
+ }
4818
+
4819
+ return nodes;
4820
+ };
4821
+
4822
+ var sanitizeTables = function sanitizeTables(_ref) {
4823
+ var doc = _ref[0],
4824
+ editor = _ref[1];
4825
+
4826
+ var _getNodeEntryFromSele = getNodeEntryFromSelection(editor, BLOCKS.TABLE),
4827
+ node = _getNodeEntryFromSele[0];
4828
+
4829
+ var isTableInCurrentSelection = !!node;
4830
+
4831
+ if (isTableInCurrentSelection) {
4832
+ removeDisallowedTableChildElements(doc.childNodes);
4833
+ } else {
4834
+ removeTableGrandchildren(doc.childNodes);
4835
+ }
4836
+
4837
+ return [doc, editor];
4838
+ };
4839
+
4840
+
4841
+
4842
+ var sanitizers = {
4843
+ __proto__: null,
4844
+ removeComments: removeComments,
4845
+ sanitizeTables: sanitizeTables
4846
+ };
4847
+
4848
+ var MIME_TYPE_HTML = 'text/html'; // TODO: Upgrade tslib so we can just flow(...sanitizers);
4849
+
4850
+ var sanitizeDocument = /*#__PURE__*/flow.apply(undefined, /*#__PURE__*/Object.values(sanitizers));
4851
+
4852
+ var sanitizeHtml = function sanitizeHtml(html, editor) {
4853
+ var doc = new DOMParser().parseFromString(html, MIME_TYPE_HTML);
4854
+
4855
+ var _sanitizeDocument = sanitizeDocument([doc, editor]),
4856
+ sanitizedDoc = _sanitizeDocument[0];
4857
+
4858
+ var sanitizedData = new XMLSerializer().serializeToString(sanitizedDoc);
4859
+ return sanitizedData;
4860
+ };
4861
+
4862
+ var htmlToDataTransfer = function htmlToDataTransfer(html) {
4863
+ var data = new DataTransfer();
4864
+ data.setData(MIME_TYPE_HTML, html);
4865
+ return data;
4866
+ };
4867
+
4868
+ function withPasteHandling(editor) {
4869
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4870
+ return function (_event) {
4871
+ var insertData = editor.insertData;
4872
+
4873
+ editor.insertData = function (data) {
4874
+ var html = data.getData(MIME_TYPE_HTML);
4875
+
4876
+ if (html) {
4877
+ var sanitized = sanitizeHtml(html, editor);
4878
+ var newData = htmlToDataTransfer(sanitized);
4879
+ insertData(newData);
4880
+ }
4881
+ };
4882
+ };
4883
+ }
4884
+
4885
+ var createPastePlugin = function createPastePlugin() {
4886
+ return {
4887
+ onKeyDown: withPasteHandling
4888
+ };
4889
+ };
4890
+
4373
4891
  var _templateObject$6, _styles$2, _withParagraphOptions;
4374
- var styles$k = (_styles$2 = {}, _styles$2[BLOCKS.PARAGRAPH] = /*#__PURE__*/css(_templateObject$6 || (_templateObject$6 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n line-height: ", ";\n margin-bottom: 1.5em;\n "])), tokens.lineHeightDefault), _styles$2);
4892
+ var styles$n = (_styles$2 = {}, _styles$2[BLOCKS.PARAGRAPH] = /*#__PURE__*/css(_templateObject$6 || (_templateObject$6 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n line-height: ", ";\n margin-bottom: 1.5em;\n "])), tokens.lineHeightDefault), _styles$2);
4375
4893
  function Paragraph(props) {
4376
4894
  return /*#__PURE__*/createElement("div", Object.assign({}, props.attributes, {
4377
- className: styles$k[BLOCKS.PARAGRAPH]
4895
+ className: styles$n[BLOCKS.PARAGRAPH]
4378
4896
  }), props.children);
4379
4897
  }
4380
4898
  function createParagraphPlugin() {
@@ -4390,9 +4908,8 @@ function createParagraphPlugin() {
4390
4908
  type: BLOCKS.PARAGRAPH,
4391
4909
  deserialize: function deserialize(element) {
4392
4910
  var isParagraphText = element.nodeName === 'P';
4393
- var isDivText = element.nodeName === 'DIV' && !element.getAttribute('data-entity-type');
4394
4911
  var isNotEmpty = element.textContent !== '';
4395
- var isText = (isDivText || isParagraphText) && isNotEmpty;
4912
+ var isText = isParagraphText && isNotEmpty;
4396
4913
  if (!isText) return;
4397
4914
  return {
4398
4915
  type: BLOCKS.PARAGRAPH
@@ -4553,7 +5070,8 @@ var _excluded = ["sdk", "isInitiallyDisabled", "onAction"];
4553
5070
 
4554
5071
  var getPlugins = function getPlugins(sdk, tracking) {
4555
5072
  var plugins = [// Core
4556
- createReactPlugin(), createHistoryPlugin(), // Global shortcuts
5073
+ createReactPlugin(), createHistoryPlugin(), // Behavior
5074
+ createPastePlugin(), // Global shortcuts
4557
5075
  createNewLinePlugin(), createInsertBeforeFirstVoidBlockPlugin(), // Block Elements
4558
5076
  createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(tracking), createEmbeddedEntryBlockPlugin(sdk), createEmbeddedAssetBlockPlugin(sdk), // Inline elements
4559
5077
  createHyperlinkPlugin(sdk), createEmbeddedEntityInlinePlugin(sdk), // Marks
@@ -4626,8 +5144,6 @@ var RichTextEditor = function RichTextEditor(props) {
4626
5144
  sdk: sdk
4627
5145
  }, /*#__PURE__*/React__default.createElement(SdkProvider, {
4628
5146
  sdk: sdk
4629
- }, /*#__PURE__*/React__default.createElement(ContentfulEditorProvider, {
4630
- sdk: sdk
4631
5147
  }, /*#__PURE__*/React__default.createElement(TrackingProvider, {
4632
5148
  onAction: onAction || noop
4633
5149
  }, /*#__PURE__*/React__default.createElement(FieldConnector, {
@@ -4641,15 +5157,17 @@ var RichTextEditor = function RichTextEditor(props) {
4641
5157
  disabled = _ref.disabled,
4642
5158
  setValue = _ref.setValue,
4643
5159
  externalReset = _ref.externalReset;
4644
- return /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
5160
+ return /*#__PURE__*/React__default.createElement(ContentfulEditorProvider, {
5161
+ sdk: sdk
5162
+ }, /*#__PURE__*/React__default.createElement(ConnectedRichTextEditor, Object.assign({}, otherProps, {
4645
5163
  key: "rich-text-editor-" + externalReset,
4646
5164
  value: lastRemoteValue,
4647
5165
  sdk: sdk,
4648
5166
  onAction: onAction || noop,
4649
5167
  isDisabled: disabled,
4650
5168
  onChange: setValue
4651
- }));
4652
- })))));
5169
+ })));
5170
+ }))));
4653
5171
  };
4654
5172
 
4655
5173
  var LINK_TYPES$1 = {