@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
820 lines (818 loc) • 40.2 kB
JavaScript
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);