Code Display
Read-only code surfaces — a highlighted code block, a single-line snippet, a tabbed CLI command block and a unified/split diff.
Code Block — A read-only code-output card with a language tag, an optional filename title, line numbers, a scrollable body, an actions slot and a copy-to-clipboard button.
Preview
function greet(string $name): string
{
return "Hello, {$name}!";
}
<x-ui.code-block language="php" class="mx-auto w-full max-w-xl" />
Installation
php artisan ui:add code-block
Note
This component ships an Alpine behavior module at
resources/js/ui/code-block.js. Import it once from your bundle so it registers on alpine:init:
import './code-block.js';
Use with AI
A brief for your coding agent: install command, usage, props, guidance and the rules. Copy it, or open a prompt about this component in an assistant.
# Brok UI: Code Block (`code-block`)
A read-only code-output card with a language tag, an optional filename title, line numbers, a scrollable body, an actions slot and a copy-to-clipboard button.
Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.
## Install
```bash
php artisan ui:add code-block
```
## Usage
```blade
<x-ui.code-block language="php" class="mx-auto w-full max-w-xl" />
```
## Props
- `language` (string, default `php`)
- `code` (string, default `function greet(string \$name): string\n{\n return \"Hello, {\$name}!\";\n}`)
- `title` (mixed|null, default `null`)
- `numbered` (bool, default `false`)
- `scrollable` (bool, default `false`)
- `maxHeight` (mixed|null, default `null`)
- `wrap` (bool, default `false`) — Long lines wrap inside the card instead of scrolling sideways. With numbered, each source line is its own row, so a number stays level with the first visual line of its wrapped line. The copy button still copies the original text.
## Use when
- Use for exact technical detail, code readability, diagnostics, and copyable reference material.
- Showing a multi-line code sample or command output that a reader will copy.
- Documenting a file, where the language tag and filename title give the snippet its context.
## Avoid when
- Do not surface developer-specific patterns in end-user flows unless the task genuinely requires them.
- Offering an editable surface; this block is read-only.
- Showing a one-line command inline, where code-line is the smaller control.
## Anti-patterns
- Exposing developer tooling in end-user flows without a task need
## Rules
- Use the `<brok:code-block>` tag (or `<x-ui.code-block>`) in Blade; do not rewrite the component.
- Prefer the documented props and variants over utility-class overrides; when a utility must win, use the `!` important modifier.
- Use semantic design tokens (`bg-primary`, `text-muted-foreground`), never raw colour utilities.
- Keep the `data-slot` attributes; they are the styling and test hooks.
## Links
- Docs: https://brokui.dev/docs/components/code-block
- Registry JSON (files, props, contract): https://brokui.dev/r/open/code-block.json
Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.
Examples
@php
$code = "\$response = Http::withToken(config('services.billing.token'))->retry(3, 200)->post('https://billing.example.com/v1/invoices/finalize', ['invoice' => \$invoice->id, 'notify' => true]);\n\nreturn \$response->json('data.status');";
@endphp
{{-- wrap: long lines wrap at the card edge; with numbered, each number stays level with the first line of its wrapped line. --}}
<div class="mx-auto flex w-full max-w-xl flex-col gap-4">
<x-ui.code-block language="php" title="FinalizeInvoice.php" :code="$code" wrap numbered />
<x-ui.code-block language="php" :code="$code" wrap />
</div>
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| language | string | php | |
| code | string | function greet(string \$name): string\n{\n re... | |
| title | mixed | null | null | |
| numbered | bool | false | |
| scrollable | bool | false | |
| maxHeight | mixed | null | null | |
| wrap | bool | false | Long lines wrap inside the card instead of scrolling sideways. With numbered, each source line is its own row, so a number stays level with the first visual line of its wrapped line. The copy button still copies the original text. |
Slots
default—
Data slots
Stable hooks for CSS overrides and browser tests.
Behavior
- The body is read-only text; only the copy button and the actions slot are interactive.
- Line numbers are rendered beside the body when numbered is set, and stay outside the copied text.
- With scrollable set, the body scrolls inside maxHeight instead of growing the card.
- With wrap set, long lines and unbroken tokens wrap at the card edge; the copied text keeps its original line breaks and has no line numbers.
- Installs a JavaScript behavior module when the registry item includes resources/js/ui files.
- Declares registry capability flags: a11y, interactive, responsive, rtl, darkMode, localized.
Guidance
Expose exact technical or diagnostic information.
Use when
- Use for exact technical detail, code readability, diagnostics, and copyable reference material.
- Showing a multi-line code sample or command output that a reader will copy.
- Documenting a file, where the language tag and filename title give the snippet its context.
Avoid when
- Do not surface developer-specific patterns in end-user flows unless the task genuinely requires them.
- Offering an editable surface; this block is read-only.
- Showing a one-line command inline, where code-line is the smaller control.
Use instead
- Plain-language product UI for nontechnical users
Anti-patterns
- Exposing developer tooling in end-user flows without a task need
- Anatomy
- Theming hooks
Accessibility
- Keyboard
- No component-owned keyboard interaction; native element behavior applies.
- Focus
none
- The copy control comes from copy-button, which announces the copied state; decorative chrome is marked aria-hidden.
- Code is plain text, so a screen reader reads it as written and a browser can find it with in-page search.
- Semantic HTML and a stable
data-slotattribute for styling and scripting hooks. - Focus-visible rings use the
ringtoken, so keyboard focus is always visible. - Disabled and invalid states are conveyed to assistive tech, not by color alone.
- Targets WCAG 2.2 AA; verify contrast in light, dark, admin and customer surfaces in the preview.
- Labels go through
__()and layout uses logical properties (ms-*,text-start), so it mirrors underdir="rtl"— flip the preview to RTL to confirm. - Dark mode uses the same semantic tokens under the
darkclass; high contrast follows forced-color system tokens.
Livewire
Livewire can update this component through forwarded wire:* attributes.
Source
The exact, editable file ui:add writes
into your app. Previews render this same code; there are no preview-only components.
@props([
'language' => 'php',
'code' => "function greet(string \$name): string\n{\n return \"Hello, {\$name}!\";\n}",
'title' => null,
'numbered' => false,
'scrollable' => false,
'maxHeight' => null,
// Opt-in: long lines wrap inside the card instead of scrolling sideways.
'wrap' => false,
])
@php
$code = (string) $code;
$numbered = filter_var($numbered, FILTER_VALIDATE_BOOLEAN);
$scrollable = filter_var($scrollable, FILTER_VALIDATE_BOOLEAN);
$lineCount = max(1, substr_count($code, "\n") + 1);
$wrap = filter_var($wrap, FILTER_VALIDATE_BOOLEAN);
// A capped, vertically-scrollable body when asked (or when maxHeight is set).
$maxH = $maxHeight !== null ? (int) $maxHeight : null;
$scroll = $scrollable || $maxH !== null;
@endphp
{{--
Code block — a read-only code-output card. The code is rendered, never
evaluated: it lives inside <pre><code> (Blade escapes it). The header carries
a language pill, an optional filename title and `actions` slot, plus a
<x-ui.copy-button> that copies the plain string we pass it (never an HTML
blob). Optional line numbers, a scrollable/capped body and line wrapping
are additive.
--}}
<div
data-slot="code-block"
{{ $attributes->merge(['class' => 'overflow-hidden rounded-lg border border-border bg-card text-foreground']) }}
>
<div class="flex items-center justify-between gap-2 border-b border-border px-3 py-2">
<div class="flex min-w-0 items-center gap-2">
@if ($title !== null)
<code class="truncate font-mono text-xs font-medium text-foreground">{{ $title }}</code>
@endif
<span class="inline-flex shrink-0 items-center rounded-sm bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground">{{ $language }}</span>
</div>
<div class="flex items-center gap-1">
{{ $actions ?? '' }}
<x-ui.copy-button
:value="$code"
:label="__('Copy code')"
:copied-label="__('Copied')"
class="size-7 h-7 w-7 border-transparent bg-transparent text-muted-foreground hover:bg-muted hover:text-foreground"
/>
</div>
</div>
<div class="overflow-auto" @if ($maxH !== null) style="max-height: {{ $maxH }}px;" @elseif ($scroll) style="max-height: 24rem;" @endif>
@if ($wrap && $numbered)
{{-- One grid row per source line: a wrapped line grows its row, so
its number stays level with the line's first visual line. --}}
<pre dir="ltr" data-wrap class="grid grid-cols-[auto_minmax(0,1fr)] font-mono text-sm leading-6 [&>*:nth-child(-n+2)]:pt-3 [&>*:nth-last-child(-n+2)]:pb-3">@foreach (preg_split("/\r\n|\n|\r/", $code) as $line)<span aria-hidden="true" class="select-none border-e border-border bg-muted/30 px-3 text-end text-muted-foreground tabular-nums">{{ $loop->iteration }}</span><code class="min-w-0 whitespace-pre-wrap break-words px-3">{{ $line }}</code>@endforeach</pre>
@elseif ($wrap)
<pre dir="ltr" data-wrap class="p-3"><code class="whitespace-pre-wrap break-words font-mono text-sm leading-6">{{ $code }}</code></pre>
@elseif ($numbered)
<div class="flex min-w-max">
<div aria-hidden="true" class="shrink-0 select-none whitespace-pre border-e border-border bg-muted/30 px-3 py-3 text-end font-mono text-sm leading-6 text-muted-foreground tabular-nums">@for ($i = 1; $i <= $lineCount; $i++){{ $i }}@if ($i < $lineCount){{ "\n" }}@endif @endfor</div>
<pre dir="ltr" class="flex-1 overflow-x-auto p-3"><code class="font-mono text-sm leading-6">{{ $code }}</code></pre>
</div>
@else
<pre dir="ltr" class="overflow-x-auto p-3"><code class="font-mono text-sm leading-6">{{ $code }}</code></pre>
@endif
</div>
</div>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
2.3.0 - Status
- Stable
- License
-
open - Accessibility reviewed
- No review date recorded
- Last breaking change
- No date recorded
- Deprecation
- Not deprecated
- Contract
-
v6 - Foundation
-
≥ 1.0.0