UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

80 lines (78 loc) 2.71 kB
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { PluginKey } from '@atlaskit/editor-prosemirror/state'; import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view'; import { CellSelection } from '@atlaskit/editor-tables/cell-selection'; import { findCellClosestToPos } from '@atlaskit/editor-tables/utils'; import { TableCssClassName as ClassName } from '../../types'; const EMPTY_STATE = { cellPos: -1, decorationSet: DecorationSet.empty }; export const activeCellHighlightPluginKey = new PluginKey('tableActiveCellHighlight'); /** * Returns the position of the cell containing the cursor, or -1 if the cursor * is not in a table cell or the selection is a CellSelection. */ const getActiveCellPos = state => { if (state.selection instanceof CellSelection) { return -1; } try { const cell = findCellClosestToPos(state.selection.$from); return cell ? cell.pos : -1; } catch { return -1; } }; const buildState = (cellPos, state) => { if (cellPos === -1) { return EMPTY_STATE; } try { const cell = state.doc.nodeAt(cellPos); if (!cell) { return EMPTY_STATE; } const decoration = Decoration.node(cellPos, cellPos + cell.nodeSize, { class: ClassName.ACTIVE_CURSOR_CELL }); return { cellPos, decorationSet: DecorationSet.create(state.doc, [decoration]) }; } catch { return EMPTY_STATE; } }; export const createPlugin = () => { return new SafePlugin({ key: activeCellHighlightPluginKey, state: { init: (_, state) => { return buildState(getActiveCellPos(state), state); }, apply: (tr, prev, _oldState, newState) => { if (tr.docChanged) { // Doc changed — always rebuild since positions may have shifted return buildState(getActiveCellPos(newState), newState); } if (!tr.selectionSet) { // Neither doc nor selection changed — nothing to do return prev; } // Selection changed — only rebuild if cursor moved to a different cell const nextCellPos = getActiveCellPos(newState); if (nextCellPos === prev.cellPos) { return prev; } return buildState(nextCellPos, newState); } }, props: { decorations: state => { var _activeCellHighlightP, _activeCellHighlightP2; return (_activeCellHighlightP = (_activeCellHighlightP2 = activeCellHighlightPluginKey.getState(state)) === null || _activeCellHighlightP2 === void 0 ? void 0 : _activeCellHighlightP2.decorationSet) !== null && _activeCellHighlightP !== void 0 ? _activeCellHighlightP : DecorationSet.empty; } } }); };