UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

826 lines (823 loc) 43.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.ContextualMenu = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _react2 = require("@emotion/react"); var _reactIntlNext = require("react-intl-next"); var _customSteps = require("@atlaskit/custom-steps"); var _analytics = require("@atlaskit/editor-common/analytics"); var _keymaps = require("@atlaskit/editor-common/keymaps"); var _messages = require("@atlaskit/editor-common/messages"); var _styles = require("@atlaskit/editor-common/styles"); var _uiColor = require("@atlaskit/editor-common/ui-color"); var _uiMenu = require("@atlaskit/editor-common/ui-menu"); var _userIntent = require("@atlaskit/editor-common/user-intent"); var _utils = require("@atlaskit/editor-common/utils"); var _editorPalette = require("@atlaskit/editor-palette"); var _shortcut = require("@atlaskit/editor-shared-styles/shortcut"); var _utils2 = require("@atlaskit/editor-tables/utils"); var _paintBucket = _interopRequireDefault(require("@atlaskit/icon/core/paint-bucket")); var _tableCellClear = _interopRequireDefault(require("@atlaskit/icon/core/table-cell-clear")); var _tableCellMerge = _interopRequireDefault(require("@atlaskit/icon/core/table-cell-merge")); var _tableCellSplit = _interopRequireDefault(require("@atlaskit/icon/core/table-cell-split")); var _tableColumnAddRight = _interopRequireDefault(require("@atlaskit/icon/core/table-column-add-right")); var _tableColumnDelete = _interopRequireDefault(require("@atlaskit/icon/core/table-column-delete")); var _tableColumnsDistribute = _interopRequireDefault(require("@atlaskit/icon/core/table-columns-distribute")); var _tableRowAddBelow = _interopRequireDefault(require("@atlaskit/icon/core/table-row-add-below")); var _tableRowDelete = _interopRequireDefault(require("@atlaskit/icon/core/table-row-delete")); var _primitives = require("@atlaskit/primitives"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _experiments = require("@atlaskit/tmp-editor-statsig/experiments"); var _commands = require("../../pm-plugins/commands"); var _commandsWithAnalytics = require("../../pm-plugins/commands/commands-with-analytics"); var _pluginFactory = require("../../pm-plugins/plugin-factory"); var _pluginKey = require("../../pm-plugins/plugin-key"); var _resizeState = require("../../pm-plugins/table-resizing/utils/resize-state"); var _merge = require("../../pm-plugins/transforms/merge"); var _selection = require("../../pm-plugins/utils/selection"); var _table = require("../../pm-plugins/utils/table"); var _types = require("../../types"); var _consts = require("../consts"); var _styles2 = require("./styles"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } 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) { (0, _defineProperty2.default)(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 = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(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 */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss var arrowsList = new Set(!(0, _expValEquals.expValEquals)('platform_editor_toolbar_submenu_open_click', 'isEnabled', true) ? ['ArrowRight', 'ArrowLeft'] : ['ArrowRight']); var elementBeforeIconStyles = (0, _primitives.xcss)({ marginRight: 'space.negative.075', display: 'flex' }); // eslint-disable-next-line @repo/internal/react/no-class-components var ContextualMenu = exports.ContextualMenu = /*#__PURE__*/function (_Component) { function ContextualMenu() { var _this; (0, _classCallCheck2.default)(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)); (0, _defineProperty2.default)(_this, "state", { isSubmenuOpen: false, isOpenAllowed: false }); (0, _defineProperty2.default)(_this, "dropdownMenuRef", /*#__PURE__*/_react.default.createRef()); (0, _defineProperty2.default)(_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 = (0, _utils.closestElement)(dom, '.fabric-editor-popup-scroll-parent') || (0, _utils.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"); } } }); (0, _defineProperty2.default)(_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 = (0, _pluginFactory.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 = (0, _editorPalette.hexToEditorBackgroundPaletteColor)((node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.background) || '#ffffff'); var selectedRowAndColumnFromPalette = (0, _uiColor.getSelectedRowAndColumnFromPalette)(_uiColor.cellBackgroundColorPalette, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion background, _consts.colorPalletteColumns); var selectedRowIndex = selectedRowAndColumnFromPalette.selectedRowIndex; var selectedColumnIndex = selectedRowAndColumnFromPalette.selectedColumnIndex; return { content: isDragAndDropEnabled ? formatMessage(_messages.tableMessages.backgroundColor) : formatMessage(_messages.tableMessages.cellBackground), value: { name: 'background' }, elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_paintBucket.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.backgroundColor) })) : undefined, elemAfter: // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 (0, _react2.jsx)("div", { className: _styles.DropdownMenuSharedCssClassName.SUBMENU }, (0, _react2.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: (0, _styles2.cellColourPreviewStyles)(background) // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: isDragAndDropEnabled ? _types.TableCssClassName.CONTEXTUAL_MENU_ICON_SMALL : _types.TableCssClassName.CONTEXTUAL_MENU_ICON }), isSubmenuOpen && (0, _react2.jsx)("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: _types.TableCssClassName.CONTEXTUAL_SUBMENU, ref: _this.handleSubMenuRef }, (0, _react2.jsx)(_uiMenu.ArrowKeyNavigationProvider, { type: _uiMenu.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 }, (0, _react2.jsx)(_uiColor.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: _uiColor.cellBackgroundColorPalette, paletteColorTooltipMessages: _uiColor.backgroundPaletteTooltipMessages, hexToPaletteColor: _editorPalette.hexToEditorBackgroundPaletteColor } })))), 'aria-expanded': isSubmenuOpen }; } }); // Used in the NewContextMenuItems object (0, _defineProperty2.default)(_this, "newDistributeColumnsItem", function () { var formatMessage = _this.props.intl.formatMessage; return _this.createDistributeColumnsItemInternal({ elemBefore: (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableColumnsDistribute.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.distributeColumns) })) }); }); (0, _defineProperty2.default)(_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 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState2.isDragAndDropEnabled; if (allowMergeCells) { return [{ content: formatMessage(_messages.tableMessages.mergeCells), value: { name: 'merge' }, isDisabled: !(0, _merge.canMergeCells)(state.tr), elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableCellMerge.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.mergeCells) })) : undefined }, { content: formatMessage(_messages.tableMessages.splitCell), value: { name: 'split' }, isDisabled: !(0, _utils2.splitCell)(state), elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableCellSplit.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.splitCell) })) : undefined }]; } return []; }); (0, _defineProperty2.default)(_this, "createInsertColumnItem", function () { var _this$props3 = _this.props, formatMessage = _this$props3.intl.formatMessage, editorView = _this$props3.editorView; var _getPluginState3 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState3.isDragAndDropEnabled; var content = formatMessage(isDragAndDropEnabled ? _messages.tableMessages.addColumnRight : _messages.tableMessages.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: (0, _react2.jsx)("div", { css: _shortcut.shortcutStyle }, (0, _keymaps.tooltip)(_keymaps.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 (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableColumnAddRight.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.addColumnRight) })) : undefined, 'aria-label': (0, _keymaps.tooltip)(_keymaps.addColumnAfter, String(content)) }; }); (0, _defineProperty2.default)(_this, "createInsertRowItem", function () { var _this$props4 = _this.props, formatMessage = _this$props4.intl.formatMessage, editorView = _this$props4.editorView; var _getPluginState4 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState4.isDragAndDropEnabled; var content = formatMessage(isDragAndDropEnabled ? _messages.tableMessages.addRowBelow : _messages.tableMessages.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: (0, _react2.jsx)("div", { css: _shortcut.shortcutStyle }, (0, _keymaps.tooltip)(_keymaps.addRowAfter)), elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableRowAddBelow.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.addRowBelow) })) : undefined, 'aria-label': (0, _keymaps.tooltip)(_keymaps.addRowAfter, String(content)) }; }); (0, _defineProperty2.default)(_this, "createClearCellsItem", function () { var _this$props5 = _this.props, selectionRect = _this$props5.selectionRect, formatMessage = _this$props5.intl.formatMessage, editorView = _this$props5.editorView; var _getPluginState5 = (0, _pluginFactory.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.tableMessages.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: (0, _react2.jsx)("div", { css: _shortcut.shortcutStyle }, (0, _keymaps.tooltip)(_keymaps.backspace)), elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableCellClear.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.clearCells, { 0: Math.max(noOfColumns, noOfRows) }) })) : undefined, 'aria-label': (0, _keymaps.tooltip)(_keymaps.backspace, String(content)) }; }); (0, _defineProperty2.default)(_this, "createDeleteColumnItem", function () { var _this$props6 = _this.props, selectionRect = _this$props6.selectionRect, formatMessage = _this$props6.intl.formatMessage, editorView = _this$props6.editorView; var _getPluginState6 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState6.isDragAndDropEnabled; var right = selectionRect.right, left = selectionRect.left; var noOfColumns = right - left; return { content: formatMessage(_messages.tableMessages.removeColumns, { 0: noOfColumns }), value: { name: 'delete_column' }, elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableColumnDelete.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.removeColumns, { 0: noOfColumns }) })) : undefined }; }); (0, _defineProperty2.default)(_this, "createDeleteRowItem", function () { var _this$props7 = _this.props, selectionRect = _this$props7.selectionRect, formatMessage = _this$props7.intl.formatMessage, editorView = _this$props7.editorView; var _getPluginState7 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState7.isDragAndDropEnabled; var bottom = selectionRect.bottom, top = selectionRect.top; var noOfRows = bottom - top; return { content: formatMessage(_messages.tableMessages.removeRows, { 0: noOfRows }), value: { name: 'delete_row' }, elemBefore: isDragAndDropEnabled ? (0, _react2.jsx)(_primitives.Box, { xcss: elementBeforeIconStyles }, (0, _react2.jsx)(_tableRowDelete.default, { color: "currentColor", spacing: "spacious", label: formatMessage(_messages.tableMessages.removeRows, { 0: noOfRows }) })) : undefined }; }); (0, _defineProperty2.default)(_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 = (0, _pluginFactory.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 = (0, _resizeState.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.tableMessages.distributeColumns), value: { name: 'distribute_columns' }, isDisabled: !wouldChange }, partialMenuItem); }); (0, _defineProperty2.default)(_this, "createDistributeColumnsItem", function () { var editorView = _this.props.editorView; var _getPluginState9 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState9.isDragAndDropEnabled, allowDistributeColumns = _getPluginState9.pluginConfig.allowDistributeColumns; if (allowDistributeColumns && !isDragAndDropEnabled) { return _this.createDistributeColumnsItemInternal(); } return null; }); (0, _defineProperty2.default)(_this, "createSortColumnItems", function () { var _this$props9 = _this.props, formatMessage = _this$props9.intl.formatMessage, editorView = _this$props9.editorView, allowColumnSorting = _this$props9.allowColumnSorting; var _getPluginState0 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState0.isDragAndDropEnabled; if (allowColumnSorting && !isDragAndDropEnabled) { var hasMergedCellsInTable = (0, _table.getMergedCellsPositions)(editorView.state.tr).length > 0; var warning = hasMergedCellsInTable ? { tooltipDescription: formatMessage(_messages.tableMessages.canNotSortTable), isDisabled: true } : {}; return [_objectSpread({ content: formatMessage(_messages.tableMessages.sortColumnASC), value: { name: 'sort_column_asc' } }, warning), _objectSpread({ content: formatMessage(_messages.tableMessages.sortColumnDESC), value: { name: 'sort_column_desc' } }, warning)]; } return null; }); (0, _defineProperty2.default)(_this, "createOriginalContextMenuItems", function () { var items = []; var sortColumnItems = _this.createSortColumnItems(); var backgroundColorItem = _this.createBackgroundColorItem(); var distributeColumnsItem = _this.createDistributeColumnsItem(); sortColumnItems && items.push.apply(items, (0, _toConsumableArray2.default)(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, (0, _toConsumableArray2.default)(_this.createMergeSplitCellItems())); distributeColumnsItem && items.push(distributeColumnsItem); items.push(_this.createClearCellsItem()); return [{ items: items }]; }); (0, _defineProperty2.default)(_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, (0, _toConsumableArray2.default)(mergeSplitCellItems)); items[1].items.push(insertColumnItem); items[1].items.push(insertRowItem); if ((0, _experiments.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; }); (0, _defineProperty2.default)(_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 = (0, _pluginFactory.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(_pluginKey.pluginKey, { 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': (0, _commandsWithAnalytics.sortColumnWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, selectionRect.left, _customSteps.TableSortOrder.DESC)(state, dispatch); _this.toggleOpen(); break; case 'sort_column_asc': (0, _commandsWithAnalytics.sortColumnWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, selectionRect.left, _customSteps.TableSortOrder.ASC)(state, dispatch); _this.toggleOpen(); break; case 'merge': (0, _commandsWithAnalytics.mergeCellsWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU)(state, dispatch); _this.toggleOpen(); break; case 'split': (0, _commandsWithAnalytics.splitCellWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU)(state, dispatch); _this.toggleOpen(); break; case 'distribute_columns': var newResizeStateWithAnalytics = (0, _resizeState.getNewResizeStateFromSelectedColumns)(selectionRect, state, editorView.domAtPos.bind(editorView), getEditorContainerWidth, isTableScalingEnabled, tableWithFixedColumnWidthsOption, isCommentEditor); if (newResizeStateWithAnalytics) { (0, _commandsWithAnalytics.distributeColumnsWidthsWithAnalytics)(editorAnalyticsAPI, _this.props.api)(_analytics.INPUT_METHOD.CONTEXT_MENU, newResizeStateWithAnalytics)(state, dispatch); _this.toggleOpen(); } break; case 'clear': (0, _commandsWithAnalytics.emptyMultipleCellsWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, targetCellPosition)(state, dispatch); _this.toggleOpen(); break; case 'insert_column': (0, _commandsWithAnalytics.insertColumnWithAnalytics)(_this.props.api, editorAnalyticsAPI, isTableScalingEnabled, tableWithFixedColumnWidthsOption, shouldUseIncreasedScalingPercent, isCommentEditor)(_analytics.INPUT_METHOD.CONTEXT_MENU, selectionRect.right)(state, dispatch, editorView); _this.toggleOpen(); break; case 'insert_row': (0, _commandsWithAnalytics.insertRowWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, { index: selectionRect.bottom, moveCursorToInsertedRow: true })(state, dispatch); _this.toggleOpen(); break; case 'delete_column': (0, _commandsWithAnalytics.deleteColumnsWithAnalytics)(editorAnalyticsAPI, _this.props.api, isTableScalingEnabled, tableWithFixedColumnWidthsOption, shouldUseIncreasedScalingPercent, isCommentEditor)(_analytics.INPUT_METHOD.CONTEXT_MENU, selectionRect)(state, dispatch, editorView); _this.toggleOpen(); break; case 'delete_row': var _getPluginState10 = (0, _pluginFactory.getPluginState)(state), isHeaderRowRequired = _getPluginState10.pluginConfig.isHeaderRowRequired; (0, _commandsWithAnalytics.deleteRowsWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, selectionRect, !!isHeaderRowRequired)(state, dispatch); _this.toggleOpen(); break; case 'background': { if (!(0, _expValEquals.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; } } }); (0, _defineProperty2.default)(_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; (0, _commands.toggleContextualMenu)()(state, dispatch); if (!isOpen) { _this.setState({ isSubmenuOpen: false }); } }); (0, _defineProperty2.default)(_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 ((0, _expValEquals.expValEquals)('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { _this.setState({ isSubmenuOpen: true }); return; } } (0, _commands.toggleContextualMenu)()(state, dispatch); _this.setState({ isSubmenuOpen: false }); (0, _commands.setFocusToCellMenu)(false)(state, dispatch); dom.focus(); } } else { // mouse click outside (0, _commands.toggleContextualMenu)()(state, dispatch); _this.setState({ isSubmenuOpen: false }); if (isCellMenuOpenByKeyboard) { (0, _commands.setFocusToCellMenu)(false)(state, dispatch); } } } }); // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any (0, _defineProperty2.default)(_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 (!(0, _expValEquals.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') { (0, _commands.hoverColumns)((0, _selection.getSelectedColumnIndexes)(selectionRect), true)(state, dispatch); } if (item.value.name === 'delete_row') { (0, _commands.hoverRows)((0, _selection.getSelectedRowIndexes)(selectionRect), true)(state, dispatch); } if (['sort_column_asc', 'sort_column_desc'].indexOf(item.value.name) > -1 && (0, _table.getMergedCellsPositions)(state.tr).length !== 0) { (0, _commands.hoverMergedCells)()(state, dispatch); } }); // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any (0, _defineProperty2.default)(_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 (!(0, _expValEquals.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) { (0, _commands.clearHoverSelection)()(state, dispatch); } }); (0, _defineProperty2.default)(_this, "closeSubmenu", function () { if (_this.state.isSubmenuOpen) { _this.setState({ isSubmenuOpen: false }); } }); (0, _defineProperty2.default)(_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; (0, _commandsWithAnalytics.setColorWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, color)(state, dispatch); if (!(0, _expValEquals.expValEquals)('platform_editor_toolbar_submenu_open_click', 'isEnabled', true)) { _this.toggleOpen(); } else { (0, _commands.toggleContextualMenu)()(state, dispatch); _this.setState({ isSubmenuOpen: false }); if (isCellMenuOpenByKeyboard) { (0, _commands.setFocusToCellMenu)(false)(state, dispatch); dom.focus(); } } }); return _this; } (0, _inherits2.default)(ContextualMenu, _Component); return (0, _createClass2.default)(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 = (0, _pluginFactory.getPluginState)(this.props.editorView.state), isDragAndDropEnabled = _getPluginState11.isDragAndDropEnabled, isContextualMenuOpen = _getPluginState11.isContextualMenuOpen; if (isDragAndDropEnabled && this.props.isDragMenuOpen && isContextualMenuOpen) { (0, _commands.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 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState12.isDragAndDropEnabled; var items = isDragAndDropEnabled ? this.createNewContextMenuItems() : this.createOriginalContextMenuItems(); var isOpenAllowed = false; isOpenAllowed = isCellMenuOpenByKeyboard ? this.state.isOpenAllowed : isOpen; return (0, _react2.jsx)(_userIntent.UserIntentPopupWrapper, { userIntent: "tableContextualMenuPopupOpen", api: api }, (0, _react2.jsx)("div", { "data-testid": "table-cell-contextual-menu", onMouseLeave: (0, _expValEquals.expValEquals)('platform_editor_toolbar_submenu_open_click', 'isEnabled', true) ? undefined : this.closeSubmenu, ref: this.dropdownMenuRef }, (0, _react2.jsx)(_uiMenu.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: _uiMenu.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 ? _consts.contextualMenuDropdownWidthDnD : _consts.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 }))); } }]); }(_react.Component); (0, _defineProperty2.default)(ContextualMenu, "defaultProps", { boundariesElement: typeof document !== 'undefined' ? document.body : undefined }); var _default = exports.default = (0, _reactIntlNext.injectIntl)(ContextualMenu);