Pricing

CodeBlock handbook

v1.8.2 · @snowui-design-system/components

License: Before reading component documentation, source, or npm usage instructions for the first time, read the full LICENSE. Reuse that review for the same task and version. Public API configuration and internal implementation changes have different license implications. All components use the unified runtime package; source rights remain governed by the license.

Overview

Display copyable code with syntax highlighting, line numbers, full-screen viewing, and resizing for documentation or developer tools.

When to use it

Use it to present copyable code with built-in copy and expand controls. For editing, check the supported scope first; a code display is not automatically an editor.

  • Provide code; copy and expand controls appear by default, and visibleLines sets the initial visible line count.

  • singleLine renders a single read-only line without language label, line numbers, full-screen control, or vertical scrolling. as="trailing" replaces the right-side action area.

Quick start

This example shows the recommended basic composition. See the sections below for more cases and composition limits.

<script lang="ts">	import { CodeBlock } from '@snowui-design-system/components';	const exampleCode = ["import { Button } from '@snowui-design-system/components';", '', "const launchLabel = 'Explore components';", '', '<Button variant="filled" href="/components">', '  {launchLabel}', '</Button>'].join('\n');</script> <CodeBlock style="background-color: var(--background-1);" code={exampleCode} language="svelte" showLineNumbers visibleLines={7} />

API

Keyword Type Default Description
variant "default" | "singleLine" "default" singleLine uses Input-like Leading/Content/Trailing slots. It stays on one line and omits height dragging, language, line numbers, full-screen, and vertical scrolling.
code string "" Code string to display.
language string "" Language name and formatting parser: Svelte, JS/JavaScript, JSX, TS/TypeScript, TSX, HTML, CSS/SCSS/Less, JSON/JSONC, YAML/YML, Markdown/MD, or GraphQL/GQL. An empty value infers Svelte/HTML, JSON, or JS/TS from code; an unknown explicit language preserves the source.
format boolean true Format by language by default. Normal and full-screen views, line numbers, and copy use the same result. Set false for original text. Single-line mode always preserves the source, as do parse failures, unknown languages, and inputs over 200,000 characters.
showLanguage boolean true Show the language label.
showLineNumbers boolean false Show line numbers in both normal and full-screen views so code does not shift horizontally during transition.
showCopyButton boolean true Show the copy button.
showExpandButton boolean true Show the full-screen button.
horizontalScrollbarVisibility "always" | "hover" "always" Show the horizontal scrollbar whenever content overflows, or only on host hover.
visibleLines number 5 Maximum visible code lines initially. Short content hugs its height; longer content scrolls. Full-screen mode has no such limit.
copyTimeout number 2000 Time in milliseconds to keep the copied Check icon before returning to Copy.
children Snippet — Code content or accessory source. Plain text becomes code; as="trailing" replaces the right-side actions.
parts ComponentPartsOf<{ Indicator: typeof Indicator; CopyButton: typeof CopyButton; ExpandButton: typeof ExpandButton; }> — Configure only generated CopyButton, ExpandButton, and Indicator. Explicit child accessories do not inherit these settings; action buttons may receive an emphasis.

See the base component documentation for inherited capabilities not redeclared here. This table lists only named public Props declared by this component.

Usage boundaries and details

Built-in component configuration

  • parts.Indicator configures the built-in resize Indicator.

  • To replace the handle structure, follow Indicator’s documented as roles. Explicit child Props take precedence over parts.

CodeBlock supports syntax display, lightweight highlighting, line numbers, clipboard copy, and full-screen expansion. Full-screen entry and exit use shared-element layout transitions of actual position and dimensions; code glyphs are not scaled. Icon replacement uses REPLACEMENT_APPEAR_MOTION, separate from overlay motion.


Keyword summary

Category Keyword
Content code, language, children
Feature switches format, showLanguage, showLineNumbers, showCopyButton, showExpandButton
Layout variant="default|singleLine", visibleLines, and default drag height.
Behavior copyTimeout; generated CopyButton owns clipboard behavior.
Generated components Configure generated bare CopyButton with parts.CopyButton, bare ExpandButton with parts.ExpandButton, and the resize handle with parts.Indicator.
External accessory slots singleLine supports as="leading"; all variants support as="trailing". Legacy data-as="copy-icon", copied-icon, expand-icon, and collapse-icon replace individual icons; the first two map to CopyButton icon/successIcon.
Frame passthrough class, style, ...rest


