chore: Move editor into codebase (#2930)
This commit is contained in:
114
shared/editor/nodes/TableCell.ts
Normal file
114
shared/editor/nodes/TableCell.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import Token from "markdown-it/lib/token";
|
||||
import { NodeSpec } from "prosemirror-model";
|
||||
import { Plugin } from "prosemirror-state";
|
||||
import {
|
||||
isTableSelected,
|
||||
isRowSelected,
|
||||
getCellsInColumn,
|
||||
} 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+",
|
||||
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.options.onSelectTable(state);
|
||||
});
|
||||
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.options.onSelectRow(index, state);
|
||||
});
|
||||
return grip;
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return DecorationSet.create(doc, decorations);
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user