Xandrios93
Xandrios93

Reputation: 2315

How can I integrate @lexical/table into the lexicalEditor from payload cms?

I've searched the web for a way to use tables in the slateEditor from payload and came to the solution, that I'm not able to to this.

Then I've checked if the lexical editor has tables integrated. The default editor from payload does not ship them, but with @lexer/table one should be able to activate the feature.

Initially i've compared what payload did with the list features and tried to copy it for the tables. At this time, it did not change the content.

After some time, I found the problem, which was different versions of @lexer/react and finally had a way to create a table.

I've found https://codesandbox.io/p/sandbox/lexical-table-plugin-example-thjo4z?file=%2Fsrc%2FEditor.js%3A53%2C44 which seems to be working, but has a lot of custom code and uses the default Lexical Editor

But i have no controls to edit the table structure afterwards, like in the provided sandbox example

Upvotes: 2

Views: 1668

Answers (1)

Ayman Ali
Ayman Ali

Reputation: 5

To integrate the @lexical/table plugin into the lexicalEditor from Payload CMS and ensure you have the necessary controls to edit the table structure, you'll need to follow these steps:

Step-by-Step Integration Step 1: Install Dependencies Make sure the necessary packages are installed:

npm install @lexical/react @lexical/table @lexical/utils

Step 2: Create Custom Plugins Create the necessary plugins and components for table functionality. Here's an example structure for a custom Toolbar and Table context.

plugins/TableToolbar.js Create a custom toolbar to add table-related controls.

import React from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { INSERT_TABLE_COMMAND } from '@lexical/table';

const TableToolbar = () => {
  const [editor] = useLexicalComposerContext();

  const insertTable = () => {
    editor.dispatchCommand(INSERT_TABLE_COMMAND, { rows: 3, columns: 3 });
  };

  return (
    <div className="toolbar">
      <button onClick={insertTable}>Insert Table</button>
      {/* Add more table controls as needed */}
    </div>
  );
};

export default TableToolbar;

plugins/TableCellActionMenuPlugin.js Create a custom plugin for table cell actions.

import React from 'react';

const TableCellActionMenuPlugin = ({ anchorElem }) => {
  // Implement the action menu functionality
  return <div>Table Cell Actions</div>;
};

export default TableCellActionMenuPlugin;

Step 3: Configure the Lexical Editor Integrate the plugins and components into the Lexical Editor configuration.

Editor.js Update the main Editor component to include table functionality.

import React, { useState } from 'react';
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table';
import ExampleTheme from './themes/ExampleTheme';
import ToolbarPlugin from './plugins/TableToolbar';
import TableCellActionMenuPlugin from './plugins/TableCellActionMenuPlugin';
import TableCellResizer from './plugins/TableCellResizer';

const editorConfig = {
  theme: ExampleTheme,
  onError(error) {
    throw error;
  },
  nodes: [TableCellNode, TableNode, TableRowNode],
};

const Editor = () => {
  const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);

  const onRef = (_floatingAnchorElem) => {
    if (_floatingAnchorElem !== null) {
      setFloatingAnchorElem(_floatingAnchorElem);
    }
  };

  return (
    <LexicalComposer initialConfig={editorConfig}>
      <div className="editor-container">
        <ToolbarPlugin />
        <TablePlugin />
        <TableCellResizer />
        <RichTextPlugin
          contentEditable={
            <div className="editor-input">
              <div className="editor" ref={onRef}>
                <ContentEditable className="ContentEditable__root" />
              </div>
            </div>
          }
          placeholder={<Placeholder />}
        />
      </div>
      {floatingAnchorElem && <TableCellActionMenuPlugin anchorElem={floatingAnchorElem} />}
    </LexicalComposer>
  );
};

const Placeholder = () => {
  return <div className="editor-placeholder">Play around with the table plugin...</div>;
};
export default Editor;

Step 4: Integrate with Payload CMS Ensure your custom Lexical Editor component is integrated within the Payload CMS. This usually involves configuring the rich text field in your collection to use your custom editor component.

collections/YourCollection.js Example configuration to use the custom Lexical Editor:

const YourCollection = {
  slug: 'your-collection',
  fields: [
    {
      name: 'content',
      type: 'richText',
      admin: {
        components: {
          Field: Editor, // Use your custom Editor component
        },
      },
    },
  ],
};
export default YourCollection;

This approach should give you the necessary table functionalities within the Payload CMS Lexical Editor, allowing you to insert and edit tables as needed.

Upvotes: -3

Related Questions