UNPKG

@lexical/react

Version:

This package provides Lexical components and hooks for React applications.

92 lines (83 loc) • 3.08 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 { signal } from '@lexical/extension/signals'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { $isScrollableTablesActive, setScrollableTablesActive, registerTablePlugin, registerTableSelectionObserver, registerTableCellUnmergeTransform, TableCellNode } from '@lexical/table'; import { $fullReconcile } from 'lexical'; import { useEffect, useState } from 'react'; /** * 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. * */ /** * Props for the {@link TablePlugin} component. */ /** * A plugin to enable all of the features of Lexical's TableNode. * * @param props - See type for documentation * This is a legacy plugin. When building an editor with the extension API, * configure {@link TableExtension} instead. * * @returns An element to render in your LexicalComposer */ function TablePlugin({ hasCellMerge = true, hasCellBackgroundColor = true, hasTabHandler = true, hasHorizontalScroll = false, hasNestedTables = false }) { const [editor] = useLexicalComposerContext(); useEffect(() => { const hadHorizontalScroll = $isScrollableTablesActive(editor); if (hadHorizontalScroll !== hasHorizontalScroll) { setScrollableTablesActive(editor, hasHorizontalScroll); // Re-render existing tables through the new scroll-wrapper config without // cloning every TableNode the way marking them dirty would. A full // reconcile marks no nodes dirty, so it's deferred (no synchronous render // from this effect) and produces no history entry. editor.update($fullReconcile); } }, [editor, hasHorizontalScroll]); const hasNestedTablesSignal = usePropSignal(hasNestedTables); useEffect(() => registerTablePlugin(editor, { hasNestedTables: hasNestedTablesSignal }), [editor, hasNestedTablesSignal]); useEffect(() => registerTableSelectionObserver(editor, hasTabHandler), [editor, hasTabHandler]); // Unmerge cells when the feature isn't enabled useEffect(() => { if (!hasCellMerge) { return registerTableCellUnmergeTransform(editor); } }, [editor, hasCellMerge]); // Remove cell background color when feature is disabled useEffect(() => { if (hasCellBackgroundColor) { return; } return editor.registerNodeTransform(TableCellNode, node => { if (node.getBackgroundColor() !== null) { node.setBackgroundColor(null); } }); }, [editor, hasCellBackgroundColor, hasCellMerge]); return null; } function usePropSignal(value) { const [configSignal] = useState(() => signal(value)); if (configSignal.peek() !== value) { // eslint-disable-next-line react-hooks/immutability configSignal.value = value; } return configSignal; } export { TablePlugin };