UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

265 lines (260 loc) 14.3 kB
"use strict"; var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnControls = void 0; var _react = _interopRequireWildcard(require("react")); var _hooks = require("@atlaskit/editor-common/hooks"); var _styles = require("@atlaskit/editor-common/styles"); var _editorSharedStyles = require("@atlaskit/editor-shared-styles"); var _editorTables = require("@atlaskit/editor-tables"); var _utils = require("@atlaskit/editor-tables/utils"); var _commands = require("../../../pm-plugins/commands"); var _commands2 = require("../../../pm-plugins/drag-and-drop/commands"); var _rowControls = require("../../../pm-plugins/utils/row-controls"); var _selection = require("../../../pm-plugins/utils/selection"); var _types = require("../../../types"); var _DragHandle = require("../../DragHandle"); 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 getSelectedColumns = function getSelectedColumns(selection) { if (selection instanceof _editorTables.CellSelection && selection.isColSelection()) { var rect = (0, _utils.getSelectionRect)(selection); if (!rect) { return []; } return (0, _selection.getSelectedColumnIndexes)(rect); } return []; }; var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) { var _colWidths$map$join; var editorView = _ref.editorView, tableActive = _ref.tableActive, tableRef = _ref.tableRef, hoveredCell = _ref.hoveredCell, stickyTop = _ref.stickyTop, localId = _ref.localId, isInDanger = _ref.isInDanger, rowHeights = _ref.rowHeights, colWidths = _ref.colWidths, isTableHovered = _ref.isTableHovered, tableContainerWidth = _ref.tableContainerWidth, isNumberColumnEnabled = _ref.isNumberColumnEnabled, isDragging = _ref.isDragging, getScrollOffset = _ref.getScrollOffset, api = _ref.api; var columnControlsRef = (0, _react.useRef)(null); var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['selection'], function (states) { var _states$selectionStat; return { selection: (_states$selectionStat = states.selectionState) === null || _states$selectionStat === void 0 ? void 0 : _states$selectionStat.selection }; }), selection = _useSharedPluginState.selection; var widths = (_colWidths$map$join = colWidths === null || colWidths === void 0 ? void 0 : colWidths.map(function (width) { return ( // when there is sticky header, a `margin-right: -1px` applied to `tr.sticky th` so it causes colWidths to be 1px wider // we need to reduce the width by 1px to avoid misalignment of column controls. width ? stickyTop ? "".concat(width - 2, "px") : "".concat(width - 1, "px") : '0px' ); }).join(' ')) !== null && _colWidths$map$join !== void 0 ? _colWidths$map$join : '0px'; // TODO: ED-26961 - reusing getRowsParams here because it's generic enough to work for columns -> rename var columnParams = (0, _rowControls.getRowsParams)(colWidths !== null && colWidths !== void 0 ? colWidths : []); var colIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.colIndex; var selectedColIndexes = getSelectedColumns(selection || editorView.state.selection); var firstRow = tableRef.querySelector('tr'); var hasHeaderRow = firstRow ? firstRow.getAttribute('data-header-row') : false; var rowControlStickyTop = 45; var marginTop = hasHeaderRow && stickyTop !== undefined ? rowControlStickyTop !== null && rowControlStickyTop !== void 0 ? rowControlStickyTop : 0 : 0; var handleClick = (0, _react.useCallback)(function (event) { var state = editorView.state, dispatch = editorView.dispatch; var isClickOutsideSelectedCols = // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion selectedColIndexes.length >= 1 && !selectedColIndexes.includes(colIndex); if (!selectedColIndexes || selectedColIndexes.length === 0 || isClickOutsideSelectedCols) { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (0, _commands.selectColumn)(colIndex, event.shiftKey)(state, dispatch); } if (selectedColIndexes.length > 1 && // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion selectedColIndexes.includes(colIndex) && !event.shiftKey) { (0, _commands.selectColumns)(selectedColIndexes)(state, dispatch); } }, [colIndex, selectedColIndexes, editorView]); var handleMouseOver = (0, _react.useCallback)(function () { var state = editorView.state, dispatch = editorView.dispatch; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (0, _commands.hoverColumns)([colIndex])(state, dispatch); }, [colIndex, editorView]); var handleMouseMove = (0, _react.useCallback)(function (e) { var isParentDragControls = e.nativeEvent.target.closest(".".concat(_types.TableCssClassName.DRAG_COLUMN_CONTROLS)); var colIndex = e.nativeEvent.target.getAttribute('data-start-index'); // avoid updating if event target is not related if (!isParentDragControls || !colIndex) { return; } // update hovered cell location var state = editorView.state, dispatch = editorView.dispatch; if (tableActive) { // For context: Whenever we mouse over a column or row drag handle, we will ALWAYS be hovering over the 0 index // of the opposite dimension. For example; here when we mouse over the column drag handle then we're technically // also hovering over row 0 index. And vice-versa with rows. This means we don't need to worry about knowing the // current row index. We can just force it to 0. (0, _commands.hoverCell)(0, Number(colIndex))(state, dispatch); } }, [editorView, tableActive]); var handleMouseOut = (0, _react.useCallback)(function () { if (tableActive) { var state = editorView.state, dispatch = editorView.dispatch; (0, _commands.clearHoverSelection)()(state, dispatch); } }, [editorView, tableActive]); var toggleDragMenuHandler = (0, _react.useCallback)(function (trigger, event) { var state = editorView.state, dispatch = editorView.dispatch; if (event !== null && event !== void 0 && event.shiftKey) { return; } (0, _commands2.toggleDragMenu)(undefined, 'column', colIndex, trigger)(state, dispatch); }, [editorView, colIndex]); var colIndexes = (0, _react.useMemo)(function () { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return [colIndex]; }, [colIndex]); if (stickyTop && columnControlsRef.current) { var _getScrollOffset; columnControlsRef.current.scrollLeft = (_getScrollOffset = getScrollOffset === null || getScrollOffset === void 0 ? void 0 : getScrollOffset()) !== null && _getScrollOffset !== void 0 ? _getScrollOffset : 0; } var generateHandleByType = function generateHandleByType(type, appearance, gridColumn, indexes) { var _rowHeights$reduce, _colWidths$reduce; var isHover = type === 'hover'; var isPlaceholder = appearance === 'placeholder'; var previewHeight = (_rowHeights$reduce = rowHeights === null || rowHeights === void 0 ? void 0 : rowHeights.reduce(function (sum, cur) { return sum + cur; }, 0)) !== null && _rowHeights$reduce !== void 0 ? _rowHeights$reduce : 0; var previewWidth = (_colWidths$reduce = colWidths === null || colWidths === void 0 ? void 0 : colWidths.reduce(function (sum, v, i) { return sum + (v !== null && v !== void 0 ? v : _styles.tableCellMinWidth) * (indexes.includes(i) ? 1 : 0); }, 0)) !== null && _colWidths$reduce !== void 0 ? _colWidths$reduce : _styles.tableCellMinWidth; return /*#__PURE__*/_react.default.createElement("div", { contentEditable: false, key: type, style: { gridColumn: gridColumn, // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 gridRow: '1', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 display: 'flex', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 justifyContent: 'center', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 alignItems: 'center', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 height: 'fit-content', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 placeSelf: 'center', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 zIndex: 99, // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 width: '100%', // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 position: 'relative' }, "data-testid": "table-floating-column-".concat(isHover ? colIndex : isPlaceholder ? appearance : selectedColIndexes[0], "-drag-handle") }, /*#__PURE__*/_react.default.createElement(_DragHandle.DragHandle, { isDragMenuTarget: !isHover, direction: "column", tableLocalId: localId || '', indexes: indexes, hoveredCell: hoveredCell, previewWidth: previewWidth, forceDefaultHandle: !isHover, previewHeight: previewHeight, appearance: appearance, onClick: handleClick, onMouseOver: handleMouseOver, onMouseOut: handleMouseOut, toggleDragMenu: toggleDragMenuHandler, editorView: editorView })); }; var columnHandles = function columnHandles() { var handles = []; var isColumnSelected = selectedColIndexes.length > 0; var isEntireTableSelected = (colWidths || []).length > selectedColIndexes.length; if (!tableActive) { return null; } var selectedAppearance = isColumnSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder'; // placeholder / selected need to always render at least one handle // so it can be focused via keyboard shortcuts handles.push(generateHandleByType('selected', selectedAppearance, // always position placeholder in first column to avoid overflow issues selectedAppearance === 'placeholder' ? '1 / span 1' : "".concat(selectedColIndexes[0] + 1, " / span ").concat(selectedColIndexes.length), selectedColIndexes)); if (hoveredCell && isTableHovered && colIndex !== undefined && !selectedColIndexes.includes(colIndex)) { handles.push( // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion generateHandleByType('hover', 'default', "".concat(colIndex + 1, " / span 1"), colIndexes)); } return handles; }; var containerWidth = isNumberColumnEnabled && tableContainerWidth ? tableContainerWidth - _editorSharedStyles.akEditorTableNumberColumnWidth : tableContainerWidth; return /*#__PURE__*/_react.default.createElement("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: _types.TableCssClassName.DRAG_COLUMN_CONTROLS, onMouseMove: handleMouseMove }, /*#__PURE__*/_react.default.createElement("div", { ref: columnControlsRef // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: _types.TableCssClassName.DRAG_COLUMN_CONTROLS_INNER, "data-testid": "table-floating-column-controls", style: { // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 gridTemplateColumns: widths, // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 marginTop: marginTop, // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview width: stickyTop ? containerWidth : undefined, overflowX: stickyTop ? 'hidden' : 'visible', pointerEvents: isDragging ? 'none' : undefined } }, columnParams.map(function (_ref2, index) { var startIndex = _ref2.startIndex, endIndex = _ref2.endIndex; return /*#__PURE__*/_react.default.createElement("div", { style: { gridColumn: "".concat(startIndex + 1, " / span 1") }, "data-start-index": startIndex, "data-end-index": endIndex // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: _types.TableCssClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER, contentEditable: false // Ignored via go/ees005 // eslint-disable-next-line react/no-array-index-key , key: index }, /*#__PURE__*/_react.default.createElement("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: _types.TableCssClassName.DRAG_COLUMN_FLOATING_INSERT_DOT // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 , style: columnParams.length - 1 === index ? { right: '0' } : {} })); }), columnHandles())); };