@contentful/field-editor-rich-text 2.0.0-next.28 → 2.0.0-next.30

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.
@@ -2,7 +2,7 @@ import React__default, { createContext, useContext, useMemo, createElement, useE
2
2
  import { useEntities, ScheduledIconWithTooltip, MissingEntityCard, AssetThumbnail, EntityProvider, getScheduleTooltipContent } from '@contentful/field-editor-reference';
3
3
  import { entityHelpers, shortenStorageUnit, isValidImage, ModalDialogLauncher, FieldConnector } from '@contentful/field-editor-shared';
4
4
  import { BLOCKS, INLINES, TEXT_CONTAINERS, HEADINGS, LIST_ITEM_BLOCKS, MARKS, CONTAINERS, TOP_LEVEL_BLOCKS, VOID_BLOCKS, EMPTY_DOCUMENT } from '@contentful/rich-text-types';
5
- import { usePlateEditorRef, usePlateEditorState, getNodes, toggleNodeType, getText, getAbove, setNodes, isAncestorEmpty, match, getLastChildPath, wrapNodes, getPluginType, unwrapNodes, isCollapsed, isRangeAcrossBlocks, ELEMENT_DEFAULT, findNode, getParent, getBlockAbove, isSelectionAtBlockStart, isSelectionAtBlockEnd, isFirstChild, insertNodes, moveChildren, isBlockAboveEmpty, mockPlugin, deleteFragment, isMarkActive, toggleMark, someHtmlElement, KEY_DESERIALIZE_HTML, hasSingleChild, isLastChild, someNode, getChildren as getChildren$1, createDeserializeHtmlPlugin, createDeserializeAstPlugin, createPlateEditor, getPlateSelectors, getPlateActions, Plate } from '@udecode/plate-core';
5
+ import { usePlateEditorRef, usePlateEditorState, getNodes, toggleNodeType, getText, getAbove, setNodes, isAncestorEmpty, match, getLastChildPath, wrapNodes, getPluginType, unwrapNodes, isCollapsed, isRangeAcrossBlocks, ELEMENT_DEFAULT, findNode, getParent, getBlockAbove, isSelectionAtBlockStart, isSelectionAtBlockEnd, isFirstChild, insertNodes, moveChildren, isBlockAboveEmpty, mockPlugin, deleteFragment, isMarkActive, toggleMark, someHtmlElement, KEY_DESERIALIZE_HTML, hasSingleChild, isLastChild, getChildren as getChildren$1, someNode, createDeserializeHtmlPlugin, createDeserializeAstPlugin, createPlateEditor, getPlateSelectors, getPlateActions, Plate } from '@udecode/plate-core';
6
6
  import { css, cx } from 'emotion';
7
7
  import deepEquals from 'fast-deep-equal';
8
8
  import noop from 'lodash-es/noop';
@@ -13,7 +13,7 @@ import isHotkey from 'is-hotkey';
13
13
  import { Text, Element, Editor, Transforms, Range, Path, Node, Point } from 'slate';
14
14
  import { ReactEditor, useSelected, useReadOnly, useFocused } from 'slate-react';
15
15
  import constate from 'constate';
16
- import { AssetCard, Menu, Text as Text$1, Notification, EntryCard, MenuItem, Button, Flex, Icon, InlineEntryCard, Tooltip, ModalContent, Form, FormControl, TextInput, Select, FormLabel, TextLink, ModalControls, IconButton } from '@contentful/f36-components';
16
+ import { AssetCard, Menu, Text as Text$1, Notification, EntryCard, MenuItem, Button, Flex, Icon, InlineEntryCard, Tooltip, ModalContent, Form, FormControl, TextInput, Select, FormLabel, TextLink, ModalControls, Card, IconButton } from '@contentful/f36-components';
17
17
  import mimetype from '@contentful/mimetype';
18
18
  import get from 'lodash-es/get';
19
19
  import { ClockIcon, AssetIcon, EmbeddedEntryBlockIcon, EmbeddedEntryInlineIcon, ChevronDownIcon, HorizontalRuleIcon, LinkIcon, ListBulletedIcon, ListNumberedIcon, FormatBoldIcon, CodeIcon, FormatItalicIcon, FormatUnderlinedIcon, QuoteIcon, TableIcon, PlusIcon } from '@contentful/f36-icons';
@@ -26,7 +26,7 @@ import { createBoldPlugin as createBoldPlugin$1, createCodePlugin as createCodeP
26
26
  import isPlainObject from 'is-plain-obj';
27
27
  import { createParagraphPlugin as createParagraphPlugin$1 } from '@udecode/plate-paragraph';
28
28
  import { createSelectOnBackspacePlugin as createSelectOnBackspacePlugin$1 } from '@udecode/plate-select';
29
- import { ELEMENT_TABLE, ELEMENT_TR, getEmptyRowNode, ELEMENT_TD, ELEMENT_TH, getEmptyCellNode, insertTable, deleteRow, deleteColumn, deleteTable, createTablePlugin as createTablePlugin$1, withTable, onKeyDownTable } from '@udecode/plate-table';
29
+ import { ELEMENT_TABLE, ELEMENT_TH, ELEMENT_TR, ELEMENT_TD, insertTable, getEmptyRowNode, getEmptyCellNode, deleteRow, deleteColumn, deleteTable, onKeyDownTable as onKeyDownTable$1, getTableCellEntry, createTablePlugin as createTablePlugin$1, withTable } from '@udecode/plate-table';
30
30
  import { toContentfulDocument, toSlatejsDocument } from '@contentful/contentful-slatejs-adapter';
31
31
  import { documentToPlainTextString } from '@contentful/rich-text-plain-text-renderer';
32
32
  import { createTrailingBlockPlugin } from '@udecode/plate-trailing-block';
@@ -5442,6 +5442,295 @@ var createSelectOnBackspacePlugin = function createSelectOnBackspacePlugin() {
5442
5442
  });
5443
5443
  };
