facebook / lexical

Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.
https://lexical.dev
MIT License
19.95k stars 1.7k forks source link

Bug: Unable to override ListItemNode #6807

Closed NiketaNraval90 closed 2 weeks ago

NiketaNraval90 commented 2 weeks ago

Adding Style into ListItemNode

ExtendedListItemNode.jsx


import { ListItemNode } from '@lexical/list';
import { $applyNodeReplacement } from 'lexical';

export class ExtendedListItemNode extends ListItemNode {
  __style;

  static clone(node) {
    return new ExtendedListItemNode(node.__value, node.__checked, node.__key);
  }

  constructor(value, checked, key) {
    super(key);
    this.__value = value === undefined ? 1 : value;
    this.__checked = checked;
  }

  static getType() {
    return 'extended-listitem';
  }

  getStyle() {
    const self = this.getLatest();
    return self.__style;
  }

  setStyle(style) {
    const self = this.getWritable();
    self.__style = style;
    return self;
  }

  static importDOM() {
    return {
      li: () => ({
        conversion: $convertListItemElement,
        priority: 1
      })
    };
  }

  exportJSON() {
    return {
      ...super.exportJSON(),
      checked: this.getChecked(),
      type: 'extended-listitem',
      value: this.getValue(),
      version: 1
    };
  }
}

function $convertListItemElement(domNode) {
  const ariaCheckedAttr = domNode.getAttribute('aria-checked');
  const checked = ariaCheckedAttr === 'true' ? true : ariaCheckedAttr === 'false' ? false : undefined;
  const node = $createListItemNode(checked);
  node.setStyle(domNode.style.cssText);
  return {
    node
  };
}

export function $createListItemNode(checked) {
  return $applyNodeReplacement(new ExtendedListItemNode(undefined, checked));
}

export function $isListItemNode(node) {
  return node instanceof ExtendedListItemNode;
}

Replace Node

const initialConfig = {
    editorState: null,
    namespace: 'Theme',
    editable,
    nodes: [
      ...ThemeNodes,      
      ExtendedListItemNode,
      {replace: ListItemNode, with: (node) => new ExtendedListItemNode(node.__value, node.__checked, node.__key)}
    ],
    onError: (error) => {
      throw error;
    },
    theme: Theme,
  };

After press the enter below error will ocurre.

image

Error while adding content after

image

Can Anyone help me in this.

etrepum commented 2 weeks ago

The reason why it doesn't work is because you implemented the constructor incorrectly. There may be other bugs in your code as well, but that is why you're getting this helpful error message. The correct way to subclass is not to copy and paste the constructor's code, it's to call the super's constructor with the arguments that it is expecting.

ListItemNode's constructor has three arguments:

  constructor(value?: number, checked?: boolean, key?: NodeKey) {

In your constructor, you're calling it with one argument, which is the wrong type, and is in the wrong position (typescript would catch all of this):

  constructor(value, checked, key) {
    super(key);

The right solution would be to either delete the constructor in your subclass, because you don't actually have any code in there that's doing useful work, or to correctly call the constructor with all three arguments.

NiketaNraval90 commented 2 weeks ago

Hi

Thanks, its working now by changing below code and removing constructor.

nodes: [
      ...ThemeNodes,      
      ExtendedListItemNode,
      {replace: ListItemNode, with: (node) => new ExtendedListItemNode(node.__value, node.__checked)}
    ],