Loaders
A loading-ui.com-inspired family of animated loaders — spinners, dots, orbital, bars, square grids, shapes, text and a few playful ones — all token-themed and reduced-motion safe.
Preview
<div class="w-full flex justify-center"><x-ui.terminal-loader class="w-72" /></div>
Installation
php artisan ui:add terminal-loader
Registry contract
php artisan ui:add terminal-loader
writes only the files below. The CLI validates each file hash before writing and asks before it replaces a local change, unless you pass --force.
-
resources/views/components/ui/terminal-loader.blade.php
- Registry dependencies
- None — installs on its own.
- Packages
-
composer: jml/brok:^0.2
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: Terminal Loader (`terminal-loader`)
A terminal-window loader whose command lines reveal one-by-one with a blinking block cursor, looping as ongoing work.
Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.
## Install
```bash
php artisan ui:add terminal-loader
```
## Usage
```blade
<div class="w-full flex justify-center"><x-ui.terminal-loader class="w-72" /></div>
```
## Props
- `lines` (array, default `['$ npm install', '› building modules…', '› optimizing…', '✓ ready']`) — Command lines revealed one-by-one, in order; falls back to a two-line default when empty.
- `label` (string, default `Loading`) — Accessible status label announced to screen readers.
- `variant` (string, default `default`) — Reserved for future looks; any value currently renders the same default look.
## Use when
- Use while content or system work is in progress so users understand the interface is responding.
- Indicating background build, install, or processing work with a faithful terminal-window animation.
- Wanting command lines to reveal one-by-one with a blinking cursor, looping as ongoing work.
## Avoid when
- Do not use indefinite loading indicators when you can show structure, progress, or a next step instead.
- Needing a generic, chrome-free loading indicator; use spinner or dots-loader instead.
- Showing a real, live command output stream; this component only loops a fixed, static set of lines.
## Anti-patterns
- Indefinite loading with no progress or recovery
## Rules
- Use the `<brok:terminal-loader>` tag (or `<x-ui.terminal-loader>`) 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/terminal-loader
- Registry JSON (files, props, contract): https://brokui.dev/r/open/terminal-loader.json
Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| lines | array | ['$ npm install', '› building modules…', '› opti... | Command lines revealed one-by-one, in order; falls back to a two-line default when empty. |
| label | string | Loading | Accessible status label announced to screen readers. |
| variant | string | default | Reserved for future looks; any value currently renders the same default look. |
Slots
default— Unused; the component has no visible default slot content.
Data slots
Stable hooks for CSS overrides and browser tests.
Behavior
- Lines reveal in sequence with a staggered animation delay; the last line carries a blinking block cursor.
- The whole sequence loops continuously so it reads as ongoing work; motion is disabled under prefers-reduced-motion.
- Declares registry capability flags: a11y, responsive, rtl, darkMode, localized, reducedMotion.
Guidance
Show that content or system work is in progress.
Use when
- Use while content or system work is in progress so users understand the interface is responding.
- Indicating background build, install, or processing work with a faithful terminal-window animation.
- Wanting command lines to reveal one-by-one with a blinking cursor, looping as ongoing work.
Avoid when
- Do not use indefinite loading indicators when you can show structure, progress, or a next step instead.
- Needing a generic, chrome-free loading indicator; use spinner or dots-loader instead.
- Showing a real, live command output stream; this component only loops a fixed, static set of lines.
Use instead
- Skeleton for known layout
- Determinate progress for measurable work
Anti-patterns
- Indefinite loading with no progress or recovery
- Anatomy
- Theming hooks
Accessibility
- Keyboard
- No component-owned keyboard interaction; native element behavior applies.
- Focus
none
- The root carries role="status" and an aria-label built from the label prop; the terminal window chrome and lines are aria-hidden so only the label is announced.
- Line text renders through {{ }} escaping, so arbitrary strings stay inert.
- 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([
'lines' => ['$ npm install', '› building modules…', '› optimizing…', '✓ ready'],
'label' => 'Loading',
'variant' => 'default',
])
@php
$styles = require base_path(config('ui.component_path', 'resources/views/components/ui').'/_styles.php');
$variant = $styles['normalizeVariant']($variant);
// A faithful loading-ui.com "terminal" loader: a small window where command
// lines reveal one-by-one and the last line carries a blinking block cursor.
// The whole sequence loops so it reads as ongoing work. Motion lives in
// ui.css keyed on [data-slot="terminal-loader"] and is reduced-motion gated;
// line text is escaped via {{ }} so arbitrary strings stay inert.
$variant = $variant === 'default' ? 'default' : 'default';
$lines = array_values(array_filter((array) $lines, fn ($l) => $l !== null));
if ($lines === []) {
$lines = ['$ npm install', '✓ ready'];
}
$last = count($lines) - 1;
@endphp
<div
data-slot="terminal-loader"
data-variant="{{ $variant }}"
role="status"
aria-label="{{ __($label) }}"
{{ $attributes->merge(['class' => 'inline-block bg-card border border-border rounded-lg font-mono text-xs text-muted-foreground overflow-hidden']) }}
>
<span class="sr-only">{{ __($label) }}</span>
<div class="flex items-center gap-2 border-b border-border px-3 py-2" aria-hidden="true">
<span class="size-2 rounded-full bg-muted-foreground/40"></span>
<span class="size-2 rounded-full bg-muted-foreground/40"></span>
<span class="size-2 rounded-full bg-muted-foreground/40"></span>
</div>
<div class="flex flex-col gap-1 px-3 py-3 leading-5" aria-hidden="true">
@foreach ($lines as $line)
<div class="terminal-loader-line flex items-center" style="animation-delay:{{ $loop->index * 350 }}ms">
<span>{{ $line }}</span>
@if ($loop->index === $last)
<span class="terminal-loader-cursor ms-1 inline-block h-4 w-2 bg-foreground"></span>
@endif
</div>
@endforeach
</div>
</div>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
1.1.3 - 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