uiwjs / react-md-editor

A simple markdown editor with preview, implemented with React.js and TypeScript.
https://uiwjs.github.io/react-md-editor
MIT License
2.04k stars 149 forks source link

How to properly re-render components textarea? #554

Open RARgames opened 1 year ago

RARgames commented 1 year ago
  1. How to use properly use MDEditor components textarea to re-render the default textarea? or is there any other approach to achieve things below?
    • add textarea ref to manually set focus whenever I need
    • handle some of the events like capture when the certain char is entered and do something depending on the next chars (something like auto completion search with extra popup)
    • allow adding image to textarea just by using ctrl+v (similar to github)
  2. Additionally, how to change markdown preview to work like in github comments: enter = new line? I know that I can add white-space: pre-wrap;, but it looks bad for lists (I checked in github comments and it seems that they are adding <br> for every new line and it is hidden in the writing text area). Any suggestions?
jaywcjlove commented 1 year ago

@RARgames If you want to re-render the component textarea here is an example:

https://github.com/uiwjs/react-md-editor/issues/546#issuecomment-1616233862

add textarea ref to manually set focus whenever I need

https://codesandbox.io/embed/markdown-editor-for-react-https-github-com-uiwjs-react-md-editor-issues-554-ny6dcm?fontsize=14&hidenavigation=1&theme=dark

import React, { useRef } from "react";
import ReactDOM from "react-dom";
import MDEditor from "@uiw/react-md-editor";

const mkdStr = `
# Markdown Editor

---

**Hello world!!!**

[![](https://avatars.githubusercontent.com/u/1680273?s=80&v=4)](https://avatars.githubusercontent.com/u/1680273?v=4)

\`\`\`javascript
import React from "react";
import ReactDOM from "react-dom";
import MEDitor from '@uiw/react-md-editor';

\`\`\`
`;

function App() {
  const $edit = useRef();
  const [value, setValue] = React.useState(mkdStr);
  const click = () => {
    console.log("$edit:", $edit.current);
    $edit.current.focus();
  };
  return (
    <div className="container">
      <button onClick={click}>focus</button>
      <MDEditor
        ref={(node) => {
          if (node && node.textarea) {
            $edit.current = node.textarea;
          }
        }}
        height={200}
        value={value}
        onChange={setValue}
      />
    </div>
  );
}
RARgames commented 1 year ago

Thanks, the focus part works, however the re-render part is missing something. If I use it, it breaks live scrolling/synchronizing editor and preview.

Here is the code:

<MDEditor
        value={value}
        ref={(node) => {
          if (node && node.textarea) {
            textareaRef.current = node.textarea;
          }
        }}
        onChange={setValue}
        onBlur={handleBlur}
        height={400}
        maxHeight={650}
        onKeyDown={handleEditorKeyDown}
        preview="edit"
        textareaProps={{
          placeholder: t('common.enterDescription'),
          spellCheck: 'true',
        }}
        previewOptions={{
          rehypePlugins: [[rehypeSanitize]],
        }}
        commands={[...commands.getCommands(), help]}
        components={{
          // eslint-disable-next-line react/no-unstable-nested-components
          textarea: (props, opts) => {
            const { dispatch, onChange, useContext, shortcuts } = opts;
            return (
              <textarea
                // eslint-disable-next-line react/jsx-props-no-spreading
                {...props}
                onKeyDown={(e) => {
                  if (shortcuts && useContext) {
                    // eslint-disable-next-line no-shadow
                    const { commands, commandOrchestrator } = useContext;
                    if (commands) {
                      shortcuts(e, commands, commandOrchestrator);
                    }
                  }
                }}
                onChange={(e) => {
                  if (onChange) onChange(e);
                }}
              />
            );
          },
        }}
      />
senylin commented 7 months ago

@RARgames how to fix new line problem by part2

RARgames commented 7 months ago

@senylin I did:

    .wmde-markdown>p {
      white-space: pre-wrap;
    }

    .wmde-markdown>ul {
      white-space: normal;
    }

    .wmde-markdown>ul>li {
      white-space: pre-wrap;
    }

    .wmde-markdown>ol {
      white-space: normal;
    }

    .wmde-markdown>ol>li {
      white-space: pre-wrap;
    }

    .wmde-markdown>blockquote>p {
      white-space: pre-wrap;
    }

If something is missing you can find my full styles here: https://github.com/RARgames/4gaBoards/blob/main/client/src/styles.module.scss