mdx-editor / editor

A rich text editor React component for markdown
https://mdxeditor.dev
MIT License
1.91k stars 145 forks source link

[BUG] Admonition editor autofocuses #314

Open dave-db opened 9 months ago

dave-db commented 9 months ago

If you have any admonitions/directives on the page (like tip, info, note etc), the admonition editor autofocuses on load of the editor (and will scroll the page if necessary). This is irrespective of the editor's autofocus prop setting.

Describe the bug Loading a markdown document with an admonition will jump the browser's focus to the admonition's text area on page load.

Reproduction

## Heading

- We just
- need
- enough
- text 
- to
- scroll 
- off 
- the bottom
- of 
- the page
- when the 
- editor loads

## And another thing

A couple of big images would probably help here

> But it depends on how tall the editor component is really

:::note
This is the text inside the admonition, and when the editor loads it will be autofocused and will scroll the editor down if it was out of the viewport
:::

To Reproduce Steps to reproduce the behavior: Try the markdown above

Expected behavior No focus inside the editor, even if autofocus is set on the parent Editor component

Screenshots

Desktop (please complete the following information): Operating System: Platform: darwin Arch: x64 Version: Darwin Kernel Version 22.6.0: Fri Sep 15 13:39:52 PDT 2023; root:xnu-8796.141.3.700.8~1/RELEASE_X86_64 Binaries: Node: 20.10.0 npm: 10.2.3 Relevant Packages: next: 14.0.4 eslint-config-next: 14.0.4 react: 18.2.0 react-dom: 18.2.0 typescript: 5.3.3

Chrome 119 mdx-editor @ 2.3.4

petyosi commented 9 months ago

@dave-db I tested what you're describing here - https://codesandbox.io/p/sandbox/mdx-editor-with-admonitions-ftc9rx?file=%2Fsrc%2FApp.tsx. I can't seem to get the editor to steal the focus, is there anything else that has to be done? Perhaps setting the markdown at a later stage? I've seen such behavior before on a root level.

lucas-vitrus commented 5 months ago

I actually just got the same issue here

https://github.com/mdx-editor/editor/assets/133435610/3a772e37-19f4-48be-b169-22675c84213a

Code:

 /* Descriptor */
  const CalloutDirectiveDescriptor: DirectiveDescriptor = {
    name: "callout",
    testNode(node) {
      return node.name === "callout";
    },
    // set some attribute names to have the editor display a property editor popup.
    attributes: [],
    // used by the generic editor to determine whether or not to render a nested editor.
    hasChildren: true,
    Editor: (props) => {
      const inputRef = useRef<InputRef>(null);
      useEffect(() => {
        if (inputRef) inputRef.current?.focus();
      }, []);
      return (
        <div
          style={{
            border: `1.5pt dashed ${token.colorBorder}`,
            padding: 8,
            marginTop: token.margin,
            marginBottom: token.margin,
            borderRadius: token.borderRadius,
            // background: token.colorSuccessBg,
            paddingBottom: 22,
          }}
        >
          <Text type="secondary">
            <Brain /> When to use this tool
          </Text>
          <NestedLexicalEditor<TextDirective>
            block
            getContent={(node) => node.children}
            getUpdatedMdastNode={(mdastNode, children: any) => {
              return { ...mdastNode, children };
            }}
          />
          {/* <Input.TextArea
            ref={inputRef}
            rows={4}
            maxLength={100}
            showCount
            style={{
              border: `none`,
              // background: `none`,
              resize: "none",
            }}
          /> */}
        </div>
      );
    },
  };

   /* Button */
  const CustomButton = () => {
    // grab the insertDirective action (a.k.a. publisher) from the
    // state management system of the directivesPlugin
    const insertDirective = usePublisher(insertDirective$);

    return (
      <ButtonWithTooltip
        title={"Restricted content markup"}
        onClick={() =>
          insertDirective({
            name: "callout",
            type: "textDirective",
          })
        }
      >
        <Brain />
      </ButtonWithTooltip>
    );
  };

    <MDXEditor
          className={
                  state.darkTheme ? "dark-theme dark-editor" : "light-theme"
           }
                ref={editorRef}
                markdown={content}
                onChange={onChangeContent}
                plugins={[
                  directivesPlugin({
                    directiveDescriptors: [
                      AdmonitionDirectiveDescriptor,
                      CalloutDirectiveDescriptor,
                    ],
                  }),
                  quotePlugin(),
                  headingsPlugin(),
                  codeBlockPlugin({
                    defaultCodeBlockLanguage: "js",
                  }),
                  listsPlugin(),
                  codeMirrorPlugin({
                    codeBlockLanguages: { js: "JavaScript" },
                  }),
                  markdownShortcutPlugin(),

                  thematicBreakPlugin(),
                  tablePlugin(),
                  frontmatterPlugin(),

                  toolbarPlugin({
                    toolbarContents: () => (
                      <>
                        <BoldItalicUnderlineToggles />
                        <ListsToggle />
                        <Separator />
                        <InsertFrontmatter />
                        <InsertTable />
                        <InsertAdmonition />
                        <CustomButton />
                      </>
                    ),
                  }),
                ]}
              />
lucas-vitrus commented 5 months ago

Update

if I turn off the "controlled mode":

 <MDXEditor
 // onChange={onChangeContent} // 👈 commented out and no more autofocus issue.. but now I can't update my component :(
//...
/>
petyosi commented 5 months ago

@lucas-vitrus can you help me with a sandbox? I will take a look.