Skip to content
Brok UI

Loading…

No results

Roadmap

Open source

Product roadmap sections — Now / Next / Later columns of votable feature cards.

Preview

resources/views/blocks/roadmap-columns.blade.php Blade
@props([
    'eyebrow'    => 'Roadmap',
    'heading'    => 'What we\'re building',
    'lead'       => 'Our public roadmap keeps you in the loop. Vote on features, follow progress, and see exactly what\'s shipping next.',
    'nowTitle'   => 'Now',
    'nextTitle'  => 'Next',
    'laterTitle' => 'Later',
    'nowItems'   => null,
    'nextItems'  => null,
    'laterItems' => null,
])

@php
    $nowItems ??= [
        ['title' => 'Conditional logic', 'description' => 'Show or hide fields based on user responses.', 'quarter' => 'Q2 2026', 'votes' => 214],
        ['title' => 'Branching flows', 'description' => 'Route respondents to different paths in real time.', 'quarter' => 'Q2 2026', 'votes' => 178],
        ['title' => 'Inline image uploads', 'description' => 'Embed rich media directly inside questions.', 'quarter' => 'Q2 2026', 'votes' => 95],
    ];
    $nextItems ??= [
        ['title' => 'Webhook triggers', 'description' => 'Fire events to any endpoint on submission.', 'quarter' => 'Q3 2026', 'votes' => 301],
        ['title' => 'Team workspaces', 'description' => 'Collaborate across forms with role-based access.', 'quarter' => 'Q3 2026', 'votes' => 260],
        ['title' => 'Analytics dashboard', 'description' => 'Visualise drop-off, completion and conversion.', 'quarter' => 'Q3 2026', 'votes' => 189],
    ];
    $laterItems ??= [
        ['title' => 'AI answer suggestions', 'description' => 'Smart auto-complete powered by your own data.', 'quarter' => 'Q4 2026', 'votes' => 412],
        ['title' => 'White-label embeds', 'description' => 'Remove all branding for custom deployments.', 'quarter' => 'Q1 2027', 'votes' => 337],
        ['title' => 'Offline mode', 'description' => 'Collect responses without an internet connection.', 'quarter' => 'Q1 2027', 'votes' => 198],
    ];

    $columns = [
        ['key' => 'now', 'title' => $nowTitle, 'items' => $nowItems, 'dot' => 'bg-success', 'countVariant' => 'success', 'pillVariant' => 'default', 'pill' => __('In progress'), 'headerBg' => 'bg-success/10'],
        ['key' => 'next', 'title' => $nextTitle, 'items' => $nextItems, 'dot' => 'bg-primary', 'countVariant' => 'secondary', 'pillVariant' => 'secondary', 'pill' => __('Planned'), 'headerBg' => 'bg-primary/10'],
        ['key' => 'later', 'title' => $laterTitle, 'items' => $laterItems, 'dot' => 'bg-muted-foreground', 'countVariant' => 'outline', 'pillVariant' => 'outline', 'pill' => __('Researching'), 'headerBg' => 'bg-muted'],
    ];
@endphp

<x-ui.section space="xl" {{ $attributes }}>
    <x-ui.container gutter="sm">
        <div class="mx-auto mb-12 max-w-2xl text-center sm:mb-16">
            <span class="mb-4 inline-block text-sm font-semibold uppercase tracking-widest text-primary">{{ __($eyebrow) }}</span>
            <h2 class="mt-2 text-3xl font-bold tracking-tight sm:text-4xl">{{ __($heading) }}</h2>
            <p class="mt-4 text-base leading-relaxed text-muted-foreground sm:text-lg">{{ __($lead) }}</p>
        </div>

        <div class="grid gap-6 md:grid-cols-3">
            @foreach ($columns as $col)
                <div class="flex flex-col gap-4" data-slot="roadmap-column" data-column="{{ $col['key'] }}">
                    <div class="flex items-center justify-between rounded-lg px-6 py-6 {{ $col['headerBg'] }}">
                        <div class="flex items-center gap-2">
                            <span aria-hidden="true" class="block size-2 rounded-full {{ $col['dot'] }}"></span>
                            <span class="text-sm font-semibold">{{ __($col['title']) }}</span>
                        </div>
                        <x-ui.badge variant="{{ $col['countVariant'] }}" size="sm">{{ count($col['items']) }}</x-ui.badge>
                    </div>

                    @foreach ($col['items'] as $item)
                        <x-ui.card class="p-4">
                            <x-ui.badge variant="{{ $col['pillVariant'] }}" size="sm" class="mb-4">{{ $col['pill'] }}</x-ui.badge>
                            <h3 class="mb-2 text-sm font-semibold leading-snug">{{ __($item['title']) }}</h3>
                            <p class="text-sm leading-relaxed text-muted-foreground">{{ __($item['description']) }}</p>
                            <div class="mt-4 flex items-center justify-between">
                                <span class="flex items-center gap-2 text-sm text-muted-foreground">
                                    <svg aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="size-4 shrink-0"><path fill-rule="evenodd" d="M8 3.293 2.146 9.146a.5.5 0 0 0 .708.708L8 4.707l5.146 5.147a.5.5 0 0 0 .708-.708L8 3.293Z" clip-rule="evenodd" /></svg>
                                    <span>{{ number_format($item['votes']) }}</span>
                                    <span class="sr-only">{{ __('upvotes') }}</span>
                                </span>
                                <span class="text-sm font-medium text-muted-foreground">{{ __($item['quarter']) }}</span>
                            </div>
                        </x-ui.card>
                    @endforeach
                </div>
            @endforeach
        </div>
    </x-ui.container>
