Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

CodeBlock

  • Stable
  • WCAG 2.2 evidence
  • RTL

A block of code with a header and a copy button. It shows plain code, with line numbers drawn by a CSS counter (not selectable, not copied), emphasised lines, a file name and language, or several samples in tabs. It has no syntax highlighter (owner decision D7): draw highlighted nodes yourself with renderLine, using the Figma token colours in codeTokenStyles. Presentational shell for React Server Components; only the copy button and the tab strip are client islands. Accessibility: the code area scrolls sideways inside the block (so the page never scrolls at 320 px, WCAG 1.4.10), is focusable with the keyboard and named (2.1.1, 4.1.2), and keeps its focus ring inside the block (2.4.7). Code is always left to right (1.3.2). The copy button is a real button; the result is shown on the button and announced (4.1.3). Tabs follow the WAI-ARIA tabs pattern. Consumer duties: check the contrast of your own token colours on bg/sunken; say in the text around the block what an emphasised line is about; translate the labels; keep secrets out of samples.

import { CodeBlock } from "@nexera-ui/react";
Loading example…
10
examples
18
props
2
live controls
1
platform
11
WCAG criteria
1
block uses it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
theme
lineNumbers
Generated code
import { CodeBlock } from "@nexera-ui/react";

<CodeBlock />

Examples 9

The same examples as Storybook, rendered live. Open Code to copy one.

Plain code

Without renderLine the code is plain text in the primary colour.

Loading example…

Without line numbers

Figma Show line numbers off: the lines start 16 px in. The counter is CSS, so numbers are never selected or copied.

Loading example…

Shell command

A shell command: no file name or language, a named code area ("Install command") and the copy button.

Loading example…

Pinned themes

theme pins the block to the light or dark colours whatever the page uses, as the Figma Theme variants do.

Loading example…

Tabbed

Tabs follow the WAI-ARIA tabs pattern: arrow keys, Home and End move between tabs and the copy button copies the selected sample.

Loading example…

Controlled tabs

Controlled tabs: the parent owns selectedKey and hears onSelectionChange (a function, so this needs a client component).

Loading example…

Long lines

Long lines scroll sideways inside the block, never the page, even at 320 px. The code area is focusable: Tab to it and use the arrow keys. Its focus ring is drawn inside the block.

Loading example…

Translated labels

Every visible text of the block is a prop, so it can be translated (German here). The announcements are translated too.

Loading example…

Right to left

Right-to-left page: the header mirrors (the copy button moves to the left) while the code, its line numbers and the file name stay left to right.

Loading example…

Props 18

Press "Try it" on a card to load that prop into the playground.

18 props shown

themeNexera
"light" | "dark"

Pins the block to the light or the dark colours whatever the page uses. Without it the block follows the page theme, which is the Figma Light look on a light page; Figma has Light as the default variant.

Default the page theme
lineNumbersNexera
boolean

Shows a line number before every line. The numbers are drawn by a CSS counter, so they cannot be selected or copied and are not part of the code.

Default true
codeLabelNexera
string

Accessible name of the scrollable code area, which is a focusable group: the file name when there is one, otherwise this text. Tabbed blocks name each area with its tab label. Translate it for your locale.

Default the file name, or "Code"
copyLabelNexera
string

Label of the copy button. Translate it for your locale.

Default Copy
copiedLabelNexera
string

Label of the copy button for 2 seconds after the code was copied. Translate it for your locale.

Default Copied
copiedMessageNexera
string

Message announced to assistive technology after the code was copied (WCAG 4.1.3). Translate it for your locale.

Default Copied to clipboard
copyFailedMessageNexera
string

Message announced (assertively) when the browser does not allow copying, for example on a page that is not served over HTTPS. The code can still be selected with the keyboard. Translate it for your locale.

Default Could not copy to the clipboard
typeNexera
"single-file" | "tabbed"

What the block holds: single-file is one code sample with a header showing its file name and language. Several samples chosen with tabs. The copy button copies the selected one.

Default "single-file"
codeNexera
string

The code as plain text. It is what the copy button copies, and what is drawn unless renderLine draws it differently. Line breaks (\n) start new lines; one trailing line break is ignored. Not used by a tabbed block: each tab has its own.

Default –
filenameNexera
string

File name in the header, with a file icon. The header has no name when it is left out. Not used by a tabbed block.

Default –
languageNexera
string

Language chip in the header. Shown when provided. Not used by a tabbed block: each tab has its own language.

Default –
highlightedLinesNexera
readonly number[]

Lines to emphasise (1-based): Figma fills lines 4 to 6 of its sample with nav/active-bg. They are emphasis only, so also mention them in the text around the block. Not used by a tabbed block: each tab has its own.

Default –
renderLineNexera
CodeLineRenderer

Draws each line, so you can supply highlighted nodes without a highlighter built into the library (owner decision D7: no syntax-highlighting dependency). See {@link CodeLineRenderer}. Runs where CodeBlock runs (on the server in a Server Component), so it may use any highlighter your app has. Not used by a tabbed block: each tab has its own.

Default –
tabsNexera
readonly [CodeBlockTab, ...CodeBlockTab[]]

Not used by a single file. The samples, at least one (see {@link CodeBlockTab}).

Default –
tabsLabelNexera
string

Not used by a single file. Accessible name of the tab list ("Code samples"). Translate it for your locale (WCAG 4.1.2).

Default –
selectedKeyNexera
string

Not used by a single file. Id of the selected tab (controlled). Needs a client component, because it comes with onSelectionChange.

Default –
defaultSelectedKeyNexera
string

Not used by a single file. Id of the tab selected at first (uncontrolled).

Default the first tab
onSelectionChangeNexera
(id: string) => void

Not used by a single file. Called with the id of the tab the user selected. A function cannot be passed from a Server Component: use it from a client component.

Default –

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

5 direct · 6 supporting
  • 1.1.1Non-text ContentLevel A · tested directly
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.3.2Meaningful SequenceLevel A · supporting test
  • 1.4.1Use of ColorLevel A · supporting test
  • 1.4.10ReflowLevel AA · supporting test
  • 2.1.1KeyboardLevel A · tested directly
  • 2.4.7Focus VisibleLevel AA · supporting test
  • 2.4.11Focus Not Obscured (Minimum)Level AA · supporting test
  • 2.5.8Target Size (Minimum)Level AA · supporting test
  • 4.1.2Name, Role, ValueLevel A · tested directly
  • 4.1.3Status MessagesLevel AA · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

  • data-hovered
  • data-pressed
  • data-selected
Usage
<CodeBlock className="data-hovered:opacity-90 shadow-sm" />

Used in blocks

Related components