Files
outline/shared/editor/nodes/TableCell.ts

122 lines
3.5 KiB
TypeScript

import Token from "markdown-it/lib/token";
import { NodeSpec } from "prosemirror-model";
import { Plugin } from "prosemirror-state";
import {
isTableSelected,
isRowSelected,
getCellsInColumn,
selectRow,
selectTable,
} from "prosemirror-utils";
import { DecorationSet, Decoration } from "prosemirror-view";
import Node from "./Node";
export default class TableCell extends Node {
get name() {
return "td";
}
get schema(): NodeSpec {
return {
content: "(paragraph | embed)+",
tableRole: "cell",
isolating: true,
parseDOM: [{ tag: "td" }],
toDOM(node) {
return [
"td",
node.attrs.alignment
? { style: `text-align: ${node.attrs.alignment}` }
: {},
0,
];
},
attrs: {
colspan: { default: 1 },
rowspan: { default: 1 },
alignment: { default: null },
},
};
}
toMarkdown() {
// see: renderTable
}
parseMarkdown() {
return {
block: "td",
getAttrs: (tok: Token) => ({ alignment: tok.info }),
};
}
get plugins() {
return [
new Plugin({
props: {
decorations: (state) => {
const { doc, selection } = state;
const decorations: Decoration[] = [];
const cells = getCellsInColumn(0)(selection);
if (cells) {
cells.forEach(({ pos }, index) => {
if (index === 0) {
decorations.push(
Decoration.widget(pos + 1, () => {
let className = "grip-table";
const selected = isTableSelected(selection);
if (selected) {
className += " selected";
}
const grip = document.createElement("a");
grip.className = className;
grip.addEventListener("mousedown", (event) => {
event.preventDefault();
event.stopImmediatePropagation();
this.editor.view.dispatch(selectTable(state.tr));
});
return grip;
})
);
}
decorations.push(
Decoration.widget(pos + 1, () => {
const rowSelected = isRowSelected(index)(selection);
let className = "grip-row";
if (rowSelected) {
className += " selected";
}
if (index === 0) {
className += " first";
}
if (index === cells.length - 1) {
className += " last";
}
const grip = document.createElement("a");
grip.className = className;
grip.addEventListener("mousedown", (event) => {
event.preventDefault();
event.stopImmediatePropagation();
this.editor.view.dispatch(
selectRow(
index,
event.metaKey || event.shiftKey
)(state.tr)
);
});
return grip;
})
);
});
}
return DecorationSet.create(doc, decorations);
},
},
}),
];
}
}