2 * Copyright (c) Meta Platforms, Inc. and affiliates.
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
9 import type {Spread} from 'lexical';
11 import {addClassNamesToElement} from '@lexical/utils';
13 $applyNodeReplacement,
20 SerializedElementNode,
23 import {extractStyleMapFromElement, sizeToPixels, StyleMap} from "../../utils/dom";
25 export type SerializedTableRowNode = Spread<
27 styles: Record<string, string>,
34 export class TableRowNode extends ElementNode {
38 __styles: StyleMap = new Map();
40 static getType(): string {
44 static clone(node: TableRowNode): TableRowNode {
45 const newNode = new TableRowNode(node.__key);
46 newNode.__styles = new Map(node.__styles);
50 static importDOM(): DOMConversionMap | null {
52 tr: (node: Node) => ({
53 conversion: $convertTableRowElement,
59 static importJSON(serializedNode: SerializedTableRowNode): TableRowNode {
60 const node = $createTableRowNode();
62 node.setStyles(new Map(Object.entries(serializedNode.styles)));
67 constructor(key?: NodeKey) {
71 exportJSON(): SerializedTableRowNode {
73 ...super.exportJSON(),
76 styles: Object.fromEntries(this.__styles),
77 height: this.__height || 0,
81 createDOM(config: EditorConfig): HTMLElement {
82 const element = document.createElement('tr');
85 element.style.height = `${this.__height}px`;
88 for (const [name, value] of this.__styles.entries()) {
89 element.style.setProperty(name, value);
92 addClassNamesToElement(element, config.theme.tableRow);
97 isShadowRoot(): boolean {
101 getStyles(): StyleMap {
102 const self = this.getLatest();
103 return new Map(self.__styles);
106 setStyles(styles: StyleMap): void {
107 const self = this.getWritable();
108 self.__styles = new Map(styles);
111 setHeight(height: number): number | null | undefined {
112 const self = this.getWritable();
113 self.__height = height;
114 return this.__height;
117 getHeight(): number | undefined {
118 return this.getLatest().__height;
121 updateDOM(prevNode: TableRowNode): boolean {
122 return prevNode.__height !== this.__height
123 || prevNode.__styles !== this.__styles;
126 canBeEmpty(): false {
135 export function $convertTableRowElement(domNode: Node): DOMConversionOutput {
136 const rowNode = $createTableRowNode();
137 const domNode_ = domNode as HTMLElement;
139 const height = sizeToPixels(domNode_.style.height);
140 rowNode.setHeight(height);
142 if (domNode instanceof HTMLElement) {
143 rowNode.setStyles(extractStyleMapFromElement(domNode));
146 return {node: rowNode};
149 export function $createTableRowNode(): TableRowNode {
150 return $applyNodeReplacement(new TableRowNode());
153 export function $isTableRowNode(
154 node: LexicalNode | null | undefined,
155 ): node is TableRowNode {
156 return node instanceof TableRowNode;