Single-line singleLine variant

variant="singleLine" is a read-only bar for imports, install commands, or short configuration values. It keeps <pre><code>, lightweight highlighting, and CopyButton without introducing Input or form semantics.

The layout refers to the three-slot protocol of Input:

Slot Measurement Content
Leading Hug Optional external as="leading" accessory.
Content Fill / min-width: 0 Highlighted one-line code; horizontal scrolling only when needed.
Trailing Hug External as="trailing", or generated CopyButton by default.

Single-line mode never renders language, line numbers, full-screen control, resize Indicator, vertical scrollbar, or fades. visibleLines, showLanguage, showLineNumbers, and showExpandButton do not create those structures. Horizontal overflow uses an overlay scrollbar, always visible by default or shown only on hover with horizontalScrollbarVisibility="hover". Padding matches Input: --padding-3 (12px) vertically and --padding-4 (16px) horizontally. The preferred gap is --gap-2 (8px), with a 4 CSS px floor. Frame singleLine keeps the direction fixed, Content remains Fill, and accessories do not shrink. When responsive layout is explicitly enabled, preferred gaps compress and restore through the existing Frame protocol. Radius is --radius-4 (16px).

<CodeBlock    variant="singleLine"    code="import { Button } from '@snowui-design-system/components';"/>

When Leading accessories are needed:

<CodeBlock variant="singleLine" code="pnpm add @snowui-design-system/components">    <Icon as="leading"><Package /></Icon></CodeBlock>

Automatic formatting

Formatting is enabled by default. The browser entry of Prettier and its official Svelte plugin load a parser on demand. Settings use four-space tab width, 80-character target width, JS single quotes, semicolons, no trailing commas, and one attribute per line. Svelte block order and meaningful text whitespace remain intact; long strings are not forcibly split. HTML and Markdown whitespace follows their parser, not a regex rewrite.

  • code or child text is read-only input. Formatting changes only visible/copy text, not caller data or executable examples.

  • Normal view, full screen, line numbers, highlighting, and clipboard copy use the same visible text.

  • format={false}, single-line mode, unsupported languages, invalid syntax, or input over 200,000 characters preserve the source. Formatting does not lint, execute, or complete code.

  • SSR first renders the original text; after hydration the parser updates it. Original text stays readable and copyable while loading. Async results apply only to the current code, language, and settings; stale results are discarded. If a dependency fails to load, source text remains.

  • The MIT-licensed prettier and prettier-plugin-svelte dependencies come from the package manifest. Runtime code is not sent to a formatting service. internal/code-block/format.ts remains CodeBlock-owned; no Frame capability or public formatter API is added.

<CodeBlock language="svelte" code={exampleSource} /><CodeBlock language="svelte" code={exampleSource} format={false} />

Syntax highlighting

language="text" (aliases plain, plaintext, txt) preserves text and line breaks. English letters and numbers use keyword pink; HTTP/HTTPS URLs use comment gray; other text keeps the default color. // does not start a comment in text mode. Typography inherits the same rules as other languages. For copy-only use, set showLanguage={false} and showExpandButton={false}; other defaults remain.

For code, lightweight built-in rules highlight common JS, TS, JSON, HTML, and CSS tokens. The layered approach is inspired by shiki/rehype-pretty-code in the reference repository without adding either runtime dependency.

Colors follow the Figma design and are registered as a CodeBlock exception in scripts/check-standards.js:

token Color
Background --background-2
Default text / punctuation --black-100
Line number --black-20
Comment / muted code --black-40
Language label --black-40
Action area Generated actions use Button bare emphasis="muted": --black-100 at opacity 0.4 (visually --black-40).
Keywords / numbers / literals #ff32c6
Functions / call targets #ffac60
Attributes / methods #1ac69c
String #3fa4ff
Variable #c478ff

External style declarations for background and background-* persist through full-screen entry, display, and exit. The full-screen layer inherits those declarations and external CSS variables while preserving token resolution and live updates. Normal-view dimensions, position, and padding are not copied into full screen. Without an override, Background/2 remains.

The root defaults to font-size: var(--text-12) and line-height: var(--leading-12); line numbers, pre, code, and code lines inherit these values. font-family inherits from surrounding content instead of fixing the Figma sample font.

