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/plain AND text/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 with data-lb-no-copy.
  • Save — downloads the source as a file. Filename uses data-lb-title if it already has an extension, otherwise builds {title-or-snippet}.{ext} from the language. Opt out with data-lb-no-save.
  • Open — opt-in via data-lb-open. Emits lb-code-open with {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. Emits lb-code-apply for 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;