Skip to content
Brok UI

Loading…

No results

Switch Field

Open source

A preference row: the setting's name as the switch's label, one sentence on what it changes, an optional status badge, and the switch at the end of the row.

Version
v1.0.2
Stability
stable
License
MIT
Related
Switch
Label
Field

Preview

Enforce 2FA for every member.

Off

Allow anyone with the link to view.

Disabled
Align
previews.components.switch-field.default.blade.php Blade
<div class="w-full max-w-md space-y-4">
    <x-ui.switch-field
        :label="__('Require two-factor authentication')"
        :description="__('Enforce 2FA for every member.')"
        name="require_2fa"
        checked
    />
    <x-ui.separator />
    <x-ui.switch-field
        :label="__('Public workspace')"
        :description="__('Allow anyone with the link to view.')"
        name="public_workspace"
    >
        <x-slot:badge><x-ui.badge variant="outline">{{ __('Off') }}</x-ui.badge></x-slot:badge>
    </x-ui.switch-field>
</div>
Start Current
Center Current

Installation

terminal
php artisan ui:add switch-field

Registry contract

php artisan ui:add switch-field 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/switch-field.blade.php
Registry dependencies
switch label
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.

switch-field.md
# Brok UI: Switch Field (`switch-field`)

A preference row: the setting's name as the switch's label, one sentence on what it changes, an optional status badge, and the switch at the end of the row.

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

## Install

```bash
php artisan ui:add switch-field
```

## Usage

```blade
<div class="w-full max-w-md space-y-4">
    <x-ui.switch-field
        :label="__('Require two-factor authentication')"
        :description="__('Enforce 2FA for every member.')"
        name="require_2fa"
        checked
    />
    <x-ui.separator />
    <x-ui.switch-field
        :label="__('Public workspace')"
        :description="__('Allow anyone with the link to view.')"
        name="public_workspace"
    >
        <x-slot:badge><x-ui.badge variant="outline">{{ __('Off') }}</x-ui.badge></x-slot:badge>
    </x-ui.switch-field>
</div>
```

## Props

- `label` (string, default ``) — The setting's name; rendered as the switch's associated label.
- `description` (string|null, default `null`) — One sentence on what the setting changes, under the name.
- `name` (string|null, default `null`) — Form name for the switch input; also seeds the id.
- `id` (string|null, default `null`) — Id shared by the label and the switch; derived from `name` when omitted.
- `value` (string, default `1`) — The value posted when the switch is on.
- `checked` (bool, default `false`) — Initial on/off state.
- `disabled` (bool, default `false`) — Disables the switch; the row keeps its text.
- `size` ('sm'|'md'|'lg', default `md`) — Switch size, forwarded to `switch`.
- `align` ('start'|'center', default `start`) — `start` keeps the switch on the first line of a wrapping description; `center` centres it beside a single-line setting.
- `badge` (slot|null, default `null`) — Slot: a status pill beside the name (a `badge` reading Enabled).

## Use when

- Use for a small set of mutually exclusive options that users should compare visibly before choosing.
- A settings screen lists on/off preferences, each with a name and one sentence on what it changes.
- A card of notification or security options where the whole row should name and toggle the control.

## Avoid when

- Do not hide a small option set in a dropdown when recognition and comparison matter.
- A bare on/off control inline in a sentence; use `switch` with its own label.
- A value saved only on submit with a visible checkmark; use `checkbox`.

## Anti-patterns

- Hiding a small comparable set in a dropdown

## Rules

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

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

Examples

disabled.blade.php Blade
<div class="w-full max-w-md">
    <x-ui.switch-field
        :label="__('Single sign-on')"
        :description="__('Managed by your identity provider; contact an owner to change it.')"
        name="sso"
        checked
        disabled
    />
</div>
long-content.blade.php Blade
<div class="max-w-xs">
    <x-ui.switch-field
        :label="__('Send a weekly digest of every conversation, mention and assignment to the workspace inbox')"
        :description="__('A deliberately long description that verifies wrapping beside the switch: the switch stays on the first line and the text takes the rest of the row without clipping.')"
        name="weekly_digest"
    />
</div>

API

manifest knowledge + registry-derived coverage

Props

