Skip to main content
xriptxr

Code

Info:Content
38

A read-only, syntax-highlighted code block themed entirely from the code-token family.

code block syntax highlight snippet pre monospace highlighting

Live demo

live · @xtyle/astro

Code

Themed highlighting, three languages

Every block colors itself from the --code-* family the algorithm derives, so it re-themes with the rest of the chrome.

type Theme = { bg: string; accent: string };

const derive = (theme: Theme): string =>
	`--bg-0: ${theme.bg}; --accent: ${theme.accent};`;

console.log(derive({ bg: "#0f1115", accent: "#5b8cff" }));
fn main() {
	let accent = "#5b8cff";
	println!("derive from {accent}");
}
.xtyle-code {
	color: var(--code-fg);
	background: var(--code-bg);
}

Line numbers & highlights

line-numbers adds a gutter column — a real .xtyle-code-line__number node per row, drawn by the block's fragment, so a mod can restyle or relocate it; highlight tints the lines that matter (here 2,4 ) with the derived --code-line-highlight .

function total(items) {	let sum = 0;	for (const n of items) sum += n;	return sum;}

Soft-wrap

wrap folds a long line instead of scrolling it sideways: purely declarative, no JavaScript.

const message = "a deliberately long single line that would otherwise scroll sideways, but soft-wraps instead so the whole statement stays readable in a narrow column";

Caption header

caption labels a block (a filename, say) in a header strip that rounds the block's top corners into it.

theme.ts
type Theme = { bg: string; accent: string };

const derive = (theme: Theme): string =>
	`--bg-0: ${theme.bg}; --accent: ${theme.accent};`;

console.log(derive({ bg: "#0f1115", accent: "#5b8cff" }));

Code is a turnkey, read-only code block with the tokenizer built in; it's the first component to read the --code-* family. It tokenizes with Prism, whose output is class-based, so the block re-themes live the moment the theme changes: the colors are just cascading CSS variables, never baked inline.

The lang prop names the language with aliases resolved (ts → typescript), and the source is the element's text content (or, for Astro, a code prop). Grammar loading is fully lazy and per-language. A page with no code block loads nothing; a page with a few languages loads Prism core once plus only those grammar chunks, walking each grammar's dependencies first. At runtime the block paints immediately as plain-but-themed text and recolors in place once the grammar resolves, so there is no flash and no layout shift; the Astro binding tokenizes at build and ships pre-colored with zero browser JS. preload warms a block's grammar eagerly to kill even the minor recolor flash, sharing one warm path with the page-level XtyleCode.warm() static. An unknown language falls back to plain-but-themed text rather than erroring.

When to use

How this component composes with the rest of the set.

Set lang to the source's language; use an alias (ts, html, js) and it resolves to the canonical grammar.
On a code-heavy page, call XtyleCode.warm(["ts", "rust"]) once at startup, or mark individual blocks preload, to load grammars before first paint.
For a language Prism does not ship, register it with XtyleCode.registerLanguage(name, grammar) and use that name as lang.
Reach for the Astro binding when the code is known at build time; it ships pre-colored with zero grammar bytes in the browser.

Props

8 props, straight from the manifest.

PropTypeDefaultBindingsDescription
lang html: language string —
html svelte astro
The language id, with aliases resolved (ts → typescript). An unknown id falls back to plain-but-themed text. In markup the attribute is language; lang is the HTML global and means a natural language, not a programming one.
code string —
html svelte astro
The source to highlight. Optional for html/svelte (the text content is used); the canonical input for Astro's build-time tokenization.
preload boolean false
html svelte astro
Warm this block's grammar eagerly and emit a modulepreload hint, killing the minor recolor flash on known code-heavy pages.
copy boolean true
html svelte astro
The copy-to-clipboard button. On by default; set copy="false" (or copy="none") to drop it. It only paints where it can work: hidden in an insecure context (no Clipboard API) and on the zero-JS Astro path.
wrap boolean false
html svelte astro
Soft-wrap long lines instead of scrolling them horizontally. Purely declarative; the host attribute drives a CSS rule, so it needs no JavaScript and works on the zero-JS Astro path.
lineNumbers html: line-numbers boolean false
html svelte astro
Number each line in a gutter that stays put while the code scrolls sideways. Tag-aware, so a token spanning lines (a block comment, a multi-line string) still numbers cleanly, and it co-operates with wrap (a wrapped line keeps a single number at its top). The gutter is pure derived chrome; it borrows --code-comment and --field-border, adding no tokens, and renders on the zero-JS Astro path too.
highlight string —
html svelte astro
Tint chosen lines with --code-line-highlight to call out the ones that matter: a 1-based spec like 2, 2,4, or 4-6, mixable as 1,3-5,8. Pairs with line-numbers, works under wrap, and renders on the zero-JS Astro path; it reuses a token the algorithm already derives, so it adds none.
caption string —
html svelte astro
A caption header above the block, typically a filename. Left empty, no header renders. It rounds the block's top corners into the strip and reads in the mono face; it reuses chrome tokens, so it adds none, and renders on the zero-JS Astro path.

