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, andvisibleLinessets the initial visible line count.singleLinerenders 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.
API
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.Indicatorconfigures the built-in resize Indicator.To replace the handle structure, follow Indicator’s documented
asroles. Explicit child Props take precedence overparts.
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
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:
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).
When Leading accessories are needed:
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.
codeor 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
prettierandprettier-plugin-sveltedependencies come from the package manifest. Runtime code is not sent to a formatting service.internal/code-block/format.tsremains CodeBlock-owned; no Frame capability or public formatter API is added.
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:
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:
Replacing icons
Prefer as="trailing" to replace the right-side actions, as with Input:
Legacy data-as remains available for replacing one built-in icon:
Icon transition behavior
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:
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
Basic usage
Children write the code directly
Show the line number
Set the number of lines to display
Hide the button
Hide the language logo
Custom copy timeout
External trailing Icon
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.
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.
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
ConfigurableComponentPartProps
Source: components/src/logic/component-parts.svelte.ts
ComponentPartControlledKey
Source: components/src/logic/component-parts.svelte.ts