steven-tey / novel

Notion-style WYSIWYG editor with AI-powered autocompletion.
https://novel.sh
Apache License 2.0
13.25k stars 1.08k forks source link

'Editor' cannot be used as a JSX component. #217

Closed arthureberledev closed 9 months ago

arthureberledev commented 1 year ago

Hey,

so I've been trying to create an PR that extends the editor by allowing to pass a ref to it:

const Editor = forwardRef<EditorRef, EditorProps>((props, forwardedRef) => {
   // Implementation
});

Editor.displayName = "Editor";

export default Editor;

But ever since I've implemented this, i get an type error in my frontend when trying to import this new component:

'Editor' cannot be used as a JSX component.
  Its type 'ForwardRefExoticComponent<EditorProps & RefAttributes<EditorRef>>' is not a valid JSX element type.
    Type 'ForwardRefExoticComponent<EditorProps & RefAttributes<EditorRef>>' is not assignable to type '(props: any, deprecatedLegacyContext?: any) => ReactNode'.
      Type 'ReactElement<any, string | JSXElementConstructor<any>> | null' is not assignable to type 'ReactNode'.
        Type 'ReactElement<any, string | JSXElementConstructor<any>>' is not assignable to type 'ReactNode'.
          Property 'children' is missing in type 'ReactElement<any, string | JSXElementConstructor<any>>' but required in type 'ReactPortal'.ts(2786)
index.d.ts(207, 9): 'children' is declared here.

I've already tried to update the @types/react dependency (btw. there are two of them), but this only leads to an type error in the library itself (with the same error message on the <EditorContent> Component...)

Can anyone help out with this error? Knows what could help?

andrewdoro commented 9 months ago

Hey I'll just move this to discussions. The library was also update with breaking change so now the Editor component looks like this

export type EditorContentProps = {
  children: React.ReactNode;
  className?: string;
  initialContent?: JSONContent;
} & Omit<EditorProviderProps, "content">;

export const EditorContent = ({
  className,
  children,
  initialContent,
  ...rest
}: EditorContentProps) => {
  const extensions = useMemo(() => {
    return [...simpleExtensions, ...(rest.extensions ?? [])];
  }, [rest.extensions]);

  return (
    <div className={className}>
      <EditorProvider {...rest} content={initialContent} extensions={extensions}>
        {children}
      </EditorProvider>
    </div>
  );
};