Skip to content
Brok UI

Loading…

No results

Layout

Work frame-first: decide who owns global chrome, which regions scroll, and how content reflows before choosing decorative details.

The three composition levels

Primitive

One reusable interaction or visual contract, such as button, field, dialog, or table.

Block

One focused section composed from primitives. It never owns the application viewport.

Page

An ordered content frame. Shell pages are the explicit exception that also own global navigation.

Shell ownership

Your host layout owns document metadata, global navigation, session controls, and the main viewport. A content page owns its page header, local navigation, and content regions. Avoid nested full-height shells and competing scroll containers: install a shell page only when Brok should own global navigation, and never nest one inside your existing shell.

resources/views/layouts/app.blade.php Blade
{{-- resources/views/layouts/app.blade.php — the host owns the frame --}}
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>…</head>
<body class="min-h-svh bg-background text-foreground">
    <x-pages.app-shell-bordered>
        {{-- A content page owns only what is inside the frame. --}}
        {{ $slot }}
    </x-pages.app-shell-bordered>
</body>
</html>

Layout grammar

Build screens from eight constrained layout primitives. Their props map to literal, discoverable classes and unknown values fall back safely, so feature code never needs an arbitrary pixel gap or a margin chain.

Primitive Use it for Props
section Page rhythm — vertical space between bands of content space, surface, as
container A bounded, centred reading width with gutters size, gutter, centered, as
stack One-direction flow with a fixed gap (forms, toolbars) direction, gap, align, justify, wrap, divider, as
cluster A wrapping inline group (tags, actions) gap, align, justify, wrap, as
grid Columns for collections that reflow cols, gap, as
surface A panel — tone, padding, radius, shadow in one place tone, padding, radius, shadow, as
prose Readable long-form text at a measured width size, centered, as
bleed Escape the reading column for a wide table or code block size, scroll, as

Every gap and padding value resolves to a token (gap-stack-*, py-section-*, px-gutter-*), so density and theme changes reach every screen without touching a view.

Composed example

The same markup, as a page would use it and as it renders with the default tokens:

resources/views/dashboard.blade.php Blade
<brok:section space="lg" surface="muted">
    <brok:container size="lg">
        <brok:stack gap="lg">
            <brok:prose :centered="false">
                <h2>Workspace activity</h2>
                <p>Readable copy wraps safely, including long translated strings and URLs.</p>
            </brok:prose>

            <brok:grid cols="3" gap="md">
                <brok:surface>…</brok:surface>
                <brok:surface>…</brok:surface>
                <brok:surface>…</brok:surface>
            </brok:grid>

            <brok:cluster gap="sm" justify="end">
                <brok:button variant="outline">Cancel</brok:button>
                <brok:button>Save</brok:button>
            </brok:cluster>
        </brok:stack>
    </brok:container>
</brok:section>

Open issues

12

Merged this week

24

Review queue

36

Responsive contracts

  • Use grids for collections that reflow; use stacks for fixed-direction forms and toolbars.
  • Prefer intrinsic sizing and bounded max-width containers over fixed viewport widths.
  • Move global sidebar navigation into a start-side sheet on narrow viewports.
  • Keep tabular data readable with deliberate column priority, or let it scroll inside a bleed — never the page.
  • Use logical start/end spacing so every frame mirrors in RTL.
resources/views/reports/show.blade.php Blade
<brok:prose>
    <p>The table below is wider than the reading column, so it scrolls inside a bleed instead of the page.</p>
</brok:prose>

<brok:bleed :scroll="true">
    <brok:table>…</brok:table>
</brok:bleed>
terminal
php artisan ui:build "responsive customer support dashboard"
php artisan ui:show pages/app-shell-bordered --skeleton --json