@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
190 lines (186 loc) • 8.84 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DropdownMenu = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = _interopRequireWildcard(require("react"));
var _ui = require("@atlaskit/editor-common/ui");
var _uiMenu = require("@atlaskit/editor-common/ui-menu");
var _uiReact = require("@atlaskit/editor-common/ui-react");
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
var _menu = require("@atlaskit/menu");
var _consts = require("../consts");
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); }
/* eslint-disable @atlaskit/design-system/prefer-primitives */
var DropListWithOutsideClickTargetRef = function DropListWithOutsideClickTargetRef(props) {
var setOutsideClickTargetRef = _react.default.useContext(_uiReact.OutsideClickTargetRefContext);
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
return /*#__PURE__*/_react.default.createElement(_ui.DropList, (0, _extends2.default)({
onDroplistRef: setOutsideClickTargetRef
}, props));
};
var DropListWithOutsideListeners = (0, _uiReact.withReactEditorViewOuterListeners)(DropListWithOutsideClickTargetRef);
var DropdownMenu = exports.DropdownMenu = function DropdownMenu(_ref) {
var items = _ref.items,
section = _ref.section,
disableKeyboardHandling = _ref.disableKeyboardHandling,
onItemActivated = _ref.onItemActivated,
handleClose = _ref.handleClose,
onMouseEnter = _ref.onMouseEnter,
onMouseLeave = _ref.onMouseLeave,
fitWidth = _ref.fitWidth,
fitHeight = _ref.fitHeight,
direction = _ref.direction,
mountPoint = _ref.mountPoint,
boundariesElement = _ref.boundariesElement,
scrollableElement = _ref.scrollableElement;
var _useState = (0, _react.useState)(['bottom', 'left']),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
popupPlacement = _useState2[0],
setPopupPlacement = _useState2[1];
var _useState3 = (0, _react.useState)(null),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
targetRefDiv = _useState4[0],
setTargetRefDiv = _useState4[1];
var handleRef = function handleRef(ref) {
setTargetRefDiv(ref);
};
// more offsets calculation as offsets depend on the direction and updated placement here
var offsetY = direction === 'row' ? popupPlacement[0] === 'bottom' ? -8 : -34 : 0;
var offsetX = direction === 'column' ? popupPlacement[1] === 'left' ? 0 : -7 : 0;
var innerMenu = function innerMenu() {
return /*#__PURE__*/_react.default.createElement(DropListWithOutsideListeners, {
isOpen: true,
shouldFitContainer: true,
position: popupPlacement.join(' '),
handleClickOutside: function handleClickOutside() {
return handleClose('editor');
},
handleEscapeKeydown: function handleEscapeKeydown() {
if (!disableKeyboardHandling) {
handleClose('handle');
}
},
handleEnterKeydown: function handleEnterKeydown(e) {
if (!disableKeyboardHandling) {
e.preventDefault();
e.stopPropagation();
}
},
targetRef: targetRefDiv
}, /*#__PURE__*/_react.default.createElement("div", {
style: {
height: 0,
minWidth: _consts.dragMenuDropdownWidth
}
}), /*#__PURE__*/_react.default.createElement(_menu.MenuGroup, {
role: "menu"
}, items.map(function (group, index) {
return /*#__PURE__*/_react.default.createElement(_menu.Section, {
hasSeparator: (section === null || section === void 0 ? void 0 : section.hasSeparator) && index > 0,
title: section === null || section === void 0 ? void 0 : section.title
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
,
key: index
}, group.items.map(function (item) {
var _item$key;
return /*#__PURE__*/_react.default.createElement(_uiMenu.DropdownMenuItem, {
shouldUseDefaultRole: false,
key: (_item$key = item.key) !== null && _item$key !== void 0 ? _item$key : String(item.content),
item: item,
onItemActivated: onItemActivated,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave
});
}));
})));
};
var onClose = (0, _react.useCallback)(function () {
return handleClose('handle');
}, [handleClose]);
var onSelection = (0, _react.useCallback)(function (index) {
var results = items.flatMap(function (item) {
return 'items' in item ? item.items : item;
});
// onSelection is called when any focusable element is 'activated'
// this is an issue as some menu items have toggles, which cause the index value
// in the callback to be outside of array length.
// The logic below normalises the index value based on the number
// of menu items with 2 focusable elements, and adjusts the index to ensure
// the correct menu item is sent in onItemActivated callback
var keys = ['row_numbers', 'header_row', 'header_column'];
var doubleItemCount = 0;
var firstIndex = results.findIndex(function (value) {
var key = value.key;
return key !== undefined && keys.includes(key);
});
if (firstIndex === -1 || index <= firstIndex) {
onItemActivated && onItemActivated({
item: results[index]
});
return;
}
for (var i = firstIndex; i < results.length; i += 1) {
var key = results[i].key;
if (key !== undefined && keys.includes(key)) {
doubleItemCount += 1;
}
if (firstIndex % 2 === 0 && index - doubleItemCount === i) {
onItemActivated && onItemActivated({
item: results[i]
});
return;
}
if (firstIndex % 2 === 1 && index - doubleItemCount === i) {
onItemActivated && onItemActivated({
item: results[i]
});
return;
}
}
}, [items, onItemActivated]);
return (
/*#__PURE__*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
_react.default.createElement("div", {
className: "drag-dropdown-menu-wrapper"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "drag-dropdown-menu-popup-ref",
ref: handleRef
}), /*#__PURE__*/_react.default.createElement(_ui.Popup
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
, {
target: targetRefDiv,
mountTo: mountPoint,
boundariesElement: boundariesElement,
scrollableElement: scrollableElement,
onPlacementChanged: function onPlacementChanged(placement) {
setPopupPlacement(placement);
},
fitHeight: fitHeight,
fitWidth: fitWidth,
zIndex: _editorSharedStyles.akEditorFloatingPanelZIndex,
offset: [offsetX, offsetY],
allowOutOfBounds: true // required as this popup is child of a parent popup, should be allowed to be out of bound of the parent popup, otherwise horizontal offset is not right
}, /*#__PURE__*/_react.default.createElement(_uiMenu.ArrowKeyNavigationProvider, {
closeOnTab: !disableKeyboardHandling,
type: _uiMenu.ArrowKeyNavigationType.MENU,
handleClose: onClose,
onSelection: onSelection
// disableKeyboardHandling is linked with isSubmenuOpen in DragMenu
// When isSubmenuOpen is true, the background color picker palette is open, and the picker is a ColorPaletteArrowKeyNavigationProvider
// At the same time the MenuArrowKeyNavigationProvider are renderer too, as it is the wrapper for all other DragMenu items
// In this case we want the ColorPaletteArrowKeyNavigationProvider to handle the keyboard event, not the MenuArrowKeyNavigationProvider
// Hence set disableArrowKeyNavigation to true when disableKeyboardHandling is true
,
disableArrowKeyNavigation: disableKeyboardHandling
}, innerMenu())))
);
};