Props accepted by this component: name, type, default value and description.
Prop Type Default Description
label string The setting's name; rendered as the switch's associated label.
description string | null null One sentence on what the setting changes, under the name.
name string | null null Form name for the switch input; also seeds the id.
id string | null null Id shared by the label and the switch; derived from `name` when omitted.
value string 1 The value posted when the switch is on.
checked bool false Initial on/off state.
disabled bool false Disables the switch; the row keeps its text.
size 'sm' | 'md' | 'lg' md Switch size, forwarded to `switch`.
align 'start' | 'center' start `start` keeps the switch on the first line of a wrapping description; `center` centres it beside a single-line setting.
badge slot | null null Slot: a status pill beside the name (a `badge` reading Enabled).

Slots

  • badge — A status pill beside the name (a `badge` reading Enabled).
  • default — Extra content under the description (a link, a hint).

Data slots

Stable hooks for CSS overrides and browser tests.

switch-field switch-field-content switch-field-description switch-field-label switch-field-text

Behavior

  • The label is a real `<label for>` bound to the switch, so clicking the setting's name toggles it and assistive tech reads the name as the control's name.
  • The switch keeps its own Alpine `role="switch"` wiring; this row adds no JS of its own.
  • Declares registry capability flags: a11y, authoredStateFixtures, responsive, rtl, darkMode, localized.

Guidance

Visible exclusive selection

Choose one option from a small visible set.

Use when

  • Use for a small set of mutually exclusive options that users should compare visibly before choosing.
  • A settings screen lists on/off preferences, each with a name and one sentence on what it changes.
  • A card of notification or security options where the whole row should name and toggle the control.

Avoid when

  • Do not hide a small option set in a dropdown when recognition and comparison matter.
  • A bare on/off control inline in a sentence; use `switch` with its own label.
  • A value saved only on submit with a visible checkmark; use `checkbox`.

Use instead

  • Select or combobox for long option sets

Anti-patterns

  • Hiding a small comparable set in a dropdown
Anatomy
switch-field switch-field-text switch-field-label switch-field-description switch-field-content
Theming hooks
switch-field

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 row's text names the control through `for`/`id`; the description is plain text beside it, never the only place the state is said.
  • 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/switch-field.blade.php Blade
{{--
    Switch Field — the preference row every settings screen repeats: the
    setting's name as the switch's label, one sentence on what it changes,
    and the switch at the end of the row. The label is a real <label for>, so
    the whole text names the control and clicking it toggles the switch.

    `badge` slot: a status pill beside the name ("Enabled"). The default slot
    renders under the description for anything else the row needs to say.
--}}
@props([
    'label' => '',
    'description' => null,
    'name' => null,
    'id' => null,
    'value' => '1',
    'checked' => false,
    'disabled' => false,
    'size' => 'md',
    // start: text top-aligned beside the switch (a description that may wrap);
    // center: a single-line setting.
    'align' => 'start',
    'badge' => null,
])

@php
    $id ??= filled($name) ? 'switch-field-'.\Illuminate\Support\Str::slug((string) $name) : 'switch-field-'.\Illuminate\Support\Str::random(6);
    $align = in_array($align, ['start', 'center'], true) ? $align : 'start';
    $hasBadge = $badge !== null && ! $badge->isEmpty();
@endphp

<div
    data-slot="switch-field"
    data-align="{{ $align }}"
    {{ $attributes->merge(['class' => 'flex justify-between gap-4 '.($align === 'center' ? 'items-center' : 'items-start')]) }}
>
    <div data-slot="switch-field-text" class="min-w-0 flex-1 space-y-0.5">
        <div class="flex min-w-0 flex-wrap items-center gap-2">
            <x-ui.label :for="$id" data-slot="switch-field-label">{{ $label }}</x-ui.label>
            @if ($hasBadge)
                {{ $badge }}
            @endif
        </div>
        @if ($description !== null)
            <p data-slot="switch-field-description" class="text-sm text-muted-foreground">{{ $description }}</p>
        @endif
        @if (trim($slot) !== '')
            <div data-slot="switch-field-content" class="pt-2 text-sm text-muted-foreground">{{ $slot }}</div>
        @endif
    </div>

    <x-ui.switch
        :id="$id"
        :name="$name"
        :value="$value"
        :checked="$checked"
        :disabled="$disabled"
        :size="$size"
        class="shrink-0"
    />
</div>

Ownership & lifecycle

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