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
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
import { Command, Transaction } from "prosemirror-state";
|
||||
|
||||
export default function chainTransactions(...commands: Command[]): Command {
|
||||
/**
|
||||
* Chain multiple commands into a single command and collects state as it goes.
|
||||
*
|
||||
* @param commands The commands to chain
|
||||
* @returns The chained command
|
||||
*/
|
||||
export function chainTransactions(
|
||||
...commands: (Command | undefined)[]
|
||||
): Command {
|
||||
return (state, dispatch): boolean => {
|
||||
const dispatcher = (tr: Transaction): void => {
|
||||
state = state.apply(tr);
|
||||
dispatch?.(tr);
|
||||
};
|
||||
const last = commands.pop();
|
||||
const reduced = commands.reduce(
|
||||
(result, command) => result || command(state, dispatcher),
|
||||
false
|
||||
);
|
||||
return reduced && last !== undefined && last(state, dispatch);
|
||||
commands.map((command) => command?.(state, dispatcher));
|
||||
return last !== undefined && last(state, dispatch);
|
||||
};
|
||||
}
|
||||
|
||||
67
shared/editor/lib/table.ts
Normal file
67
shared/editor/lib/table.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Attrs, Node } from "prosemirror-model";
|
||||
import { MutableAttrs } from "prosemirror-tables";
|
||||
import { TableLayout } from "../types";
|
||||
|
||||
export interface TableAttrs {
|
||||
layout: TableLayout | null;
|
||||
}
|
||||
|
||||
export interface CellAttrs {
|
||||
colspan: number;
|
||||
rowspan: number;
|
||||
colwidth: number[] | null;
|
||||
alignment: "center" | "left" | "right" | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get cell attributes from a DOM node, used when pasting table content.
|
||||
*
|
||||
* @param dom DOM node to get attributes from
|
||||
* @returns Cell attributes
|
||||
*/
|
||||
export function getCellAttrs(dom: HTMLElement | string): Attrs {
|
||||
if (typeof dom === "string") {
|
||||
return {};
|
||||
}
|
||||
|
||||
const widthAttr = dom.getAttribute("data-colwidth");
|
||||
const widths =
|
||||
widthAttr && /^\d+(,\d+)*$/.test(widthAttr)
|
||||
? widthAttr.split(",").map((s) => Number(s))
|
||||
: null;
|
||||
const colspan = Number(dom.getAttribute("colspan") || 1);
|
||||
return {
|
||||
colspan,
|
||||
rowspan: Number(dom.getAttribute("rowspan") || 1),
|
||||
colwidth: widths && widths.length === colspan ? widths : null,
|
||||
alignment:
|
||||
dom.style.textAlign === "center"
|
||||
? "center"
|
||||
: dom.style.textAlign === "right"
|
||||
? "right"
|
||||
: null,
|
||||
} satisfies CellAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to serialize cell attributes on a node, used when copying table content.
|
||||
*
|
||||
* @param node Node to get attributes from
|
||||
* @returns Attributes for the cell
|
||||
*/
|
||||
export function setCellAttrs(node: Node): Attrs {
|
||||
const attrs: MutableAttrs = {};
|
||||
if (node.attrs.colspan !== 1) {
|
||||
attrs.colspan = node.attrs.colspan;
|
||||
}
|
||||
if (node.attrs.rowspan !== 1) {
|
||||
attrs.rowspan = node.attrs.rowspan;
|
||||
}
|
||||
if (node.attrs.colwidth) {
|
||||
attrs["data-colwidth"] = node.attrs.colwidth.join(",");
|
||||
}
|
||||
if (node.attrs.alignment) {
|
||||
attrs.style = `text-align: ${node.attrs.alignment}`;
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
Reference in New Issue
Block a user