5444
5444
 
5445
+ function getCaretTopPoint() {
5446
+ var sel = document.getSelection();
5447
+ if (!sel) return;
5448
+ var r = sel.getRangeAt(0);
5449
+ var rect;
5450
+ var r2; // supposed to be textNode in most cases
5451
+ // but div[contenteditable] when empty
5452
+
5453
+ var node = r.startContainer;
5454
+ var offset = r.startOffset;
5455
+
5456
+ if (offset > 0) {
5457
+ // new range, don't influence DOM state
5458
+ r2 = document.createRange();
5459
+ r2.setStart(node, offset - 1);
5460
+ r2.setEnd(node, offset); // https://developer.mozilla.org/en-US/docs/Web/API/range.getBoundingClientRect
5461
+ // IE9, Safari?(but look good in Safari 8)
5462
+
5463
+ rect = r2.getBoundingClientRect();
5464
+ return {
5465
+ left: rect.right,
5466
+ top: rect.top
5467
+ }; // @ts-expect-error
5468
+ } else if (offset < node.length) {
5469
+ r2 = document.createRange(); // similar but select next on letter
5470
+
5471
+ r2.setStart(node, offset);
5472
+ r2.setEnd(node, offset + 1);
5473
+ rect = r2.getBoundingClientRect();
5474
+ return {
5475
+ left: rect.left,
5476
+ top: rect.top
5477
+ };
5478
+ } else {
5479
+ // textNode has length
5480
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
5481
+ // @ts-expect-error
5482
+ rect = node.getBoundingClientRect(); // @ts-expect-error
5483
+
5484
+ var styles = getComputedStyle(node);
5485
+ var lineHeight = parseInt(styles.lineHeight);
5486
+ var fontSize = parseInt(styles.fontSize); // roughly half the whitespace... but not exactly
5487
+
5488
+ var delta = (lineHeight - fontSize) / 2;
5489
+ return {
5490
+ left: rect.left,
5491
+ top: rect.top + delta
5492
+ };
5493
+ }
5494
+ }
5495
+ function closePanel(editorId) {
5496
+ document.dispatchEvent(new CustomEvent('close-rte-palette-commands', {
5497
+ detail: {
5498
+ editorId: editorId
5499
+ }
5500
+ }));
5501
+ }
5502
+ function openPanel(editorId) {
5503
+ document.dispatchEvent(new CustomEvent('open-rte-palette-commands', {
5504
+ detail: {
5505
+ editorId: editorId
5506
+ }
5507
+ }));
5508
+ }
5509
+
5510
+ // import debounce from 'lodash/debounce';
5511
+ var SLASH_COMMANDS_PLUGIN_KEY = 'SlashCommands'; // TODO: Explore a solution using marks and ReactDOM.createPortal to activate the commands panel
5512
+
5513
+ function createSlashCommandsPlugin() {
5514
+ return {
5515
+ key: SLASH_COMMANDS_PLUGIN_KEY,
5516
+ type: SLASH_COMMANDS_PLUGIN_KEY,
5517
+ handlers: {
5518
+ onClick: function onClick(editor) {
5519
+ return function () {
5520
+ closePanel(editor.id);
5521
+ };
5522
+ },
5523
+ onKeyDown: function onKeyDown(editor) {
5524
+ return function (event) {
5525
+ closePanel(editor.id);
5526
+
5527
+ if (event.key === '/') {
5528
+ openPanel(editor.id);
5529
+ }
5530
+ };
5531
+ }
5532
+ }
5533
+ };
5534
+ }
5535
+
5536
+ var style$2 = {
5537
+ container: function container(_ref) {
5538
+ var top = _ref.top,
5539
+ left = _ref.left;
5540
+ return css({
5541
+ position: 'fixed',
5542
+ top: top - 14,
5543
+ left: left + 10,
5544
+ zIndex: 1,
5545
+ boxShadow: '0 5px 15px rgba(0, 0, 0, 0.15)',
5546
+ borderRadius: '8px',
5547
+ userSelect: 'none'
5548
+ });
5549
+ }
5550
+ };
5551
+ function SlashCommandsPalette(_ref2) {
5552
+ var editorId = _ref2.editorId;
5553
+
5554
+ var _React$useState = useState(null),
5555
+ position = _React$useState[0],
5556
+ setPosition = _React$useState[1];
5557
+
5558
+ var _React$useState2 = useState(false),
5559
+ isOpen = _React$useState2[0],
5560
+ setIsOpen = _React$useState2[1]; // The user is not annoyed every time they type `/`
5561
+
5562
+
5563
+ var MAX_TRIES = 3;
5564
+
5565
+ var _React$useState3 = useState(0),
5566
+ currentTries = _React$useState3[0],
5567
+ setCurrentTries = _React$useState3[1];
5568
+
5569
+ useEffect(function () {
5570
+ function handler(event) {
5571
+ if (editorId !== event.detail.editorId) return;
5572
+ var topLeft = getCaretTopPoint();
5573
+ if (!topLeft) return;
5574
+ setPosition(topLeft);
5575
+ setIsOpen(true);
5576
+ setCurrentTries(function (curr) {
5577
+ return curr + 1;
5578
+ });
5579
+ }
5580
+
5581
+ document.addEventListener('open-rte-palette-commands', handler);
5582
+ return function () {
5583
+ document.removeEventListener('open-rte-palette-commands', handler);
5584
+ };
5585
+ }, [editorId]);
5586
+ useEffect(function () {
5587
+ function handler(event) {
5588
+ if (editorId !== event.detail.editorId) return;
5589
+ closePanel();
5590
+ }
5591
+
5592
+ document.addEventListener('close-rte-palette-commands', handler);
5593
+ return function () {
5594
+ return document.removeEventListener('close-rte-palette-commands', handler);
5595
+ };
5596
+ }, [editorId]);
5597
+ useEffect(function () {
5598
+ if (!isOpen) return;
5599
+
5600
+ function handler() {
5601
+ closePanel();
5602
+ }
5603
+
5604
+ window.addEventListener('resize', handler);
5605
+ window.addEventListener('scroll', handler, true);
5606
+ return function () {
5607
+ window.removeEventListener('resize', handler);
5608
+ window.removeEventListener('scroll', handler, true);
5609
+ };
5610
+ }, [isOpen]);
5611
+
5612
+ function closePanel() {
5613
+ setIsOpen(false);
5614
+ setPosition(null);
5615
+ }
5616
+
5617
+ if (!isOpen || !position || currentTries > MAX_TRIES) return null;
5618
+ return /*#__PURE__*/createElement("div", {
5619
+ className: style$2.container(position),
5620
+ "data-test-id": "rte-slash-commands"
5621
+ }, /*#__PURE__*/createElement(Card, null, /*#__PURE__*/createElement(Text$1, null, "Slash commands are temporarily unavailable.")));
5622
+ }
5623
+
5624
+ function insertTableAndFocusFirstCell(editor) {
5625
+ insertTable(editor, {
5626
+ header: true
5627
+ });
5628
+ replaceEmptyParagraphWithTable(editor);
5629
+ }
5630
+ function isTableActive(editor) {
5631
+ var tableElements = [ELEMENT_TABLE, ELEMENT_TH, ELEMENT_TR, ELEMENT_TD];
5632
+ return tableElements.some(function (el) {
5633
+ return isBlockSelected(editor, el);
5634
+ });
5635
+ }
5636
+ function isTableHeaderEnabled(editor) {
5637
+ var tableItem = getAbove(editor, {
5638
+ match: {
5639
+ type: BLOCKS.TABLE
5640
+ }
5641
+ });
5642
+
5643
+ if (!tableItem) {
5644
+ return false;
5645
+ }
5646
+
5647
+ var firstRow = getChildren$1(tableItem)[0];
5648
+
5649
+ if (!firstRow) {
5650
+ return false;
5651
+ }
5652
+
5653
+ return getChildren$1(firstRow).every(function (_ref) {
5654
+ var node = _ref[0];
5655
+ return node.type === BLOCKS.TABLE_HEADER_CELL;
5656
+ });
5657
+ }
5658
+ function replaceEmptyParagraphWithTable(editor) {
5659
+ var tablePath = getAncestorPathFromSelection(editor);
5660
+ if (!tablePath || isFirstChild(tablePath)) return;
5661
+ var previousPath = Path.previous(tablePath);
5662
+ if (!previousPath) return;
5663
+
5664
+ var _Editor$nodes = Editor.nodes(editor, {
5665
+ at: previousPath,
5666
+ match: function match(node) {
5667
+ return node.type === BLOCKS.PARAGRAPH;
5668
+ }
5669
+ }),
5670
+ nodes = _Editor$nodes[0];
5671
+
5672
+ if (!nodes) return;
5673
+ var previousNode = nodes[0];
5674
+ var isPreviousNodeTextEmpty = isAncestorEmpty(editor, previousNode);
5675
+
5676
+ if (isPreviousNodeTextEmpty) {
5677
+ // Switch table with previous empty paragraph
5678
+ Transforms.moveNodes(editor, {
5679
+ at: tablePath,
5680
+ to: previousPath
5681
+ }); // Remove previous paragraph that now is under the table
5682
+
5683
+ Transforms.removeNodes(editor, {
5684
+ at: tablePath
5685
+ });
5686
+ }
5687
+ }
5688
+ /**
5689
+ * Returns the number of cells in a given row vs the table width
5690
+ *
5691
+ * Note: We should only get different table rows cell counts in between
5692
+ * normalization cycles.
5693
+ */
5694
+
5695
+ var getNoOfMissingTableCellsInRow = function getNoOfMissingTableCellsInRow(editor, _ref2) {
5696
+ var rowPath = _ref2[1];
5697
+ var parent = getParent(editor, rowPath); // This is ensured by normalization. The error is here just in case
5698
+
5699
+ if (!parent) {
5700
+ throw new Error('table rows must be wrapped in a table node');
5701
+ }
5702
+
5703
+ var tablePath = parent[1]; // The longest table row determines its width
5704
+
5705
+ var tableWidth = Math.max.apply(Math, Array.from(Node.children(editor, tablePath)).map(function (_ref3) {
5706
+ var path = _ref3[1];
5707
+ return Array.from(Node.children(editor, path)).length;
5708
+ }));
5709
+ var rowWidth = Array.from(Node.children(editor, rowPath)).length;
5710
+ return tableWidth - rowWidth;
5711
+ };
5712
+ var createEmptyTableCells = function createEmptyTableCells(count) {
5713
+ var emptyTableCell = {
5714
+ type: BLOCKS.TABLE_CELL,
5715
+ data: {},
5716
+ children: [{
5717
+ type: BLOCKS.PARAGRAPH,
5718
+ data: {},
5719
+ children: [{
5720
+ text: ''
5721
+ }]
5722
+ }]
5723
+ };
5724
+ return new Array(count).fill(emptyTableCell);
5725
+ };
5726
+ var isNotEmpty = function isNotEmpty(editor, _ref4) {
5727
+ var path = _ref4[1];
5728
+ return Array.from(Node.children(editor, path)).length !== 0;
5729
+ };
5730
+ var isTable = function isTable(node) {
5731
+ return Element.isElement(node) && node.type === BLOCKS.TABLE;
5732
+ };
5733
+
5445
5734
  function hasTables(nodes) {
5446
5735
  return nodes.some(function (_ref) {
5447
5736
  var type = _ref.type;
@@ -5454,6 +5743,10 @@ var isTableHeaderCell = function isTableHeaderCell(_ref2) {
5454
5743
  return type === BLOCKS.TABLE_HEADER_CELL;
5455
5744
  };
5456
5745
 
5746
+ var isTableCellOrHeader = function isTableCellOrHeader(node) {
5747
+ return Element.isElement(node) && [BLOCKS.TABLE_HEADER_CELL, BLOCKS.TABLE_CELL].includes(node.type);
5748
+ };
5749
+
5457
5750
  function hasHeadersOutsideFirstRow(nodes) {
5458
5751
  return nodes.filter(function (_ref3) {
5459
5752
  var type = _ref3.type;
@@ -5467,6 +5760,32 @@ function hasHeadersOutsideFirstRow(nodes) {
5467
5760
  });
5468
5761
  }
5469
5762
 
5763
+ function trackInvalidTableCellChildren(editor, table) {
5764
+ var cells = table.children.flatMap(function (row) {
5765
+ var _row$children;
5766
+
5767
+ return (_row$children = row.children) != null ? _row$children : [];
5768
+ }).filter(isTableCellOrHeader); // get invalid direct children
5769
+
5770
+ var invalidNodeTypes = cells.flatMap(function (cell) {
5771
+ // Only paragraphs are allowed inside tables at the moment
5772
+ return cell.children.filter(function (node) {
5773
+ return Element.isElement(node) && node.type !== BLOCKS.PARAGRAPH;
5774
+ }).map(function (node) {
5775
+ return node.type;
5776
+ });
5777
+ });
5778
+
5779
+ for (var _iterator = _createForOfIteratorHelperLoose(new Set(invalidNodeTypes)), _step; !(_step = _iterator()).done;) {
5780
+ var _editor$tracking;
5781
+
5782
+ var nodeType = _step.value;
5783
+ (_editor$tracking = editor.tracking) == null ? void 0 : _editor$tracking.onViewportAction('invalidTablePaste', {
5784
+ nodeType: nodeType
5785
+ });
5786
+ }
5787
+ }
5788
+
5470
5789
  function addTableTrackingEvents(editor) {
5471
5790
  var insertData = editor.insertData;
5472
5791
 
@@ -5491,6 +5810,19 @@ function addTableTrackingEvents(editor) {
5491
5810
  insertData(data);
5492
5811
  }
5493
5812
  };
5813
+
5814
+ var insertFragment = editor.insertFragment;
5815
+
5816
+ editor.insertFragment = function (fragment) {
5817
+ var tables = fragment.filter(isTable);
5818
+
5819
+ for (var _iterator2 = _createForOfIteratorHelperLoose(tables), _step2; !(_step2 = _iterator2()).done;) {
5820
+ var table = _step2.value;
5821
+ trackInvalidTableCellChildren(editor, table);
5822
+ }
5823
+
5824
+ return insertFragment(fragment);
5825
+ };
5494
5826
  }
5495
5827
 
5496
5828
  var addRow = function addRow(editor, getNextRowPath) {
@@ -5612,116 +5944,6 @@ var setHeader = function setHeader(editor, enable) {
5612
5944
  });
5613
5945
  };
5614
5946
 
5615
- function insertTableAndFocusFirstCell(editor) {
5616
- insertTable(editor, {
5617
- header: true
5618
- });
5619
- replaceEmptyParagraphWithTable(editor);
5620
- }
5621
- function isTableActive(editor) {
5622
- var tableElements = [ELEMENT_TABLE, ELEMENT_TH, ELEMENT_TR, ELEMENT_TD];
5623
- return tableElements.some(function (el) {
5624
- return isBlockSelected(editor, el);
5625
- });
5626
- }
5627
- function isTableHeaderEnabled(editor) {
5628
- var tableItem = getAbove(editor, {
5629
- match: {
5630
- type: BLOCKS.TABLE
5631
- }
5632
- });
5633
-
5634
- if (!tableItem) {
5635
- return false;
5636
- }
5637
-
5638
- var firstRow = getChildren$1(tableItem)[0];
5639
-
5640
- if (!firstRow) {
5641
- return false;
5642
- }
5643
-
5644
- return getChildren$1(firstRow).every(function (_ref) {
5645
- var node = _ref[0];
5646
- return node.type === BLOCKS.TABLE_HEADER_CELL;
5647
- });
5648
- }
5649
- function replaceEmptyParagraphWithTable(editor) {
5650
- var tablePath = getAncestorPathFromSelection(editor);
5651
- if (!tablePath || isFirstChild(tablePath)) return;
5652
- var previousPath = Path.previous(tablePath);
5653
- if (!previousPath) return;
5654
-
5655
- var _Editor$nodes = Editor.nodes(editor, {
5656
- at: previousPath,
5657
- match: function match(node) {
5658
- return node.type === BLOCKS.PARAGRAPH;
5659
- }
5660
- }),
5661
- nodes = _Editor$nodes[0];
5662
-
5663
- if (!nodes) return;
5664
- var previousNode = nodes[0];
5665
- var isPreviousNodeTextEmpty = isAncestorEmpty(editor, previousNode);
5666
-
5667
- if (isPreviousNodeTextEmpty) {
5668
- // Switch table with previous empty paragraph
5669
- Transforms.moveNodes(editor, {
5670
- at: tablePath,
5671
- to: previousPath
5672
- }); // Remove previous paragraph that now is under the table
5673
-
5674
- Transforms.removeNodes(editor, {
5675
- at: tablePath
5676
- });
5677
- }
5678
- }
5679
- /**
5680
- * Returns the number of cells in a given row vs the table width
5681
- *
5682
- * Note: We should only get different table rows cell counts in between
5683
- * normalization cycles.
5684
- */
5685
-
5686
- var getNoOfMissingTableCellsInRow = function getNoOfMissingTableCellsInRow(editor, _ref2) {
5687
- var rowPath = _ref2[1];
5688
- var parent = getParent(editor, rowPath); // This is ensured by normalization. The error is here just in case
5689
-
5690
- if (!parent) {
5691
- throw new Error('table rows must be wrapped in a table node');
5692
- }
5693
-
5694
- var tablePath = parent[1]; // The longest table row determines its width
5695
-
5696
- var tableWidth = Math.max.apply(Math, Array.from(Node.children(editor, tablePath)).map(function (_ref3) {
5697
- var path = _ref3[1];
5698
- return Array.from(Node.children(editor, path)).length;
5699
- }));
5700
- var rowWidth = Array.from(Node.children(editor, rowPath)).length;
5701
- return tableWidth - rowWidth;
5702
- };
5703
- var createEmptyTableCells = function createEmptyTableCells(count) {
5704
- var emptyTableCell = {
5705
- type: BLOCKS.TABLE_CELL,
5706
- data: {},
5707
- children: [{
5708
- type: BLOCKS.PARAGRAPH,
5709
- data: {},
5710
- children: [{
5711
- text: ''
5712
- }]
5713
- }]
5714
- };
5715
- return new Array(count).fill(emptyTableCell);
5716
- };
5717
- var isNotEmpty = function isNotEmpty(editor, _ref4) {
5718
- var path = _ref4[1];
5719
- return Array.from(Node.children(editor, path)).length !== 0;
5720
- };
5721
- var isTable = function isTable(node) {
5722
- return Element.isElement(node) && node.type === BLOCKS.TABLE;
5723
- };
5724
-
5725
5947
  var styles$i = {
5726
5948
  topRight: /*#__PURE__*/css({
5727
5949
  position: 'absolute',
@@ -5836,43 +6058,102 @@ var TableActions = function TableActions() {
5836
6058
  };
5837
6059
 
5838
6060
  var _templateObject$7;
5839
- var style$2 = /*#__PURE__*/css(_templateObject$7 || (_templateObject$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n border-collapse: collapse;\n padding: 10px 12px;\n min-width: 48px;\n position: relative;\n vertical-align: top;\n\n div:last-child {\n margin-bottom: 0;\n }\n"])), tokens.gray400);
6061
+ var style$3 = /*#__PURE__*/css(_templateObject$7 || (_templateObject$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n border-collapse: collapse;\n padding: 10px 12px;\n min-width: 48px;\n position: relative;\n vertical-align: top;\n\n div:last-child {\n margin-bottom: 0;\n }\n"])), tokens.gray400);
5840
6062
  var Cell = function Cell(props) {
5841
6063
  var isSelected = useSelected();
5842
6064
  return /*#__PURE__*/createElement("td", Object.assign({}, props.attributes, props.element.data, {
5843
- className: style$2
6065
+ className: style$3
5844
6066
  }), isSelected && /*#__PURE__*/createElement(TableActions, null), props.children);
5845
6067
  };
5846
6068
 
5847
6069
  var _templateObject$8;
5848
- var style$3 = /*#__PURE__*/css(_templateObject$8 || (_templateObject$8 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n background-color: ", ";\n border: 1px solid ", ";\n border-collapse: collapse;\n padding: 10px 12px;\n font-weight: ", ";\n text-align: left;\n min-width: 48px;\n position: relative;\n\n div:last-child {\n margin-bottom: 0;\n }\n"])), tokens.gray200, tokens.gray400, tokens.fontWeightMedium);
6070
+ var style$4 = /*#__PURE__*/css(_templateObject$8 || (_templateObject$8 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n background-color: ", ";\n border: 1px solid ", ";\n border-collapse: collapse;\n padding: 10px 12px;\n font-weight: ", ";\n text-align: left;\n min-width: 48px;\n position: relative;\n\n div:last-child {\n margin-bottom: 0;\n }\n"])), tokens.gray200, tokens.gray400, tokens.fontWeightNormal);
5849
6071
  var HeaderCell = function HeaderCell(props) {
5850
6072
  var isSelected = useSelected();
5851
6073
  return /*#__PURE__*/createElement("th", Object.assign({}, props.attributes, props.element.data, {
5852
- className: style$3
6074
+ className: style$4
5853
6075
  }), isSelected && /*#__PURE__*/createElement(TableActions, null), props.children);
5854
6076
  };
5855
6077
 
5856
6078
  var _templateObject$9;
5857
- var style$4 = /*#__PURE__*/css(_templateObject$9 || (_templateObject$9 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n border-collapse: collapse;\n\n &:hover td {\n background-color: transparent !important;\n }\n"])), tokens.gray400);
6079
+ var style$5 = /*#__PURE__*/css(_templateObject$9 || (_templateObject$9 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n border: 1px solid ", ";\n border-collapse: collapse;\n\n &:hover td {\n background-color: transparent !important;\n }\n"])), tokens.gray400);
5858
6080
  var Row = function Row(props) {
5859
6081
  return /*#__PURE__*/createElement("tr", Object.assign({}, props.attributes, {
5860
- className: style$4
6082
+ className: style$5
5861
6083
  }), props.children);
5862
6084
  };
5863
6085
 
5864
6086
  var _templateObject$a;
5865
- var style$5 = /*#__PURE__*/css(_templateObject$a || (_templateObject$a = /*#__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);
6087
+ var style$6 = /*#__PURE__*/css(_templateObject$a || (_templateObject$a = /*#__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);
5866
6088
  var Table = function Table(props) {
5867
6089
  return /*#__PURE__*/createElement("div", {
5868
6090
  "data-block-type": BLOCKS.TABLE
5869
6091
  }, /*#__PURE__*/createElement("table", Object.assign({
5870
- className: style$5
6092
+ className: style$6
5871
6093
  }, props.attributes), /*#__PURE__*/createElement("tbody", null, props.children)));
5872
6094
  };
5873
6095
 
5874
- var createTableOnKeyDown = function createTableOnKeyDown(editor, plugin) {
5875
- var defaultHandler = onKeyDownTable(editor, plugin);
6096
+ /**
6097
+ * Removes table wrappers when pasting a single table cell
6098
+ *
6099
+ * In Plate/Slate, copying the content of a table cell wraps
6100
+ * it in a <table><tr><td>{content}</td></tr></table> even
6101
+ * when copying partial cell content.
6102
+ *
6103
+ * That's really annoying as there is no way to remove the table
6104
+ * wrappers in that case.
6105
+ */
6106
+
6107
+ var trimUnnecessaryTableWrapper = function trimUnnecessaryTableWrapper(node) {
6108
+ if (!Element.isElement(node)) {
6109
+ return [node];
6110
+ } // must be a table with a single row
6111
+
6112
+
6113
+ if (node.type !== BLOCKS.TABLE || node.children.length !== 1) {
6114
+ return [node];
6115
+ }
6116
+
6117
+ var row = node.children[0]; // the row must contain a single cell
6118
+
6119
+ if (row.children.length !== 1) {
6120
+ return [node];
6121
+ }
6122
+
6123
+ var cell = row.children[0];
6124
+ return cell.children;
6125
+ };
6126
+
6127
+ var insertTableFragment = function insertTableFragment(editor) {
6128
+ var insertFragment = editor.insertFragment;
6129
+ return function (fragments) {
6130
+ var _editor$selection;
6131
+
6132
+ if (!editor.selection) {
6133
+ return;
6134
+ }
6135
+
6136
+ fragments = fragments.flatMap(trimUnnecessaryTableWrapper); // 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
6137
+ // More info: https://github.com/ianstormtaylor/slate/pull/4489 and https://github.com/ianstormtaylor/slate/issues/4542
6138
+
6139
+ var isInsertingTable = fragments.some(function (fragment) {
6140
+ return isTable(fragment);
6141
+ });
6142
+ var isTableFirstFragment = fragments.findIndex(function (fragment) {
6143
+ return isTable(fragment);
6144
+ }) === 0;
6145
+ var currentLineHasText = getText(editor, (_editor$selection = editor.selection) == null ? void 0 : _editor$selection.focus.path) !== '';
6146
+
6147
+ if (isInsertingTable && isTableFirstFragment && currentLineHasText) {
6148
+ insertEmptyParagraph(editor);
6149
+ }
6150
+
6151
+ return insertFragment(fragments);
6152
+ };
6153
+ };
6154
+
6155
+ var onKeyDownTable = function onKeyDownTable(editor, plugin) {
6156
+ var defaultHandler = onKeyDownTable$1(editor, plugin);
5876
6157
  return function (event) {
5877
6158
  // This fixes `Cannot resolve a Slate point from DOM point: [object HTMLDivElement]` when typing while the cursor is before table
5878
6159
  var windowSelection = window.getSelection();
@@ -5904,6 +6185,27 @@ var createTableOnKeyDown = function createTableOnKeyDown(editor, plugin) {
5904
6185
  event.stopPropagation();
5905
6186
  return;
5906
6187
  }
6188
+ } // Pressing Tab on the last cell creates a new row
6189
+ // Otherwise, jumping between cells is handled in the defaultKeyDownTable
6190
+
6191
+
6192
+ if (event.key === 'Tab' && !event.shiftKey) {
6193
+ event.preventDefault();
6194
+ var res = getTableCellEntry(editor, {});
6195
+
6196
+ if (res) {
6197
+ var tableElement = res.tableElement,
6198
+ tableRow = res.tableRow,
6199
+ tableCell = res.tableCell;
6200
+ var isLastCell = isLastChild(tableRow, tableCell[1]);
6201
+ var isLastRow = isLastChild(tableElement, tableRow[1]);
6202
+
6203
+ if (isLastRow && isLastCell) {
6204
+ addRowBelow(editor); // skip default handler
6205
+
6206
+ return;
6207
+ }
6208
+ }
5907
6209
  }
5908
6210
 
5909
6211
  defaultHandler(event);
@@ -5916,34 +6218,13 @@ var createTablePlugin = function createTablePlugin() {
5916
6218
  return createTablePlugin$1({
5917
6219
  type: BLOCKS.TABLE,
5918
6220
  handlers: {
5919
- onKeyDown: createTableOnKeyDown
6221
+ onKeyDown: onKeyDownTable
5920
6222
  },
5921
6223
  withOverrides: function withOverrides(editor, plugin) {
5922
6224
  // injects important fixes from plate's original table plugin
5923
6225
  withTable(editor, plugin);
5924
6226
  addTableTrackingEvents(editor);
5925
- var insertFragment = editor.insertFragment;
5926
-
5927
- editor.insertFragment = function (fragments) {
5928
- var _editor$selection;
5929
-
5930
- // 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
5931
- // More info: https://github.com/ianstormtaylor/slate/pull/4489 and https://github.com/ianstormtaylor/slate/issues/4542
5932
- var isInsertingTable = fragments.some(function (fragment) {
5933
- return isTable(fragment);
5934
- });
5935
- var isTableFirstFragment = fragments.findIndex(function (fragment) {
5936
- return isTable(fragment);
5937
- }) === 0;
5938
- var currentLineHasText = getText(editor, (_editor$selection = editor.selection) == null ? void 0 : _editor$selection.focus.path) !== '';
5939
-
5940
- if (isInsertingTable && isTableFirstFragment && currentLineHasText) {
5941
- insertEmptyParagraph(editor);
5942
- }
5943
-
5944
- insertFragment(fragments);
5945
- };
5946
-
6227
+ editor.insertFragment = insertTableFragment(editor);
5947
6228
  return editor;
5948
6229
  },
5949
6230
  overrideByKey: (_overrideByKey = {}, _overrideByKey[ELEMENT_TABLE] = {
@@ -6391,7 +6672,7 @@ var getPlugins = function getPlugins(sdk, onAction) {
6391
6672
  return [// AST must come after the HTML deserializer
6392
6673
  createDeserializeHtmlPlugin(), createDeserializeAstPlugin(), createDeserializeDocxPlugin(), // Tracking - This should come first so all plugins below will have access to `editor.tracking`
6393
6674
  createTrackingPlugin(onAction), // Global / Global shortcuts
6394
- createDragAndDropPlugin(), // Block Elements
6675
+ createDragAndDropPlugin(), createSlashCommandsPlugin(), // Block Elements
6395
6676
  createParagraphPlugin(), createListPlugin(), createHrPlugin(), createHeadingPlugin(), createQuotePlugin(), createTablePlugin(), createEmbeddedEntryBlockPlugin(sdk), createEmbeddedAssetBlockPlugin(sdk), // Inline elements
6396
6677
  createHyperlinkPlugin(sdk), createEmbeddedEntityInlinePlugin(sdk), // Marks
6397
6678
  createMarksPlugin(), // Other
@@ -6869,7 +7150,9 @@ var ConnectedRichTextEditor = function ConnectedRichTextEditor(props) {
6869
7150
  isDisabled: props.isDisabled
6870
7151
  }, /*#__PURE__*/React__default.createElement(Toolbar, {
6871
7152
  isDisabled: props.isDisabled
6872
- }))))));
7153
+ })), /*#__PURE__*/React__default.createElement(SlashCommandsPalette, {
7154
+ editorId: id
7155
+ })))));
6873
7156
  };
6874
7157
 
6875
7158
  var RichTextEditor = function RichTextEditor(props) {