smart145/inline-boolean
A lightweight Laravel package for inline boolean toggles: flip true/false attributes right from list tables and admin views, with a single click and no full form submission. Easy to wire into Blade or Livewire and simple to customize.
Read composer.json before installing. The single tagged release is 2020-04-10, so treat every constraint in there as a promise from a different era. Check the php, laravel/framework, and (if present) laravel/nova requirements against your app. If you're on PHP 8.2+ or Laravel 10/11, expect resolution to fail — and accept that failure rather than reaching for --ignore-platform-reqs.
composer require smart145/inline-boolean
Expect a small footprint: a service provider (auto-discovered), a publishable config and views, and a prebuilt JS/CSS asset. Publish and read them before wiring anything up:
php artisan vendor:publish --provider="Smart145\InlineBoolean\InlineBooleanServiceProvider"
Open the published config first — that's where the route/endpoint, authorization callback, and asset registration live. Then open the published Blade view: it tells you exactly which data attributes and classes the JS hooks into, which is the fastest way to understand the component's contract.
First use case: the publish/moderation toggle. Drop the component into a table row for published, is_active, featured, or verified — high-value, low-blast-radius fields ops users flip constantly:
<x-inline-boolean :model="$post" field="published" />
First thing to verify after it renders: open the Network tab, click the toggle once, and record the exact request — method, URL, payload, and CSRF header. That single observation tells you whether it posts to your app's policy-checked route or a package-owned one, and that answer gates everything in the Gotchas section.
Use it in tables and detail pages, not forms. The toggle is an interaction control for surfaces where the value is already persisted. Keep your normal validated Boolean input in create/edit forms so required, rules(), and form-level authorization still apply where they belong.
Standardize via a Blade component wrapper or trait. Instead of hand-configuring labels and colors on every view, define one helper so every toggle in the admin behaves identically:
// app/View/Components/FlagToggle.php
class FlagToggle extends Component
{
public function __construct(public Model $model, public string $field) {}
public function render()
{
return view('components.flag-toggle');
}
}
Then enforce authorization server-side, not just by hiding the button. The write happens outside the normal form update path, so make the policy explicit:
// In the controller/route the toggle posts to
$this->authorize('update', $model);
$model->update([$field => $request->boolean($field)]);
Chain side effects in an observer, not the controller. A published toggle that doesn't set published_at, or a cache key that isn't invalidated, will look like a package bug. Handle it in a model observer so it fires for the toggle, the form, and tinker alike:
Post::saving(function (Post $post) {
if ($post->isDirty('published')) {
$post->published_at = $post->published ? now() : null;
}
});
Test the endpoint directly. The positive path is easy to eyeball; the negative path is what you're paid to get right:
public function test_user_without_permission_cannot_toggle()
{
$user = User::factory()->create(); // no update grant
$post = Post::factory()->create(['published' => false]);
$this->actingAs($user)
->postJson(route('inline-boolean.update'), [
'model' => Post::class, 'id' => $post->id,
'field' => 'published', 'value' => true,
])
->assertForbidden();
$this->assertFalse($post->fresh()->published);
}
Debounce and guard the client. Rapid clicks write-amplify; add a disabled guard while a request is in flight. Two admins on the same record will diverge — there's no realtime channel, so the second admin's view only corrects on reload.
The prebuilt JS bundle is the fragile part. It ships compiled with no reproducible build step you can audit. Check the browser console for registration errors ("Unknown custom element", Vue/mixin errors) and grep the shipped JS for the component name it's resolving. If it doesn't mount, you get an empty cell or raw true/false with nothing else in the log.
Verify the request path before shipping. If the toggle posts to a package-owned controller, confirm that controller calls authorize() against your policy before writing. A list-view write that bypasses authorizedToUpdate is a policy bypass — disqualifying for production without a fork and a negative-permission test.
The most dangerous failure is a silent 403/422. If the component flips optimistically and the server rejects, a user can see a green toggle believing it saved. Test a permission failure specifically: does the UI roll back? If not, at minimum ensure the next index load shows the server value — and confirm that it does.
CSRF / 419s. The component advertises CSRF handling, but confirm the token is read from the meta tag or a cookie your layout actually renders. A single-page that omits <meta name="csrf-token"> will 419 on every click with a cryptic failure.
exceptOnForms() is not a validation strategy. The inline path won't run your field rules or Nullable handling. Booleans are mostly safe, but coupled invariants (e.g. "can't unpublish an invoiced record") belong in the model or a policy method, not the form.
Stale dependent state. Inline writes may not fire the same events the resource form does, so metrics and dependent fields can go stale. Refresh on load, or invalidate caches from the observer.
Debug checklist when the toggle doesn't work — in ~10 minutes: (1) is the component actually rendered for this view (check the Blade output)? (2) does the JS component resolve in the console? (3) what does the Network request show — URL, status, body? (4) does the policy return true for this user against this specific model? Those four isolate it.
Vendor the source if it's going into production. Debugging a black-box bundle is harder than debugging your own component. Copy the view + JS into your app's resources/ where you can read, rebuild, and add tests. Zero stars, zero dependents, no CI, no changelog, no security advisories means once it's in, you're the maintainer.
Extension points, in order of usefulness: (1) subclass or wrap the Blade component to bake in can/readonly/label defaults; (2) override the published views and styles for full control of markup and optimistic-UI behavior; (3) fork and vendor the JS so you own the rollback and debounce logic.
How can I help you explore Laravel packages today?