2024-07-10 MDX
Code Example with Syntax Highlighting
Here an inline code: console.log('hello')
example.
Here is a code block:
javascriptconsole.log("Hello, world!");
typescriptconst greeting: string = "Hello, world!";
console.log(greeting);
pythonprint("Hello, world!")
Code Component
The Code
component is designed to display a block of code with syntax highlighting and a copy-to-clipboard functionality. Here's a breakdown of its parts:
-
Imports and Initial Setup:
React
,useRef
, anduseState
are imported from React.- The
props
parameter is defined with anany
type to allow flexibility in the types of props passed to the component.
-
State and Refs:
copied
: A boolean state to track if the code has been copied to the clipboard.codeRef
: A reference to the<code>
HTML element, used to access the code content for copying.
-
Language Extraction:
- The
className
is extracted fromprops
. - A regex is used to match and extract the language part of the class name, which is assumed to be in the format
language-<lang>
.
- The
-
Copy Functionality:
handleCopy
: A function that copies the code text to the clipboard. It accesses the text content of thecodeRef
element, writes it to the clipboard, and updates thecopied
state to provide user feedback.
-
Rendering:
- The component returns a
div
containing:- A header with the detected language and a copy button.
- A
pre
element wrapping acode
element to display the code with proper formatting and syntax highlighting.
- The
whiteSpace: "pre-wrap"
style ensures that long lines of code wrap within the container.
- The component returns a
Code Component Code
jsx"use client";
import React, { useRef, useState } from "react";
const Code = (props: any) => {
const [copied, setCopied] = useState(false);
const codeRef = useRef < HTMLElement > null;
// Extract the language from the className
const className = props.className || "";
const matches = className.match(/language-(?<lang>.*)/);
const language = matches?.groups?.lang || "";
// Handle copy functionality
const handleCopy = () => {
if (codeRef.current) {
const codeText = codeRef.current.innerText;
navigator.clipboard.writeText(codeText).then(() => {
setCopied(true);
setTimeout(() => setCopied(false), 2000); // Reset after 2 seconds
});
}
};
return (
<div className="code-block gap-0 rounded-lg text-white pb-6">
<div className="flex justify-between items-center bg-gray-900 py-2 px-4 rounded-t-lg">
<span className="text-gray-300">{language}</span>
<button
type="button"
className="text-gray-300 hover:text-white"
onClick={handleCopy}
>
{copied ? "Copied!" : "Copy"}
</button>
</div>
<pre className="bg-gray-800 p-4 rounded-b-lg overflow-auto">
<code
ref={codeRef}
className={`${className} bg-gray-800`}
style={{ whiteSpace: "pre-wrap" }}
>
{props.children}
</code>
</pre>
</div>
);
};
export default Code;
InlineCode Component
The InlineCode
component is a simple component designed to display inline code snippets. Here's a breakdown:
-
Imports:
React
is imported from React.
-
Props Interface:
InlineCodeProps
: An interface defining the props for the component, which includes achildren
prop of typeReact.ReactNode
.
-
Rendering:
- The component returns a
code
element styled with Tailwind CSS classes to visually distinguish inline code from regular text. - The
children
prop is rendered within thecode
element, allowing any content passed to theInlineCode
component to be displayed as inline code.
- The component returns a
InlineCode Component Code
jsx"use client";
import type React from "react";
interface InlineCodeProps {
children: React.ReactNode;
}
const InlineCode: React.FC<InlineCodeProps> = ({ children }) => {
return (
<code className="bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100 px-2 py-1 rounded text-base">
{children}
</code>
);
};
export default InlineCode;
By using these components, you can easily add code blocks and inline code snippets with syntax highlighting to your React application.
How Syntax Highlighting is Achieved
To enable syntax highlighting for code blocks in our MDX content, we use two main tools:
-
rehype-highlight: This plugin for
rehype
adds syntax highlighting to code blocks usinghighlight.js
. It's configured in our MDX setup to automatically apply syntax highlighting to code blocks. -
tailwind-highlightjs: This TailwindCSS plugin adds styles for syntax highlighting provided by
highlight.js
. By including it in our TailwindCSS configuration, we ensure that the highlighted code blocks are styled consistently with our overall design.