</x-ui.section>

Installation

terminal
php artisan ui:add blocks/roadmap-columns

Installs these dependencies automatically:

Registry contract

Install confidence

php artisan ui:add blocks/roadmap-columns 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.4
License
open
Stability
stable
Contract
v1
Foundation
≥ 1.0.0
Type Generated target
blade resources/views/blocks/roadmap-columns.blade.php

Registry dependencies

badge card container 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.

roadmap-columns.md
# Brok UI block: Roadmap (`roadmap-columns`)

A product roadmap in Now, Next and Later columns of feature cards, each with a status pill, description, upvote count and target quarter.

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/roadmap-columns
```

## Render it

```blade
<x-blocks.roadmap-columns />
```

## Props

- `eyebrow` (string, default `Roadmap`) — Small label shown above the heading.
- `heading` (string, default `What we\'re building`) — Section heading.
- `lead` (string, default `Our public roadmap keeps you in the loop. Vote on features, follow progress, and see exactly what\'s shipping next.`) — Supporting lead paragraph under the heading.
- `now-title` (string, default `Now`) — Heading for the "in progress" column.
- `next-title` (string, default `Next`) — Heading for the "planned" column.
- `later-title` (string, default `Later`) — Heading for the "researching" column.
- `now-items` (mixed|null, default `null`) — Feature cards in the Now column; null falls back to sample data.
- `next-items` (mixed|null, default `null`) — Feature cards in the Next column; null falls back to sample data.
- `later-items` (mixed|null, default `null`) — Feature cards in the Later column; null falls back to sample data.

## Use when

- Showing a public product roadmap organised into Now, Next and Later columns of feature cards with status pills and upvote counts.
- Wanting a Kanban-style, at-a-glance view of what is shipping rather than a chronological timeline.

## Avoid when

- Wanting a chronological, quarter-by-quarter view of milestones instead of status columns; use roadmap-timeline instead.

## Rules

- Render the installed block with `<x-blocks.roadmap-columns />` 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/roadmap-columns
- Registry JSON (files, props, contract): https://brokui.dev/r/open/blocks/roadmap-columns.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

  • Showing a public product roadmap organised into Now, Next and Later columns of feature cards with status pills and upvote counts.
  • Wanting a Kanban-style, at-a-glance view of what is shipping rather than a chronological timeline.

Avoid when

  • Wanting a chronological, quarter-by-quarter view of milestones instead of status columns; use roadmap-timeline instead.

Anti-patterns

  • Do not replace semantic props with conflicting utility classes.
  • Do not remove labels, focus styles, or state attributes.
Anatomy
root roadmap-column

Usage

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

resources/views/welcome.blade.php Blade
<x-blocks.roadmap-columns />

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/roadmap-columns.blade.php Blade
@props([
    'eyebrow'    => 'Roadmap',
    'heading'    => 'What we\'re building',
    'lead'       => 'Our public roadmap keeps you in the loop. Vote on features, follow progress, and see exactly what\'s shipping next.',
    'nowTitle'   => 'Now',
    'nextTitle'  => 'Next',
    'laterTitle' => 'Later',
    'nowItems'   => null,
    'nextItems'  => null,
    'laterItems' => null,
])

