@profpowell/code-block
v2.9.0
Published
A code block web component with syntax highlighting (via highlight.js), copy functionality, line numbers, and theme support
Downloads
1,272
Maintainers
Readme
code-block
A feature-rich code block web component with syntax highlighting, copy-to-clipboard, and extensive customization options. Designed for tutorials, documentation, and educational content.
Highlights
See the live demo for all features in action
| Feature | Description |
|---------|-------------|
| Multi-File Tabs | Tabbed interface for related code files with <code-block-group> |
| Line Highlighting | Draw attention to specific lines with highlight-lines="3,5-7" |
| Focus Mode | Dim non-highlighted lines with focus-mode for emphasis |
| Share & Download | One-click download or open in CodePen |
| Collapsible Blocks | Expandable code with "Show more" for long snippets |
| Lazy Loading | Defer syntax highlighting until visible for performance |
| Diff Support | Visualize code changes with +/- line highlighting |
| Custom Themes | Full CSS custom property support for branding |
| Light & Dark | GitHub-inspired color schemes |
Features
- 13 Web Languages - HTML, CSS, JS, JSON, YAML, PHP, and more
- Line Numbers - Optional line number display
- Filename Headers - Show file paths in the header
- Copy to Clipboard - One-click copy with visual feedback
- Word Wrap - Toggle between scroll and wrap for long lines
- Shadow DOM - Encapsulated styles that won't conflict with your app
- Accessible - ARIA labels, keyboard focus, screen reader support
- TypeScript Support - Full type definitions included
Installation
npm
npm install @profpowell/code-blockGit Submodule
Add this repository as a git submodule to your project:
git submodule add https://github.com/ProfPowell/code-block.git lib/code-block
cd lib/code-block && npm installThen import the component:
import './lib/code-block/code-block.js';Usage
Once imported, the <code-block> custom element is automatically registered:
<code-block language="javascript">
function greet(name) {
return `Hello, ${name}!`;
}
</code-block>With Custom Label
<code-block language="python" label="Data Processing">
import pandas as pd
df = pd.read_csv('data.csv')
print(df.head())
</code-block>Dark Theme
<code-block language="css" theme="dark">
.container {
display: grid;
gap: 1rem;
}
</code-block>With Line Numbers
<code-block language="javascript" show-lines>
class EventEmitter {
constructor() {
this.events = new Map();
}
on(event, callback) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event).push(callback);
}
}
</code-block>Combined Options
<code-block language="typescript" theme="dark" show-lines label="User Service">
interface User {
id: number;
name: string;
}
class UserService {
async getUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
}
</code-block>Supported Languages
The component includes an optimized bundle with 13 web development languages:
| Language | Values |
|----------|--------|
| HTML | html, markup |
| XML | xml |
| XHTML | xhtml |
| SVG | svg |
| CSS | css |
| JavaScript | javascript, js |
| JSON | json |
| YAML | yaml, yml |
| PHP | php |
| HTTP | http |
| Diff | diff |
| Plain Text | plaintext, text, txt |
| CSV | csv |
Additional languages can be added by importing them from highlight.js.
API
Attributes
| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| language | string | 'plaintext' | Programming language for highlighting |
| label | string | language | Label displayed in the header |
| theme | 'light' | 'dark' | 'light' | Color theme |
| show-lines | boolean | false | Display line numbers |
| filename | string | — | File path shown in header |
| highlight-lines | string | — | Lines to highlight (e.g., "3,5-7") |
| focus-mode | boolean | false | Dim non-highlighted lines for emphasis |
| collapsed | boolean | false | Start in collapsed state |
| max-lines | number | 10 | Lines visible when collapsed |
| max-height | string | — | Max height with scrolling (e.g., "300px") |
| wrap | boolean | false | Wrap long lines |
| copy-text | string | 'Copy' | Custom copy button text |
| copied-text | string | 'Copied!' | Custom success message |
| show-share | boolean | false | Show share button |
| show-download | boolean | false | Show download button |
| lazy | boolean | false | Defer highlighting until visible |
Methods
| Method | Returns | Description |
|--------|---------|-------------|
| copyCode() | Promise<void> | Copy code to clipboard |
| setCode(code) | void | Update code content |
| getCode() | string | Get current code |
| downloadCode() | void | Download as file |
| openInCodePen() | void | Open in CodePen |
| toggleCollapsed() | void | Toggle collapsed state |
| render() | void | Re-render the component |
CSS Custom Properties
The component exposes 60+ CSS custom properties for full theme control. Properties marked "theme-aware" adapt automatically to light/dark mode.
Container & Layout
| Property | Default | Description |
|----------|---------|-------------|
| --cb-bg | theme-aware | Outer container background |
| --cb-code-bg | theme-aware | Code area background |
| --cb-border-color | theme-aware | Border color used throughout |
| --cb-border-radius | 8px | Outer container border radius |
| --cb-margin | 1rem 0 | Component outer margin |
| --cb-shadow | theme-aware | Box shadow on dropdown menus |
Typography
| Property | Default | Description |
|----------|---------|-------------|
| --cb-font-family | Consolas, Monaco, Courier New, monospace | Code font |
| --cb-ui-font-family | -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif | UI font (buttons, menus) |
| --cb-font-size | 0.875rem | Base code font size |
| --cb-text-color | theme-aware | Default code text color |
| --cb-line-height | 1.6 | Code line height |
Header
| Property | Default | Description |
|----------|---------|-------------|
| --cb-header-bg | theme-aware | Header bar background |
| --cb-header-padding | 0.5rem 1rem | Header padding |
| --cb-label-color | theme-aware | Language label and icon color |
| --cb-filename-color | theme-aware | Filename text color |
Buttons
| Property | Default | Description |
|----------|---------|-------------|
| --cb-button-bg | theme-aware | Button background |
| --cb-button-color | theme-aware | Button text color |
| --cb-button-border | theme-aware | Button border color |
| --cb-button-border-width | 1px | Button border width |
| --cb-button-border-style | solid | Button border style (solid, none, etc.) |
| --cb-button-radius | 4px | Border radius for copy and action buttons |
| --cb-button-padding | 4px 12px | Copy button padding |
| --cb-button-font-size | 0.75rem | Copy button font size |
| --cb-button-hover-bg | theme-aware | Copy button hover background |
| --cb-button-hover-border | theme-aware | Copy button hover border color |
| --cb-action-button-hover-bg | theme-aware | Icon button hover background |
| --cb-success-color | #238636 | Copied-success state color |
| --cb-error-color | #da3633 | Copy-failed state color |
| --cb-focus-color | theme-aware | Focus ring color |
Code Area & Line Numbers
| Property | Default | Description |
|----------|---------|-------------|
| --cb-code-padding | 1rem | Code area and gutter padding |
| --cb-line-numbers-bg | theme-aware | Line-numbers gutter background |
| --cb-line-numbers-color | theme-aware | Line-numbers text color |
Syntax Highlighting
| Property | Default (Light / Dark) | Description |
|----------|----------------------|-------------|
| --cb-keyword | #d73a49 / #ff7b72 | Keywords |
| --cb-string | #22863a / #a5d6ff | Strings |
| --cb-comment | theme-aware | Comments |
| --cb-function | #6f42c1 / #d2a8ff | Function names |
| --cb-number | #005cc5 / #79c0ff | Numbers |
| --cb-attribute | #005cc5 / #79c0ff | HTML/XML attributes |
| --cb-tag | #22863a / #7ee787 | HTML/XML tags |
| --cb-meta | #e36209 / #ffa657 | Meta/preprocessor tokens |
| --cb-builtin | #d73a49 / #ffa198 | Built-in names |
See docs/api.html for the complete reference including diff, expand/collapse, scrollbar, highlight, and focus-mode properties.
Example: Vanilla Breeze Integration
code-block {
--cb-button-radius: 0;
--cb-button-border-style: none;
--cb-border-radius: 0;
--cb-ui-font-family: 'Inter', sans-serif;
--cb-font-family: 'JetBrains Mono', monospace;
}Programmatic Usage
// Get a reference to a code block
const codeBlock = document.querySelector('code-block');
// Copy code programmatically
await codeBlock.copyCode();
// Update code content dynamically
codeBlock.setCode('const updated = true;');
// Get current code
const code = codeBlock.getCode();
// Get all supported languages (static method)
const languages = CodeBlock.getSupportedLanguages();
console.log(`Supports ${languages.length} languages`);Server-Side Rendering (SSR)
For static sites and documentation, code blocks can be pre-rendered at build time using the SSR module. This eliminates client-side syntax highlighting and displays code instantly using Declarative Shadow DOM.
Installation
The SSR module is included in the package — no extra install needed:
import { prerenderCodeBlock, prerenderCodeBlocksInHtml } from '@profpowell/code-block/ssr'Single Block
const html = prerenderCodeBlock({
code: 'const x = 42;',
language: 'javascript',
theme: 'dark',
showLines: true,
filename: 'app.js',
})
// Returns complete <code-block data-ssr> with Declarative Shadow DOMProcess an HTML Page
const page = prerenderCodeBlocksInHtml(rawHtml)
// Finds all <code-block> elements and pre-renders them
// Skips blocks with src attribute or data-ssr (already processed)SSG Integration (Cook, Eleventy, etc.)
The SSR module runs in Node.js and can be used as a build step in any static site generator:
// Example Cook plugin
import { prerenderCodeBlocksInHtml } from '@profpowell/code-block/ssr'
// Process HTML after all other transforms
file.src = prerenderCodeBlocksInHtml(file.src)How It Works
- Build time:
prerenderCodeBlock()runs highlight.js in Node.js and generates the full shadow DOM HTML - Output: A
<code-block data-ssr>element with<template shadowrootmode="open">containing pre-rendered styles and highlighted code, plus a<textarea>preserving raw code for copy-to-clipboard - Browser: The Declarative Shadow DOM template is parsed into a real shadow root — code is visible immediately, before any JavaScript loads
- Hydration: When the component JS loads, it detects
data-ssr, skips re-rendering, and attaches interactive event listeners (copy, download, share, expand/collapse)
Options
prerenderCodeBlock() accepts all the same options as the component's HTML attributes:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| code | string | required | Source code to highlight |
| language | string | 'plaintext' | Language for highlighting |
| theme | string | 'light' | 'light' or 'dark' |
| filename | string | — | Filename in header |
| label | string | — | Custom label |
| showLines | boolean | false | Show line numbers |
| highlightLines | string | — | Lines to highlight, e.g. "2,4-6" |
| focusMode | boolean | false | Dim non-highlighted lines |
| collapsed | boolean | false | Start collapsed |
| maxLines | number | 10 | Visible lines when collapsed |
| maxHeight | string | — | Max height with scroll |
| wrap | boolean | false | Word wrap |
| noCopy | boolean | false | Hide copy button |
| copyText | string | 'Copy' | Copy button text |
| showShare | boolean | false | Show share button |
| showDownload | boolean | false | Show download button |
Demo
Open demo.html in a browser to see all features in action:
- Multi-file tabbed interface
- Line highlighting
- Focus mode
- Share & download buttons
- Collapsible code blocks
- Lazy loading for performance
- Diff visualization
- CSS custom properties
- Light and dark themes
- Complete API reference
Browser Support
Works in all modern browsers that support:
- Custom Elements v1
- Shadow DOM v1
- ES6 Modules
- Clipboard API
Dependencies
- highlight.js ^11.11.1 - Syntax highlighting
License
MIT License - see LICENSE for details.
