UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

816 lines (813 loc) 43.2 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 _paintBucketEditorBackgroundColor = _interopRequireDefault(require("@atlaskit/icon/core/migration/paint-bucket--editor-background-color")); 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 _crossCircle = _interopRequireDefault(require("@atlaskit/icon/glyph/cross-circle")); var _remove = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/remove")); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _primitives = require("@atlaskit/primitives"); var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure"); 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 _AddColRightIcon = require("../icons/AddColRightIcon"); var _AddRowBelowIcon = require("../icons/AddRowBelowIcon"); var _MergeCellsIcon = require("../icons/MergeCellsIcon"); var _SplitCellIcon = require("../icons/SplitCellIcon"); 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(['ArrowRight', 'ArrowLeft']); 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) { var parent = (0, _utils.closestElement)( // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting _this.props.editorView.dom, '.fabric-editor-popup-scroll-parent'); if (!parent && (0, _platformFeatureFlags.fg)('platform_editor_fix_table_menus_jira')) { parent = (0, _utils.closestElement)( // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting _this.props.editorView.dom, '.ak-editor-content-area'); } if (!(parent && ref)) { return; } var boundariesRect = parent.getBoundingClientRect(); var rect = ref.getBoundingClientRect(); if ((0, _platformFeatureFlags.fg)('platform_editor_fix_table_menus_jira')) { 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"); } } } else { if (rect.left + rect.width > boundariesRect.width) { ref.style.left = "-".concat(rect.width, "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)(_paintBucketEditorBackgroundColor.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, 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', 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), LEGACY_fallbackIcon: _MergeCellsIcon.MergeCellsIcon })) }); }); (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), LEGACY_fallbackIcon: _MergeCellsIcon.MergeCellsIcon })) : 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), LEGACY_fallbackIcon: _SplitCellIcon.SplitCellIcon })) : 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), LEGACY_fallbackIcon: _AddColRightIcon.AddColRightIcon })) : 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), LEGACY_fallbackIcon: _AddRowBelowIcon.AddRowBelowIcon })) : 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) }), LEGACY_fallbackIcon: _crossCircle.default })) : 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 }), LEGACY_fallbackIcon: _remove.default })) : 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 }), LEGACY_fallbackIcon: _remove.default })) : 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': { // 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 }); } 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(); } (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 (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 (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; var state = editorView.state, dispatch = editorView.dispatch; (0, _commandsWithAnalytics.setColorWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.CONTEXT_MENU, color)(state, dispatch); _this.toggleOpen(); }); 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: "render", value: function render() { var _this2 = this; var _this$props13 = this.props, isOpen = _this$props13.isOpen, mountPoint = _this$props13.mountPoint, offset = _this$props13.offset, boundariesElement = _this$props13.boundariesElement, editorView = _this$props13.editorView, isCellMenuOpenByKeyboard = _this$props13.isCellMenuOpenByKeyboard, api = _this$props13.api; var _getPluginState11 = (0, _pluginFactory.getPluginState)(editorView.state), isDragAndDropEnabled = _getPluginState11.isDragAndDropEnabled; var items = isDragAndDropEnabled ? this.createNewContextMenuItems() : this.createOriginalContextMenuItems(); var isOpenAllowed = false; isOpenAllowed = isCellMenuOpenByKeyboard ? this.state.isOpenAllowed : isOpen; var popupContent = function popupContent() { return (0, _react2.jsx)("div", { "data-testid": "table-cell-contextual-menu" // eslint-disable-next-line @atlassian/a11y/mouse-events-have-key-events , onMouseLeave: _this2.closeSubmenu, ref: _this2.dropdownMenuRef }, (0, _react2.jsx)(_uiMenu.DropdownMenu, { mountTo: (0, _platformFeatureFlags.fg)('platform_editor_fix_table_menus_jira') ? undefined : mountPoint //This needs be removed when the a11y is completely handled //Disabling key navigation now as it works only partially , arrowKeyNavigationProviderOptions: { type: _uiMenu.ArrowKeyNavigationType.MENU, disableArrowKeyNavigation: !isCellMenuOpenByKeyboard || _this2.state.isSubmenuOpen }, items: items, isOpen: isOpenAllowed, onOpenChange: _this2.handleOpenChange, onItemActivated: _this2.onMenuItemActivated, onMouseEnter: _this2.handleItemMouseEnter, onMouseLeave: _this2.handleItemMouseLeave, fitHeight: 188, fitWidth: isDragAndDropEnabled ? _consts.contextualMenuDropdownWidthDnD : _consts.contextualMenuDropdownWidth, shouldFocusFirstItem: function shouldFocusFirstItem() { return Boolean(isCellMenuOpenByKeyboard); }, boundariesElement: boundariesElement, offset: offset, section: isDragAndDropEnabled ? { hasSeparator: true } : undefined, allowEnterDefaultBehavior: _this2.state.isSubmenuOpen })); }; if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_lovability_user_intent', 'isEnabled', true)) { return (0, _react2.jsx)(_userIntent.UserIntentPopupWrapper, { userIntent: "tablePopupOpen", api: api }, popupContent()); } return popupContent(); } }]); }(_react.Component); (0, _defineProperty2.default)(ContextualMenu, "defaultProps", { boundariesElement: typeof document !== 'undefined' ? document.body : undefined }); var _default = exports.default = (0, _reactIntlNext.injectIntl)(ContextualMenu);