Code Block
NewCustomize
Install tabs
Installation
npx shadcn@latest add https://uibrik.com/r/code-block.jsonInstall the packages
npm install motion shikiAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/code-block/code-block.tsx"use client"; import { useCallback, useEffect, useId, useRef, useState, useSyncExternalStore, type CSSProperties } from "react"; import { AnimatePresence, MotionConfig, motion } from "motion/react"; import type { HighlighterCore } from "shiki/core"; import { cn } from "@/lib/utils"; // A code block for docs and landing pages. The code renders as plain text // straight away (and on the server), then Shiki colours it in place once the // block is near the viewport, so nothing shifts and pages with many blocks // only pay for the ones being read. Shiki, its regex engine and each grammar // are loaded on demand and shared by every block on the page. // // Tabs slide an underline between them and the body eases to the new height. // Blocks given the same `syncKey` switch tabs together, and the choice is // remembered, so picking pnpm once picks it everywhere. Lines can be marked, // diffs get +/- gutters (copy gives you the result, not the patch), and long // snippets can collapse behind a "Show all" that eases open. export type CodeLang = "tsx" | "jsx" | "ts" | "js" | "bash" | "json" | "css" | "html" | "python" | "text"; export type CodeTab = { /** Shown on the tab, e.g. a file name or a package manager. */ label: string;
Adds the files to
components/uibrik/code-block and installs motion and shiki. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/code-block.Usage
import { CodeBlock } from "@/components/uibrik/code-block/code-block";const tabs = [ { label: "npm", code: "npm install motion react-use-measure", lang: "bash" }, { label: "pnpm", code: "pnpm add motion react-use-measure", lang: "bash" }, // …2 more];<CodeBlock lineNumbers wrap={false} copyable code="" lang="tsx" tabs={tabs} syncKey="pm" diff={false} // title="…" // value="…" // defaultValue="…" // onValueChange={(label) => {}} // highlightLines={[0]}/>Props
CodeBlock- lineNumbers
- Type boolean
- true
- A gutter of line numbers. Copying never picks them up.
- wrap
- Type boolean
- false
- Wrap long lines instead of scrolling sideways.
- collapseAfter
- Type number
- 15
- Fold longer snippets behind Show all. 0 never folds.
- copyable
- Type boolean
- true
- The copy button. A diff copies the code after the change.
- code / lang
- Type string / "tsx" | "jsx" | "ts" | "js" | "bash" | "json" | "css" | "html" | "python" | "text"
- "tsx"
- A single snippet and its language.
- tabs
- Type { label; code; lang? }[]
- –
- Several snippets, one per tab.
- title
- Type string
- –
- File name or caption for a single snippet.
- value / defaultValue / onValueChange
- Type string / string / (label) => void
- –
- Selected tab, controlled or not.
- syncKey
- Type string
- –
- Blocks with the same key switch tabs together and remember the choice in this browser.
- highlightLines
- Type number[]
- –
- 1-based lines to mark.
- diff
- Type boolean
- false
- Lines starting with + or - show as added or removed.
- className
- Type string
- –
- Classes for the frame.