Appearance

States

scroll-focus

.xtyle-code:focus-visible

Keyboard focus on a block wide enough to scroll horizontally, which turns tabbable only when it overflows: an outline sitting outside the border box, so the scrolled code can't cover it.

Anatomy

The named parts that make up the component. Created from script it renders a shadow root, where a ::part() handle is reachable from your own stylesheet and the class beside it is internal. Upgraded over server-rendered markup it renders light DOM, where the class is the handle.

pre

Success:::part(pre) .xtyle-code

The block surface: the scroll container that carries the code background and padding.

--code-bg --code-fg --radius-md --font-mono --text-sm --space-4

code

Success:::part(code) .xtyle-code code

The tokenized source: .token.* spans colored by the per-scope code tokens.

--code-keyword --code-string --code-comment --code-function

caption

Success:::part(caption) .xtyle-code-caption

An optional header strip above the block, set via caption (a filename, say); reads in the mono face on a neutral surface and rounds the block's top corners into it.

--neutral-bg --neutral-text --field-border --radius-md --font-mono --text-xs

copy

Success:::part(copy) .xtyle-code-copy

The copy-to-clipboard button, anchored top-right; fades in on hover or focus and flashes a vivid Copied state on success.

--neutral-bg --field-border --radius-sm --success-vivid

line

internal .xtyle-code-line

A single logical line of source, wrapped as a row when line-numbers or highlight is set.

line-number

internal .xtyle-code-line__number

The per-line gutter cell, shown when line-numbers is set; it sticks to the left edge as the code scrolls sideways and reads dimmed, like a comment. It is a real node the fragment draws, one per row, so a mod can restyle it, move it to the trailing edge, or grow a fold column beside it.

--code-comment --field-border --code-bg --space-4 --space-2

line-highlight

internal .xtyle-code-line[data-line-highlight]

A line called out by highlight; the whole row is tinted with --code-line-highlight, the low-alpha accent the algorithm derives for exactly this.

--code-line-highlight

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 38/38 consumed tokens produced default register: 311 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors }) → coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--border-thick --border-thin --code-attr --code-bg --code-comment --code-fg --code-function --code-keyword --code-line-highlight --code-number --code-operator --code-punctuation --code-regexp --code-selection --code-string --code-tag --code-type --code-variable --duration-fast --ease-standard --field-border --font-mono --font-sans --leading-normal --neutral --neutral-bg --neutral-fg --neutral-text --radius-md --radius-sm --ring --space-1 --space-2 --space-4 --success --success-vivid --text-sm --text-xs

Slots

default
html svelte

The source code as text content (html/svelte). For Astro, pass the source via the code prop instead.

Accessibility

Renders semantic <pre><code>, so assistive tech announces the block as preformatted code.
Coloring is presentational only: the token spans add no meaning, so the code reads identically with styles off.
The copy control is a real <button> with an accessible name, keyboard-operable, and reachable on touch where there is no hover; on a successful copy its name updates to Copied so the action is announced.
A block whose lines run wider than the frame scrolls horizontally and becomes a keyboard-scrollable region (a tabindex stop only while it overflows), with a focus outline so a keyboard user can see they've landed there before arrowing across it (WCAG 2.1.1 / 2.4.7). Set wrap to soft-wrap instead, and no scroll region appears.

Code

Languages and preload

A TypeScript block and a preloaded Rust block, both colored from the code-token family.

<xtyle-code lang="ts">const greet = (name: string) =&gt; `hi ${name}`;</xtyle-code>

