Valstar.dev

Markdown logo

A super simple and limited markdown React component


Many of the websites I make these days are internal facing and allow for quite a bit of user input. In a lot of these cases I would liek to give the users some ability to customize the content but not so much that they will break teh flow of the site.

To accomplish this you have a few choices, you can import a rich text editor like Quill or a markdown editor like React Markdown Editor; but these solutions are pretty large packages and often will give the user more functionallity then we really need.

So this is a solution that I often use in many of my projects (customized for each use case), try it out:

Editor

Preview

Title

Subtitle

  • list
  • list 2

and some more text that is styled a little bit yeah

export const Preview = ({ value }) => {
  // Clean any html from teh user
  const cleanValue = value.replace(/<\/?[^>]+(>|$)/gi, '');

  // ul - unorderd lists
  let final = cleanValue.replace(/^\s*\n\*/gm, '<ul>\n*');
  final = final.replace(/^(\*.+)\s*\n([^\*])/gm, '$1\n</ul>\n\n$2');
  final = final.replace(/^\*(.+)/gm, '<li>$1</li>');

  // ol - orderd lists
  final = final.replace(/^\s*\n\d\./gm, '<ol>\n1.');
  final = final.replace(/^(\d\..+)\s*\n([^\d\.])/gm, '$1\n</ol>\n\n$2');
  final = final.replace(/^\d\.(.+)/gm, '<li>$1</li>');

  // Headings
  final = final.replace(/[\#]{4}(.+)/g, '<h5>$1</h5>');
  final = final.replace(/[\#]{3}(.+)/g, '<h4>$1</h4>');
  final = final.replace(/[\#]{2}(.+)/g, '<h3>$1</h3>');
  final = final.replace(/[\#]{1}(.+)/g, '<h2>$1</h2>');

  // font styles: bold, italic, strikethrough
  final = final.replace(/[\*\_]{2}([^\*\_]+)[\*\_]{2}/g, '<b>$1</b>');
  final = final.replace(/[\*\_]{1}([^\*\_]+)[\*\_]{1}/g, '<i>$1</i>');
  final = final.replace(/[\~]{2}([^\~]+)[\~]{2}/g, '<del>$1</del>');

  // final pass for paragraphs
  final = final.replace(/^\s*(\n)?(.+)/gm, function (m) {
    return /\<(\/)?(h\d|ul|ol|li|blockquote|pre|img)/.test(m) ? m : '<p>' + m + '</p>';
  });

  return <div dangerouslySetInnerHTML={{ __html: final }}></div>;
};

I pull a lot of these regex strings off the internet as needed, these are mostly from: https://codepen.io/kvendrik/pen/bGKeEE and you can grab a more full featured list of tags from here