Skip to content
Brok UI

Loading…

No results

Process

Open source

How-it-works sections — a horizontal step row and a vertical numbered timeline.

Preview

resources/views/blocks/process-vertical.blade.php Blade
@props([
    'eyebrow' => 'How it works',
    'heading' => 'Three simple steps to get started',
    'lead'    => 'Everything you need to go from idea to launch — without the guesswork. Follow these steps and you will be up and running in no time.',
    'steps'   => null,
])

@php
    $steps ??= [
        ['icon' => 'search', 'title' => 'Discover & plan', 'body' => 'Explore the library, bookmark the components you need, and sketch out your layout. Our interactive docs make planning straightforward.', 'duration' => '~5 min'],
        ['icon' => 'install', 'title' => 'Install in one command', 'body' => 'Run a single artisan command and the component drops straight into your project — no build step, no runtime dependency.', 'duration' => '~1 min'],
        ['icon' => 'compose', 'title' => 'Compose & customise', 'body' => 'Edit the generated Blade directly. Every token, every class, every slot is yours. Adjust colours, copy, and layout to match your brand.', 'duration' => '~10 min'],
        ['icon' => 'ship', 'title' => 'Ship with confidence', 'body' => 'Deploy as you normally would. Zero runtime coupling means updates to this library never break your production app.', 'duration' => 'Ongoing'],
    ];

    $icons = [
        'search' => '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>',
        'install' => '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>',
        'compose' => '<path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>',
        'ship' => '<path d="M12 2 2 7l10 5 10-5-10-5Z"/><path d="m2 17 10 5 10-5"/><path d="m2 12 10 5 10-5"/>',
    ];
@endphp

<x-ui.section space="xl" {{ $attributes }} aria-labelledby="process-vertical-01-heading">
    <x-ui.container size="md" gutter="sm">
        <div class="mx-auto max-w-2xl text-center">
            @if (! empty($eyebrow))
                <x-ui.badge variant="secondary" class="mb-6">{{ __($eyebrow) }}</x-ui.badge>
            @endif
            <h2 id="process-vertical-01-heading" class="text-balance text-3xl font-bold tracking-tight sm:text-4xl">{{ __($heading) }}</h2>
            @if (! empty($lead))
                <p class="mt-4 text-pretty text-lg text-muted-foreground">{{ __($lead) }}</p>
            @endif
        </div>

        <ol class="mt-16 sm:mt-20" aria-label="{{ __('Process steps') }}">
            @foreach ($steps as $i => $step)
                <li class="relative flex gap-6 sm:gap-8">
                    <div class="flex flex-col items-center">
                        <span class="relative z-10 inline-flex size-10 shrink-0 items-center justify-center rounded-full bg-primary font-semibold tabular-nums text-primary-foreground" aria-hidden="true">{{ $i + 1 }}</span>
                        @unless ($loop->last)
                            <span class="mt-2 w-px grow border-s border-dashed border-border" aria-hidden="true"></span>
                        @endunless
                    </div>

                    <div class="{{ $loop->last ? 'pb-0' : 'pb-10 sm:pb-12' }} flex-1">
                        <x-ui.card>
                            <x-ui.card.header class="flex-row items-start gap-4 pb-4">
                                @if (! empty($step['icon']) && isset($icons[$step['icon']]))
                                    <x-ui.icon.tile>
                                        <svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{!! $icons[$step['icon']] !!}</svg>
                                    </x-ui.icon.tile>
                                @endif
                                <div class="flex min-w-0 flex-1 flex-wrap items-center justify-between gap-x-4 gap-y-2">
                                    <x-ui.card.title class="text-sm font-semibold leading-snug">{{ __($step['title']) }}</x-ui.card.title>
                                    @if (! empty($step['duration']))
                                        <x-ui.badge variant="outline" size="sm" class="shrink-0 whitespace-nowrap">{{ __($step['duration']) }}</x-ui.badge>
                                    @endif
                                </div>
                            </x-ui.card.header>
                            <x-ui.card.content>
                                <p class="text-pretty text-sm text-muted-foreground">{{ __($step['body']) }}</p>
                            </x-ui.card.content>
                        </x-ui.card>
                    </div>
                </li>
            @endforeach
        </ol>
    </x-ui.container>
