@contentful/field-editor-rich-text 2.1.2 → 2.2.1

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,24 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.2.1](https://github.com/contentful/field-editors/compare/@contentful/field-editor-rich-text@2.2.0...@contentful/field-editor-rich-text@2.2.1) (2022-07-06)
7
+
8
+ ### Bug Fixes
9
+
10
+ - add validations to rt-command embedding, allow table embedding, improve click handling ([#1178](https://github.com/contentful/field-editors/issues/1178)) ([83704a6](https://github.com/contentful/field-editors/commit/83704a6d234ceba8850ba5be5a085bfeb1b3a293))
11
+
12
+ # [2.2.0](https://github.com/contentful/field-editors/compare/@contentful/field-editor-rich-text@2.1.3...@contentful/field-editor-rich-text@2.2.0) (2022-07-06)
13
+
14
+ ### Features
15
+
16
+ - add tracking for rich-text-commands ([#1174](https://github.com/contentful/field-editors/issues/1174)) ([75fc492](https://github.com/contentful/field-editors/commit/75fc49210a5789bf029ddb81413349d74f441f28))
17
+
18
+ ## [2.1.3](https://github.com/contentful/field-editors/compare/@contentful/field-editor-rich-text@2.1.2...@contentful/field-editor-rich-text@2.1.3) (2022-07-06)
19
+
20
+ ### Bug Fixes
21
+
22
+ - rt-commands palette closes on click outside ([#1175](https://github.com/contentful/field-editors/issues/1175)) ([b9dd434](https://github.com/contentful/field-editors/commit/b9dd43497a874b35318230074d7de411012c7eee))
23
+
6
24
  ## [2.1.2](https://github.com/contentful/field-editors/compare/@contentful/field-editor-rich-text@2.1.1...@contentful/field-editor-rich-text@2.1.2) (2022-07-06)
7
25
 
8
26
  **Note:** Version bump only for package @contentful/field-editor-rich-text
@@ -16,15 +16,17 @@ var noop = _interopDefault(require('lodash/noop'));
16
16
  var plateSerializerDocx = require('@udecode/plate-serializer-docx');
17
17
  var plateBreak = require('@udecode/plate-break');
18
18
  var plateResetNode = require('@udecode/plate-reset-node');
19
- var slate = require('slate');
20
- var Slate = require('slate-react');
19
+ var reactPopper = require('react-popper');
21
20
  var f36Components = require('@contentful/f36-components');
21
+ var f36Utils = require('@contentful/f36-utils');
22
22
  var constate = _interopDefault(require('constate'));
23
23
  var isHotkey = _interopDefault(require('is-hotkey'));
24
- var tokens = _interopDefault(require('@contentful/f36-tokens'));
24
+ var slate = require('slate');
25
+ var Slate = require('slate-react');
25
26
  var find = _interopDefault(require('lodash/find'));
26
27
  var flow = _interopDefault(require('lodash/flow'));
27
28
  var get = _interopDefault(require('lodash/get'));
29
+ var tokens = _interopDefault(require('@contentful/f36-tokens'));
28
30
  var f36Icons = require('@contentful/f36-icons');
29
31
  var plateList = require('@udecode/plate-list');
30
32
  var castArray = _interopDefault(require('lodash/castArray'));
@@ -341,6 +343,131 @@ var createResetNodePlugin = function createResetNodePlugin() {
341
343
  });
342
344
  };
343
345
 
346
+ /**
347
+ * Trim leading slash character if found. Bails otherwise.
348
+ *
349
+ * @example
350
+ * trimLeadingSlash("/my query") // --> "my query"
351
+ */
352
+ function trimLeadingSlash(text) {
353
+ if (!text.startsWith('/')) {
354
+ return text;
355
+ }
356
+
357
+ return text.slice(1);
358
+ }
359
+
360
+ function useSdk(_ref) {
361
+ var sdk = _ref.sdk;
362
+ var sdkMemo = React.useMemo(function () {
363
+ return sdk;
364
+ }, []); // eslint-disable-line -- TODO: explain this disable
365
+
366
+ return sdkMemo;
367
+ }
368
+
369
+ var _constate = /*#__PURE__*/constate(useSdk),
370
+ SdkProvider = _constate[0],
371
+ useSdkContext = _constate[1];
372
+
373
+ var useCommandList = function useCommandList(commandItems, container) {
374
+ var _React$useState = React.useState(function () {
375
+ // select the first item on initial render
376
+ if ('group' in commandItems[0]) {
377
+ return commandItems[0].commands[0].id;
378
+ }
379
+
380
+ return commandItems[0].id;
381
+ }),
382
+ selectedItem = _React$useState[0],
383
+ setSelectedItem = _React$useState[1];
384
+
385
+ var _React$useState2 = React.useState(commandItems.length > 0),
386
+ isOpen = _React$useState2[0],
387
+ setIsOpen = _React$useState2[1];
388
+
389
+ React.useEffect(function () {
390
+ if (!container.current) {
391
+ return;
392
+ }
393
+
394
+ var buttons = Array.from(container.current.querySelectorAll('button'));
395
+ var currBtn = buttons.find(function (btn) {
396
+ return btn.id === selectedItem;
397
+ });
398
+ var currIndex = currBtn ? buttons.indexOf(currBtn) : 0;
399
+ var shouldSelectFirstBtn = !currBtn && buttons.length;
400
+
401
+ if (shouldSelectFirstBtn) {
402
+ setSelectedItem(buttons[0].id);
403
+ buttons[0].scrollIntoView({
404
+ block: 'nearest',
405
+ inline: 'start'
406
+ });
407
+ }
408
+
409
+ function handleKeyDown(event) {
410
+ if (isHotkey('up', event)) {
411
+ event.preventDefault();
412
+
413
+ if (currIndex === 0) {
414
+ return;
415
+ }
416
+
417
+ setSelectedItem(buttons[currIndex - 1].id);
418
+ buttons[currIndex - 1].scrollIntoView({
419
+ block: 'nearest',
420
+ inline: 'start'
421
+ });
422
+ } else if (isHotkey('down', event)) {
423
+ event.preventDefault();
424
+
425
+ if (currIndex === buttons.length - 1) {
426
+ return;
427
+ }
428
+
429
+ setSelectedItem(buttons[currIndex + 1].id);
430
+ buttons[currIndex + 1].scrollIntoView({
431
+ block: 'nearest',
432
+ inline: 'start'
433
+ });
434
+ } else if (isHotkey('enter', event)) {
435
+ event.preventDefault();
436
+
437
+ if (currBtn) {
438
+ setSelectedItem('');
439
+ currBtn.click();
440
+ }
441
+ } //TODO: handle shift+enter, which must be detected using separate events
442
+
443
+ }
444
+
445
+ if (commandItems.length) {
446
+ window.addEventListener('keydown', handleKeyDown);
447
+ }
448
+
449
+ return function () {
450
+ return window.removeEventListener('keydown', handleKeyDown);
451
+ };
452
+ }, [commandItems, container, selectedItem]);
453
+ React.useEffect(function () {
454
+ var handleMousedown = function handleMousedown(event) {
455
+ if (container.current && !container.current.contains(event.target)) {
456
+ setIsOpen(false);
457
+ }
458
+ };
459
+
460
+ document.addEventListener('mousedown', handleMousedown);
461
+ return function () {
462
+ document.removeEventListener('mousedown', handleMousedown);
463
+ };
464
+ }, [container]);
465
+ return {
466
+ selectedItem: selectedItem,
467
+ isOpen: isOpen
468
+ };
469
+ };
470
+
344
471
  var IS_SAFARI = typeof navigator !== 'undefined' && /*#__PURE__*/ /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
345
472
  var IS_CHROME = /*#__PURE__*/ /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9.]+)(:?\s|$)/.test(navigator.userAgent);
346
473
 
@@ -545,112 +672,36 @@ function toggleElement(editor, options, editorOptions) {
545
672
  });
546
673
  }
547
674
 
548
- /**
549
- * Trim leading slash character if found. Bails otherwise.
550
- *
551
- * @example
552
- * trimLeadingSlash("/my query") // --> "my query"
553
- */
554
- function trimLeadingSlash(text) {
555
- if (!text.startsWith('/')) {
556
- return text;
557
- }
558
-
559
- return text.slice(1);
560
- }
561
-
562
- function useSdk(_ref) {
563
- var sdk = _ref.sdk;
564
- var sdkMemo = React.useMemo(function () {
565
- return sdk;
566
- }, []); // eslint-disable-line -- TODO: explain this disable
567
-
568
- return sdkMemo;
569
- }
570
-
571
- var _constate = /*#__PURE__*/constate(useSdk),
572
- SdkProvider = _constate[0],
573
- useSdkContext = _constate[1];
574
-
575
- var useCommandList = function useCommandList(commandItems, container) {
576
- var _React$useState = React.useState(function () {
577
- // select the first item on initial render
578
- if ('group' in commandItems[0]) {
579
- return commandItems[0].commands[0].id;
580
- }
581
-
582
- return commandItems[0].id;
583
- }),
584
- selectedItem = _React$useState[0],
585
- setSelectedItem = _React$useState[1];
586
-
587
- React.useEffect(function () {
588
- if (!(container != null && container.current)) {
589
- return;
590
- }
591
-
592
- var buttons = Array.from(container.current.querySelectorAll('button'));
593
- var currBtn = buttons.find(function (btn) {
594
- return btn.id === selectedItem;
595
- });
596
- var currIndex = currBtn ? buttons.indexOf(currBtn) : 0;
597
- var shouldSelectFirstBtn = !currBtn && buttons.length;
598
-
599
- if (shouldSelectFirstBtn) {
600
- setSelectedItem(buttons[0].id);
601
- buttons[0].scrollIntoView({
602
- block: 'nearest',
603
- inline: 'start'
604
- });
605
- }
606
-
607
- function handleKeyDown(event) {
608
- if (isHotkey('up', event)) {
609
- event.preventDefault();
610
-
611
- if (currIndex === 0) {
612
- return;
613
- }
614
-
615
- setSelectedItem(buttons[currIndex - 1].id);
616
- buttons[currIndex - 1].scrollIntoView({
617
- block: 'nearest',
618
- inline: 'start'
619
- });
620
- } else if (isHotkey('down', event)) {
621
- event.preventDefault();
622
-
623
- if (currIndex === buttons.length - 1) {
624
- return;
625
- }
675
+ var VALIDATIONS = {
676
+ ENABLED_MARKS: 'enabledMarks',
677
+ ENABLED_NODE_TYPES: 'enabledNodeTypes'
678
+ };
679
+ var DEFAULT_ENABLED_NODE_TYPES = [Contentful.BLOCKS.DOCUMENT, Contentful.BLOCKS.PARAGRAPH, 'text'];
626
680
 
627
- setSelectedItem(buttons[currIndex + 1].id);
628
- buttons[currIndex + 1].scrollIntoView({
629
- block: 'nearest',
630
- inline: 'start'
631
- });
632
- } else if (isHotkey('enter', event)) {
633
- event.preventDefault();
681
+ var getRichTextValidation = function getRichTextValidation(field, validationType) {
682
+ return flow(function (v) {
683
+ return find(v, validationType);
684
+ }, function (v) {
685
+ return get(v, validationType);
686
+ })(field.validations);
687
+ };
634
688
 
635
- if (currBtn) {
636
- setSelectedItem('');
637
- currBtn.click();
638
- }
639
- } //TODO: handle shift+enter, which must be detected using separate events
689
+ var isFormattingOptionEnabled = function isFormattingOptionEnabled(field, validationType, nodeTypeOrMark) {
690
+ var enabledFormattings = getRichTextValidation(field, validationType); // TODO: In the future, validations will always be opt-in. In that case
691
+ // we don't need this step.
640
692
 
641
- }
693
+ if (enabledFormattings === undefined) {
694
+ return true;
695
+ }
642
696
 
643
- if (commandItems.length) {
644
- window.addEventListener('keydown', handleKeyDown);
645
- }
697
+ return DEFAULT_ENABLED_NODE_TYPES.concat(enabledFormattings).includes(nodeTypeOrMark);
698
+ };
646
699
 
647
- return function () {
648
- return window.removeEventListener('keydown', handleKeyDown);
649
- };
650
- }, [commandItems, container, selectedItem]);
651
- return {
652
- selectedItem: selectedItem
653
- };
700
+ var isNodeTypeEnabled = function isNodeTypeEnabled(field, nodeType) {
701
+ return isFormattingOptionEnabled(field, VALIDATIONS.ENABLED_NODE_TYPES, nodeType);
702
+ };
703
+ var isMarkEnabled = function isMarkEnabled(field, mark) {
704
+ return isFormattingOptionEnabled(field, VALIDATIONS.ENABLED_MARKS, mark);
654
705
  };
655
706
 
656
707
  var COMMAND_PROMPT = 'command-prompt';
@@ -1562,36 +1613,125 @@ var removeQuery = function removeQuery(editor) {
1562
1613
 
1563
1614
  var useCommands = function useCommands(sdk, query, editor) {
1564
1615
  var contentTypes = sdk.space.getCachedContentTypes();
1616
+ var canInsertBlocks = !isNodeTypeSelected(editor, Contentful.BLOCKS.TABLE);
1617
+ var inlineAllowed = isNodeTypeEnabled(sdk.field, Contentful.INLINES.EMBEDDED_ENTRY);
1618
+ var entriesAllowed = isNodeTypeEnabled(sdk.field, Contentful.BLOCKS.EMBEDDED_ENTRY) && canInsertBlocks;
1619
+ var assetsAllowed = isNodeTypeEnabled(sdk.field, Contentful.BLOCKS.EMBEDDED_ASSET) && canInsertBlocks;
1565
1620
 
1566
1621
  var _useState = React.useState(function () {
1567
- var contentTypeCommands = contentTypes.map(function (contentType) {
1622
+ var getEmbedEntry = function getEmbedEntry(contentType) {
1623
+ return {
1624
+ id: contentType.sys.id,
1625
+ label: "Embed " + contentType.name,
1626
+ callback: function callback() {
1627
+ fetchEntries(sdk, contentType, query).then(function (entries) {
1628
+ removeQuery(editor);
1629
+
1630
+ if (!entries.length) {
1631
+ setCommands([{
1632
+ id: 'no-results',
1633
+ label: 'No results'
1634
+ }]);
1635
+ } else {
1636
+ setCommands(entries.map(function (entry) {
1637
+ return {
1638
+ id: entry.id + "-" + entry.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1639
+ label: entry.displayTitle,
1640
+ callback: function callback() {
1641
+ removeCommand(editor);
1642
+
1643
+ if (editor.selection) {
1644
+ var selection = editor.selection;
1645
+ editor.insertSoftBreak();
1646
+ insertBlock(editor, Contentful.BLOCKS.EMBEDDED_ENTRY, entry.entry);
1647
+ slate.Transforms.select(editor, selection);
1648
+ editor.tracking.onCommandPaletteAction('insert', {
1649
+ nodeType: Contentful.BLOCKS.EMBEDDED_ENTRY
1650
+ });
1651
+ }
1652
+ }
1653
+ };
1654
+ }));
1655
+ }
1656
+ });
1657
+ }
1658
+ };
1659
+ };
1660
+
1661
+ var getEmbedInline = function getEmbedInline(contentType) {
1662
+ return {
1663
+ id: contentType.sys.id + "-inline",
1664
+ label: "Embed " + contentType.name + " - Inline",
1665
+ callback: function callback() {
1666
+ fetchEntries(sdk, contentType, query).then(function (entries) {
1667
+ removeQuery(editor);
1668
+
1669
+ if (!entries.length) {
1670
+ setCommands([{
1671
+ id: 'no-results',
1672
+ label: 'No results'
1673
+ }]);
1674
+ } else {
1675
+ setCommands(entries.map(function (entry) {
1676
+ return {
1677
+ id: entry.id + "-" + entry.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1678
+ label: entry.displayTitle,
1679
+ callback: function callback() {
1680
+ var inlineNode = createInlineEntryNode(entry.id);
1681
+ removeCommand(editor);
1682
+ slate.Transforms.insertNodes(editor, inlineNode);
1683
+ editor.insertText('');
1684
+ editor.tracking.onCommandPaletteAction('insert', {
1685
+ nodeType: Contentful.INLINES.EMBEDDED_ENTRY
1686
+ });
1687
+ }
1688
+ };
1689
+ }));
1690
+ }
1691
+ });
1692
+ }
1693
+ };
1694
+ };
1695
+
1696
+ var contentTypeCommands = entriesAllowed || inlineAllowed ? contentTypes.map(function (contentType) {
1568
1697
  return {
1569
1698
  group: contentType.name,
1699
+ commands: entriesAllowed && inlineAllowed ? [getEmbedEntry(contentType), getEmbedInline(contentType)] : entriesAllowed ? [getEmbedEntry(contentType)] : [getEmbedInline(contentType)]
1700
+ };
1701
+ }) : [];
1702
+
1703
+ if (assetsAllowed) {
1704
+ var assetCommand = {
1705
+ group: 'Assets',
1570
1706
  commands: [{
1571
- id: contentType.sys.id,
1572
- label: "Embed " + contentType.name,
1707
+ id: 'embed-asset',
1708
+ label: 'Embed Asset',
1573
1709
  callback: function callback() {
1574
- fetchEntries(sdk, contentType, query).then(function (entries) {
1710
+ fetchAssets(sdk, query).then(function (assets) {
1575
1711
  removeQuery(editor);
1576
1712
 
1577
- if (!entries.length) {
1713
+ if (!assets.length) {
1578
1714
  setCommands([{
1579
1715
  id: 'no-results',
1580
1716
  label: 'No results'
1581
1717
  }]);
1582
1718
  } else {
1583
- setCommands(entries.map(function (entry) {
1719
+ setCommands(assets.map(function (asset) {
1584
1720
  return {
1585
- id: entry.id + "-" + entry.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1586
- label: entry.displayTitle,
1721
+ id: asset.id + "-" + asset.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1722
+ label: asset.displayTitle,
1723
+ thumbnail: asset.thumbnail,
1587
1724
  callback: function callback() {
1588
1725
  removeCommand(editor);
1589
1726
 
1590
1727
  if (editor.selection) {
1591
1728
  var selection = editor.selection;
1592
1729
  editor.insertSoftBreak();
1593
- insertBlock(editor, Contentful.BLOCKS.EMBEDDED_ENTRY, entry.entry);
1730
+ insertBlock(editor, Contentful.BLOCKS.EMBEDDED_ASSET, asset.entity);
1594
1731
  slate.Transforms.select(editor, selection);
1732
+ editor.tracking.onCommandPaletteAction('insert', {
1733
+ nodeType: Contentful.BLOCKS.EMBEDDED_ASSET
1734
+ });
1595
1735
  }
1596
1736
  }
1597
1737
  };
@@ -1599,75 +1739,12 @@ var useCommands = function useCommands(sdk, query, editor) {
1599
1739
  }
1600
1740
  });
1601
1741
  }
1602
- }, {
1603
- id: contentType.sys.id + "-inline",
1604
- label: "Embed " + contentType.name + " - Inline",
1605
- callback: function callback() {
1606
- fetchEntries(sdk, contentType, query).then(function (entries) {
1607
- removeQuery(editor);
1608
-
1609
- if (!entries.length) {
1610
- setCommands([{
1611
- id: 'no-results',
1612
- label: 'No results'
1613
- }]);
1614
- } else {
1615
- setCommands(entries.map(function (entry) {
1616
- return {
1617
- id: entry.id + "-" + entry.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1618
- label: entry.displayTitle,
1619
- callback: function callback() {
1620
- var inlineNode = createInlineEntryNode(entry.id);
1621
- removeCommand(editor);
1622
- slate.Transforms.insertNodes(editor, inlineNode);
1623
- editor.insertText('');
1624
- }
1625
- };
1626
- }));
1627
- }
1628
- });
1629
- }
1630
1742
  }]
1631
1743
  };
1632
- });
1633
- var assetCommand = {
1634
- group: 'Assets',
1635
- commands: [{
1636
- id: 'embed-asset',
1637
- label: 'Embed Asset',
1638
- callback: function callback() {
1639
- fetchAssets(sdk, query).then(function (assets) {
1640
- removeQuery(editor);
1641
-
1642
- if (!assets.length) {
1643
- setCommands([{
1644
- id: 'no-results',
1645
- label: 'No results'
1646
- }]);
1647
- } else {
1648
- setCommands(assets.map(function (asset) {
1649
- return {
1650
- id: asset.id + "-" + asset.displayTitle.replace(/\W+/g, '-').toLowerCase(),
1651
- label: asset.displayTitle,
1652
- thumbnail: asset.thumbnail,
1653
- callback: function callback() {
1654
- removeCommand(editor);
1744
+ return [].concat(contentTypeCommands, [assetCommand]);
1745
+ }
1655
1746
 
1656
- if (editor.selection) {
1657
- var selection = editor.selection;
1658
- editor.insertSoftBreak();
1659
- insertBlock(editor, Contentful.BLOCKS.EMBEDDED_ASSET, asset.entity);
1660
- slate.Transforms.select(editor, selection);
1661
- }
1662
- }
1663
- };
1664
- }));
1665
- }
1666
- });
1667
- }
1668
- }]
1669
- };
1670
- return [].concat(contentTypeCommands, [assetCommand]);
1747
+ return contentTypeCommands;
1671
1748
  }),
1672
1749
  commands = _useState[0],
1673
1750
  setCommands = _useState[1];
@@ -1753,7 +1830,6 @@ var styles = {
1753
1830
  margin: tokens.spacingXs + " 0"
1754
1831
  }),
1755
1832
  menuHeader: /*#__PURE__*/emotion.css({
1756
- position: 'sticky',
1757
1833
  zIndex: tokens.zIndexDefault,
1758
1834
  top: 0,
1759
1835
  backgroundColor: tokens.gray100,
@@ -1852,29 +1928,35 @@ var CommandListItems = function CommandListItems(_ref4) {
1852
1928
 
1853
1929
  var CommandList = function CommandList(_ref5) {
1854
1930
  var query = _ref5.query,
1855
- editor = _ref5.editor;
1931
+ editor = _ref5.editor,
1932
+ textContainer = _ref5.textContainer;
1856
1933
  var sdk = useSdkContext();
1857
- var container = React.useRef(null);
1934
+ var popoverContainer = React.useRef(null);
1935
+ var popper = reactPopper.usePopper(textContainer, popoverContainer == null ? void 0 : popoverContainer.current, {
1936
+ placement: 'bottom-start'
1937
+ });
1858
1938
  var commandItems = useCommands(sdk, query, editor);
1859
1939
 
1860
- var _useCommandList = useCommandList(commandItems, container),
1861
- selectedItem = _useCommandList.selectedItem;
1940
+ var _useCommandList = useCommandList(commandItems, popoverContainer),
1941
+ selectedItem = _useCommandList.selectedItem,
1942
+ isOpen = _useCommandList.isOpen;
1862
1943
 
1863
- if (commandItems.length === 0) {
1944
+ if (!commandItems.length) {
1864
1945
  return null;
1865
1946
  }
1866
1947
 
1867
1948
  return /*#__PURE__*/React.createElement("div", {
1868
1949
  className: styles.container,
1869
1950
  tabIndex: -1,
1870
- ref: container,
1871
1951
  contentEditable: false
1872
1952
  }, /*#__PURE__*/React.createElement("div", {
1873
1953
  role: "alert"
1874
- }, /*#__PURE__*/React.createElement(f36Components.ScreenReaderOnly, null, "Richtext commands. Currently focused item: ", selectedItem, ". Press ", /*#__PURE__*/React.createElement("kbd", null, "enter"), " to select, ", /*#__PURE__*/React.createElement("kbd", null, "arrows"), " to navigate, ", /*#__PURE__*/React.createElement("kbd", null, "escape"), " to close.")), /*#__PURE__*/React.createElement("div", {
1875
- "aria-hidden": true
1876
- }, /*#__PURE__*/React.createElement(f36Components.Popover, {
1877
- isOpen: true,
1954
+ }, /*#__PURE__*/React.createElement(f36Components.ScreenReaderOnly, null, "Richtext commands. Currently focused item: ", selectedItem, ". Press ", /*#__PURE__*/React.createElement("kbd", null, "enter"), " to select, ", /*#__PURE__*/React.createElement("kbd", null, "arrows"), " to navigate, ", /*#__PURE__*/React.createElement("kbd", null, "escape"), " to close.")), /*#__PURE__*/React.createElement(f36Utils.Portal, null, /*#__PURE__*/React.createElement("div", Object.assign({
1955
+ "aria-hidden": true,
1956
+ ref: popoverContainer,
1957
+ style: popper.styles.popper
1958
+ }, popper.attributes.popper), /*#__PURE__*/React.createElement(f36Components.Popover, {
1959
+ isOpen: isOpen,
1878
1960
  usePortal: false,
1879
1961
 
1880
1962
  /* eslint-disable-next-line jsx-a11y/no-autofocus -- we want to keep focus on text input*/
@@ -1900,7 +1982,7 @@ var CommandList = function CommandList(_ref5) {
1900
1982
  padding: "none",
1901
1983
  spacing: "spacingS",
1902
1984
  className: styles.footerList
1903
- }, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "\u2191"), /*#__PURE__*/React.createElement("kbd", null, "\u2193"), " to navigate"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "\u21B5"), " to confirm"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "esc"), " to close")))))));
1985
+ }, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "\u2191"), /*#__PURE__*/React.createElement("kbd", null, "\u2193"), " to navigate"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "\u21B5"), " to confirm"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("kbd", null, "esc"), " to close"))))))));
1904
1986
  };
1905
1987
 
1906
1988
  var CommandPrompt = function CommandPrompt(props) {
@@ -1908,10 +1990,19 @@ var CommandPrompt = function CommandPrompt(props) {
1908
1990
  return trimLeadingSlash(props.text.text);
1909
1991
  }, [props.text.text]);
1910
1992
  var editor = props.editor;
1911
- var canInsertBlocks = !isNodeTypeSelected(editor, Contentful.BLOCKS.TABLE);
1912
- return /*#__PURE__*/React.createElement("span", Object.assign({}, props.attributes), props.children, canInsertBlocks && /*#__PURE__*/React.createElement(CommandList, {
1993
+
1994
+ var _React$useState = React.useState(),
1995
+ textElement = _React$useState[0],
1996
+ setTextElement = _React$useState[1];
1997
+
1998
+ return /*#__PURE__*/React.createElement("span", Object.assign({
1999
+ ref: function ref(e) {
2000
+ setTextElement(e);
2001
+ }
2002
+ }, props.attributes), props.children, /*#__PURE__*/React.createElement(CommandList, {
1913
2003
  query: query,
1914
- editor: editor
2004
+ editor: editor,
2005
+ textContainer: textElement
1915
2006
  }));
1916
2007
  };
1917
2008
 
@@ -1922,6 +2013,7 @@ var createOnKeyDown = function createOnKeyDown() {
1922
2013
  var _setMarks;
1923
2014
 
1924
2015
  plateCore.setMarks(editor, (_setMarks = {}, _setMarks[COMMAND_PROMPT] = true, _setMarks));
2016
+ editor.tracking.onCommandPaletteAction('openRichTextCommandPalette');
1925
2017
  }
1926
2018
 
1927
2019
  var isActive = plateCore.isMarkActive(editor, COMMAND_PROMPT);
@@ -1951,6 +2043,7 @@ var createOnKeyDown = function createOnKeyDown() {
1951
2043
  key: COMMAND_PROMPT,
1952
2044
  at: _range
1953
2045
  });
2046
+ editor.tracking.onCommandPaletteAction('cancelRichTextCommandPalette');
1954
2047
  }
1955
2048
  }
1956
2049
  };