Top-right actions in normal and full-screen mode use bare emphasis="muted" icon buttons. Each has 4px vertical and 8px horizontal padding, 8px radius, a translucent CodeBlock background, and 20px backdrop blur. Button raises emphasis to 100% on hover; keyboard focus has a visible outline. The inline trailing copy control in single-line mode does not use this toolbar styling.

Language labels and action groups retain at least 4 CSS px between them in normal and full-screen modes. This rule does not change spacing between icon-only actions, code characters, or line-number annotations. The toolbar uses internal Pin at pin-top-right, 8px from the top and 4px from the right. Long language labels truncate to available width. Code and vertical scrollbar start below the toolbar, so buttons do not cover content. The bottom-right resize handle is Indicator appearance="corner"; only the corner responds to dragging. By default it adjusts width and height together, from a visible 2px Black/10 state to 4px Black/20 on hover, focus, or drag.


Built-in icons

CopyButton and ExpandButton own their default icons and resolve them through internal ComponentIcon; callers do not need to import those dependencies:

Icon Use
Copy Copy button before copying.
Check Shown briefly after successful copy.
ArrowsOutSimple Expand button before entering full screen.
ArrowsInSimple Collapse button in full screen.

Replacing icons

Prefer as="trailing" to replace the right-side actions, as with Input:

<CodeBlock code="console.log('hello')">    <Icon as="trailing"><Lightning /></Icon></CodeBlock>

Legacy data-as remains available for replacing one built-in icon:

data-as value Replaced built-in icon
copy-icon Copy icon (Copy).
copied-icon Success icon (Check).
expand-icon Expand icon (ArrowsOutSimple).
collapse-icon Collapse icon (ArrowsInSimple).

Icon transition behavior

Scene Motion
Copy click Copy exits → Check enters with REPLACEMENT_APPEAR_MOTION; Check stays for copyTimeout ms.
Copy timeout Check exits → Copy enters with the same preset.
Expand click ArrowsOutSimple exits → ArrowsInSimple enters with the same preset.
Collapse click / Esc ArrowsInSimple exits → ArrowsOutSimple enters with the same preset.
Enter full screen Capture the normal rectangle; the overlay uses shared-element layout to animate actual top, left, width, and height without scaling code glyphs.
Exit full screen Retract the overlay to the normal rectangle before unmounting; normal code layout remains stable and line numbers do not appear or disappear at the last frame.

Icon replacement uses REPLACEMENT_APPEAR_MOTION. Duration, easing, and scale follow the motion preset catalog; the Frame appear bridge variable remains only for compatibility.


Scrolling and height

Height follows code content and visibleLines: shorter content hugs its height; longer content shows that many lines and scrolls. Default visibleLines={5} matches Textarea’s automatic height limit. The bottom-right handle adjusts manual height, after which the code area fills remaining container height and scrolls.

Callers may provide initial height through style. After the first drag, the interaction’s manual height takes precedence over the initial style.height; other user styles keep their merge priority.

When code scrolls vertically, transparent fades appear at the top and bottom. The shared .snowui-scroll-mask from layout.css is the static CSS form of the edge-fade capability (see components/src/lib/edge-fade.md). Its mask-image changes content alpha without drawing a visible color. Scrollbars use the shared overlay styles from scrollbar.css:

Structure Description
.snowui-overlay-scrollbar-viewport Scrollable viewport; native scrollbar hidden.
.snowui-overlay-scrollbar Custom overlay vertical/horizontal track that consumes no layout width. Horizontal overflow is visible by default or host-hover only.
.snowui-overlay-scrollbar-thumb Shared style/hook owns thumb appearance and dragging.
.snowui-scroll-mask + data-scroll-mask Transparent fade at scroll edges.
.snowui-indicator-corner Shared dual-axis Indicator handle at bottom-right; Indicator owns its positioning.

useOverlayScrollbar manages horizontal overflow in normal, full-screen, and single-line views, plus vertical overflow in normal and full-screen views. CodeBlock declares track placement; shared styles own thumb dimensions, visibility, hover shape, and dragging. The vertical bar disappears with host hover; the horizontal bar remains visible on overflow unless horizontalScrollbarVisibility="hover" makes it hover-only.


Frame capability integration