</x-ui.section>

Installation

terminal
php artisan ui:add blocks/process-vertical

Installs these dependencies automatically:

Registry contract

Install confidence

php artisan ui:add blocks/process-vertical writes only the generated targets below. The CLI validates each file hash before writing and prompts before replacing local changes unless --force is used.

Version
1.0.5
License
open
Stability
stable
Contract
v1
Foundation
≥ 1.0.0
Type Generated target
blade resources/views/blocks/process-vertical.blade.php

Registry dependencies

badge card container icon section

Package dependencies

composer: jml/brok:^0.2

Use with AI

A brief for your coding agent: what the block is, the install command, how to render it, its props and the rules. Copy it, or open a prompt about this block in an assistant.

process-vertical.md
# Brok UI block: Process Vertical (`process-vertical`)

A vertical how-it-works timeline of numbered steps connected by a dashed rail, each step a card with an icon, title, duration badge and description.

Brok UI is a Laravel Blade registry. `ui:add` copies this block into the app as plain Blade the app owns; it composes installed `<brok:*>` primitives and semantic design tokens.

## Install

```bash
php artisan ui:add blocks/process-vertical
```

## Render it

```blade
<x-blocks.process-vertical />
```

## Props

- `eyebrow` (string, default `How it works`) — Small label shown above the heading inside a badge.
- `heading` (string, default `Three simple steps to get started`) — Section heading.
- `lead` (string, default `Everything you need to go from idea to launch — without the guesswork. Follow these steps and you will be up and running in no time.`) — Supporting copy under the heading.
- `steps` (mixed|null, default `null`) — Array of {icon, title, body, duration} step entries; null falls back to a default 4-step sample.

## Use when

- Explaining a sequential process as a vertical timeline of numbered steps connected by a dashed line, each step in a card with an icon, title, body and an optional duration badge.
- Wanting to communicate how long each step takes (e.g. "~5 min") alongside the step description.

## Avoid when

- Needing a compact horizontal 3-column step grid instead of a vertical timeline; use process-horizontal.

## Rules

- Render the installed block with `<x-blocks.process-vertical />` and pass data through its props; edit the copied file only for structural changes.
- Keep the semantic design tokens (`bg-background`, `text-muted-foreground`); never swap in raw colour utilities.
- Keep the `data-slot` attributes and the logical (start/end) spacing so the markup still mirrors under `dir="rtl"`.

## Links

- Docs: https://brokui.dev/blocks/process-vertical
- Registry JSON (files, props, contract): https://brokui.dev/r/open/blocks/process-vertical.json

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

Guidance

Use when

  • Explaining a sequential process as a vertical timeline of numbered steps connected by a dashed line, each step in a card with an icon, title, body and an optional duration badge.
  • Wanting to communicate how long each step takes (e.g. "~5 min") alongside the step description.

Avoid when

  • Needing a compact horizontal 3-column step grid instead of a vertical timeline; use process-horizontal.

Anti-patterns

  • Do not replace semantic props with conflicting utility classes.
  • Do not remove labels, focus styles, or state attributes.
Anatomy
section eyebrow badge heading lead step list numbered marker connector line step card icon tile duration badge

Usage

Render the block as a component, passing data where useful:

resources/views/welcome.blade.php Blade
<x-blocks.process-vertical />

Built from primitives

Composes <brok:*> Semantic tokens Re-themeable RTL-ready

This block composes installed <brok:*> primitives and semantic design tokens only — it does not reimplement any primitive. Re-theme it (light, dark, admin, customer) by editing CSS variables; flip the preview to RTL to confirm it mirrors.

Source

The exact, editable file ui:add writes into your app. The preview above renders this same source — there are no preview-only blocks.

resources/views/blocks/process-vertical.blade.php Blade
@props([
    'eyebrow' => 'How it works',
    'heading' => 'Three simple steps to get started',
    'lead'    => 'Everything you need to go from idea to launch — without the guesswork. Follow these steps and you will be up and running in no time.',
    'steps'   => null,
])