@php
    $nowItems ??= [
        ['title' => 'Conditional logic', 'description' => 'Show or hide fields based on user responses.', 'quarter' => 'Q2 2026', 'votes' => 214],
        ['title' => 'Branching flows', 'description' => 'Route respondents to different paths in real time.', 'quarter' => 'Q2 2026', 'votes' => 178],
        ['title' => 'Inline image uploads', 'description' => 'Embed rich media directly inside questions.', 'quarter' => 'Q2 2026', 'votes' => 95],
    ];
    $nextItems ??= [
        ['title' => 'Webhook triggers', 'description' => 'Fire events to any endpoint on submission.', 'quarter' => 'Q3 2026', 'votes' => 301],
        ['title' => 'Team workspaces', 'description' => 'Collaborate across forms with role-based access.', 'quarter' => 'Q3 2026', 'votes' => 260],
        ['title' => 'Analytics dashboard', 'description' => 'Visualise drop-off, completion and conversion.', 'quarter' => 'Q3 2026', 'votes' => 189],
    ];
    $laterItems ??= [
        ['title' => 'AI answer suggestions', 'description' => 'Smart auto-complete powered by your own data.', 'quarter' => 'Q4 2026', 'votes' => 412],
        ['title' => 'White-label embeds', 'description' => 'Remove all branding for custom deployments.', 'quarter' => 'Q1 2027', 'votes' => 337],
        ['title' => 'Offline mode', 'description' => 'Collect responses without an internet connection.', 'quarter' => 'Q1 2027', 'votes' => 198],
    ];

    $columns = [
        ['key' => 'now', 'title' => $nowTitle, 'items' => $nowItems, 'dot' => 'bg-success', 'countVariant' => 'success', 'pillVariant' => 'default', 'pill' => __('In progress'), 'headerBg' => 'bg-success/10'],
        ['key' => 'next', 'title' => $nextTitle, 'items' => $nextItems, 'dot' => 'bg-primary', 'countVariant' => 'secondary', 'pillVariant' => 'secondary', 'pill' => __('Planned'), 'headerBg' => 'bg-primary/10'],
        ['key' => 'later', 'title' => $laterTitle, 'items' => $laterItems, 'dot' => 'bg-muted-foreground', 'countVariant' => 'outline', 'pillVariant' => 'outline', 'pill' => __('Researching'), 'headerBg' => 'bg-muted'],
    ];
@endphp

<x-ui.section space="xl" {{ $attributes }}>
    <x-ui.container gutter="sm">
        <div class="mx-auto mb-12 max-w-2xl text-center sm:mb-16">
            <span class="mb-4 inline-block text-sm font-semibold uppercase tracking-widest text-primary">{{ __($eyebrow) }}</span>
            <h2 class="mt-2 text-3xl font-bold tracking-tight sm:text-4xl">{{ __($heading) }}</h2>
            <p class="mt-4 text-base leading-relaxed text-muted-foreground sm:text-lg">{{ __($lead) }}</p>
        </div>

        <div class="grid gap-6 md:grid-cols-3">
            @foreach ($columns as $col)
                <div class="flex flex-col gap-4" data-slot="roadmap-column" data-column="{{ $col['key'] }}">
                    <div class="flex items-center justify-between rounded-lg px-6 py-6 {{ $col['headerBg'] }}">
                        <div class="flex items-center gap-2">
                            <span aria-hidden="true" class="block size-2 rounded-full {{ $col['dot'] }}"></span>
                            <span class="text-sm font-semibold">{{ __($col['title']) }}</span>
                        </div>
                        <x-ui.badge variant="{{ $col['countVariant'] }}" size="sm">{{ count($col['items']) }}</x-ui.badge>
                    </div>

                    @foreach ($col['items'] as $item)
                        <x-ui.card class="p-4">
                            <x-ui.badge variant="{{ $col['pillVariant'] }}" size="sm" class="mb-4">{{ $col['pill'] }}</x-ui.badge>
                            <h3 class="mb-2 text-sm font-semibold leading-snug">{{ __($item['title']) }}</h3>
                            <p class="text-sm leading-relaxed text-muted-foreground">{{ __($item['description']) }}</p>
                            <div class="mt-4 flex items-center justify-between">
                                <span class="flex items-center gap-2 text-sm text-muted-foreground">
                                    <svg aria-hidden="true" viewBox="0 0 16 16" fill="currentColor" class="size-4 shrink-0"><path fill-rule="evenodd" d="M8 3.293 2.146 9.146a.5.5 0 0 0 .708.708L8 4.707l5.146 5.147a.5.5 0 0 0 .708-.708L8 3.293Z" clip-rule="evenodd" /></svg>
                                    <span>{{ number_format($item['votes']) }}</span>
                                    <span class="sr-only">{{ __('upvotes') }}</span>
                                </span>
                                <span class="text-sm font-medium text-muted-foreground">{{ __($item['quarter']) }}</span>
                            </div>
                        </x-ui.card>
                    @endforeach
                </div>
            @endforeach
        </div>
    </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.4
Status
Stable
License
open
Deprecation
Not deprecated
Contract
v1
Foundation
≥ 1.0.0