@@ -2952,38 +3045,6 @@ function getWithEmbeddedEntryInlineEvents(sdk) {
2952
3045
  };
2953
3046
  }
2954
3047
 
2955
- var VALIDATIONS = {
2956
- ENABLED_MARKS: 'enabledMarks',
2957
- ENABLED_NODE_TYPES: 'enabledNodeTypes'
2958
- };
2959
- var DEFAULT_ENABLED_NODE_TYPES = [Contentful.BLOCKS.DOCUMENT, Contentful.BLOCKS.PARAGRAPH, 'text'];
2960
-
2961
- var getRichTextValidation = function getRichTextValidation(field, validationType) {
2962
- return flow(function (v) {
2963
- return find(v, validationType);
2964
- }, function (v) {
2965
- return get(v, validationType);
2966
- })(field.validations);
2967
- };
2968
-
2969
- var isFormattingOptionEnabled = function isFormattingOptionEnabled(field, validationType, nodeTypeOrMark) {
2970
- var enabledFormattings = getRichTextValidation(field, validationType); // TODO: In the future, validations will always be opt-in. In that case
2971
- // we don't need this step.
2972
-
2973
- if (enabledFormattings === undefined) {
2974
- return true;
2975
- }
2976
-
2977
- return DEFAULT_ENABLED_NODE_TYPES.concat(enabledFormattings).includes(nodeTypeOrMark);
2978
- };
2979
-
2980
- var isNodeTypeEnabled = function isNodeTypeEnabled(field, nodeType) {
2981
- return isFormattingOptionEnabled(field, VALIDATIONS.ENABLED_NODE_TYPES, nodeType);
2982
- };
2983
- var isMarkEnabled = function isMarkEnabled(field, mark) {
2984
- return isFormattingOptionEnabled(field, VALIDATIONS.ENABLED_MARKS, mark);
2985
- };
2986
-
2987
3048
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _dropdown, _LABELS;
2988
3049
  var styles$5 = {
2989
3050
  dropdown: (_dropdown = {