Code Block
Syntax-highlighted code display with optional filename and copy button.
<arc-code-block> Overview
>
CodeBlock displays source code in a styled container with a header bar, optional filename, language badge, and a one-click copy button. The header renders the filename in monospace font on the left, the language identifier as an uppercase Tomorrow badge on the right, and a "Copy" button that writes the code content to the clipboard via the Clipboard API. After a successful copy, the button text and border color switch to a green "Copied" state for two seconds before reverting.
The code body renders inside a `<pre>` element with the monospace font stack (JetBrains Mono), a line-height of 1.8, and horizontal overflow scrolling for long lines. Code content is provided via the `code` property — there is no default slot, so content placed between the tags is not rendered. The tab-size is set to 2 for compact indentation.
**Highlighting is opt-in.** CodeBlock is the one component in ARC UI with a heavy dependency: shiki and its grammars are around 13.6 MB, which no other component touches. So shiki is an *optional peer dependency*, and CodeBlock is the one component the main barrel does not re-export — a bundler resolves the dynamic imports of everything it can reach, so being in the barrel would have made shiki everyone's install. Import it by its own subpath and install shiki alongside:
```
npm install shiki @shikijs/langs
```
```js
import '@arclux/arc-ui/code-block';
```
Without shiki, CodeBlock still renders: the layout, the header, the copy button, and the code itself all work — the code is simply not colored, and the console says so once. `@arclux/arc-ui/register` does not register CodeBlock for the same reason; import the subpath.
CodeBlock is marked as a hybrid component: the code display works without JavaScript (the layout and styling are pure CSS), but the copy-to-clipboard functionality requires JS and a secure context (HTTPS). The component gracefully handles copy failures with a silent try-catch, so it degrades without errors on HTTP or restricted environments.Guidelines
When to use
- Set the language prop to help users identify the code syntax at a glance
- Provide a filename when showing code from a specific file for context
- Install shiki and @shikijs/langs when you want highlighting — the component works without them, just uncolored
- Import `@arclux/arc-ui/code-block` directly; the main barrel and `/register` deliberately exclude it
- Place CodeBlock in documentation pages, API references, and tutorial content
- Test copy functionality on HTTPS — the Clipboard API requires a secure context
When not to use
- Do not pass content between the tags — there is no default slot; use the `code` prop
- Do not expect highlighting without shiki installed — check the console if code renders uncolored
- Do not use CodeBlock for single-line inline code; use arc-text variant="code" instead
- Do not omit the language prop when the syntax is not obvious from context
- Do not override the font-family unless you are intentionally switching to a different monospace font
- Do not assume copy will always work — it requires HTTPS and a user gesture in modern browsers
Features
- One-click copy-to-clipboard via the Clipboard API with a 2-second "Copied" confirmation
- Header bar with filename (monospace), language badge (uppercase Tomorrow), and copy button
- Horizontal scroll overflow for long code lines without wrapping
- Syntax highlighting via shiki — an optional peer dependency, imported only by this component
- Renders uncolored but fully functional when shiki is not installed
- Code content via the "code" prop (this component has no default slot)
- JetBrains Mono font stack with 1.8 line-height and tab-size of 2
- Graceful degradation: copy fails silently on insecure contexts without breaking the UI
- Six exposed CSS parts: code-block, header, filename, lang, copy, body, pre, code
- Surface and card background tokens for seamless integration with dark themes
Preview
Usage
Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.
<arc-code-block language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
</arc-code-block> import { CodeBlock } from '@arclux/arc-ui-react';
<CodeBlock language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
export default function Example() {
return (
</CodeBlock>
);
} <script setup>
import { CodeBlock } from '@arclux/arc-ui-vue';
</script>
<template>
<CodeBlock language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
</CodeBlock>
</template> <script>
import { CodeBlock } from '@arclux/arc-ui-svelte';
</script>
<CodeBlock language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
</CodeBlock> import { Component } from '@angular/core';
import { CodeBlock } from '@arclux/arc-ui-angular';
@Component({
imports: [CodeBlock],
template: `
<arc-code-block language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
</arc-code-block>
`,
})
export class MyComponent {} import { CodeBlock } from '@arclux/arc-ui-solid';
<CodeBlock language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
export default function Example() {
return (
</CodeBlock>
);
} import { CodeBlock } from '@arclux/arc-ui-preact';
<CodeBlock language="js" filename="example.js">
import { Button } from '@arclux/arc-ui';
export default function Example() {
return (
</CodeBlock>
);
} <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-code-block — requires code-block.css + base.css (or arc-ui.css) -->
<div class="arc-code-block">
<div class="code-block">
<div class="code-block__header">
<span class="code-block__filename">Filename</span>
<span class="code-block__lang">Language</span>
<button
class="code-block__copy"
aria-label="_copied"
>_copied</button>
</div>
<div class="code-block__body">
<pre class="code-block__pre"><code>Code</code></pre>
</div>
</div>
</div> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-code-block — self-contained, no external CSS needed -->
<style>
.arc-code-block .code-block__copy:hover { color: rgb(232, 232, 236);
border-color: rgb(51, 51, 64); }
</style>
<div class="arc-code-block" style="display: block">
<div class="code-block" style="background: rgb(10, 10, 15); border: 1px solid rgb(34, 34, 41); border-radius: 14px; overflow: hidden">
<div style="display: flex; align-items: center; justify-content: space-between; padding: 4px 16px; border-bottom: 1px solid rgb(24, 24, 30); background: rgb(13, 13, 18)">
<span style="font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12px; color: rgb(124, 124, 137)">Filename</span>
<span style="font-family: 'Tomorrow', system-ui, sans-serif; font-size: 10px; letter-spacing: 1px; text-transform: uppercase; color: rgb(107, 107, 128)">Language</span>
<button
class="code-block__copy" style="display: flex; align-items: center; gap: 4px; background: none; border: 1px solid rgb(34, 34, 41); border-radius: 4px; color: rgb(124, 124, 137); font-family: 'Tomorrow', system-ui, sans-serif; font-size: 10px; letter-spacing: 1px; text-transform: uppercase; padding: 4px 8px; cursor: pointer"
aria-label="_copied"
>_copied</button>
</div>
<div style="padding: 16px; overflow-x: auto">
<pre style="margin: 0; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 13px; line-height: 1.8; color: rgb(232, 232, 236); white-space: pre; tab-size: 2"><code>Code</code></pre>
</div>
</div>
</div> API
-
languagestring'' - Programming language identifier (e.g. `js`, `css`, `html`). Displayed in uppercase in the header bar.
-
filenamestring'' - Optional filename displayed in the header in monospace font. When empty, the header shows only the language.
-
codestring'' - Code content to display. Used as the `<pre><code>` content and copied to clipboard when the copy button is clicked.
-
variant'default' | 'window' | 'basic''default' - Visual variant. `default` shows the standard layout with optional filename header and status bar. `window` adds a macOS-style title bar with colored orbs and centered filename. `basic` strips all chrome for a compact, minimal display.