Code Block
A composed component built from .code-sample, .code-block, and
.code-copy-btn. Supports Prism.js syntax highlighting, a CSS-generated
language header bar, and a one-click copy button.
Source files: showcase/showcase.css, showcase/showcase.js
Anatomy
Three elements compose a full code sample:
-
.code-sample— Outer wrapper. Setsposition: relativeand holds adata-langattribute used by the::beforepseudo-element to render the header bar label. -
.code-copy-btn— Absolutely positioned button in the header bar. Reads the<pre>text content and writes to the clipboard. Shows "Copied!" feedback for 1.5 s. -
.code-block— The<pre>element that contains a<code class="language-*">child for Prism.js tokenization.
<div class="code-sample" data-lang="html">
<button class="code-copy-btn" type="button" data-copy>Copy</button>
<pre class="code-block"><code class="language-html">
<!-- your escaped HTML here -->
</code></pre>
</div>
HTML
Set data-lang="html" and class="language-html" on the inner <code>.
<div class="wm-card card" style="padding: 1rem;">
<h3>Card Title</h3>
<p>Card body text.</p>
</div>
JavaScript
Use data-lang="js" and class="language-js" (or language-javascript).
const saved = localStorage.getItem('wm-showcase-theme');
if (saved === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
}
CSS
Use data-lang="css" and class="language-css".
:root {
--wm-color-accent: #3b82f6;
--wm-radius-md: 0.5rem;
}
[data-theme="dark"] {
--wm-color-bg: #141414;
--wm-color-surface: #1a1a1a;
}
Bash / Shell
Use data-lang="bash" and class="language-bash".
npm install @wintermuted/ui-theme
# or
yarn add @wintermuted/ui-theme
Mermaid Diagrams
Mermaid usage now has a dedicated component page with setup guidance, rendering examples, and docs patterns.
Copy Button Behavior
The .code-copy-btn element requires a data-copy attribute to be wired
by showcase.js. On click, the script reads pre.textContent.trim()
(post-Prism tokenization) and calls navigator.clipboard.writeText(). The button
label changes to "Copied!" for 1.5 seconds, then resets.
The copy button is always visible — positioned absolutely in the header bar. No hover required.
// showcase.js — wireCopyButtons()
document.querySelectorAll('[data-copy]').forEach((btn) => {
btn.addEventListener('click', () => {
const pre = btn.closest('.code-sample').querySelector('pre');
navigator.clipboard.writeText(pre.textContent.trim()).then(() => {
btn.textContent = 'Copied!';
setTimeout(() => (btn.textContent = 'Copy'), 1500);
});
});
});
Header Bar via CSS
The language label in the header bar is generated entirely in CSS using the ::before
pseudo-element and the attr() function. No JavaScript reads the data-lang
attribute — the label is purely decorative metadata for the reader.
/* showcase.css */
.code-sample {
position: relative;
}
.code-sample::before {
content: attr(data-lang);
display: flex;
align-items: center;
height: 2rem;
padding: 0 0.75rem;
background: var(--wm-color-surface-strong);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--wm-color-text-muted);
}
Prism.js Integration
Syntax highlighting is handled by Prism.js 1.29.0 loaded from CDN. Include the core script,
autoloader plugin, and a theme CSS before your page scripts. The autoloader fetches language
grammar files on demand based on the class="language-*" attribute.
<!-- In <head> -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css"
crossorigin
/>
<!-- Before closing </body> -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"
crossorigin
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"
crossorigin
></script>
// Configure autoloader path and trigger highlight
if (typeof Prism !== 'undefined') {
Prism.plugins.autoloader.languages_path =
'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/';
Prism.highlightAll();
}