UNPKG

phx-react

Version:

PHX REACT

180 lines • 6.24 kB
/** * 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 { DecoratorNode } from 'lexical'; import * as React from 'react'; import { Suspense } from 'react'; export const cellHTMLCache = new Map(); export const cellTextContentCache = new Map(); const emptyEditorJSON = '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}'; const plainTextEditorJSON = (text) => text === '' ? emptyEditorJSON : `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":${text},"type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`; const TableComponent = React.lazy( // @ts-ignore () => import('./TableComponent')); export function createUID() { return Math.random() .toString(36) .replace(/[^a-z]+/g, '') .substr(0, 5); } function createCell(type) { return { colSpan: 1, id: createUID(), json: emptyEditorJSON, type, width: null, }; } export function createRow() { return { cells: [], height: null, id: createUID(), }; } export function extractRowsFromHTML(tableElem) { const rowElems = tableElem.querySelectorAll('tr'); const rows = []; for (let y = 0; y < rowElems.length; y++) { const rowElem = rowElems[y]; const cellElems = rowElem.querySelectorAll('td,th'); if (!cellElems || cellElems.length === 0) { continue; } const cells = []; for (let x = 0; x < cellElems.length; x++) { const cellElem = cellElems[x]; const isHeader = cellElem.nodeName === 'TH'; const cell = createCell(isHeader ? 'header' : 'normal'); cell.json = plainTextEditorJSON(JSON.stringify(cellElem.innerText.replace(/\n/g, ' '))); cells.push(cell); } const row = createRow(); row.cells = cells; rows.push(row); } return rows; } function convertTableElement(domNode) { const rowElems = domNode.querySelectorAll('tr'); if (!rowElems || rowElems.length === 0) { return null; } const rows = []; for (let y = 0; y < rowElems.length; y++) { const rowElem = rowElems[y]; const cellElems = rowElem.querySelectorAll('td,th'); if (!cellElems || cellElems.length === 0) { continue; } const cells = []; for (let x = 0; x < cellElems.length; x++) { const cellElem = cellElems[x]; const isHeader = cellElem.nodeName === 'TH'; const cell = createCell(isHeader ? 'header' : 'normal'); cell.json = plainTextEditorJSON(JSON.stringify(cellElem.innerText.replace(/\n/g, ' '))); cells.push(cell); } const row = createRow(); row.cells = cells; rows.push(row); } return { node: $createTableNode(rows) }; } export function exportTableCellsToHTML(rows, rect) { const table = document.createElement('table'); const colGroup = document.createElement('colgroup'); const tBody = document.createElement('tbody'); const firstRow = rows[0]; for (let x = rect != null ? rect.startX : 0; x < (rect != null ? rect.endX + 1 : firstRow.cells.length); x++) { const col = document.createElement('col'); colGroup.append(col); } for (let y = rect != null ? rect.startY : 0; y < (rect != null ? rect.endY + 1 : rows.length); y++) { const row = rows[y]; const cells = row.cells; const rowElem = document.createElement('tr'); for (let x = rect != null ? rect.startX : 0; x < (rect != null ? rect.endX + 1 : cells.length); x++) { const cell = cells[x]; const cellElem = document.createElement(cell.type === 'header' ? 'th' : 'td'); cellElem.innerHTML = cellHTMLCache.get(cell.json) || ''; rowElem.appendChild(cellElem); } tBody.appendChild(rowElem); } table.appendChild(colGroup); table.appendChild(tBody); return table; } export class TableNode extends DecoratorNode { static getType() { return 'tablesheet'; } static clone(node) { return new TableNode(Array.from(node.__rows), node.__key); } static importJSON(serializedNode) { return $createTableNode(serializedNode.rows); } exportJSON() { return { rows: this.__rows, type: 'tablesheet', version: 1, }; } static importDOM() { return { // eslint-disable-next-line @typescript-eslint/no-unused-vars table: (_node) => ({ conversion: convertTableElement, priority: 0, }), }; } exportDOM() { return { element: exportTableCellsToHTML(this.__rows) }; } constructor(rows, key) { super(key); this.__rows = rows || []; } createDOM() { return document.createElement('div'); } updateDOM() { return false; } decorate(_, config) { return (React.createElement(Suspense, null, React.createElement(TableComponent, { nodeKey: this.__key, rows: this.__rows, theme: config.theme }))); } isInline() { return false; } } export function $isTableNode(node) { return node instanceof TableNode; } export function $createTableNode(rows) { return new TableNode(rows); } export function $createTableNodeWithDimensions(rowCount, columnCount, includeHeaders = true) { const rows = []; for (let y = 0; y < columnCount; y++) { const row = createRow(); rows.push(row); for (let x = 0; x < rowCount; x++) { row.cells.push(createCell(includeHeaders === true && (y === 0 || x === 0) ? 'header' : 'normal')); } } return new TableNode(rows); } //# sourceMappingURL=TableNode.js.map