@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
307 lines (302 loc) • 15.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DragControlsWithSelection = exports.DragControls = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _hooks = require("@atlaskit/editor-common/hooks");
var _editorTables = require("@atlaskit/editor-tables");
var _utils = require("@atlaskit/editor-tables/utils");
var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
var _commands = require("../../../pm-plugins/commands");
var _commands2 = require("../../../pm-plugins/drag-and-drop/commands");
var _pluginFactory = require("../../../pm-plugins/plugin-factory");
var _rowControls = require("../../../pm-plugins/utils/row-controls");
var _selection = require("../../../pm-plugins/utils/selection");
var _types = require("../../../types");
var _consts = require("../../consts");
var _DragHandle = require("../../DragHandle");
var _RowDropTarget = _interopRequireDefault(require("../RowDropTarget"));
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 getSelectedRows = function getSelectedRows(selection) {
if (selection instanceof _editorTables.CellSelection && selection.isRowSelection()) {
var rect = (0, _utils.getSelectionRect)(selection);
if (!rect) {
return [];
}
return (0, _selection.getSelectedRowIndexes)(rect);
}
return [];
};
var DragControls = exports.DragControls = function DragControls(_ref) {
var _tableNode$attrs$loca, _tableNode$attrs;
var tableRef = _ref.tableRef,
tableNode = _ref.tableNode,
tableWidth = _ref.tableWidth,
hoveredCell = _ref.hoveredCell,
tableActive = _ref.tableActive,
editorView = _ref.editorView,
isInDanger = _ref.isInDanger,
isResizing = _ref.isResizing,
isTableHovered = _ref.isTableHovered,
hoverRows = _ref.hoverRows,
selectRow = _ref.selectRow,
selectRows = _ref.selectRows,
updateCellHoverLocation = _ref.updateCellHoverLocation,
api = _ref.api,
selection = _ref.selection;
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
isDragging = _useState2[0],
setIsDragging = _useState2[1];
var rowHeights = (0, _rowControls.getRowHeights)(tableRef);
var rowsParams = (0, _rowControls.getRowsParams)(rowHeights);
var heights = rowHeights.map(function (height) {
return "".concat(height - 1, "px");
}).join(' ');
var selectedRowIndexes = getSelectedRows(selection !== null && selection !== void 0 ? selection : editorView.state.selection);
var currentNodeLocalId = (_tableNode$attrs$loca = tableNode === null || tableNode === void 0 || (_tableNode$attrs = tableNode.attrs) === null || _tableNode$attrs === void 0 ? void 0 : _tableNode$attrs.localId) !== null && _tableNode$attrs$loca !== void 0 ? _tableNode$attrs$loca : '';
(0, _react.useEffect)(function () {
return (0, _adapter.monitorForElements)({
canMonitor: function canMonitor(_ref2) {
var source = _ref2.source;
var _ref3 = source.data,
type = _ref3.type,
localId = _ref3.localId,
indexes = _ref3.indexes;
if (!indexes || !localId || type !== 'table-row') {
return false;
}
var _getTablePluginState = (0, _pluginFactory.getPluginState)(editorView.state),
tableNode = _getTablePluginState.tableNode;
// If the draggable localId is the same as the current selected table localId then we will allow the monitor
// watch for changes
return localId === (tableNode === null || tableNode === void 0 ? void 0 : tableNode.attrs.localId);
},
onDragStart: function onDragStart() {
setIsDragging(true);
},
onDrop: function onDrop() {
setIsDragging(false);
}
});
}, [editorView]);
var toggleDragMenuHandler = (0, _react.useCallback)(function (trigger, event) {
if (event !== null && event !== void 0 && event.shiftKey) {
return;
}
(0, _commands2.toggleDragMenu)(undefined, 'row', hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex, trigger)(editorView.state, editorView.dispatch);
}, [editorView, hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex]);
var rowIndex = hoveredCell === null || hoveredCell === void 0 ? void 0 : hoveredCell.rowIndex;
var handleMouseOut = (0, _react.useCallback)(function () {
if (tableActive) {
var state = editorView.state,
dispatch = editorView.dispatch;
(0, _commands.clearHoverSelection)()(state, dispatch);
}
}, [editorView, tableActive]);
var handleMouseMove = (0, _react.useCallback)(function (e) {
var target = e.nativeEvent.target instanceof Element ? e.nativeEvent.target : null;
var isParentDragControls = target === null || target === void 0 ? void 0 : target.closest(".".concat(_types.TableCssClassName.DRAG_ROW_CONTROLS));
var rowIndex = target === null || target === void 0 ? void 0 : target.getAttribute('data-start-index');
// avoid updating if event target is not related
if (!isParentDragControls || !rowIndex) {
return;
}
updateCellHoverLocation(Number(rowIndex));
}, [updateCellHoverLocation]);
var rowIndexes = (0, _react.useMemo)(function () {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return [rowIndex];
}, [rowIndex]);
var handleMouseOver = (0, _react.useCallback)(function () {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
hoverRows([rowIndex]);
}, [hoverRows, rowIndex]);
var handleClick = (0, _react.useCallback)(function (e) {
var isClickOutsideSelectedRows =
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
selectedRowIndexes.length >= 1 && !selectedRowIndexes.includes(rowIndex);
if (!selectedRowIndexes || selectedRowIndexes.length === 0 || isClickOutsideSelectedRows) {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
selectRow(rowIndex, e.shiftKey);
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (selectedRowIndexes.length > 1 && selectedRowIndexes.includes(rowIndex) && !e.shiftKey) {
selectRows(selectedRowIndexes);
}
}, [rowIndex, selectRow, selectRows, selectedRowIndexes]);
var generateHandleByType = function generateHandleByType(type, appearance, gridRow, indexes) {
var isHover = type === 'hover';
var previewHeight = rowHeights.reduce(function (sum, v, i) {
return sum + v * (indexes.includes(i) ? 1 : 0);
}, 0);
return /*#__PURE__*/_react.default.createElement("div", {
key: type,
style: {
gridRow: gridRow,
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
gridColumn: '2',
// DragHandle uses `transform: rotate(90)`, which doesn't affect its parent (this div) causing the width of this element to be the true height of the drag handle
// 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
width: '9px',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
height: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
position: 'relative',
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
right: '-0.5px',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
pointerEvents: 'none'
},
"data-testid": "table-floating-row-".concat(isHover ? rowIndex : selectedRowIndexes[0], "-drag-handle")
}, /*#__PURE__*/_react.default.createElement(_DragHandle.DragHandle, {
isDragMenuTarget: !isHover,
direction: "row",
tableLocalId: currentNodeLocalId,
indexes: indexes,
forceDefaultHandle: !isHover,
previewWidth: tableWidth,
previewHeight: previewHeight,
appearance: appearance,
hoveredCell: hoveredCell,
onClick: handleClick,
onMouseOver: handleMouseOver,
onMouseOut: handleMouseOut,
toggleDragMenu: toggleDragMenuHandler,
editorView: editorView
}));
};
var rowHandles = function rowHandles() {
var handles = [];
var isRowSelected = selectedRowIndexes.length > 0;
var isEntireTableSelected = rowHeights.length > selectedRowIndexes.length;
if (!tableActive) {
return null;
}
// placeholder / selected need to always render at least one handle
// so it can be focused via keyboard shortcuts
handles.push(generateHandleByType('selected', isRowSelected && isEntireTableSelected ? isInDanger ? 'danger' : 'selected' : 'placeholder', "".concat(selectedRowIndexes[0] + 1, " / span ").concat(selectedRowIndexes.length), selectedRowIndexes));
if (hoveredCell && isTableHovered && rowIndex !== undefined && !selectedRowIndexes.includes(rowIndex) && rowIndex < rowHeights.length) {
handles.push(generateHandleByType('hover', 'default', "".concat(rowIndex + 1, " / span 1"), rowIndexes));
}
return handles;
};
if (isResizing) {
return null;
}
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_ROW_CONTROLS,
style: {
gridTemplateRows: heights,
gridTemplateColumns: isDragging ? // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
"".concat(_consts.dropTargetExtendedWidth, "px 14px ").concat(tableWidth, "px") : '0px 14px 0px',
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview
left: isDragging ? // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
"-".concat(_consts.dropTargetExtendedWidth + 2, "px") : "var(--ds-space-negative-025, -2px)"
},
onMouseMove: handleMouseMove,
contentEditable: false
}, rowsParams.map(function (_ref4, index) {
var startIndex = _ref4.startIndex,
endIndex = _ref4.endIndex;
return (
/*#__PURE__*/
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
_react.default.createElement(_react.Fragment, {
key: index
}, /*#__PURE__*/_react.default.createElement("div", {
style: {
gridRow: "".concat(index + 1, " / span 1"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
gridColumn: '2'
},
"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_ROW_FLOATING_INSERT_DOT_WRAPPER,
contentEditable: false
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
,
key: "insert-dot-".concat(index)
}, /*#__PURE__*/_react.default.createElement("div", {
className: _types.TableCssClassName.DRAG_ROW_FLOATING_INSERT_DOT
})), isDragging && /*#__PURE__*/_react.default.createElement(_RowDropTarget.default
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
, {
key: "drop-target-".concat(index),
index: index,
localId: currentNodeLocalId,
style: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
gridColumn: '1 / span 3',
gridRow: "".concat(index + 1, " / span 1"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
height: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
pointerEvents: 'auto',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
position: 'relative',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
left: "var(--ds-space-negative-100, -8px)"
}
}))
);
}), rowHandles());
};
var DragControlsWithSelection = exports.DragControlsWithSelection = function DragControlsWithSelection(_ref5) {
var editorView = _ref5.editorView,
tableRef = _ref5.tableRef,
tableNode = _ref5.tableNode,
tableWidth = _ref5.tableWidth,
tableActive = _ref5.tableActive,
hoveredCell = _ref5.hoveredCell,
isInDanger = _ref5.isInDanger,
isTableHovered = _ref5.isTableHovered,
isResizing = _ref5.isResizing,
hoverRows = _ref5.hoverRows,
selectRow = _ref5.selectRow,
selectRows = _ref5.selectRows,
updateCellHoverLocation = _ref5.updateCellHoverLocation,
api = _ref5.api;
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;
return /*#__PURE__*/_react.default.createElement(DragControls, {
editorView: editorView,
tableRef: tableRef,
tableNode: tableNode,
tableWidth: tableWidth,
tableActive: tableActive,
hoveredCell: hoveredCell,
isInDanger: isInDanger,
isTableHovered: isTableHovered,
isResizing: isResizing,
hoverRows: hoverRows,
selectRow: selectRow,
selectRows: selectRows,
updateCellHoverLocation: updateCellHoverLocation,
api: api,
selection: selection
});
};