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.19k stars 160 forks source link

Header links not working under react-router #356

Open yusuf-kh opened 2 years ago

yusuf-kh commented 2 years ago

Hi

The headers are currently rendered by using anchor tags. However, and as expected, these won't work if they are under a react-router path. Is there a way to replace all anchor links in the markdown with react-router's Link tag?

jaywcjlove commented 2 years ago

I disabled it, did you show it?

@yusuf-kh

jaywcjlove commented 2 years ago

https://github.com/uiwjs/react-markdown-preview#options-props

You need to write a rehype plugin

strawhatgami commented 2 years ago

Quick & dirty rehype plugin to restore onClick() behaviour on anchors when using react-router:

import {visit} from 'unist-util-visit';

const onNode = (node) => {
  if (node.tagName != 'a' || typeof node.properties?.href !== 'string') {
    return;
  };

  const url = node.properties.href;
  if (!url.startsWith('#')) return;

  node.properties.onClick = (e) => {
    e.preventDefault();

    // Show anchor change in address bar
    history.pushState({}, "", url);

    // Scroll to anchor
    const hash = url.replace('#', '');
    const id = decodeURIComponent(hash);
    const element = document.getElementById(id);

    if (!element) return;
    element.scrollIntoView();
  };
}

export default function rehypeAnchorOnClick() {
  return (tree) => {
    visit(tree, 'element', onNode)
  }
}

To use:

import rehypeAnchorOnClick from './rehypeAnchorOnClickPlugin';
...
      <MDEditor.Markdown 
        source={value}
        rehypePlugins={[[rehypeAnchorOnClick]]}
      />

Note: doesn't work well with rehype-sanitize, but OK with rehype-slug

jMoulis commented 1 year ago

@strawhatgami Hello, I tried the plugin you've wrote but I have a log error telling me that Warning: Expected onClick listener to be a function, instead got a value of string type. Did you had the same error?