Toggle
Basic Usage
The Toggle field renders a switch-style toggle. By default, it stores true when on and false when off.
Toggle::make('notifications')
->label('Email notifications')
->default(true);Use Toggle for a single on/off value. For multiple related choices, use CheckboxGroup; for one-of-many choices, use Radio.
Custom Values
Customize what gets stored when the toggle is on or off:
Toggle::make('status')
->onValue('active')
->offValue('inactive');
Toggle::make('is_public')
->onValue(1)
->offValue(0);Supported cross-stack values are strings, numbers, booleans, and null. PHP preserves a model or default value that strictly matches either configured value. Any other value is converted using PHP truthiness, then mapped to onValue or offValue. Vue and React also use strict value equality to decide whether the switch is on.
For example, this field writes null when it is off:
Toggle::make('status')
->onValue('enabled')
->offValue(null);Validation
Toggle does not add a boolean or acceptance rule automatically. Add the Laravel rule that matches the configured values. required() only adds Laravel's required rule and exposes aria-required; it does not mean the switch must be on. Use accepted for an on/off value that must be enabled.
Labels
Add text labels that appear next to the toggle. Labels pair well with custom stored values when the submitted value is not a boolean:
Toggle::make('visibility')
->label('Portal visibility')
->onValue('public')
->offValue('private')
->onLabel('Public')
->offLabel('Private')
->color('#16a34a')
->default('public');onLabel() and offLabel() are optional visible state labels. They do not change the accessible name of the switch, which comes from the field label or an explicitly forwarded aria-label.
Icons
You may add icons inside the toggle thumb by passing resolver-backed icon names. See Icons:
Toggle::make('dark_mode')
->onIcon('MoonIcon')
->offIcon('SunIcon');The icon resolver receives the configured name only for the active state. Icons are decorative and do not replace the field label.
Size
Three sizes are available: sm, md (default), and lg.
Toggle::make('small_toggle')->label('Small')->sm();
Toggle::make('medium_toggle')->label('Medium')->md();
Toggle::make('large_toggle')->label('Large')->lg();Or use the generic method:
Toggle::make('notifications')->size('lg');Vue and React fall back to the medium styles for any unrecognized serialized size. Use sm(), md(), or lg() for the supported public contract.
Color
Customize the active color of the toggle with any valid CSS color value:
Toggle::make('notifications')->color('#16a34a');
Toggle::make('maintenance_mode')->color('rgb(220 38 38)');The custom color applies only to the on-state track. Passing null restores the theme accent color.
Loading
Show a loading spinner while an update is pending. A loading toggle is busy and disabled, so user interaction may not change it until loading ends:
Toggle::make('syncing')->loading();
Toggle::make('locked_setting')->disabled();Using the Component Directly
You may render Toggle with local state, or pass serialized field props during manual form rendering.
<script setup lang="ts">
import { Toggle } from '@inertiaui/form-vue/components'
import { Moon, Sun } from '@lucide/vue'
import { ref } from 'vue'
import type { IconResolverFn } from '@inertiaui/form-vue'
const theme = ref<'dark' | 'light'>('light')
const saving = ref(false)
const canEdit = ref(true)
const icons = { MoonIcon: Moon, SunIcon: Sun }
const iconResolver: IconResolverFn = (icon) => icons[icon as keyof typeof icons] ?? null
const toggleParts = {
track: 'ring-1 ring-zinc-950/10',
thumb: 'ring-1 ring-zinc-950/10',
}
const trackBlur = () => {}
</script>
<template>
<Toggle
v-model="theme"
id="theme-mode"
name="theme_mode"
label="Theme mode"
help="Applied to the current workspace."
on-value="dark"
off-value="light"
on-label="Dark"
off-label="Light"
on-icon="MoonIcon"
off-icon="SunIcon"
size="lg"
color="#16a34a"
:loading="saving"
:disabled="!canEdit"
:icon-resolver="iconResolver"
required
precognitive
invalid
error="Choose an available theme mode."
badge="Workspace"
badge-class="bg-zinc-100 text-zinc-700"
label-trailing="Required"
label-trailing-class="text-zinc-500"
tooltip="Shown to every member of this workspace."
help-position="below"
layout="stacked"
control-position="end"
label-class="font-medium"
help-class="text-zinc-500"
error-class="text-red-600"
wrapper-class="max-w-xl"
control-class="bg-white"
class="font-medium"
:part-classes="toggleParts"
data-testid="theme-toggle"
aria-label="Theme mode"
@blur="trackBlur"
/>
</template>import { useState } from 'react'
import { MoonIcon, SunIcon } from 'lucide-react'
import { Toggle } from '@inertiaui/form-react/components'
import type { IconResolverFn } from '@inertiaui/form-react'
const icons = { MoonIcon, SunIcon }
const iconResolver: IconResolverFn = (icon) => icons[icon as keyof typeof icons] ?? null
const toggleParts = {
track: 'ring-1 ring-zinc-950/10',
thumb: 'ring-1 ring-zinc-950/10',
}
export default function ThemeToggle() {
const [theme, setTheme] = useState<'dark' | 'light'>('light')
const [saving] = useState(false)
const [canEdit] = useState(true)
const trackBlur = () => {}
return (
<Toggle
value={theme}
onValueChange={(value) => setTheme(value as 'dark' | 'light')}
id="theme-mode"
name="theme_mode"
label="Theme mode"
help="Applied to the current workspace."
onValue="dark"
offValue="light"
onLabel="Dark"
offLabel="Light"
onIcon="MoonIcon"
offIcon="SunIcon"
size="lg"
color="#16a34a"
loading={saving}
disabled={!canEdit}
iconResolver={iconResolver}
required
precognitive
invalid
error="Choose an available theme mode."
badge="Workspace"
badgeClass="bg-zinc-100 text-zinc-700"
labelTrailing="Required"
labelTrailingClass="text-zinc-500"
tooltip="Shown to every member of this workspace."
helpPosition="below"
layout="stacked"
controlPosition="end"
labelClass="font-medium"
helpClass="text-zinc-500"
errorClass="text-red-600"
wrapperClass="max-w-xl"
controlClass="bg-white"
class="font-medium"
partClasses={toggleParts}
data-testid="theme-toggle"
aria-label="Theme mode"
onBlur={trackBlur}
/>
)
}Vue uses v-model. React uses controlled value plus onValueChange. Native attributes and listeners target the underlying button; see Native Attributes and Events.
All shared field methods remain available. See Validation, Conditional Visibility, Authorization, Model Binding, Form Class, Icons, and Styling for rules, visibility, authorization, model values, runtime configuration, icon resolvers, labels, help, layout, and classes.