Dashral Pro is hereSee pricing

Dashral

Code BlockNew

Code to read and copy, with a file name or tabs, line numbers and marked lines.

$ pnpm dlx shadcn@latest add @dashral/code-block
components/save-button.tsxtsx
import { Button } from "@/components/dashral/button" export function SaveButton({ saving }: { saving: boolean }) {  return (    <Button loading={saving} loadingText="Saving…">      Save changes    </Button>  )}

Installation

$ pnpm dlx shadcn@latest add @dashral/code-block

Adds the component, the components it builds on, its npm packages and the theme tokens it uses. Or by its full URL: https://dashral.com/r/code-block.json

Usage

example.tsx
import { CodeBlock } from "@/components/dashral/code-block"

<CodeBlock filename="app/page.tsx" language="tsx" code={source} lineNumbers highlightLines={[4, 5]} />

Using the npm package? Import from @dashral/ui/components/code-block instead, here and in the examples; the rest is the same.

Examples

Install command

tabs: one command per package manager; the arrow keys move between them.

bash
pnpm dlx shadcn@latest add @dashral/rating

Line numbers and marked lines

lineNumbers, and highlightLines for the lines a step changed.

app/api/invoices/route.tsts
export async function GET(request: Request) {  const { searchParams } = new URL(request.url)  const page = Number(searchParams.get("page") ?? 1)   const invoices = await db.invoice.findMany({    where: { status: "open" },    orderBy: { due: "asc" },    skip: (page - 1) * 20,    take: 20,  })   return Response.json({ invoices, page })}

Without a header

The copy button floats in the corner; wrap breaks long lines.

DATABASE_URL="postgres://app:secret@localhost:5432/app"RESEND_API_KEY="re_123"NEXT_PUBLIC_SITE_URL="http://localhost:3000"
[12:04:31] build  ✓ compiled 412 modules in 3.2s — the longest line here keeps going so that it wraps instead of scrolling sideways when wrap is on[12:04:33] deploy ✓ uploaded to sin1[12:04:35] deploy ✓ live at https://app.example.com

API reference

CodeBlock

Also takes every prop of <div>(opens in a new tab).

PropTypeDefault
codestring

The code, as plain text: what's shown and copied.

—
filenamestring

A file name in the header.

—
languagestring

Shown at the header's end, and set as data-language on the <pre>.

—
tabs{ label, code, language? }[]

Several snippets, one at a time, e.g. a command per package manager. In place of code.

—
defaultTab / onTabChangestring / (label) => void

The tab shown first, and a call when another is picked.

the first
lineNumbersboolean

Numbers each line.

false
highlightLinesnumber[]

Lines to mark, from 1.

—
wrapboolean

Long lines wrap instead of scrolling sideways.

false
maxHeightnumber | string

Scrolls past this height.

—
copyableboolean

The copy button.

true
childrenReactNode

Your highlighter's markup in place of the plain lines; code is still what's copied.

—
classNames{ header, pre, line }

Classes for each part.

—
classNamestring

Extra classes, merged with cn() so yours win.

—

Keyboard

KeysAction
TabTo the code (it scrolls with the arrow keys), the tabs and the copy button
←or→Between tabs
HomeorEndThe first or last tab

Accessibility

  • The tabs follow the tabs pattern (tablist, tab, tabpanel, aria-selected).
  • Line numbers are hidden from screen readers and from selection, so they're never copied.
  • Code runs left to right on an Arabic page too.