1.0.0 • Published 2 months ago

react-md-highlighter v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
2 months ago

Made in Nigeria issues forks PRs Welcome license

react-md-highlight

An alternative to react-syntax-highlighter with markdown support.

This component is a wrapper based off of rehype-pretty-code. If you need more info on extending its superpowers, you should check them out.

It uses Shiki's syntax-highlighting engine, the same as VSCode's. So that means, your favorite VScode them can be used with this component.

Usage

Install it with your favorite package manager like so:

pnpm install react-md-highlighter

Go ahead and import it in your components, and that's all.

import "./App.css";
import { MdHighlight } from "react-md-highlighter";

const content = `
# Sample Markdown Content

This is a paragraph of regular text.

\`\`\`js {2}
function greet(name) {
    console.log(\`Hello, \${name}!\`);
}

greet("World");
\`\`\`

This is another paragraph of text.
`;

function App() {
  return (
    <>
      <div>
        <p>Md highlight</p>

        <MdHighlight>{content}</MdHighlight>
      </div>
    </>
  );
}

export default App;

Customizing

With <MdHighlight /> the component's styling is completely up to you. It doesn't come with any CSS shipped with it. You have control over how your content is styled, down to the code snippets.

  • Let's start with theming

    You can change your theme by passing any vscode theme name as a string to the options prop as shown below. If your vscode theme isn't available. Feel freen to open an issue, and it'll be included.

    <MdHighlight
      options={{
        theme: "aurora-x",
      }}
    >
      {content}
    </MdHighlight>

    By default, the background of your corresponding theme is added to the codeblock. If you want to fully customize it so it matches your UI, you can disable it by setting the keepBackground property to false.

    You can also customize the default language with the defaultLang prop for all code snippets either inline or blocks.

    Learn more about the available options here

  • Meta props

    The meta props are basically attached to the codeblock at the top just after the tripple backticks.

    An example of a meta prop is the file extension or language type. see an example below.

    ```js
      console.log("Hellow MdHighlight")
    ```;

    These props or strings after the backtcks helps us tell rehype-pretty-code how to generate the respective html which in turn helps you style the blocks.

    This is the html equivalent of the snippet above:

    <p>This is another code block</p>
    
    <figure data-rehype-pretty-code-figure="">
      <pre
        style="background-color:#07090F;color:#bbbbbb"
        tabindex="0"
        data-language="js"
        data-theme="aurora-x"
      >
          <code data-language="js" data-theme="aurora-x" style="display: grid;">
              <span data-line=""><span style="color:#EEFFFF">console</span>
                  <span style="color:#89DDFF">.</span><span style="color:#82AAFF">log</span>
                  <span style="color:#BBBBBB">(</span><span style="color:#89DDFF">"</span>
                  <span style="color:#C3E88D">Hellow MdHighlight</span>
                  <span style="color:#89DDFF">"</span>
                  <span style="color:#BBBBBB">)</span>
              </span>
          </code>
      </pre>
    </figure>

    And its attribbutes are what you'll use when styling the code blocks.

    • Line higlights

      Say you want to highlight a specific line in your code block now... To do that, you'll need to update your meta prop and pass in a range of line numbers like so: {1-3, 8, 9} and so on.

      ```tsx {1,3, 4-7}
          function App() {
              return (
                <>
                  <div>
                    <p>Md highlight</p>
                    <MdHighlight>{content}</MdHighlight>
                  </div>
                </>
              );
          }
      
          export default App;
      ```;

      The snippet beocomes this, in HTML. Now, you can target the span(s) with data-highlighted-line attribute and style it as you wish

      <figure data-rehype-pretty-code-figure="">
        <pre
          style="background-color:#07090F;color:#bbbbbb"
          tabindex="0"
          data-language="tsx"
          data-theme="aurora-x"
        >
          <code data-language="tsx" data-theme="aurora-x" style="display: grid;">
              <span data-line="" data-highlighted-line=""><span style="color:#C792EA">function</span><span style="color:#82AAFF"> App</span><span style="color:#89DDFF">()</span><span style="color:#89DDFF"> {</span>
              </span>
              <span data-line=""><span style="color:#89DDFF">    return</span><span style="color:#BBBBBB"> (</span>
              </span>
              <span data-line="" data-highlighted-line=""><span style="color:#89DDFF">      &lt;&gt;</span></span>
              <span data-line="" data-highlighted-line=""><span style="color:#89DDFF">        &lt;</span><span style="color:#F07178">div</span><span style="color:#89DDFF">&gt;</span></span>
              <span data-line="" data-highlighted-line=""><span style="color:#89DDFF">          &lt;</span><span style="color:#F07178">p</span><span style="color:#89DDFF">&gt;Md highlight&lt;/</span>
              <span style="color:#F07178">p</span><span style="color:#89DDFF">&gt;</span></span>
              <span data-line="" data-highlighted-line=""><span style="color:#89DDFF">          &lt;</span><span style="color:#F07178">content</span><span style="color:#89DDFF">}&lt;/</span>
              <span style="color:#FFCB6B">MdHighlight</span><span style="color:#89DDFF">&gt;</span></span>
              <span data-line="" data-highlighted-line=""><span style="color:#89DDFF">        &lt;/</span><span style="color:#F07178">div</span><span style="color:#89DDFF">&gt;</span></span>
              <span data-line=""><span style="color:#89DDFF">      &lt;/&gt;</span></span>
              <span data-line=""><span style="color:#BBBBBB">    )</span><span style="color:#89DDFF">;</span></span>
              <span data-line=""><span style="color:#89DDFF">}</span></span>
              <span data-line=""> </span>
              <span data-line=""><span style="color:#89DDFF">export</span><span style="color:#89DDFF"> default</span><span style="color:#EEFFFF"> App</span><span style="color:#89DDFF">;</span></span>
          </code>
        </pre>
      </figure>

      Your css would be something similar to this

      span[data-highlighted-line] {
        background: #ffcb6b;
      }
      • Line numbers

      To show line numbers in your code snippets, you have to target the all spans in the code element with the data-line attribute, and use both the counter-reset and counter-increment properties from CSS to update the block.

      code {
        counter-reset: line;
      }
      
      code > [data-line]::before {
        counter-increment: line;
        content: counter(line);
      }
      • Filenames

      To include details about a snippet, perhaps a filename in this case, you can use the title meta prop to achieve that.

      ```js title="index.js"
      console.log("Hellow MdHighlight")
      ```;

      When you add a tile like so, we get a figcaption element inserted into the figure like so.

      <figcaption
        data-rehype-pretty-code-title=""
        data-language="js"
        data-theme="aurora-x"
      >
        index.js
      </figcaption>

      Then you can proceed to style it as you deem fit. A good example can be seen on the snippets this from this blog, and here's how to accomplish smething similar.

      figcaption[data-rehype-pretty-code-title] {
        margin-bottom: 0.125rem;
        background-color: #111111;
        font-family: var(--inter);
        font-size: 12px;
        line-height: 1rem;
        padding: 1em 1.5em;
        border-top-right-radius: 8px;
        border-top-left-radius: 8px;
        border-bottom: 1px solid var(--alt-white);
      }
      
      figcaption[data-language]::after {
        content: attr(data-language);
        float: right;
        font-weight: 700;
        color: var(--text-disabled);
        text-transform: uppercase;
      }

      code snippet from Caleb Olojo's blog showing the title meta prop

Contributing

Want to contribute? See the guideline

License

MIT