Code Block
Styled code surface for snippets, configs, theme exports. Optional header strip with language label and filename, optional line numbers, opt-in regex highlighter for js, ts, json, css, html, bash. Lightweight — no highlighting library, just spans driven by per-language regex. Inline counterpart .lb-code for prose-level snippets.
a11y (built in): Copy / Save / Open / Apply are real <button type="button">s, each with an aria-label and the system :focus-visible outline, and they are always visible rather than hover-revealed, so keyboard and touch users reach the same affordances as a mouse. Copy confirms in place — the button swaps its own icon and label to Copied for 1.5s, no toast to chase — and the line-number gutter is CSS counter() content marked user-select: none, so numbers never enter the selection or the clipboard (Copy writes the raw source as plain text).
Usage: <pre data-lb-code-block><code>…</code></pre>. Add data-lb-lang, data-lb-title, data-lb-numbers, data-lb-no-copy as needed.
Plain — no header, no highlighting
Just a styled surface and an always-visible copy button anchored top-right. Use for one-line install commands and short config snippets.
npm install letbe-ds
With filename + language label
Header strip carries a filename on the left, the language label on the right, and the copy button. Highlighter runs when data-lb-lang is set.
import { signIn } from './session';
interface AuthOptions {
redirect?: string;
remember?: boolean;
}
export async function authenticate(opts: AuthOptions = {}) {
// attempt the sign-in flow
const session = await signIn(opts);
return session.token;
}
JSON with line numbers
Add data-lb-numbers for a numbered gutter — useful when you reference specific lines in surrounding prose.
{
"name": "letbe-ds",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "python3 -m http.server 8080",
"lint": "node --check js/lb.js"
}
}
HTML
Tags and attributes use distinct token colors. Note the < / > need escaping in the HTML source — same as anywhere code is embedded inside HTML.
<div class="lb-card lb-card--padded">
<div class="lb-card__heading">
<div class="lb-card__title">Active users</div>
<div class="lb-card__subtitle">Last 7 days</div>
</div>
<div class="lb-stat">
<div class="lb-stat__value">12,486</div>
</div>
</div>
CSS
Custom properties (--var-name) are picked out as attribute tokens; at-rules and selectors are highlighted distinctly.
:root {
--lb-radius-field: 6px;
--lb-radius-overlay: 12px;
}
@media (prefers-color-scheme: dark) {
:root {
--lb-bg-default: #0a0a0a;
}
}
.lb-button {
padding: 8px 16px;
background: var(--lb-action-bg-primary);
border-radius: var(--lb-radius-field);
}
Bash
Common shell commands, control flow, and quoted strings.
# Install dependencies and start the dev server
npm install
git checkout -b feat/charts
if [ -d "dist" ]; then
echo "Cleaning previous build…"
rm -rf dist
fi
npm run build && npm run dev
Inline code — .lb-code
For prose-level snippets — the name of a file, a flag, a command name. Sits inline with body text without breaking line height. Add .lb-code to a <code> tag.
Run npm install letbe-ds to add the system to your project, then import the CSS via
@import "letbe-ds/components.css" in your stylesheet. The kebab-case attribute
data-lb-component drives auto-init.
No copy button — data-lb-no-copy
Hide the copy button when the snippet is illustrative rather than something to grab.
// pseudocode — illustrates the pattern, not runnable
function pipeline(input) {
return transform(filter(parse(input)));
}
Action row — Save / Open / Apply
The Copy button is joined by additional actions, all always-visible (per forum feedback that hover-only chrome hides discoverable affordances):
- Copy — smart dual-format. Writes both
text/plainANDtext/html(with syntax-highlight preservation) to the clipboard, so pasting into a rich-text editor gets formatted code while terminal pastes get clean plain text. Opt out withdata-lb-no-copy. - Save — downloads the source as a file. Filename uses
data-lb-titleif it already has an extension, otherwise builds{title-or-snippet}.{ext}from the language. Opt out withdata-lb-no-save. - Open — opt-in via
data-lb-open. Emitslb-code-openwith{source, lang, title}— consumer routes to their editor of choice (in-page panel, VS Code deep link, etc.). - Apply — opt-in via
data-lb-apply. Primary-styled. Emitslb-code-applyfor dev-surface consumers building “apply this change to file X” flows.
All four also available programmatically: el._lbCodeBlock.copy() / save() / openInEditor() / apply().
// Try Copy → paste into a rich-text editor to see syntax highlighting preserved.
// Try Save → download as src/api.ts. Open and Apply emit events.
export async function fetchUser(id: string) {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('Failed to fetch user');
return response.json();
}
Without a header, the actions float top-right with a card background so they stay legible over highlighted code:
rm -rf node_modules
npm install
npm run dev
Programmatic update — setSource()
Swap the rendered code at runtime — useful for theme exports, query inspectors, or any block whose source comes from app state.
// Click a button to swap the source live
const value = 42;