UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

820 lines (818 loc) 40.2 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable @atlaskit/design-system/prefer-primitives */ /** * @jsxRuntime classic * @jsx jsx */ import React, { Component } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { jsx } from '@emotion/react'; import { injectIntl } from 'react-intl-next'; import { TableSortOrder as SortOrder } from '@atlaskit/custom-steps'; import { INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { addColumnAfter, addRowAfter, backspace, tooltip } from '@atlaskit/editor-common/keymaps'; import { tableMessages as messages } from '@atlaskit/editor-common/messages'; import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles'; import { backgroundPaletteTooltipMessages, cellBackgroundColorPalette, ColorPalette, getSelectedRowAndColumnFromPalette } from '@atlaskit/editor-common/ui-color'; import { ArrowKeyNavigationProvider, ArrowKeyNavigationType, DropdownMenu } from '@atlaskit/editor-common/ui-menu'; import { UserIntentPopupWrapper } from '@atlaskit/editor-common/user-intent'; import { closestElement } from '@atlaskit/editor-common/utils'; import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette'; import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut'; import { splitCell } from '@atlaskit/editor-tables/utils'; import PaintBucketIcon from '@atlaskit/icon/core/paint-bucket'; import TableCellClearIcon from '@atlaskit/icon/core/table-cell-clear'; import TableCellMergeIcon from '@atlaskit/icon/core/table-cell-merge'; import TableCellSplitIcon from '@atlaskit/icon/core/table-cell-split'; import TableColumnAddRightIcon from '@atlaskit/icon/core/table-column-add-right'; import TableColumnDeleteIcon from '@atlaskit/icon/core/table-column-delete'; import TableColumnsDistributeIcon from '@atlaskit/icon/core/table-columns-distribute'; import TableRowAddBelowIcon from '@atlaskit/icon/core/table-row-add-below'; import TableRowDeleteIcon from '@atlaskit/icon/core/table-row-delete'; // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss import { Box, xcss } from '@atlaskit/primitives'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { clearHoverSelection, hoverColumns, hoverMergedCells, hoverRows, setFocusToCellMenu, toggleContextualMenu } from '../../pm-plugins/commands'; import { deleteColumnsWithAnalytics, deleteRowsWithAnalytics, distributeColumnsWidthsWithAnalytics, emptyMultipleCellsWithAnalytics, insertColumnWithAnalytics, insertRowWithAnalytics, mergeCellsWithAnalytics, setColorWithAnalytics, sortColumnWithAnalytics, splitCellWithAnalytics } from '../../pm-plugins/commands/commands-with-analytics'; import { getPluginState } from '../../pm-plugins/plugin-factory'; import { pluginKey as tablePluginKey } from '../../pm-plugins/plugin-key'; import { getNewResizeStateFromSelectedColumns } from '../../pm-plugins/table-resizing/utils/resize-state'; import { canMergeCells } from '../../pm-plugins/transforms/merge'; import { getSelectedColumnIndexes, getSelectedRowIndexes } from '../../pm-plugins/utils/selection'; import { getMergedCellsPositions } from '../../pm-plugins/utils/table'; import { TableCssClassName as ClassName } from '../../types'; import { colorPalletteColumns, contextualMenuDropdownWidth, contextualMenuDropdownWidthDnD } from '../consts'; import { cellColourPreviewStyles } from './styles'; var arrowsList = new Set(!expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true) ? ['ArrowRight', 'ArrowLeft'] : ['ArrowRight']); var elementBeforeIconStyles = xcss({ marginRight: 'space.negative.075', display: 'flex' }); // eslint-disable-next-line @repo/internal/react/no-class-components export var ContextualMenu = /*#__PURE__*/function (_Component) { function ContextualMenu() { var _this; _classCallCheck(this, ContextualMenu); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, ContextualMenu, [].concat(args)); _defineProperty(_this, "state", { isSubmenuOpen: false, isOpenAllowed: false }); _defineProperty(_this, "dropdownMenuRef", /*#__PURE__*/React.createRef()); _defineProperty(_this, "handleSubMenuRef", function (ref) { // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting var dom = _this.props.editorView.dom; var parent = closestElement(dom, '.fabric-editor-popup-scroll-parent') || closestElement(dom, '.ak-editor-content-area'); if (!(parent && ref)) { return; } var boundariesRect = parent.getBoundingClientRect(); var rect = ref.getBoundingClientRect(); if (!!_this.props.mountPoint) { return; } var offsetParent = ref === null || ref === void 0 ? void 0 : ref.offsetParent; if (!offsetParent) { return; } var offsetParentRect = offsetParent.getBoundingClientRect(); var rightOverflow = offsetParentRect.right + rect.width - boundariesRect.right; var leftOverflow = boundariesRect.left - (offsetParentRect.left - rect.width); if (rightOverflow > leftOverflow) { ref.style.left = "-".concat(rect.width, "px"); } // if it overflows regardless of side, let it overlap with the parent menu if (leftOverflow > 0 && rightOverflow > 0) { if (rightOverflow < leftOverflow) { ref.style.left = "".concat(offsetParentRect.width - rightOverflow, "px"); } else { ref.style.left = "-".concat(rect.width - leftOverflow, "px"); } } }); _defineProperty(_this, "createBackgroundColorItem", function () { var _this$props = _this.props, allowBackgroundColor = _this$props.allowBackgroundColor, state = _this$props.editorView.state, isOpen = _this$props.isOpen, formatMessage = _this$props.intl.formatMessage, editorView = _this$props.editorView, isCellMenuOpenByKeyboard = _this$props.isCellMenuOpenByKeyboard; var isSubmenuOpen = _this.state.isSubmenuOpen; var _getPluginState = getPluginState(editorView.state), targetCellPosition = _getPluginState.targetCellPosition, isDragAndDropEnabled = _getPluginState.isDragAndDropEnabled; if (allowBackgroundColor) { var _node$attrs, _node$attrs2; var node = isOpen && targetCellPosition ? state.doc.nodeAt(targetCellPosition) : null; var background = hexToEditorBackgroundPaletteColor((node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.background) || '#ffffff'); var selectedRowAndColumnFromPalette = getSelectedRowAndColumnFromPalette(cellBackgroundColorPalette, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion background, colorPalletteColumns); var selectedRowIndex = selectedRowAndColumnFromPalette.selectedRowIndex; var selectedColumnIndex = selectedRowAndColumnFromPalette.selectedColumnIndex; return { content: isDragAndDropEnabled ? formatMessage(messages.backgroundColor) : formatMessage(messages.cellBackground), value: { name: 'background' }, elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(PaintBucketIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.backgroundColor) })) : undefined, elemAfter: // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 jsx("div", { className: DropdownMenuSharedCssClassName.SUBMENU }, jsx("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 css: cellColourPreviewStyles(background) // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: isDragAndDropEnabled ? ClassName.CONTEXTUAL_MENU_ICON_SMALL : ClassName.CONTEXTUAL_MENU_ICON }), isSubmenuOpen && jsx("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: ClassName.CONTEXTUAL_SUBMENU, ref: _this.handleSubMenuRef }, jsx(ArrowKeyNavigationProvider, { type: ArrowKeyNavigationType.COLOR, selectedRowIndex: selectedRowIndex || 0, selectedColumnIndex: selectedColumnIndex || 0 // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , handleClose: function handleClose() { _this.setState({ isSubmenuOpen: false }); if (_this.dropdownMenuRef && _this.dropdownMenuRef.current) { var focusableItems = _this.dropdownMenuRef.current.querySelectorAll('div[tabindex="-1"]:not([disabled])'); if (focusableItems && focusableItems.length) { focusableItems[0].focus(); } } }, isPopupPositioned: true // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion , isOpenedByKeyboard: isCellMenuOpenByKeyboard }, jsx(ColorPalette, { cols: 7, onClick: _this.setColor, selectedColor: (node === null || node === void 0 || (_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.background) || '#ffffff' // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , paletteOptions: { palette: cellBackgroundColorPalette, paletteColorTooltipMessages: backgroundPaletteTooltipMessages, hexToPaletteColor: hexToEditorBackgroundPaletteColor } })))), 'aria-expanded': isSubmenuOpen }; } }); // Used in the NewContextMenuItems object _defineProperty(_this, "newDistributeColumnsItem", function () { var formatMessage = _this.props.intl.formatMessage; return _this.createDistributeColumnsItemInternal({ elemBefore: jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableColumnsDistributeIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.distributeColumns) })) }); }); _defineProperty(_this, "createMergeSplitCellItems", function () { var _this$props2 = _this.props, allowMergeCells = _this$props2.allowMergeCells, state = _this$props2.editorView.state, formatMessage = _this$props2.intl.formatMessage, editorView = _this$props2.editorView; var _getPluginState2 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState2.isDragAndDropEnabled; if (allowMergeCells) { return [{ content: formatMessage(messages.mergeCells), value: { name: 'merge' }, isDisabled: !canMergeCells(state.tr), elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableCellMergeIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.mergeCells) })) : undefined }, { content: formatMessage(messages.splitCell), value: { name: 'split' }, isDisabled: !splitCell(state), elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableCellSplitIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.splitCell) })) : undefined }]; } return []; }); _defineProperty(_this, "createInsertColumnItem", function () { var _this$props3 = _this.props, formatMessage = _this$props3.intl.formatMessage, editorView = _this$props3.editorView; var _getPluginState3 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState3.isDragAndDropEnabled; var content = formatMessage(isDragAndDropEnabled ? messages.addColumnRight : messages.insertColumn); return { content: content, value: { name: 'insert_column' }, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 elemAfter: jsx("div", { css: shortcutStyle }, tooltip(addColumnAfter)), elemBefore: isDragAndDropEnabled ? // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableColumnAddRightIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.addColumnRight) })) : undefined, 'aria-label': tooltip(addColumnAfter, String(content)) }; }); _defineProperty(_this, "createInsertRowItem", function () { var _this$props4 = _this.props, formatMessage = _this$props4.intl.formatMessage, editorView = _this$props4.editorView; var _getPluginState4 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState4.isDragAndDropEnabled; var content = formatMessage(isDragAndDropEnabled ? messages.addRowBelow : messages.insertRow); return { content: content, value: { name: 'insert_row' }, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 elemAfter: jsx("div", { css: shortcutStyle }, tooltip(addRowAfter)), elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableRowAddBelowIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.addRowBelow) })) : undefined, 'aria-label': tooltip(addRowAfter, String(content)) }; }); _defineProperty(_this, "createClearCellsItem", function () { var _this$props5 = _this.props, selectionRect = _this$props5.selectionRect, formatMessage = _this$props5.intl.formatMessage, editorView = _this$props5.editorView; var _getPluginState5 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState5.isDragAndDropEnabled; var top = selectionRect.top, bottom = selectionRect.bottom, right = selectionRect.right, left = selectionRect.left; var noOfColumns = right - left; var noOfRows = bottom - top; var content = formatMessage(messages.clearCells, { 0: Math.max(noOfColumns, noOfRows) }); return { content: content, value: { name: 'clear' }, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 elemAfter: jsx("div", { css: shortcutStyle }, tooltip(backspace)), elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableCellClearIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.clearCells, { 0: Math.max(noOfColumns, noOfRows) }) })) : undefined, 'aria-label': tooltip(backspace, String(content)) }; }); _defineProperty(_this, "createDeleteColumnItem", function () { var _this$props6 = _this.props, selectionRect = _this$props6.selectionRect, formatMessage = _this$props6.intl.formatMessage, editorView = _this$props6.editorView; var _getPluginState6 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState6.isDragAndDropEnabled; var right = selectionRect.right, left = selectionRect.left; var noOfColumns = right - left; return { content: formatMessage(messages.removeColumns, { 0: noOfColumns }), value: { name: 'delete_column' }, elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableColumnDeleteIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.removeColumns, { 0: noOfColumns }) })) : undefined }; }); _defineProperty(_this, "createDeleteRowItem", function () { var _this$props7 = _this.props, selectionRect = _this$props7.selectionRect, formatMessage = _this$props7.intl.formatMessage, editorView = _this$props7.editorView; var _getPluginState7 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState7.isDragAndDropEnabled; var bottom = selectionRect.bottom, top = selectionRect.top; var noOfRows = bottom - top; return { content: formatMessage(messages.removeRows, { 0: noOfRows }), value: { name: 'delete_row' }, elemBefore: isDragAndDropEnabled ? jsx(Box, { xcss: elementBeforeIconStyles }, jsx(TableRowDeleteIcon, { color: "currentColor", spacing: "spacious", label: formatMessage(messages.removeRows, { 0: noOfRows }) })) : undefined }; }); _defineProperty(_this, "createDistributeColumnsItemInternal", function (partialMenuItem) { var _newResizeState$chang; var _this$props8 = _this.props, selectionRect = _this$props8.selectionRect, editorView = _this$props8.editorView, getEditorContainerWidth = _this$props8.getEditorContainerWidth, getEditorFeatureFlags = _this$props8.getEditorFeatureFlags, formatMessage = _this$props8.intl.formatMessage; var _getPluginState8 = getPluginState(editorView.state), _getPluginState8$isTa = _getPluginState8.isTableScalingEnabled, isTableScalingEnabled = _getPluginState8$isTa === void 0 ? false : _getPluginState8$isTa; var _ref = getEditorFeatureFlags ? getEditorFeatureFlags() : {}, _ref$tableWithFixedCo = _ref.tableWithFixedColumnWidthsOption, tableWithFixedColumnWidthsOption = _ref$tableWithFixedCo === void 0 ? false : _ref$tableWithFixedCo; var newResizeState = getNewResizeStateFromSelectedColumns(selectionRect, editorView.state, editorView.domAtPos.bind(editorView), getEditorContainerWidth, isTableScalingEnabled, tableWithFixedColumnWidthsOption); var wouldChange = (_newResizeState$chang = newResizeState === null || newResizeState === void 0 ? void 0 : newResizeState.changed) !== null && _newResizeState$chang !== void 0 ? _newResizeState$chang : false; return _objectSpread({ content: formatMessage(messages.distributeColumns), value: { name: 'distribute_columns' }, isDisabled: !wouldChange }, partialMenuItem); }); _defineProperty(_this, "createDistributeColumnsItem", function () { var editorView = _this.props.editorView; var _getPluginState9 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState9.isDragAndDropEnabled, allowDistributeColumns = _getPluginState9.pluginConfig.allowDistributeColumns; if (allowDistributeColumns && !isDragAndDropEnabled) { return _this.createDistributeColumnsItemInternal(); } return null; }); _defineProperty(_this, "createSortColumnItems", function () { var _this$props9 = _this.props, formatMessage = _this$props9.intl.formatMessage, editorView = _this$props9.editorView, allowColumnSorting = _this$props9.allowColumnSorting; var _getPluginState0 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState0.isDragAndDropEnabled; if (allowColumnSorting && !isDragAndDropEnabled) { var hasMergedCellsInTable = getMergedCellsPositions(editorView.state.tr).length > 0; var warning = hasMergedCellsInTable ? { tooltipDescription: formatMessage(messages.canNotSortTable), isDisabled: true } : {}; return [_objectSpread({ content: formatMessage(messages.sortColumnASC), value: { name: 'sort_column_asc' } }, warning), _objectSpread({ content: formatMessage(messages.sortColumnDESC), value: { name: 'sort_column_desc' } }, warning)]; } return null; }); _defineProperty(_this, "createOriginalContextMenuItems", function () { var items = []; var sortColumnItems = _this.createSortColumnItems(); var backgroundColorItem = _this.createBackgroundColorItem(); var distributeColumnsItem = _this.createDistributeColumnsItem(); sortColumnItems && items.push.apply(items, _toConsumableArray(sortColumnItems)); backgroundColorItem && items.push(backgroundColorItem); items.push(_this.createInsertColumnItem()); items.push(_this.createInsertRowItem()); items.push(_this.createDeleteColumnItem()); items.push(_this.createDeleteRowItem()); items.push.apply(items, _toConsumableArray(_this.createMergeSplitCellItems())); distributeColumnsItem && items.push(distributeColumnsItem); items.push(_this.createClearCellsItem()); return [{ items: items }]; }); _defineProperty(_this, "createNewContextMenuItems", function () { var _items$0$items; var backgroundColorItem = _this.createBackgroundColorItem(); var mergeSplitCellItems = _this.createMergeSplitCellItems(); var insertColumnItem = _this.createInsertColumnItem(); var insertRowItem = _this.createInsertRowItem(); var clearCellsItem = _this.createClearCellsItem(); var deleteColumnItem = _this.createDeleteColumnItem(); var deleteRowItem = _this.createDeleteRowItem(); // Group items so when table.menu.group-items FF is enabled, a divider shows under split cell, above add column var items = [{ items: [] }, { items: [] }]; backgroundColorItem && items[0].items.push(backgroundColorItem); (_items$0$items = items[0].items).push.apply(_items$0$items, _toConsumableArray(mergeSplitCellItems)); items[1].items.push(insertColumnItem); items[1].items.push(insertRowItem); if (editorExperiment('platform_editor_controls', 'variant1')) { items[1].items.push(_this.newDistributeColumnsItem()); } items[1].items.push(clearCellsItem); items[1].items.push(deleteColumnItem); items[1].items.push(deleteRowItem); return items; }); _defineProperty(_this, "onMenuItemActivated", function (_ref2) { var item = _ref2.item; var _this$props0 = _this.props, editorView = _this$props0.editorView, selectionRect = _this$props0.selectionRect, editorAnalyticsAPI = _this$props0.editorAnalyticsAPI, getEditorContainerWidth = _this$props0.getEditorContainerWidth, getEditorFeatureFlags = _this$props0.getEditorFeatureFlags, isCellMenuOpenByKeyboard = _this$props0.isCellMenuOpenByKeyboard, isCommentEditor = _this$props0.isCommentEditor; // TargetCellPosition could be outdated: https://product-fabric.atlassian.net/browse/ED-8129 var state = editorView.state, dispatch = editorView.dispatch; var _getPluginState1 = getPluginState(state), targetCellPosition = _getPluginState1.targetCellPosition, _getPluginState1$isTa = _getPluginState1.isTableScalingEnabled, isTableScalingEnabled = _getPluginState1$isTa === void 0 ? false : _getPluginState1$isTa; var _ref3 = getEditorFeatureFlags ? getEditorFeatureFlags() : {}, _ref3$tableWithFixedC = _ref3.tableWithFixedColumnWidthsOption, tableWithFixedColumnWidthsOption = _ref3$tableWithFixedC === void 0 ? false : _ref3$tableWithFixedC; // context menu opened by keyboard and any item except 'background' activated // or color has been chosen from color palette if (isCellMenuOpenByKeyboard && (item.value.name !== 'background' || item.value.name === 'background' && _this.state.isSubmenuOpen)) { var tr = state.tr; tr.setMeta(tablePluginKey, { type: 'SET_CELL_MENU_OPEN', data: { isCellMenuOpenByKeyboard: false } }); dispatch(tr); editorView.dom.focus(); // otherwise cursor disappears from cell } var shouldUseIncreasedScalingPercent = isTableScalingEnabled && (tableWithFixedColumnWidthsOption || // When in comment editor, we need the scaling percent to be 40% while tableWithFixedColumnWidthsOption is not visible isCommentEditor); switch (item.value.name) { case 'sort_column_desc': sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, selectionRect.left, SortOrder.DESC)(state, dispatch); _this.toggleOpen(); break; case 'sort_column_asc': sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, selectionRect.left, SortOrder.ASC)(state, dispatch); _this.toggleOpen(); break; case 'merge': mergeCellsWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU)(state, dispatch); _this.toggleOpen(); break; case 'split': splitCellWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU)(state, dispatch); _this.toggleOpen(); break; case 'distribute_columns': var newResizeStateWithAnalytics = getNewResizeStateFromSelectedColumns(selectionRect, state, editorView.domAtPos.bind(editorView), getEditorContainerWidth, isTableScalingEnabled, tableWithFixedColumnWidthsOption, isCommentEditor); if (newResizeStateWithAnalytics) { distributeColumnsWidthsWithAnalytics(editorAnalyticsAPI, _this.props.api)(INPUT_METHOD.CONTEXT_MENU, newResizeStateWithAnalytics)(state, dispatch); _this.toggleOpen(); } break; case 'clear': emptyMultipleCellsWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, targetCellPosition)(state, dispatch); _this.toggleOpen(); break; case 'insert_column': insertColumnWithAnalytics(_this.props.api, editorAnalyticsAPI, isTableScalingEnabled, tableWithFixedColumnWidthsOption, shouldUseIncreasedScalingPercent, isCommentEditor)(INPUT_METHOD.CONTEXT_MENU, selectionRect.right)(state, dispatch, editorView); _this.toggleOpen(); break; case 'insert_row': insertRowWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, { index: selectionRect.bottom, moveCursorToInsertedRow: true })(state, dispatch); _this.toggleOpen(); break; case 'delete_column': deleteColumnsWithAnalytics(editorAnalyticsAPI, _this.props.api, isTableScalingEnabled, tableWithFixedColumnWidthsOption, shouldUseIncreasedScalingPercent, isCommentEditor)(INPUT_METHOD.CONTEXT_MENU, selectionRect)(state, dispatch, editorView); _this.toggleOpen(); break; case 'delete_row': var _getPluginState10 = getPluginState(state), isHeaderRowRequired = _getPluginState10.pluginConfig.isHeaderRowRequired; deleteRowsWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, selectionRect, !!isHeaderRowRequired)(state, dispatch); _this.toggleOpen(); break; case 'background': { if (!expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { // This is called twice. // 1st time when user chooses the background color item. // 2nd when color has been chosen from color palette. // here we are handling the 1st call relying on the isSubmenuOpen state value if (isCellMenuOpenByKeyboard && !_this.state.isSubmenuOpen) { _this.setState({ isSubmenuOpen: true }); } } else { _this.setState(function (prevState) { return { isSubmenuOpen: !prevState.isSubmenuOpen }; }); } break; } } }); _defineProperty(_this, "toggleOpen", function () { var _this$props1 = _this.props, isOpen = _this$props1.isOpen, _this$props1$editorVi = _this$props1.editorView, state = _this$props1$editorVi.state, dispatch = _this$props1$editorVi.dispatch; toggleContextualMenu()(state, dispatch); if (!isOpen) { _this.setState({ isSubmenuOpen: false }); } }); _defineProperty(_this, "handleOpenChange", function (payload) { var _this$props10 = _this.props, _this$props10$editorV = _this$props10.editorView, state = _this$props10$editorV.state, dispatch = _this$props10$editorV.dispatch, dom = _this$props10$editorV.dom, isCellMenuOpenByKeyboard = _this$props10.isCellMenuOpenByKeyboard; if (payload) { var event = payload.event; if (event && event instanceof KeyboardEvent) { if (!_this.state.isSubmenuOpen) { if (arrowsList.has(event.key)) { // preventing default behavior for avoiding cursor jump to next/previous table column // when left/right arrow pressed. event.preventDefault(); if (expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { _this.setState({ isSubmenuOpen: true }); return; } } toggleContextualMenu()(state, dispatch); _this.setState({ isSubmenuOpen: false }); setFocusToCellMenu(false)(state, dispatch); dom.focus(); } } else { // mouse click outside toggleContextualMenu()(state, dispatch); _this.setState({ isSubmenuOpen: false }); if (isCellMenuOpenByKeyboard) { setFocusToCellMenu(false)(state, dispatch); } } } }); // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any _defineProperty(_this, "handleItemMouseEnter", function (_ref4) { var item = _ref4.item; var _this$props11 = _this.props, _this$props11$editorV = _this$props11.editorView, state = _this$props11$editorV.state, dispatch = _this$props11$editorV.dispatch, selectionRect = _this$props11.selectionRect; if (!expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { if (item.value.name === 'background') { if (!_this.state.isSubmenuOpen) { _this.setState({ isSubmenuOpen: true }); } } } if (item.value.name === 'delete_column') { hoverColumns(getSelectedColumnIndexes(selectionRect), true)(state, dispatch); } if (item.value.name === 'delete_row') { hoverRows(getSelectedRowIndexes(selectionRect), true)(state, dispatch); } if (['sort_column_asc', 'sort_column_desc'].indexOf(item.value.name) > -1 && getMergedCellsPositions(state.tr).length !== 0) { hoverMergedCells()(state, dispatch); } }); // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any _defineProperty(_this, "handleItemMouseLeave", function (_ref5) { var item = _ref5.item; var _this$props$editorVie = _this.props.editorView, state = _this$props$editorVie.state, dispatch = _this$props$editorVie.dispatch; if (!expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { if (item.value.name === 'background') { _this.closeSubmenu(); } } if (['sort_column_asc', 'sort_column_desc', 'delete_column', 'delete_row'].indexOf(item.value.name) > -1) { clearHoverSelection()(state, dispatch); } }); _defineProperty(_this, "closeSubmenu", function () { if (_this.state.isSubmenuOpen) { _this.setState({ isSubmenuOpen: false }); } }); _defineProperty(_this, "setColor", function (color) { var _this$props12 = _this.props, editorView = _this$props12.editorView, editorAnalyticsAPI = _this$props12.editorAnalyticsAPI, isCellMenuOpenByKeyboard = _this$props12.isCellMenuOpenByKeyboard; var state = editorView.state, dispatch = editorView.dispatch, dom = editorView.dom; setColorWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.CONTEXT_MENU, color)(state, dispatch); if (!expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { _this.toggleOpen(); } else { toggleContextualMenu()(state, dispatch); _this.setState({ isSubmenuOpen: false }); if (isCellMenuOpenByKeyboard) { setFocusToCellMenu(false)(state, dispatch); dom.focus(); } } }); return _this; } _inherits(ContextualMenu, _Component); return _createClass(ContextualMenu, [{ key: "componentDidMount", value: function componentDidMount() { // ArrowKeyNavigationProvider in DropdownMenu expects that menu handle will stay focused // until user pressed ArrowDown. // Behavior above fails the A11Y requirement about first item in menu should be focused immediately. // so here is triggering componentDidUpdate inside dropdown to set focus on first element var isCellMenuOpenByKeyboard = this.props.isCellMenuOpenByKeyboard; if (isCellMenuOpenByKeyboard) { this.setState(_objectSpread(_objectSpread({}, this.state), {}, { isOpenAllowed: isCellMenuOpenByKeyboard })); } } }, { key: "componentDidUpdate", value: function componentDidUpdate() { var _getPluginState11 = getPluginState(this.props.editorView.state), isDragAndDropEnabled = _getPluginState11.isDragAndDropEnabled, isContextualMenuOpen = _getPluginState11.isContextualMenuOpen; if (isDragAndDropEnabled && this.props.isDragMenuOpen && isContextualMenuOpen) { toggleContextualMenu()(this.props.editorView.state, this.props.editorView.dispatch); } } }, { key: "render", value: function render() { var _this$props13 = this.props, isOpen = _this$props13.isOpen, offset = _this$props13.offset, boundariesElement = _this$props13.boundariesElement, editorView = _this$props13.editorView, isCellMenuOpenByKeyboard = _this$props13.isCellMenuOpenByKeyboard, api = _this$props13.api; var _getPluginState12 = getPluginState(editorView.state), isDragAndDropEnabled = _getPluginState12.isDragAndDropEnabled; var items = isDragAndDropEnabled ? this.createNewContextMenuItems() : this.createOriginalContextMenuItems(); var isOpenAllowed = false; isOpenAllowed = isCellMenuOpenByKeyboard ? this.state.isOpenAllowed : isOpen; return jsx(UserIntentPopupWrapper, { userIntent: "tableContextualMenuPopupOpen", api: api }, jsx("div", { "data-testid": "table-cell-contextual-menu", onMouseLeave: expValEquals('platform_editor_toolbar_submenu_open_click', 'isEnabled', true) ? undefined : this.closeSubmenu, ref: this.dropdownMenuRef }, jsx(DropdownMenu //This needs be removed when the a11y is completely handled //Disabling key navigation now as it works only partially // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { arrowKeyNavigationProviderOptions: { type: ArrowKeyNavigationType.MENU, disableArrowKeyNavigation: !isCellMenuOpenByKeyboard || this.state.isSubmenuOpen }, items: items, isOpen: isOpenAllowed, onOpenChange: this.handleOpenChange, onItemActivated: this.onMenuItemActivated, onMouseEnter: this.handleItemMouseEnter, onMouseLeave: this.handleItemMouseLeave, fitHeight: 188, fitWidth: isDragAndDropEnabled ? contextualMenuDropdownWidthDnD : contextualMenuDropdownWidth // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , shouldFocusFirstItem: function shouldFocusFirstItem() { return Boolean(isCellMenuOpenByKeyboard); }, boundariesElement: boundariesElement, offset: offset, section: isDragAndDropEnabled ? { hasSeparator: true } : undefined, allowEnterDefaultBehavior: this.state.isSubmenuOpen }))); } }]); }(Component); _defineProperty(ContextualMenu, "defaultProps", { boundariesElement: typeof document !== 'undefined' ? document.body : undefined }); export default injectIntl(ContextualMenu);