Mockups
Device and browser frames for screenshots — a browser-window chrome, a generic device bezel and an iPhone shell.
iPhone Mockup — A polished iPhone frame with Dynamic Island, side buttons and an optional status bar that wraps any screen content.
Preview
Good morning
Today
Product sync
10:00 — Google Meet
Design critique
14:00 — Studio B
<div class="w-full flex justify-center py-4">
<x-ui.iphone-mockup time="9:41">
<div class="flex h-full flex-col bg-gradient-to-b from-primary/10 to-background p-5">
<p class="text-xs font-medium text-muted-foreground">Good morning</p>
<h3 class="mt-1 text-xl font-bold text-foreground">Today</h3>
<div class="mt-4 space-y-2">
<div class="rounded-xl border border-border bg-card p-3 shadow-sm">
<p class="text-sm font-semibold text-foreground">Product sync</p>
<p class="text-xs text-muted-foreground">10:00 — Google Meet</p>
</div>
<div class="rounded-xl border border-border bg-card p-3 shadow-sm">
<p class="text-sm font-semibold text-foreground">Design critique</p>
<p class="text-xs text-muted-foreground">14:00 — Studio B</p>
</div>
</div>
</div>
</x-ui.iphone-mockup>
</div>
Installation
php artisan ui:add iphone-mockup
Registry contract
php artisan ui:add iphone-mockup
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/iphone-mockup.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: iPhone Mockup (`iphone-mockup`)
A polished iPhone frame with Dynamic Island, side buttons and an optional status bar that wraps any screen content.
Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.
## Install
```bash
php artisan ui:add iphone-mockup
```
## Usage
```blade
<div class="w-full flex justify-center py-4">
<x-ui.iphone-mockup time="9:41">
<div class="flex h-full flex-col bg-gradient-to-b from-primary/10 to-background p-5">
<p class="text-xs font-medium text-muted-foreground">Good morning</p>
<h3 class="mt-1 text-xl font-bold text-foreground">Today</h3>
<div class="mt-4 space-y-2">
<div class="rounded-xl border border-border bg-card p-3 shadow-sm">
<p class="text-sm font-semibold text-foreground">Product sync</p>
<p class="text-xs text-muted-foreground">10:00 — Google Meet</p>
</div>
<div class="rounded-xl border border-border bg-card p-3 shadow-sm">
<p class="text-sm font-semibold text-foreground">Design critique</p>
<p class="text-xs text-muted-foreground">14:00 — Studio B</p>
</div>
</div>
</div>
</x-ui.iphone-mockup>
</div>
```
## Props
- `color` (mixed|null, default `null`) — Bezel color class; defaults to bg-foreground.
- `island` (bool, default `true`) — Shows the Dynamic Island notch at the top of the screen.
- `statusBar` (bool, default `true`) — Shows the time and signal/wifi/battery status bar.
- `time` (string, default `9:41`) — Time text shown in the status bar.
- `label` (string, default `iPhone mockup`) — Accessible label for the mockup; defaults to 'iPhone mockup'.
## Use when
- Use only when visual expression supports storytelling, brand differentiation, or a clear showcase moment.
- Framing app or website screenshots inside a detailed, brand-accurate iPhone frame, including the Dynamic Island and status bar.
## Avoid when
- Do not place heavy effects in task-dense workflows where clarity, speed, and readability matter more.
- A generic, less detailed phone, tablet, or laptop schematic is enough; use device instead.
## Anti-patterns
- Heavy effects in forms or task-dense workflows
- Motion that interferes with reading or focus
## Rules
- Use the `<brok:iphone-mockup>` tag (or `<x-ui.iphone-mockup>`) 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/iphone-mockup
- Registry JSON (files, props, contract): https://brokui.dev/r/open/iphone-mockup.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 |
|---|---|---|---|
| color | mixed | null | null | Bezel color class; defaults to bg-foreground. |
| island | bool | true | Shows the Dynamic Island notch at the top of the screen. |
| statusBar | bool | true | Shows the time and signal/wifi/battery status bar. |
| time | string | 9:41 | Time text shown in the status bar. |
| label | string | iPhone mockup | Accessible label for the mockup; defaults to 'iPhone mockup'. |
Slots
default—
Data slots
Stable hooks for CSS overrides and browser tests.
Behavior
- island and statusBar independently toggle the Dynamic Island notch and the time/signal/battery status bar drawn at the top of the screen.
- The screen surface uses bg-background so slotted content always inherits the current theme.
- Declares registry capability flags: a11y, responsive, rtl, darkMode, localized.
Guidance
Support brand expression or a showcase moment.
Use when
- Use only when visual expression supports storytelling, brand differentiation, or a clear showcase moment.
- Framing app or website screenshots inside a detailed, brand-accurate iPhone frame, including the Dynamic Island and status bar.
Avoid when
- Do not place heavy effects in task-dense workflows where clarity, speed, and readability matter more.
- A generic, less detailed phone, tablet, or laptop schematic is enough; use device instead.
Use instead
- Static content-first presentation
Anti-patterns
- Heavy effects in forms or task-dense workflows
- Motion that interferes with reading or focus
- Anatomy
- Theming hooks
Accessibility
- Keyboard
- No component-owned keyboard interaction; native element behavior applies.
- Focus
none
- The root carries role=img and an aria-label from the label prop, since the frame and status bar icons are entirely decorative chrome around the slot.
- 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([
'color' => null,
'island' => true,
'statusBar' => true,
'time' => '9:41',
'label' => 'iPhone mockup',
])
@php
// Bezel colour token; defaults to the foreground (a dark, neutral frame).
// Pass a full token class (e.g. "bg-card") to override — never a raw colour.
$bezel = $color ?: 'bg-foreground';
@endphp
{{--
iPhone mockup — a polished phone frame that wraps any screen content. Models
the Dynamic Island, side buttons and an optional status bar, with the screen
on a `bg-background` surface so the slot inherits the theme. Decorative only
(role="img"); for a generic phone/tablet/laptop schematic use the `device`
component instead.
--}}
<div
data-slot="iphone-mockup"
role="img"
aria-label="{{ __($label) }}"
{{ $attributes->merge(['class' => 'relative inline-block']) }}
>
{{-- Side buttons: proud of the bezel by a hair, at the real positions —
mute switch, volume up and down on the start side, power on the end. --}}
<span class="{{ $bezel }} absolute -start-0.5 top-[15%] h-6 w-1 rounded-s-sm" aria-hidden="true"></span>
<span class="{{ $bezel }} absolute -start-0.5 top-[24%] h-10 w-1 rounded-s-sm" aria-hidden="true"></span>
<span class="{{ $bezel }} absolute -start-0.5 top-[32%] h-10 w-1 rounded-s-sm" aria-hidden="true"></span>
<span class="{{ $bezel }} absolute -end-0.5 top-[26%] h-14 w-1 rounded-e-sm" aria-hidden="true"></span>
<div class="{{ $bezel }} relative w-60 max-w-full rounded-[3rem] p-2 shadow-2xl ring-1 ring-inset ring-background/15">
<div class="relative aspect-[9/19.5] w-full overflow-hidden rounded-[2.5rem] bg-background ring-1 ring-inset ring-foreground/60">
@if ($island)
{{-- Dynamic Island: a third of the screen width, on the status-bar line. --}}
<div class="absolute left-1/2 top-3 z-20 h-6 w-[31%] -translate-x-1/2 rounded-full bg-foreground" aria-hidden="true">
<span class="absolute end-2 top-1/2 size-2 -translate-y-1/2 rounded-full bg-background/20"></span>
</div>
@endif
@if ($statusBar)
{{-- Status bar shares the island's line: time in the start third,
signal / wifi / battery in the end third. --}}
<div class="absolute inset-x-0 top-3 z-10 flex h-6 items-center justify-between px-6 text-2xs font-semibold tabular-nums text-foreground" aria-hidden="true">
<span class="w-[31%] text-center">{{ $time }}</span>
<span class="flex w-[31%] items-center justify-center gap-1">
<svg viewBox="0 0 24 24" fill="currentColor" class="size-3"><path d="M2 16h3v4H2zM7 12h3v8H7zM12 8h3v12h-3zM17 4h3v16h-3z" /></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" class="size-3"><path d="M5 13a10 10 0 0 1 14 0M8.5 16.5a5 5 0 0 1 7 0M12 20h.01" /></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="size-4"><rect x="2" y="7" width="17" height="10" rx="2.5" /><rect x="4" y="9" width="12" height="6" rx="1" fill="currentColor" stroke="none" /><path d="M21 10.5v3" stroke-linecap="round" /></svg>
</span>
</div>
@endif
<div class="size-full {{ $statusBar ? 'pt-11' : '' }}">
{{ $slot }}
</div>
</div>
</div>
</div>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
1.1.1 - 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