Files
outline/shared/editor/nodes/TableView.ts
Tom Moor da19054555 Table improvements (#6958)
* Header toggling, resizable columns

* Allow all blocks in table cells, disable column resizing in read-only

* Fixed dynamic scroll shadows

* Refactor, scroll styling

* fix scrolling, tweaks

* fix: Table layout lost on sort

* fix: Caching of grip decorators

* refactor

* stash

* fix first render shadows

* stash

* First add column grip, styles

* Just add column/row click handlers left

* fix: isTableSelected for single cell table

* Refactor mousedown handlers

* fix: 'Add row before' command missing on first row

* fix overflow on rhs

* fix: Error clicking column grip when menu is open

* Hide table controls when printing

* Restore table header background

* fix: Header behavior when adding columns and rows at the edges

* Tweak header styling

* fix: Serialize and parsing of column attributes when copy/pasting
fix: Column width is lost when changing column alignment
2024-05-31 14:52:39 -07:00

92 lines
2.6 KiB
TypeScript

import { Node } from "prosemirror-model";
import { TableView as ProsemirrorTableView } from "prosemirror-tables";
import { EditorStyleHelper } from "../styles/EditorStyleHelper";
import { TableLayout } from "../types";
export class TableView extends ProsemirrorTableView {
public constructor(public node: Node, public cellMinWidth: number) {
super(node, cellMinWidth);
this.dom.removeChild(this.table);
this.dom.classList.add(EditorStyleHelper.table);
// Add an extra wrapper to enable scrolling
this.scrollable = this.dom.appendChild(document.createElement("div"));
this.scrollable.appendChild(this.table);
this.scrollable.classList.add(EditorStyleHelper.tableScrollable);
this.scrollable.addEventListener(
"scroll",
() => {
this.updateClassList(this.node);
},
{
passive: true,
}
);
this.updateClassList(node);
// We need to wait for the next tick to ensure dom is rendered and scroll shadows are correct.
setTimeout(() => {
if (this.dom) {
this.updateClassList(node);
}
}, 0);
}
public override update(node: Node) {
this.updateClassList(node);
return super.update(node);
}
public override ignoreMutation(record: MutationRecord): boolean {
if (
record.type === "attributes" &&
record.target === this.dom &&
(record.attributeName === "class" || record.attributeName === "style")
) {
return true;
}
return (
record.type === "attributes" &&
(record.target === this.table || this.colgroup.contains(record.target))
);
}
private updateClassList(node: Node) {
this.dom.classList.toggle(
EditorStyleHelper.tableFullWidth,
node.attrs.layout === TableLayout.fullWidth
);
const shadowLeft = !!(this.scrollable && this.scrollable.scrollLeft > 0);
const shadowRight = !!(
this.scrollable &&
this.scrollable.scrollWidth > this.scrollable.clientWidth &&
this.scrollable.scrollLeft + this.scrollable.clientWidth <
this.scrollable.scrollWidth - 1
);
this.dom.classList.toggle(EditorStyleHelper.tableShadowLeft, shadowLeft);
this.dom.classList.toggle(EditorStyleHelper.tableShadowRight, shadowRight);
if (this.scrollable) {
this.dom.style.setProperty(
"--table-height",
`${this.scrollable?.clientHeight}px`
);
this.dom.style.setProperty(
"--table-width",
`${this.scrollable?.clientWidth}px`
);
} else {
this.dom.style.removeProperty("--table-height");
this.dom.style.removeProperty("--table-width");
}
}
private scrollable: HTMLDivElement | null = null;
}