Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Toggle Switch Field Laravel Package

naif/toggle-switch-field

A Laravel Nova field that renders a clean, interactive toggle switch for boolean attributes, making on/off settings easier to scan and edit in your admin panel. Simple to install and configure, it replaces default checkboxes with a polished switch UI.

View on GitHub
Deep Wiki
Context7

Getting Started

What it is: a Laravel Nova field package that renders a boolean attribute as an on/off toggle switch instead of Nova's default checkbox. It is a thin UI wrapper — the storage layer is still a normal boolean column on your model.

Requirements to check before installing

  • Laravel Nova 4.x or 5.x (field packages are tightly coupled to Nova's asset pipeline — confirm the supported Nova major in the README before you commit).
  • PHP version matches the package's composer.json constraint.
  • A boolean-ish column already exists, or you're about to add one.

Install

composer require naif/toggle-switch-field

Field packages normally register their compiled JS through a FieldServiceProvider and need no manual publish. If the README asks for it, publish assets and rebuild:

php artisan vendor:publish --tag=toggle-switch-field-assets

Where to look first (in priority order)

  1. README.md — the canonical usage snippet and the exact field class FQCN.
  2. src/ — find the field class. Check what it extends: if it extends Laravel\Nova\Fields\Boolean you inherit the entire Boolean API (trueValue, falseValue, nullable, resolveUsing) for free. That single detail determines how much of the patterns below apply.
  3. resources/js/ — the Vue component. Confirms which props (trueLabel, falseLabel, colors, sizes) the field actually supports.
  4. config/ — if present, tells you whether labels/colors are configurable globally vs. per-field.

First use case

You have a users.is_active column and a Nova User resource where admins flip accounts on and off several times a day. Replace the checkbox:

use Naif\ToggleSwitchField\ToggleSwitchField; // verify FQCN in README

public function fields(NovaRequest $request): array
{
    return [
        ID::make()->sortable(),
        Text::make('Name')->rules('required', 'max:255'),
        ToggleSwitchField::make('Active', 'is_active')
            ->default(true)
            ->rules('boolean'),
    ];
}

Migrate and cast so the value round-trips cleanly:

// migration
$table->boolean('is_active')->default(true)->index();

// app/Models/User.php
protected $casts = ['is_active' => 'boolean'];

The ->index() matters more than it looks — the whole point of a toggle is fast filtering, and you'll end up writing User::where('is_active', true) constantly.

Implementation Patterns

1. The one-line upgrade path from Boolean

If the field extends Nova's Boolean, adoption is a single line per field. That's the intended workflow: treat it as a drop-in skin, keep the rest of the field configuration identical.

// before
Boolean::make('Active', 'is_active')->rules('boolean'),
// after
ToggleSwitchField::make('Active', 'is_active')->rules('boolean'),

2. Forms only, read-only on detail

Toggles are for the edit form. On index/detail, a plain text badge often reads better in dense tables.

ToggleSwitchField::make('Active', 'is_active')
    ->onlyOnForms()
    ->rules('boolean'),

Boolean::make('Active', 'is_active')   // renders "Yes/No" on index & detail
    ->exceptOnForms(),

3. Feature-flag style usage

This is where toggles earn their keep — a resource full of booleans that read as a control panel:

Panel::make('Feature Flags', [
    ToggleSwitchField::make('Beta Access', 'flag_beta'),
    ToggleSwitchField::make('New Dashboard', 'flag_dashboard'),
    ToggleSwitchField::make('Email Digest', 'flag_digest'),
]),

Group them in one Panel so the whole block saves in a single update request.

4. Coupling state to a timestamp

A boolean that implies a date is a classic source of drift. Use fillUsing to keep them in sync:

ToggleSwitchField::make('Active', 'is_active')
    ->fillUsing(function ($request, $model, $attribute, $requestAttribute) {
        $value = (bool) $request->input($requestAttribute);
        $model->{$attribute} = $value;

        if ($value && ! $model->activated_at) {
            $model->activated_at = now();
        }
    }),

5. Guarding destructive flips

Deactivating an account is not the same risk as renaming it. Gate it:

ToggleSwitchField::make('Active', 'is_active')
    ->canSee(fn (NovaRequest $request) => $request->user()->isAdmin())
    ->hideWhenUpdating(fn (NovaRequest $request) => $request->user()->id === $request->resourceId),

Note hideWhenUpdating on a field you also rely on for filtering is a footgun — decide whether the field should be invisible or read-only (->readonly()) instead.

6. Validation is still your job

The toggle controls the widget, not the input. A crafted request can post is_active="drop table".

ToggleSwitchField::make('Active', 'is_active')->rules('required', 'boolean'),

7. Testing the toggle

The Vue component is irrelevant to your test suite — assert at the HTTP layer:

public function test_admin_can_deactivate_user(): void
{
    $this->actingAs($this->admin)
        ->putJson("/nova-api/users/{$this->user->id}", ['is_active' => false])
        ->assertOk();

    $this->assertFalse($this->user->fresh()->is_active);
}

If you want a unit-level guard against someone silently swapping the field, assert the field instance type in a Nova resource test:

$this->assertInstanceOf(ToggleSwitchField::class, (new User)->fields(NovaRequest::create('/'))[2]);

Gotchas and Tips

It's a small package — plan for the bus factor. Six stars and zero dependents means no community pressure to fix Nova upgrades. Two mitigations: pin the exact version in composer.json, and wrap usage in your own field subclass so swapping back to Boolean is a one-file change.

namespace App\Nova\Fields;

class Toggle extends \Naif\ToggleSwitchField\ToggleSwitchField
{
    public function component()
    {
        return 'toggle-switch-field'; // override here if you ever fork it
    }
}

The toggle renders as a plain checkbox. That means the JS component failed to load, not that the field is broken. Check, in order: the browser console for a 404 on the component chunk; whether nova:publish (or the package's asset tag) was actually run in this environment; whether your public/vendor/ directory survived your deploy (common on containerized/Forge deploys where build artifacts are gitignored). Re-run the publish step as part of your deploy script.

Nova already has a toggle-ish Boolean field. Before adding a dependency, confirm the value is real — custom on/off labels, a specific size, brand colors. If you just want a nicer boolean, Nova's built-in Boolean in Nova 4/5 is already serviceable. The honest cost/benefit here is one more package in your composer.json for a UI nicety.

Tri-state is not a toggle. nullable booleans (true/false/null, where null means "not yet decided") do not map to a two-position switch. If you have null semantics, use a Select with three options. Toggles silently coerce null → false on save and you'll lose the distinction.

MySQL tinyint(1) vs Postgres boolean. On Postgres, posting the string "false" to a boolean column throws. Cast on the model ('is_active' => 'boolean') and validate with the boolean rule so the request payload is normalized before it reaches the driver.

Labels are the accessibility story. A bare switch conveys nothing to a screen reader without an associated label. If the package exposes label props, use them; otherwise put the field in a Panel with a heading so context is never purely visual. Also sanity-check dark mode — small packages rarely test it, and a switch with a transparent track disappears entirely.

Inline editing on the index is generally not supported. If rapid toggling from the index is your actual requirement, that's a different feature — use a Nova Action (ToggleActive) or Nova 4's inline edit on a Boolean, not this field.

Upgrading Nova will break this before it breaks anything else. After any Nova major bump, run the package's publish/rebuild step and click every toggle in staging. If there's no compatible release, the escape hatch is subclassing Nova's Boolean and shipping your own three-line Vue component — realistically that's less work than the dependency is saving you, which is worth knowing before you spread the field across twenty resources.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings