UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

295 lines 13.2 kB
import { tableMessages as messages } from '@atlaskit/editor-common/messages'; import { tableCellMinWidth } from '@atlaskit/editor-common/styles'; import { TableMap } from '@atlaskit/editor-tables'; import { findCellClosestToPos, findCellRectClosestToPos, findTableClosestToPos, getSelectionRect, isSelectionType, nextCell } from '@atlaskit/editor-tables/utils'; import { TableDecorations } from '../../types'; import { getDecorations } from '../decorations/plugin'; import { buildColumnResizingDecorations, clearColumnResizingDecorations } from '../decorations/utils/column-resizing'; import { createCommand, getPluginState } from '../plugin-factory'; import { getPluginState as getTableResizingPluginState, createCommand as tableResizingPluginCreateCommand } from '../table-resizing/plugin-factory'; import { pluginKey as tableResizingPK } from '../table-resizing/plugin-key'; import { updateControls } from '../table-resizing/utils/dom'; import { currentColWidth, getTableMaxWidth, getScalingPercentForTableWithoutWidth, getTableScalingPercent } from '../table-resizing/utils/misc'; import { resizeColumn } from '../table-resizing/utils/resize-column'; import { getResizeState } from '../table-resizing/utils/resize-state'; import { updateColumnWidths } from '../transforms/column-width'; import { createColumnLineResize, updateDecorations } from '../utils/decoration'; import { getSelectedColumnIndexes } from '../utils/selection'; var getTablePluginCommand = function getTablePluginCommand(actionPayload, originalTr) { return createCommand(function () { return actionPayload; }, function (tr) { return (originalTr || tr).setMeta('addToHistory', false); }); }; var updateResizeHandleAndStatePosition = function updateResizeHandleAndStatePosition(rowIndex, columnIndex, nextResizeHandlePos, nodeViewPortalProviderAPI) { return function (state, dispatch) { var customTr = state.tr; var _getPluginState = getPluginState(state), allowColumnResizing = _getPluginState.pluginConfig.allowColumnResizing, getIntl = _getPluginState.getIntl, isDragAndDropEnabled = _getPluginState.isDragAndDropEnabled; var fakeDispatch = function fakeDispatch(tr) { customTr = tr; }; if (!allowColumnResizing) { return false; } var decorationsWithWidget = buildColumnResizingDecorations(rowIndex, columnIndex, true, getIntl, nodeViewPortalProviderAPI)({ tr: customTr, decorationSet: getDecorations(state) }); var decorationsWithWidgetAndHandle = updateDecorations(customTr.doc, decorationsWithWidget, createColumnLineResize(state.selection, { right: columnIndex }, isDragAndDropEnabled), TableDecorations.COLUMN_RESIZING_HANDLE_LINE); getTablePluginCommand({ type: 'START_KEYBOARD_COLUMN_RESIZE', data: { resizeHandleRowIndex: rowIndex, resizeHandleColumnIndex: columnIndex, resizeHandleIncludeTooltip: true, isKeyboardResize: true, decorationSet: decorationsWithWidgetAndHandle } }, customTr)(state, fakeDispatch); customTr.setMeta(tableResizingPK, { type: 'SET_RESIZE_HANDLE_POSITION', data: { resizeHandlePos: nextResizeHandlePos } }); if (dispatch) { dispatch(customTr); return true; } return false; }; }; export var initiateKeyboardColumnResizing = function initiateKeyboardColumnResizing(_ref) { var ariaNotify = _ref.ariaNotify, getIntl = _ref.getIntl, nodeViewPortalProviderAPI = _ref.nodeViewPortalProviderAPI; return function (state, dispatch, view) { var selection = state.selection; var selectionRect = isSelectionType(selection, 'cell') ? // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion getSelectionRect(selection) : findCellRectClosestToPos(selection.$from); var cell = findCellClosestToPos(selection.$from); if (ariaNotify && getIntl) { ariaNotify(getIntl().formatMessage(messages.startedColumnResize), { priority: 'important' }); } if (selectionRect && cell && view) { return updateResizeHandleAndStatePosition(selectionRect.top, selectionRect.right, cell.pos, nodeViewPortalProviderAPI)(state, dispatch); } return false; }; }; export var activateNextResizeArea = function activateNextResizeArea(_ref2) { var direction = _ref2.direction, ariaNotify = _ref2.ariaNotify, getIntl = _ref2.getIntl, nodeViewPortalProviderAPI = _ref2.nodeViewPortalProviderAPI; return function (state, dispatch, view) { var _ref3 = getTableResizingPluginState(state) || {}, resizeHandlePos = _ref3.resizeHandlePos; // If No resizing has initiated, skip to regular handler if (!resizeHandlePos) { return false; } var selection = state.selection; var cell = findCellClosestToPos(selection.$from); if (!cell) { // cursor position may be changed by mouse to be outside of table; return false; } var $currentCell = state.doc.resolve(resizeHandlePos); if (!$currentCell) { return false; } var tableNode = $currentCell.node(-1); var closestTable = findTableClosestToPos($currentCell); var tableMap = TableMap.get(tableNode); if (!tableNode || !closestTable || !tableMap) { return false; } var currentCellRect = tableMap.findCell($currentCell.pos - $currentCell.start(-1)); var $nextCell = nextCell($currentCell, 'horiz', direction); if (ariaNotify && getIntl) { if (direction === 1) { ariaNotify(getIntl().formatMessage(messages.focusedOtherResize, { direction: 'right' }), { priority: 'important' }); } if (direction === -1) { ariaNotify(getIntl().formatMessage(messages.focusedOtherResize, { direction: 'left' }), { priority: 'important' }); } } if ($nextCell) { // we are somewhere in between the side columns of the table var offset = $nextCell.pos - $nextCell.start(-1); var rectForNextCell = tableMap.findCell(offset); return updateResizeHandleAndStatePosition(rectForNextCell.top, rectForNextCell.right, $nextCell.pos, nodeViewPortalProviderAPI)(state, dispatch, view); } else { // current position is in the one of the side columns of the table(left or right) if (currentCellRect.left === 0) { var lastCellInCurrentRow = tableMap.positionAt(currentCellRect.top, tableMap.width - 1, tableNode) + closestTable.start; var $lastCell = state.doc.resolve(lastCellInCurrentRow); return updateResizeHandleAndStatePosition(currentCellRect.top, tableMap.width, $lastCell.pos, nodeViewPortalProviderAPI)(state, dispatch, view); } else if (tableMap.width === currentCellRect.right) { var firsCellInCurrentRow = tableMap.positionAt(currentCellRect.top, 0, tableNode) + closestTable.start; var _$nextCell = state.doc.resolve(firsCellInCurrentRow); return updateResizeHandleAndStatePosition(currentCellRect.top, 1, _$nextCell.pos, nodeViewPortalProviderAPI)(state, dispatch); } } return false; }; }; export var changeColumnWidthByStep = function changeColumnWidthByStep(_ref4) { var stepSize = _ref4.stepSize, getEditorContainerWidth = _ref4.getEditorContainerWidth, isTableScalingEnabled = _ref4.isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled = _ref4.isTableFixedColumnWidthsOptionEnabled, isCommentEditor = _ref4.isCommentEditor, ariaNotify = _ref4.ariaNotify, api = _ref4.api, getIntl = _ref4.getIntl; return function (state, dispatch, view) { var _originalTable$attrs; var customTr = state.tr; var fakeDispatch = function fakeDispatch(tr) { customTr = tr; }; var _getTableResizingPlug = getTableResizingPluginState(state), resizeHandlePos = _getTableResizingPlug.resizeHandlePos; var cell = findCellClosestToPos(state.selection.$from); if (!view || !resizeHandlePos || !cell) { return false; } var $cell = state.doc.resolve(resizeHandlePos); var tableStartPosition = $cell.start(-1); var originalTable = $cell.node(-1); var map = TableMap.get(originalTable); var domAtPos = view.domAtPos.bind(view); var colIndex = map.colCount($cell.pos - tableStartPosition) + ($cell.nodeAfter ? $cell.nodeAfter.attrs.colspan : 1) - 1; var dom = null; var domAtPosition = domAtPos(tableStartPosition); dom = domAtPosition.node instanceof HTMLTableElement ? domAtPosition.node : null; if (dom && dom.nodeName !== 'TABLE') { dom = dom.closest('table'); } var cellAttrs = cell === null || cell === void 0 ? void 0 : cell.node.attrs; var width = currentColWidth(view, cell === null || cell === void 0 ? void 0 : cell.pos, cellAttrs); tableResizingPluginCreateCommand({ type: 'SET_DRAGGING', data: { dragging: { startX: 0, startWidth: width } } })(state, fakeDispatch); var maxSize = getTableMaxWidth({ table: originalTable, tableStart: tableStartPosition, state: state, layout: originalTable.attrs.layout, getEditorContainerWidth: getEditorContainerWidth }); var isTableScalingEnabledOnCurrentTable = isTableScalingEnabled; var isTableScalingWithFixedColumnWidthsOptionEnabled = isTableScalingEnabled && isTableFixedColumnWidthsOptionEnabled; if (isTableScalingWithFixedColumnWidthsOptionEnabled) { isTableScalingEnabledOnCurrentTable = originalTable.attrs.displayMode !== 'fixed'; } var shouldUseIncreasedScalingPercent = isTableScalingWithFixedColumnWidthsOptionEnabled; if (isTableScalingEnabled && isCommentEditor) { isTableScalingEnabledOnCurrentTable = true; shouldUseIncreasedScalingPercent = true; } var initialResizeState = getResizeState({ minWidth: tableCellMinWidth, maxSize: maxSize, table: originalTable, tableRef: dom, start: tableStartPosition, domAtPos: domAtPos, isTableScalingEnabled: isTableScalingEnabledOnCurrentTable, shouldUseIncreasedScalingPercent: shouldUseIncreasedScalingPercent, isCommentEditor: isCommentEditor }); updateControls()(state); var selectionRect = getSelectionRect(state.selection); var selectedColumns = selectionRect ? getSelectedColumnIndexes(selectionRect) : []; // only selected (or selected - 1) columns should be distributed var resizingSelectedColumns = selectedColumns.indexOf(colIndex) > -1 || selectedColumns.indexOf(colIndex + 1) > -1; var scalePercent = isTableScalingEnabled && isCommentEditor && !((_originalTable$attrs = originalTable.attrs) !== null && _originalTable$attrs !== void 0 && _originalTable$attrs.width) ? getScalingPercentForTableWithoutWidth(originalTable, dom) : getTableScalingPercent(originalTable, dom, shouldUseIncreasedScalingPercent); var newResizeState = resizeColumn(initialResizeState, colIndex, stepSize, dom, originalTable, resizingSelectedColumns ? selectedColumns : undefined, isTableScalingEnabled, scalePercent); customTr = updateColumnWidths(newResizeState, originalTable, tableStartPosition, api)(customTr); if (dispatch) { dispatch(customTr); } if (ariaNotify && getIntl) { ariaNotify(getIntl().formatMessage(messages.changedColumnWidth, { width: Math.floor(newResizeState.cols[colIndex].width) })); if (newResizeState.cols.length === colIndex + 1) { if (newResizeState.overflow === true) { ariaNotify(getIntl().formatMessage(messages.columnResizeLast), { priority: 'important' }); } if (newResizeState.overflow === false) { ariaNotify(getIntl().formatMessage(messages.columnResizeOverflow), { priority: 'important' }); } } } return true; }; }; export var stopKeyboardColumnResizing = function stopKeyboardColumnResizing(_ref5) { var ariaNotify = _ref5.ariaNotify, getIntl = _ref5.getIntl, originalTr = _ref5.originalTr; return function (state, dispatch) { var customTr = originalTr || state.tr; var fakeDispatch = function fakeDispatch(tr) { customTr = tr; }; var decorationWithoutWidget = clearColumnResizingDecorations()({ tr: customTr, decorationSet: getDecorations(state) }); var decorationWithoutWidgetAndHandle = updateDecorations(customTr.doc, decorationWithoutWidget, [], TableDecorations.COLUMN_RESIZING_HANDLE_LINE); getTablePluginCommand({ type: 'STOP_KEYBOARD_COLUMN_RESIZE', data: { decorationSet: decorationWithoutWidgetAndHandle } }, customTr)(state, fakeDispatch); tableResizingPluginCreateCommand({ type: 'STOP_RESIZING' }, function () { return customTr.setMeta('scrollIntoView', false); })(state, fakeDispatch); if (ariaNotify && getIntl) { ariaNotify(getIntl().formatMessage(messages.columnResizeStop), { priority: 'important' }); } if (dispatch) { dispatch(customTr); return true; } return false; }; };