resources/js/wysiwyg/lexical/table/LexicalTableRowNode.ts
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import type {Spread} from 'lexical';
import {addClassNamesToElement} from '@lexical/utils';
import {
$applyNodeReplacement,
DOMConversionMap,
DOMConversionOutput,
EditorConfig,
ElementNode,
LexicalNode,
NodeKey,
SerializedElementNode,
} from 'lexical';
import {PIXEL_VALUE_REG_EXP} from './constants';
export type SerializedTableRowNode = Spread<
{
height?: number;
},
SerializedElementNode
>;
/** @noInheritDoc */
export class TableRowNode extends ElementNode {
/** @internal */
__height?: number;
static getType(): string {
return 'tablerow';
}
static clone(node: TableRowNode): TableRowNode {
return new TableRowNode(node.__height, node.__key);
}
static importDOM(): DOMConversionMap | null {
return {
tr: (node: Node) => ({
conversion: $convertTableRowElement,
priority: 0,
}),
};
}
static importJSON(serializedNode: SerializedTableRowNode): TableRowNode {
return $createTableRowNode(serializedNode.height);
}
constructor(height?: number, key?: NodeKey) {
super(key);
this.__height = height;
}
exportJSON(): SerializedTableRowNode {
return {
...super.exportJSON(),
...(this.getHeight() && {height: this.getHeight()}),
type: 'tablerow',
version: 1,
};
}
createDOM(config: EditorConfig): HTMLElement {
const element = document.createElement('tr');
if (this.__height) {
element.style.height = `${this.__height}px`;
}
addClassNamesToElement(element, config.theme.tableRow);
return element;
}
isShadowRoot(): boolean {
return true;
}
setHeight(height: number): number | null | undefined {
const self = this.getWritable();
self.__height = height;
return this.__height;
}
getHeight(): number | undefined {
return this.getLatest().__height;
}
updateDOM(prevNode: TableRowNode): boolean {
return prevNode.__height !== this.__height;
}
canBeEmpty(): false {
return false;
}
canIndent(): false {
return false;
}
}
export function $convertTableRowElement(domNode: Node): DOMConversionOutput {
const domNode_ = domNode as HTMLTableCellElement;
let height: number | undefined = undefined;
if (PIXEL_VALUE_REG_EXP.test(domNode_.style.height)) {
height = parseFloat(domNode_.style.height);
}
return {node: $createTableRowNode(height)};
}
export function $createTableRowNode(height?: number): TableRowNode {
return $applyNodeReplacement(new TableRowNode(height));
}
export function $isTableRowNode(
node: LexicalNode | null | undefined,
): node is TableRowNode {
return node instanceof TableRowNode;
}