CodeBlock
Renders a code block with tokenized source code, line numbers, and a toolbar.
When targeting JavaScript or TypeScript languages, the provided source code is
type-checked and will throw errors that can be optionally displayed. Additionally,
the source code will be formatted using prettier
if installed and quick info
is available when hovering symbols.
Style Overrides
The CodeBlock
component can be styled using the, css
, className
, and style
props to target specific descendant components. In most cases, its a good idea to create your own component that wraps the CodeBlock
component and applies the style overrides you need:
import {
type CodeBlockProps,
CodeBlock as BaseCodeBlock,
Tokens,
} from 'renoun/components'
import styles from './CodeBlock.module.css'
export function CodeBlock(props: CodeBlockProps) {
return (
<BaseCodeBlock
{...props}
css={{
// Clear the default styles
container: {
boxShadow: undefined,
borderRadius: undefined,
},
...props.css,
}}
className={{
container: styles.container,
token: styles.token,
...props.className,
}}
/>
)
}
Component Overrides
If you need more customization, the CodeBlock
component can be fully overridden by importing it from renoun/components
and extending it as needed:
import {
type CodeBlockProps,
CodeBlock as BaseCodeBlock,
Tokens,
} from 'renoun/components'
export function CodeBlock({
children,
...props
}: Omit<CodeBlockProps, 'children'> & { children: string }) {
return (
<BaseCodeBlock {...props}>
<pre
style={{
whiteSpace: 'pre',
wordWrap: 'break-word',
overflow: 'auto',
}}
>
<Tokens>{children}</Tokens>
</pre>
</BaseCodeBlock>
)
}
Formatting
The CodeBlock
source text is formatted by default using prettier
if it is installed within the workspace. The shouldFormat
prop can be used to disable this behavior:
<CodeBlock language="ts" shouldFormat={false}>
const foo = 'bar'
</CodeBlock>
Examples
Basic
View Sourceconst beep = 'boop'
import { CodeBlock } from 'renoun/components' export function Basic() { return <CodeBlock language="ts">const beep = 'boop'</CodeBlock> }
Type Checking
View Sourceconst a = 1 a + b
import { CodeBlock } from 'renoun/components' export function TypeChecking() { return ( <CodeBlock language="ts" allowCopy={false} allowErrors showErrors> const a = 1; a + b; </CodeBlock> ) }
Ordered
View Sourceexample.tsconst a = 1
example.tsconst a = 1 const b = 2
import { CodeBlock } from 'renoun/components' export function Ordered() { return ( <div style={{ display: 'grid', gap: '2rem' }}> <CodeBlock path="01.example.ts">const a = 1;</CodeBlock> <CodeBlock path="02.example.ts">const a = 1; const b = 2;</CodeBlock> </div> ) }
Line Numbering
View Sourceline-numbers.ts1 2 3 4 5
const a = 1 const b = 2 const add = a + b const subtract = a - b
import { CodeBlock } from 'renoun/components' export function LineNumbering() { return ( <CodeBlock path="line-numbers.ts" showLineNumbers highlightedLines="4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Highlighting
View Sourceline-highlight.tsconst a = 1 const b = 2 const add = a + b const subtract = a - b
import { CodeBlock } from 'renoun/components' export function LineHighlighting() { return ( <CodeBlock path="line-highlight.ts" highlightedLines="2, 4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Focusing
View Sourceline-focus.tsconst a = 1 const b = 2 const add = a + b const subtract = a - b
import { CodeBlock } from 'renoun/components' export function LineFocusing() { return ( <CodeBlock path="line-focus.ts" focusedLines="2, 4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Highlight and Focus
View Sourceline-highlight-and-focus.tsconst a = 1 const b = 2 const add = a + b const subtract = a - b
import { CodeBlock } from 'renoun/components' export function LineHighlightAndFocus() { return ( <CodeBlock path="line-highlight-and-focus.ts" highlightedLines="2, 4" focusedLines="2, 4" > {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Tokens Only
View Sourceconst a = 1 const b = 2 a + b
import { Tokens } from 'renoun/components' export function TokensOnly() { return ( <pre> <Tokens language="ts">{`const a = 1\nconst b = 2\na + b`}</Tokens> </pre> ) }
Custom Styles
View Source./counter/Counter.tsx1 2 3 4 5 6 7 8 9 10 11 12 13 14
'use client' import React from 'react' import { useCounter } from './useCounter.js' export default function Counter({ initialCount }: { initialCount: number }) { const { count, decrement, increment } = useCounter(initialCount) return ( <div> <button onClick={decrement}>-</button> <span>{count}</span> <button onClick={increment}>+</button> </div> ) }
import { CodeBlock, LineNumbers, Tokens, Toolbar } from 'renoun/components' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { readFile } from 'node:fs/promises' const directoryPath = dirname(fileURLToPath(import.meta.url)) export async function CustomStyles() { const code = await readFile( join(directoryPath, './counter/Counter.tsx'), 'utf-8' ) return ( <CodeBlock path="./counter/Counter.tsx" workingDirectory={directoryPath}> <div style={{ fontSize: '1rem', borderRadius: '0.25rem', boxShadow: '0 0 0 1px var(--color-separator)', }} > <Toolbar allowCopy css={{ padding: '0.5lh', boxShadow: 'inset 0 -1px 0 0 var(--color-separator)', }} /> <pre style={{ display: 'grid', gridTemplateColumns: 'min-content max-content', padding: '0.5lh 0', lineHeight: 1.4, whiteSpace: 'pre', wordWrap: 'break-word', overflow: 'auto', }} > <LineNumbers css={{ padding: '0 0.5lh', backgroundColor: 'var(--color-background)', }} /> <code style={{ paddingRight: '0.5lh' }}> <Tokens>{code}</Tokens> </code> </pre> </div> </CodeBlock> ) }
API Reference
CodeBlockProps
CodeBlockProps
Properties
children *
React.ReactNode
Pass a code string to highlight or override default rendering using Tokens
, LineNumbers
, and Toolbar
components.
path
string
Name or path of the code block. Ordered file names will be stripped from the name e.g. 01.index.tsx
becomes index.tsx
.
workingDirectory
string
The working directory to use when analyzing the source code. This will read the local file system contents from the workingDirectory
joined with the path
prop instead of creating a virtual file.
language
Languages
Language of the source code provided to the Tokens
component. When path
is defined, the file extension will be used to determine the language by default.
highlightedLines
string
A string of comma separated lines and ranges to highlight e.g. '1, 3-5, 7'
.
focusedLines
string
A string of comma separated lines and ranges to focus e.g. '6-8, 12'
.
unfocusedLinesOpacity
number
Opacity of unfocused lines when using focusedLines
.
allowCopy
boolean | string
Show or hide a button that copies the source code to the clipboard. Accepts a boolean or a string that will be copied.
allowErrors
boolean | string
Whether or not to allow errors. Accepts a boolean or comma-separated list of allowed error codes.
showErrors
boolean
Show or hide error diagnostics.
showLineNumbers
boolean
Show or hide line numbers.
showToolbar
boolean
Show or hide the toolbar.
shouldAnalyze
boolean
Whether or not to analyze the source code for type errors and provide quick information on hover.
shouldFormat
boolean
Whether or not to format the source code using prettier
if installed.
css
{ container?: CSSObject; toolbar?: CSSObject; lineNumbers?: CSSObject; token?: CSSObject; popover?: CSSObject; copyButton?: CSSObject; }
CSS styles to apply to code block elements.
container
CSSObject
toolbar
CSSObject
lineNumbers
CSSObject
token
CSSObject
popover
CSSObject
copyButton
CSSObject
className
{ container?: string; toolbar?: string; lineNumbers?: string; token?: string; popover?: string; copyButton?: string; }
Class names to apply to code block elements.
container
string
toolbar
string
lineNumbers
string
token
string
popover
string
copyButton
string
style
{ container?: React.CSSProperties; toolbar?: React.CSSProperties; lineNumbers?: React.CSSProperties; token?: React.CSSProperties; popover?: React.CSSProperties; copyButton?: React.CSSProperties; }
Styles to apply to code block elements.
container
React.CSSProperties
toolbar
React.CSSProperties
lineNumbers
React.CSSProperties
token
React.CSSProperties
popover
React.CSSProperties
copyButton
React.CSSProperties
CodeBlock
(props: CodeBlockProps) => React.JSX.Element
Renders a code block with tokenized source code, line numbers, and a toolbar.
When targeting JavaScript or TypeScript languages, the provided source code is
type-checked and will throw errors that can be optionally displayed. Additionally,
the source code will be formatted using prettier
if installed and quick info
is available when hovering symbols.
Parameters
CodeBlockProps
Returns
ElementparsePreProps
(props: React.ComponentProps<"pre">) => { children: string; language?: Languages; } & Omit<React.ComponentProps<"pre">, "children" | "className" | "style">
Parses the props of an MDX pre
element for passing to CodeBlock
.
Parameters
props *
React.DetailedHTMLProps<React.HTMLAttributes<HTMLPreElement>, HTMLPreElement>
Returns
{ children: string; language?: Languages | undefined; } & Omit<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>, "style" | ... 1 more ... | "children">