<xtyle-code lang="rust" preload>fn main() { println!("hello"); }</xtyle-code>

Soft-wrap long lines

wrap folds long lines into the column instead of scrolling them sideways. It's a declarative host attribute, so it needs no JavaScript and works on the static Astro path.

<xtyle-code lang="ts" wrap>const message = "a long line that soft-wraps in a narrow column instead of scrolling sideways";</xtyle-code>

Line numbers

line-numbers adds a counter gutter that sticks to the left edge as the code scrolls and keeps a single number per logical line even under wrap.

<xtyle-code lang="ts" line-numbers>function add(a: number, b: number) {
	return a + b;
}

const sum = add(2, 3);</xtyle-code>

Highlighting lines

highlight tints the lines that matter, via a 1-based spec like 2,4 or 4-6, drawn from the --code-line-highlight token the algorithm already derives; it pairs with line-numbers.

<xtyle-code lang="ts" line-numbers highlight="2,4">function total(items) {
	let sum = 0;
	for (const n of items) sum += n;
	return sum;
}</xtyle-code>

A caption header

caption adds a header strip above the block for a filename or label, rounding the top corners into it. It reuses chrome tokens and renders on the static Astro path.

<xtyle-code lang="ts" caption="theme.ts">export const accent = "#5b8cff";</xtyle-code>

Languages

Every language the code block can highlight, 299 in all; each grammar lazy-loaded per block. An unknown language renders as plain, themed text rather than erroring.

Added by xtyle

Info:astro Info:svelte

Prism ships neither; xtyle adds them. Everything else is Prism's canonical set.

Aliases

adoc → asciidoc arm-asm → armasm art → arturo atom → markup avdl → avro-idl avs → avisynth cfc → cfscript cilk → cilkcpp
All 299 languages
abapabnfactionscriptadaagdaalantlr4apacheconfapexaplapplescriptaqlarduinoarffarmasmarturoasciidocasm6502asmatmelaspnetastroautohotkeyautoitavisynthavro-idlawkbashbasicbatchbbcodebbjbicepbirbbisonbnfbqnbrainfuckbrightscriptbrobslccfscriptchaiscriptcilcilkccilkcppclikeclojurecmakecobolcoffeescriptconcurnascooklangcoqcppcrystalcsharpcshtmlcspcsscss-extrascsvcuecypherddartdataweavedaxdhalldiffdjangodns-zone-filedockerdotebnfeditorconfigeiffelejselixirelmerberlangetluaexcel-formulafactorfalsefirestore-security-rulesflowfortranfsharpftlgapgcodegdscriptgedcomgettextgherkingitglslgmlgngogo-modulegradlegraphqlgroovyhamlhandlebarshaskellhaxehclhlslhoonhpkphstshttpichigojamiconicu-message-formatidrisiecstignoreinform7iniiojjavajavadocjavadoclikejavascriptjavastacktracejexljoliejqjs-extrasjs-templatesjsdocjsonjson5jsonpjsstacktracejsxjuliakeepalivedkeymankotlinkumirkustolatexlattelesslilypondlinker-scriptliquidlisplivescriptllvmloglolcodeluamagmamakefilemarkdownmarkupmarkup-templatingmatamatlabmaxscriptmelmermaidmetafontmizarmongodbmonkeymoonscriptn1qln4jsnand2tetris-hdlnaniscriptnasmneonnevodnginxnimnixnsisobjectivecocamlodinopenclopenqasmozparigpparserpascalpascaligopcaxispeoplecodeperlphpphp-extrasphpdocplant-umlplsqlpowerquerypowershellprocessingprologpromqlpropertiesprotobufpslpugpuppetpurepurebasicpurescriptpythonqqmlqoreqsharprracketreasonregexregorenpyrescriptrestriproboconfrobotframeworkrubyrustsassassscalaschemescssshell-sessionsmalismalltalksmartysmlsoliditysolution-filesoysparqlsplunk-splsqfsqlsquirrelstanstatastylussupercollidersvelteswiftsystemdt4-cst4-templatingt4-vbtaptcltextiletomltremortsxtt2turtletwigtypescripttyposcriptunrealscriptuorazorurivvalavbnetvelocityverilogvhdlvimvisual-basicwarpscriptwasmweb-idlwgslwikiwolframwrenxeoraxml-docxojoxqueryyamlyangzig