CodeBlock

Displays code with syntax highlighting, copying, and optional line numbers, diffs or folding.

import { CodeBlock } from "@usefragments/ui";Source

Preview

<CodeBlock code={`import { Button } from '@usefragments/ui';

function App() {
  return <Button>Click me</Button>;
}`} language="tsx" />

Usage

Use when

  • Code examples inside prose or docs
  • Install and config snippets
  • Showing what changed, as a diff

Avoid when

  • The user needs to edit it (use an editor)
  • A couple of words inline (use a code element)

Implementation notes

  • Set language every time; wrong highlighting is worse than none
  • title names a real file or labels the snippet; it sits in the header with the copy action
  • size sm in dense panels and side columns; md everywhere else
  • Line numbers earn their keep once you need to point at a line
  • highlightLines for emphasis; addedLines and removedLines for diffs
  • maxHeight or collapsible keeps a long file from swallowing the page
  • CodeBlock.Tabbed groups the same snippet across languages

Installation

pnpm add @usefragments/ui

The npm package stays managed by your package manager. Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Additional packages

  • shiki — Optional — provides syntax highlighting; without it code renders unhighlighted.
pnpm add shiki

Anatomy

Import CodeBlock once, then compose its parts with dot notation.

  • CodeBlock.Tabbed

Examples

With Title

The title sits in a header inside the block, beside the copy action.

<CodeBlock title="Installation" code="npm install @usefragments/ui" language="bash" />

Small

Mono 11 for dense panels and side columns.

<CodeBlock size="sm" language="bash" title="Run in CI" code="npx @usefragments/cli check --ci" />

With Line Numbers

Turn these on once a snippet is long enough to point at.

<CodeBlock code={`const greeting = "Hello";
const name = "World";
console.log(\`\${greeting}, \${name}!\`);`} language="typescript" showLineNumbers />

Custom Start Line

Numbering starts where the excerpt actually starts in the file.

<CodeBlock
  code={`  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count}
    </button>
  );

With Highlighted Lines

Marks the lines the prose is talking about.

<CodeBlock code={`import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (

Diff View

Added and removed lines, side by side with the rest.

<CodeBlock
  code={`import { useState } from 'react';
import { useCallback } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

Word Wrap

Long lines break instead of scrolling sideways.

<CodeBlock
  code={`const longString = "This is a very long string that would normally cause horizontal scrolling, but with word wrap enabled it will break to the next line instead.";`}
  language="typescript"
  wordWrap
/>

Max Height with Scroll

Caps the height so one snippet cannot own the page.

<CodeBlock
  code={`// This code block has a maximum height
function processItems(items: string[]) {
  const results = [];
  for (const item of items) {
    if (item.startsWith('_')) {

Collapsible

Shows the opening lines and hides the rest behind a toggle.

<CodeBlock
  code={`import React, { useState, useEffect } from 'react';

interface User {
  id: string;
  name: string;

JSON

Config files highlight the same way source does.

<CodeBlock title="package.json" code={`{
  "name": "my-app",
  "dependencies": {
    "@usefragments/ui": "^0.3.0"
  }
}`} language="json" />

Without Copy Button

Drop the copy button when the snippet is not meant to be reused.

<CodeBlock code="const simple = true;" language="typescript" showCopy={false} />

API reference

Component props
Prop
Type
Default
Description
addedLines(string | number)[] | undefinedNot setLines marked as added in diff view (e.g., [2, "4-6"])
codeRequiredstringNot setThe code string to display
collapsedLinesnumber | undefined5Number of lines to show when collapsed
collapsibleboolean | undefinedfalseAllow collapsing/expanding the code block
defaultCollapsedboolean | undefinedfalseInitial collapsed state (only applies when collapsible is true)
highlightLines(string | number)[] | undefinedNot setLines to highlight (e.g., [1, 3, "5-7"])
languageCodeBlockLanguage | undefinedmdhtmlrubytextgotsxtypescripttsjavascriptjsjsxbashshellcssscsssassjsonxmlmarkdownyamlymlpythonpyrustjavakotlinswiftccppcsharpphpsqlgraphqldiffplaintexttsxProgramming language for syntax highlighting
maxHeightnumber | undefinedNot setMaximum height in pixels (enables scrolling)
onCopy(() => void) | undefinedNot setCallback fired when the copy button is clicked and copy succeeds
removedLines(string | number)[] | undefinedNot setLines marked as removed in diff view (e.g., [1, 3])
showCopyboolean | undefinedtrueShow the copy action. It stays visible and says Copied or Couldn't copy for two seconds
showLineNumbersboolean | undefinedfalseWhether to display line numbers
sizeCodeBlockSize | undefinedsmmdmdCode type step: md is mono 12 for documents and replies, sm is mono 11 for dense panels
startLineNumbernumber | undefined1Starting line number (useful for code excerpts)
Tabbed.classNamestring | undefinedNot setAdditional class name
Tabbed.collapsedLinesnumber | undefinedNot setLines shown while folded.
Tabbed.collapsibleboolean | undefinedNot setFold long code to `collapsedLines` with a "Show N more lines" bar
Tabbed.defaultCollapsedboolean | undefinedNot setStart folded (only with `collapsible`)
Tabbed.defaultTabstring | undefinedNot setDefault selected tab (by tab value, or label when value is omitted)
Tabbed.maxHeightnumber | undefinedNot setMaximum height in pixels; the code scrolls past it
Tabbed.onCopy((tabLabel: string) => void) | undefinedNot setCalled after a tab's code reaches the clipboard. Receives the tab label.
Tabbed.onValueChange((value: string) => void) | undefinedNot setCalled when the selected tab changes
Tabbed.showCopyboolean | undefinedNot setShow the copy action.
Tabbed.showLineNumbersboolean | undefinedNot setShow line numbers
Tabbed.sizeCodeBlockSize | undefinedsmmdNot setCode type step.
Tabbed.tabsRequiredCodeBlockTab[]Not setArray of code tabs
Tabbed.valuestring | undefinedNot setControlled selected tab value
Tabbed.wordWrapboolean | undefinedNot setWrap long lines instead of scrolling sideways
titleReact.ReactNodeNot setA file name or label, shown in a header inside the block beside the copy action
wordWrapboolean | undefinedfalseEnable word wrapping for long lines
styleCSSProperties | undefinedNot set—

Accessibility

  • Renders as semantic pre and code inside a focusable, named scroll region, so a keyboard can scroll long lines
  • The copy action is labelled Copy code and always visible; its result is announced in a status region and shown as words
  • The fold bar names what it shows (Show 5 more lines, Show less) and reports aria-expanded and aria-controls
  • Colours follow the theme; added and removed lines also carry a + or - marker
  • CardparentCan be wrapped in Card for additional context
  • TabschildUse in Tabs for showing code in multiple languages

Next steps