Skip to content
Brok UI

Loading…

No results

Stack

Open source

A flexbox layout primitive that arranges children in a row or column with consistent spacing, alignment, and optional dividers.

Version
v1.2.4
Stability
stable
License
MIT
Related
Cluster
Grid
Surface

Preview

Vertical (col)

Item one
Item two
Item three

Horizontal (row)

Alpha Beta Gamma

Vertical with dividers

Section A
Section B
Section C
Align
previews.components.stack.default.blade.php Blade
<div class="flex flex-col gap-10 p-6">
    {{-- Vertical stack (default) --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Vertical (col)') }}</p>
        <x-ui.stack gap="3" class="w-48">
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item one') }}</div>
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item two') }}</div>
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item three') }}</div>
        </x-ui.stack>
    </div>

    {{-- Horizontal stack --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Horizontal (row)') }}</p>
        <x-ui.stack direction="row" gap="3" align="center">
            <span class="inline-flex items-center rounded-full bg-primary px-3 py-1 text-xs font-medium text-primary-foreground">{{ __('Alpha') }}</span>
            <span class="inline-flex items-center rounded-full bg-secondary px-3 py-1 text-xs font-medium text-secondary-foreground">{{ __('Beta') }}</span>
            <span class="inline-flex items-center rounded-full bg-muted px-3 py-1 text-xs font-medium text-muted-foreground">{{ __('Gamma') }}</span>
        </x-ui.stack>
    </div>

    {{-- Vertical stack with dividers --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Vertical with dividers') }}</p>
        <x-ui.stack gap="0" divider class="w-48 rounded-lg border border-border bg-card">
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section A') }}</div>
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section B') }}</div>
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section C') }}</div>
        </x-ui.stack>
    </div>
</div>
Stretch Current
Start Current
Center Current
End Current

Installation

terminal
php artisan ui:add stack

Registry contract

php artisan ui:add stack 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.

  • blade resources/views/components/ui/stack.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.

stack.md
# Brok UI: Stack (`stack`)

A flexbox layout primitive that arranges children in a row or column with consistent spacing, alignment, and optional dividers.

Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.

## Install

```bash
php artisan ui:add stack
```

## Usage

```blade
<div class="flex flex-col gap-10 p-6">
    {{-- Vertical stack (default) --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Vertical (col)') }}</p>
        <x-ui.stack gap="3" class="w-48">
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item one') }}</div>
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item two') }}</div>
            <div class="rounded-lg border border-border bg-card px-4 py-3 text-sm text-card-foreground">{{ __('Item three') }}</div>
        </x-ui.stack>
    </div>

    {{-- Horizontal stack --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Horizontal (row)') }}</p>
        <x-ui.stack direction="row" gap="3" align="center">
            <span class="inline-flex items-center rounded-full bg-primary px-3 py-1 text-xs font-medium text-primary-foreground">{{ __('Alpha') }}</span>
            <span class="inline-flex items-center rounded-full bg-secondary px-3 py-1 text-xs font-medium text-secondary-foreground">{{ __('Beta') }}</span>
            <span class="inline-flex items-center rounded-full bg-muted px-3 py-1 text-xs font-medium text-muted-foreground">{{ __('Gamma') }}</span>
        </x-ui.stack>
    </div>

    {{-- Vertical stack with dividers --}}
    <div>
        <p class="mb-3 text-xs font-medium uppercase tracking-widest text-muted-foreground">{{ __('Vertical with dividers') }}</p>
        <x-ui.stack gap="0" divider class="w-48 rounded-lg border border-border bg-card">
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section A') }}</div>
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section B') }}</div>
            <div class="px-4 py-3 text-sm text-card-foreground">{{ __('Section C') }}</div>
        </x-ui.stack>
    </div>
</div>
```

## Props

- `direction` (string, default `col`) — Flex direction: col (vertical stack) or row (horizontal stack).
- `gap` (string, default `4`) — Gap between items, from the fixed step vocabulary (0-16, or sm/md/lg tokens).
- `align` (string, default `stretch`) — Cross-axis alignment: start, center, end, baseline, or stretch.
- `justify` (string, default `start`) — Main-axis distribution: start, center, end, between, around, or evenly.
- `wrap` (bool, default `false`) — Whether items wrap onto new lines when they run out of space.
- `divider` (bool, default `false`) — Draws a border between adjacent children instead of relying on gap alone.
- `as` (string, default `div`) — HTML tag to render: div, section, nav, header, footer, ul, or ol.

## Use when

- Use to structure hierarchy, spacing, and responsiveness so content is easier to scan and navigate.
- Arranging a simple one-dimensional row or column of elements with consistent spacing.
- Needing an optional divider line drawn between children instead of hand-composing separator elements.

## Avoid when

- Do not let layout primitives substitute for semantics, headings, or interaction rules users still need.
- Items should wrap onto multiple lines as space runs out; use cluster instead.
- Laying out a two-dimensional grid of cards or tiles; use grid.

## Anti-patterns

- Using visual layout as a substitute for semantic structure

## Rules

- Use the `<brok:stack>` tag (or `<x-ui.stack>`) 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/stack
- Registry JSON (files, props, contract): https://brokui.dev/r/open/stack.json

Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.

API

manifest knowledge + registry-derived coverage

Props

Props accepted by this component: name, type, default value and description.
Prop Type Default Description
direction string col Flex direction: col (vertical stack) or row (horizontal stack).
gap string 4 Gap between items, from the fixed step vocabulary (0-16, or sm/md/lg tokens).
align string stretch Cross-axis alignment: start, center, end, baseline, or stretch.
justify string start Main-axis distribution: start, center, end, between, around, or evenly.
wrap bool false Whether items wrap onto new lines when they run out of space.
divider bool false Draws a border between adjacent children instead of relying on gap alone.
as string div HTML tag to render: div, section, nav, header, footer, ul, or ol.

Slots

  • default — Items arranged in the stack.

Renders as div, section, nav, header, footer, ul, ol.

Data slots

Stable hooks for CSS overrides and browser tests.

stack

Behavior

  • Renders a flex container along the chosen direction from an approved gap vocabulary, so every gap value maps to a literal Tailwind class Tailwind's JIT can discover.
  • With divider enabled, adjacent children are separated by a border instead of (or in addition to) the gap, oriented to match the row or column direction.
  • Declares registry capability flags: a11y, responsive, rtl, darkMode, localized.

Guidance

Layout and content structure

Structure content hierarchy and responsive relationships.

Use when

  • Use to structure hierarchy, spacing, and responsiveness so content is easier to scan and navigate.
  • Arranging a simple one-dimensional row or column of elements with consistent spacing.
  • Needing an optional divider line drawn between children instead of hand-composing separator elements.

Avoid when

  • Do not let layout primitives substitute for semantics, headings, or interaction rules users still need.
  • Items should wrap onto multiple lines as space runs out; use cluster instead.
  • Laying out a two-dimensional grid of cards or tiles; use grid.

Use instead

  • Semantic HTML with standard flow

Anti-patterns

  • Using visual layout as a substitute for semantic structure
Anatomy
root
Theming hooks
stack

Accessibility

WCAG 2.2 AA Keyboard focus-visible RTL-ready Localized labels Dark mode
Keyboard
No component-owned keyboard interaction; native element behavior applies.
Focus
none
  • The wrapper carries no semantics of its own beyond the chosen as tag; use a ul/ol with list item children when the stack represents a list.
  • Semantic HTML and a stable data-slot attribute for styling and scripting hooks.
  • Focus-visible rings use the ring token, 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 under dir="rtl" — flip the preview to RTL to confirm.
  • Dark mode uses the same semantic tokens under the dark class; high contrast follows forced-color system tokens.

Livewire

Safe

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.

resources/views/components/ui/stack.blade.php Blade
@props([
    'direction' => 'col',
    'gap'       => '4',
    'align'     => 'stretch',
    'justify'   => 'start',
    'wrap'      => false,
    'divider'   => false,
    'as'        => 'div',
])

@php
    $allowedTags = ['div', 'section', 'nav', 'header', 'footer', 'ul', 'ol'];
    $tag = in_array($as, $allowedTags, true) ? $as : 'div';
    $dirClass = match ($direction) {
        'row'   => 'flex flex-row',
        default => 'flex flex-col',
    };

    $alignClass = match ($align) {
        'start'    => 'items-start',
        'center'   => 'items-center',
        'end'      => 'items-end',
        'baseline' => 'items-baseline',
        default    => 'items-stretch',
    };

    $justifyClass = match ($justify) {
        'center'  => 'justify-center',
        'end'     => 'justify-end',
        'between' => 'justify-between',
        'around'  => 'justify-around',
        'evenly'  => 'justify-evenly',
        default   => 'justify-start',
    };

    $divideClass = $divider
        ? ($direction === 'row' ? 'divide-x divide-border' : 'divide-y divide-border')
        : '';

    // Fixed vocabulary: every class is literal so Tailwind can discover it.
    // Unknown values fall back to the standard 16px stack rhythm.
    $gaps = [
        '0' => 'gap-0',
        '1' => 'gap-1',
        '2' => 'gap-2',
        '3' => 'gap-3',
        '4' => 'gap-4',
        '6' => 'gap-6',
        '8' => 'gap-8',
        '12' => 'gap-12',
        '16' => 'gap-16',
        'sm' => 'gap-stack-sm',
        'md' => 'gap-stack-md',
        'lg' => 'gap-stack-lg',
    ];
    $gapKey      = array_key_exists((string) $gap, $gaps) ? (string) $gap : '4';
    $gapClass    = $gaps[$gapKey];
    $wrapClass   = $wrap ? 'flex-wrap' : '';

    $classes = trim(implode(' ', array_filter([
        $dirClass,
        $gapClass,
        $alignClass,
        $justifyClass,
        $wrapClass,
        $divideClass,
    ])));
@endphp

<{{ $tag }}
    data-slot="stack"
    data-direction="{{ $direction === 'row' ? 'row' : 'col' }}"
    data-gap="{{ $gapKey }}"
    {{ $attributes->merge(['class' => $classes]) }}
>{{ $slot }}</{{ $tag }}>

Ownership & lifecycle

Owner, release state, review evidence and adoption for this item.
Owner
Platform UI (@JoshJML)
Current version
1.2.4
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