Skip to content
Brok UI

Loading…

No results

Settings Pages

Open source

Full settings screens — personal account settings with anchored section navigation and server-ready forms, and organization settings with a side-column section nav.

Preview

resources/views/pages/settings-page.blade.php Blade
{{--
    Settings Page 01 — a full account-settings screen that composes the
    settings-* blocks behind a sticky section nav. No JS: the nav is anchor
    links to each section (scroll-mt keeps headings clear of the viewport top),
    so it is robust and fully accessible. Swap or reorder the <section>s to fit
    your app; each wraps a single installed settings block.
--}}
@props([
    'profileHref' => '#',
    'actions' => null,
    'billingLinks' => null,
    'statusMessage' => null,
])

@php
    $actions ??= [
        'profile' => '#',
        'billing' => '#',
        'security' => '#',
        'notifications' => '#',
        'integrations' => '#',
    ];
    $billingLinks ??= ['upgrade' => '#', 'cancel' => '#', 'payment' => '#'];
@endphp

<main id="main-content" data-visual-contracts="VC-010">
    <x-ui.form.guard
        data-slot="page-settings"
        class="mx-auto w-full max-w-5xl px-4 py-8 sm:px-6 lg:px-8"
    >
    <header class="mb-8 flex flex-wrap items-end justify-between gap-4">
        <div>
            <h1 class="text-2xl font-semibold tracking-tight text-foreground">{{ __('Settings') }}</h1>
            <p class="mt-2 text-sm text-muted-foreground">{{ __('Manage your profile, billing, security, notifications and integrations.') }}</p>
        </div>
        <x-ui.button :href="$profileHref" variant="outline">{{ __('View profile') }}</x-ui.button>
    </header>

    @if ($statusMessage)
        <x-ui.alert variant="success" role="status" class="mb-6">{{ __($statusMessage) }}</x-ui.alert>
    @endif

    <div class="grid gap-8 lg:grid-cols-[12rem_minmax(0,1fr)]">
        <nav class="min-w-0 lg:sticky lg:top-8 lg:self-start" aria-label="{{ __('Settings sections') }}">
            <ul class="flex w-full max-w-full gap-2 overflow-x-auto pb-2 lg:flex-col lg:gap-0.5 lg:overflow-visible lg:pb-0">
                @foreach ([
                    'profile' => 'Profile',
                    'billing' => 'Billing',
                    'security' => 'Security',
                    'notifications' => 'Notifications',
                    'integrations' => 'Integrations',
                ] as $anchor => $label)
                    <li>
                        <a
                            href="#{{ $anchor }}"
                            class="block whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                        >{{ __($label) }}</a>
                    </li>
                @endforeach
            </ul>
        </nav>

        <div class="min-w-0 space-y-12">
            <section id="profile" class="scroll-mt-8" aria-label="{{ __('Profile') }}">
                <x-blocks.settings-account :action="$actions['profile'] ?? '#'" />
            </section>
            <section id="billing" class="scroll-mt-8" aria-label="{{ __('Billing') }}">
                <x-blocks.settings-billing
                    :upgrade-href="$billingLinks['upgrade'] ?? '#'"
                    :cancel-href="$billingLinks['cancel'] ?? '#'"
                    :payment-href="$billingLinks['payment'] ?? '#'"
                />
            </section>
            <section id="security" class="scroll-mt-8" aria-label="{{ __('Security') }}">
                <x-blocks.settings-security :action="$actions['security'] ?? '#'" />
            </section>
            <section id="notifications" class="scroll-mt-8" aria-label="{{ __('Notifications') }}">
                <x-blocks.settings-notifications :action="$actions['notifications'] ?? '#'" />
            </section>
            <section id="integrations" class="scroll-mt-8" aria-label="{{ __('Integrations') }}">
                <x-blocks.settings-integrations :action="$actions['integrations'] ?? '#'" />
            </section>
        </div>
    </div>
    </x-ui.form.guard>
</main>

Installation

terminal
php artisan ui:add pages/settings-page

Registry contract

Install confidence

php artisan ui:add pages/settings-page 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.3.4
License
open
Stability
stable
Contract
v2
Foundation
≥ 1.0.0
Type Generated target
blade resources/views/pages/settings-page.blade.php

Registry dependencies

button form blocks/settings-account blocks/settings-billing blocks/settings-security blocks/settings-notifications blocks/settings-integrations alert

Package dependencies

composer: jml/brok:^0.2

Use with AI

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

settings-page.md
# Brok UI page: Settings Page (`settings-page`)

A server-ready account-settings screen with section endpoints, billing links, success feedback, submit locking, unsaved-change protection, and responsive anchored navigation.

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

## Install

```bash
php artisan ui:add pages/settings-page
```

## Render it

```blade
<x-pages.settings-page />
```

## Props

