Need to create a custom node to create heading1, formatted and normal fonts on choosing each button and created a custom node for it.
NewNode.js
import { ElementNode } from 'lexical';
export class NewNode extends ElementNode {
constructor(payload, key) {
super(key);
this._payload = payload;
}
createDOM(_config) {
const element = document.createElement(this._payload.type);
const keys = this._payload.theme.split('.');
// Use reduce to traverse the theme object dynamically
const className = keys.reduce((obj, key) => obj && obj[key] !== undefined ? obj[key] : undefined, _config.theme);
element.className = className;
return element;
}
static clone(node) {
return new NewNode(node._payload, node.__key);
}
updateDOM() {
return false;
}
exportJSON() {
return {
type: 'NewNode',
version: 1,
children: [],
format: '',
indent: 1,
direction: null
};
}
}
Plugin.js
import { useEffect } from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $setBlocksType } from '@lexical/selection';
import {
$getSelection,
createCommand
} from 'lexical';
import { NewNode } from '../NewNode';
export const NEW_FORMAT_COMMAND = createCommand('NEW_FORMAT_COMMAND');
export const $createNewNode = (payload) => new NewNode(payload);
export const StylePlugin = () => {
const [editor] = useLexicalComposerContext();
if (!editor.hasNode(NewNode)) {
throw new Error('"NewNode" does not register on editor!');
}
useEffect(() => {
return editor.registerCommand(
NEW_FORMAT_COMMAND,
(payload) => {
const selection = $getSelection();
$setBlocksType(selection, () => $createNewNode(payload));
return true;
},
1,
);
}, []);
return null;
};
Its working as expected when $createNewNode(payload) is replaced by $createHeadingNode('h1'). But I want to use the newNode to display the changes. However the enter key doesn't seem to be working with the newNode
I can't figure out why the issue is being caused. On pressing enter key, a new paragraph is supposed to be added.