@php
    $steps ??= [
        ['icon' => 'search', 'title' => 'Discover & plan', 'body' => 'Explore the library, bookmark the components you need, and sketch out your layout. Our interactive docs make planning straightforward.', 'duration' => '~5 min'],
        ['icon' => 'install', 'title' => 'Install in one command', 'body' => 'Run a single artisan command and the component drops straight into your project — no build step, no runtime dependency.', 'duration' => '~1 min'],
        ['icon' => 'compose', 'title' => 'Compose & customise', 'body' => 'Edit the generated Blade directly. Every token, every class, every slot is yours. Adjust colours, copy, and layout to match your brand.', 'duration' => '~10 min'],
        ['icon' => 'ship', 'title' => 'Ship with confidence', 'body' => 'Deploy as you normally would. Zero runtime coupling means updates to this library never break your production app.', 'duration' => 'Ongoing'],
    ];

    $icons = [
        'search' => '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>',
        'install' => '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>',
        'compose' => '<path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>',
        'ship' => '<path d="M12 2 2 7l10 5 10-5-10-5Z"/><path d="m2 17 10 5 10-5"/><path d="m2 12 10 5 10-5"/>',
    ];
@endphp

<x-ui.section space="xl" {{ $attributes }} aria-labelledby="process-vertical-01-heading">
    <x-ui.container size="md" gutter="sm">
        <div class="mx-auto max-w-2xl text-center">
            @if (! empty($eyebrow))
                <x-ui.badge variant="secondary" class="mb-6">{{ __($eyebrow) }}</x-ui.badge>
            @endif
            <h2 id="process-vertical-01-heading" class="text-balance text-3xl font-bold tracking-tight sm:text-4xl">{{ __($heading) }}</h2>
            @if (! empty($lead))
                <p class="mt-4 text-pretty text-lg text-muted-foreground">{{ __($lead) }}</p>
            @endif
        </div>

        <ol class="mt-16 sm:mt-20" aria-label="{{ __('Process steps') }}">
            @foreach ($steps as $i => $step)
                <li class="relative flex gap-6 sm:gap-8">
                    <div class="flex flex-col items-center">
                        <span class="relative z-10 inline-flex size-10 shrink-0 items-center justify-center rounded-full bg-primary font-semibold tabular-nums text-primary-foreground" aria-hidden="true">{{ $i + 1 }}</span>
                        @unless ($loop->last)
                            <span class="mt-2 w-px grow border-s border-dashed border-border" aria-hidden="true"></span>
                        @endunless
                    </div>

                    <div class="{{ $loop->last ? 'pb-0' : 'pb-10 sm:pb-12' }} flex-1">
                        <x-ui.card>
                            <x-ui.card.header class="flex-row items-start gap-4 pb-4">
                                @if (! empty($step['icon']) && isset($icons[$step['icon']]))
                                    <x-ui.icon.tile>
                                        <svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{!! $icons[$step['icon']] !!}</svg>
                                    </x-ui.icon.tile>
                                @endif
                                <div class="flex min-w-0 flex-1 flex-wrap items-center justify-between gap-x-4 gap-y-2">
                                    <x-ui.card.title class="text-sm font-semibold leading-snug">{{ __($step['title']) }}</x-ui.card.title>
                                    @if (! empty($step['duration']))
                                        <x-ui.badge variant="outline" size="sm" class="shrink-0 whitespace-nowrap">{{ __($step['duration']) }}</x-ui.badge>
                                    @endif
                                </div>
                            </x-ui.card.header>
                            <x-ui.card.content>
                                <p class="text-pretty text-sm text-muted-foreground">{{ __($step['body']) }}</p>
                            </x-ui.card.content>
                        </x-ui.card>
                    </div>
                </li>
            @endforeach
        </ol>
    </x-ui.container>
</x-ui.section>

Ownership & lifecycle

Owner, release state, review evidence and adoption for this item.
Owner
Platform UI (@JoshJML)
Current version
1.0.5
Status
Stable
License
open
Deprecation
Not deprecated
Contract
v1
Foundation
≥ 1.0.0