- `profile-href` (string, default `#`) — Profile page destination.
- `actions` (array|null, default `null`) — Profile, security, notification, and integration endpoints by section key.
- `billing-links` (array|null, default `null`) — Upgrade, cancel, and payment destinations.
- `status-message` (string|null, default `null`) — Success feedback after a section redirect.

## Use when

- Use for account or workspace settings that have independent server-owned sections.

## Avoid when

- Use a small settings dialog when there are only one or two reversible controls.

## Rules

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

  • Use for account or workspace settings that have independent server-owned sections.

Avoid when

  • Use a small settings dialog when there are only one or two reversible controls.

Anti-patterns

  • Do not replace semantic props with conflicting utility classes.
  • Do not remove labels, focus styles, or state attributes.
Anatomy
page heading section navigation server feedback profile billing security notification preferences integrations
Theming hooks
Uses semantic design tokens across customer settings surfaces.

Usage

Render the page as a component, or wire it to a route. Pass data where useful:

resources/views/welcome.blade.php Blade
<x-pages.settings-page />

Built from blocks & primitives

This page 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 pages.

resources/views/pages/settings-page.blade.php Blade
{{--
    Settings Page 01 — a full account-settings screen that composes the
    settings-* blocks behind a sticky section nav. No JS: the nav is anchor
    links to each section (scroll-mt keeps headings clear of the viewport top),
    so it is robust and fully accessible. Swap or reorder the <section>s to fit
    your app; each wraps a single installed settings block.
--}}
@props([
    'profileHref' => '#',
    'actions' => null,
    'billingLinks' => null,
    'statusMessage' => null,
])

@php
    $actions ??= [
        'profile' => '#',
        'billing' => '#',
        'security' => '#',
        'notifications' => '#',
        'integrations' => '#',
    ];
    $billingLinks ??= ['upgrade' => '#', 'cancel' => '#', 'payment' => '#'];
@endphp

<main id="main-content" data-visual-contracts="VC-010">
    <x-ui.form.guard
        data-slot="page-settings"
        class="mx-auto w-full max-w-5xl px-4 py-8 sm:px-6 lg:px-8"
    >
    <header class="mb-8 flex flex-wrap items-end justify-between gap-4">
        <div>
            <h1 class="text-2xl font-semibold tracking-tight text-foreground">{{ __('Settings') }}</h1>
            <p class="mt-2 text-sm text-muted-foreground">{{ __('Manage your profile, billing, security, notifications and integrations.') }}</p>
        </div>
        <x-ui.button :href="$profileHref" variant="outline">{{ __('View profile') }}</x-ui.button>
    </header>

    @if ($statusMessage)
        <x-ui.alert variant="success" role="status" class="mb-6">{{ __($statusMessage) }}</x-ui.alert>
    @endif

    <div class="grid gap-8 lg:grid-cols-[12rem_minmax(0,1fr)]">
        <nav class="min-w-0 lg:sticky lg:top-8 lg:self-start" aria-label="{{ __('Settings sections') }}">
            <ul class="flex w-full max-w-full gap-2 overflow-x-auto pb-2 lg:flex-col lg:gap-0.5 lg:overflow-visible lg:pb-0">
                @foreach ([
                    'profile' => 'Profile',
                    'billing' => 'Billing',
                    'security' => 'Security',
                    'notifications' => 'Notifications',
                    'integrations' => 'Integrations',
                ] as $anchor => $label)
                    <li>
                        <a
                            href="#{{ $anchor }}"
                            class="block whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                        >{{ __($label) }}</a>
                    </li>
                @endforeach
            </ul>
        </nav>

        <div class="min-w-0 space-y-12">
            <section id="profile" class="scroll-mt-8" aria-label="{{ __('Profile') }}">
                <x-blocks.settings-account :action="$actions['profile'] ?? '#'" />
            </section>
            <section id="billing" class="scroll-mt-8" aria-label="{{ __('Billing') }}">
                <x-blocks.settings-billing
                    :upgrade-href="$billingLinks['upgrade'] ?? '#'"
                    :cancel-href="$billingLinks['cancel'] ?? '#'"
                    :payment-href="$billingLinks['payment'] ?? '#'"
                />
            </section>
            <section id="security" class="scroll-mt-8" aria-label="{{ __('Security') }}">
                <x-blocks.settings-security :action="$actions['security'] ?? '#'" />
            </section>
            <section id="notifications" class="scroll-mt-8" aria-label="{{ __('Notifications') }}">
                <x-blocks.settings-notifications :action="$actions['notifications'] ?? '#'" />
            </section>
            <section id="integrations" class="scroll-mt-8" aria-label="{{ __('Integrations') }}">
                <x-blocks.settings-integrations :action="$actions['integrations'] ?? '#'" />
            </section>
        </div>
    </div>
    </x-ui.form.guard>
</main>

Ownership & lifecycle

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