ozanyurtsever/verbum

Allow access to LexicalComposerContext

Nicolas-PredictaLab opened this issue · 4 comments

Is your feature request related to a problem? Please describe.
For some plugins, we need to access editor from useLexicalComposerContext() - How to do that ?
For example, the FloatingLinkEditor needs it.

Describe the solution you'd like
Being able to access it like with vanilla Lexical : const [editor] = useLexicalComposerContext() - Or tell us how to access own Verbum one ?

Perhaps it helps.
Seems related to #8.
If you want to get editor instance, you should use onChange prop.
There is onChange interface.

Example (i use it for $convertToMarkdownString Lexical plugin):

type EditorState = {
  editorState: string
  editorInstance?: LexicalEditor
}

const Editor = () => {
  const [editorState, setEditorState] = useState<EditorState>({ editorState: '' })

  return(
    <EditorComposer>
      <Editor
        onChange={(editorState, editorInstance) => {
          setEditorState({ editorState, editorInstance })
        }}
      >
        <ToolbarPlugin defaultFontSize="20px">
          <BoldButton />
          <ItalicButton />
          <UnderlineButton />
          <CodeFormatButton />
          <InsertLinkButton />
          <Divider />
          <AlignDropdown />
        </ToolbarPlugin>
      </Editor>
    </EditorComposer>
  )
}

Ok I see, that's totally related.
I still have an issue with editorState.editorInstance still could be undefined according to Typescript.. I might miss a thing.

type EditorState = {
  editorState: string
  editorInstance?: LexicalEditor
}

const NoteViewer = (): JSX.Element => {
  const [editorState, setEditorState] = useState<EditorState>({
    editorState: '',
  })

  return (
    <EditorComposer>
      <Editor
        actionsEnabled
        onChange={(editorState, editorInstance) => {
          setEditorState({editorState, editorInstance})
        }}
      >
        <ToolbarPlugin defaultFontSize="20px">
          
          {editorState.editorInstance && (
            <FloatingLinkEditor editor={editorState.editorInstance} />
          )}

          <FontFamilyDropdown />
          <FontSizeDropdown />
          <Divider />
          <BoldButton />
          <ItalicButton />
          <UnderlineButton />
          <CodeFormatButton />
          <InsertLinkButton />
          <TextColorPicker />
          <BackgroundColorPicker />
          <TextFormatDropdown />
          <Divider />
          <InsertDropdown
            enableTwitter
            enableYoutube
            enableHorizontalRule
            enableImage
            enableStickyNote
            enableTable
          />
          <Divider />
          <AlignDropdown />
        </ToolbarPlugin>
      </Editor>
    </EditorComposer>
  )
}

export default NoteViewer

Typescript error :

Cannot assign type 'Element | undefined' to type 'ReactElement<any, string | JSXElementConstructor<any>>'.
Cannot assign type 'undefined' to type 'ReactElement<any, string | JSXElementConstructor<any>>'.ts(2322)

I don't know what is FloatingLinkEditor, but i see that you trying to check editorState.editorInstance for no undefined. And you can't reach that with && construction.

It gives you JSX.Element | undefined type:
image

But ToolbarPlugin waiting for children?: React.ReactElement | React.ReactElement[]; type.

I can suggest you some solutions.

  1. create some verify function with type definition, like this:
  const someFunction = (): React.ReactElement => {
    if (editorState.editorInstance !== undefined) {
      return <FloatingLinkEditor editor={editorState.editorInstance} />
    } else {
      return <></>
    }
  }

  <ToolbarPlugin defaultFontSize="20px">
    {someFunction()}
    <BoldButton />
    <ItalicButton />
    <UnderlineButton />
    <CodeFormatButton />
    <InsertLinkButton />
    <Divider />
    <AlignDropdown />
  </ToolbarPlugin>
  1. or use ternary operator, like this:
  <ToolbarPlugin defaultFontSize="20px">
    {editorState.editorInstance ? <FloatingLinkEditor editor={editorState.editorInstance} /> : <></>}
    <BoldButton />
    <ItalicButton />
    <UnderlineButton />
    <CodeFormatButton />
    <InsertLinkButton />
    <Divider />
    <AlignDropdown />
  </ToolbarPlugin>

Maybe this is not the best solutions, hope it's helps.

Oh ok cool, I'll test. this.
FloatingLinkEditor is a plugin in the Verbum doc, don't know yet what the purpose of it.
image