Frame ability Integration layer Description
Ordinary Frame Root Frame No default hover motion; single-line mode uses Frame singleLine and the three-slot Auto Layout protocol.
enableResponsive Root Frame Defaults to false; the CodeBlock container does not need breakpoint behavior.
enableContext Root Frame Default false
enableScaleObserver Root Frame Default false
enableDefaultMotion Root Frame Default true
stateContent Copy Button Internal Frame Driver Copy ↔ Check icon cross-fade
Shared-element layout transition Root Frame / Full-screen Overlay Frame Capture the normal rectangle and transition actual position and size with strategy: "layout"; avoid scale() on code glyphs.
Appear Full-screen Overlay Frame Supplies layout transition timing bridge variables.
Icon button The actual Button hosts of CopyButton and ExpandButton. Configure through public Props and parts; explicit accessories retain their own inputs (built-in icon rule §2.7).

Basic usage

<CodeBlock code={`const x = 1;`} language="ts" />

Children write the code directly

<CodeBlock language="ts">{`const x = 1;console.log(x);`}</CodeBlock>

Show the line number

<CodeBlock code={codeStr} language="tsx" showLineNumbers />

Set the number of lines to display

<CodeBlock code={codeStr} language="tsx" visibleLines={8} />

Hide the button

<CodeBlock code={codeStr} showCopyButton={false} showExpandButton={false} />

Hide the language logo

<CodeBlock code={codeStr} language="tsx" showLanguage={false} />

Custom copy timeout

<CodeBlock code={codeStr} copyTimeout={3000} />

External trailing Icon

<CodeBlock language="bash">    <Icon as="trailing"><Lightning /></Icon>    {`pnpm installpnpm build`}</CodeBlock>

Layout model

Normal mode uses a composite management layout (LayoutProtocol §12.6). singleLine uses a slot host layout: its root owns Leading/Content/Trailing and omits normal-mode scrolling, full-screen, and resize subtrees.

The normal-mode structure includes:

  • Toolbar fixed at the top, outside the code scroller.

  • Scrollable code area (overflow-x: auto).

  • On-demand fixed full-screen overlay.


CodeBlock style overlay

Read the full LICENSE first; reuse that review for the same task, version, and scope.

First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.

Variable Purpose and default reference
--snowui-button-background-override Background (see component source for the default).
--snowui-button-padding-override padding y+x
--snowui-button-radius-override border-radius
--snowui-code-block-bg-override Background (see component source for the default).
--snowui-code-block-code-gap-override Code area gap (see component source code for the default value)
--snowui-code-block-content-height-override Code area height (default 5lh, about 5 lines)
--snowui-code-block-fg-override Foreground (default #1c1c1c; syntax color value is fixed in the component)
--snowui-code-block-gap-override Operation button gap (default var(--gap-2) = 8px)
--snowui-code-block-padding-override Overall padding (default state 20px; singleLine up and down 12px / left and right 16px)
--snowui-code-block-padding-x-override Left and right padding (default var(--padding-5) = 20px; singleLine var(--padding-4) = 16px)
--snowui-code-block-padding-y-override Upper and lower padding (default var(--padding-5) = 20px; singleLine var(--padding-3) = 12px)
--snowui-code-block-radius-override Rounded corner (default var(--radius-4) = 16px)
--snowui-code-block-scroll-mask-size-override Scrolling edge transparent fading size (default 32px)

Design Guide · Token · Combination Boundary

CodeBlock type and status

Required Props: no named required Props.

Bindable Props: this component declares no named two-way binding; handle state updates through public callbacks or its host.

Inheritance statement: Partial<FrameProps>. The inheritance ability is subject to the public document of the base class; the fields in Omit have been excluded and cannot be used as they are according to the base class.

Share Frame API · Return API

The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.

ComponentPartsOf

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartsOf<    T extends Record<string, Component<any>>,> = {    [K in keyof T]?: ConfigurableComponentPartProps<T[K]>;};

ConfigurableComponentPartProps

Source: components/src/logic/component-parts.svelte.ts

export type ConfigurableComponentPartProps<C extends Component<any>> = Partial<    Omit<ComponentProps<C>, ComponentPartControlledKey>>;

ComponentPartControlledKey

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartControlledKey =    | "children"    | "as"    | "value"    | "defaultValue"    | "open"    | "selected"    | "checked"    | "disabled"    | "readonly"    | "id"    | `on${string}`    | `aria-${string}`;