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

Dimmer Laravel Package

awcodes/dimmer

A lightweight Filament plugin from awcodes that adds a dimmer overlay to your panel, letting you fade or spotlight areas of the UI so key content stands out. Simple to install and easy to drop into any Livewire view.

View on GitHub
Deep Wiki
Context7

Getting Started

Dimmer is a small utility package for dimming the rest of the page while spot­lighting a single element — useful for onboarding tours, "look here" callouts, and surfacing the first invalid form field. It is a thin service provider plus Blade/Alpine assets, so there is very little to wire up.

composer require awcodes/dimmer

Then, if you want to tweak behaviour locally:

php artisan vendor:publish --tag="dimmer-config"
php artisan vendor:publish --tag="dimmer-views"   # only if you truly need to edit markup

Look here first, in this order:

  1. README.md — the public API surface is tiny and the README is the canonical reference for component/attribute names.
  2. src/DimmerServiceProvider.php — tells you which views, config keys, and asset tags exist. If a feature "doesn't work", confirm the provider is auto-discovered (composer dump-autoload after odd upgrades).
  3. resources/views/ — the Blade component. Reading it is faster than guessing at which attributes are forwarded to the root element.
  4. config/dimmer.php — defaults for overlay opacity, transitions, and class names (key names vary by version; read the shipped file rather than copying snippets from blog posts).

First use case — spotlight a target on click. Give the element you want to highlight an ID, drop the Dimmer component into your layout, and drive it from Alpine state:

<div x-data="{ spotlight: false }">
    <x-dimmer :active="spotlight" target="#new-filter" />

    <button type="button" @click="spotlight = true">What's this?</button>

    <select id="new-filter" wire:model.live="filter">…</select>
</div>

Verify in the browser that the overlay renders above your content and below the target. That single check catches most integration problems.

Implementation Patterns

Declarative toggling via Alpine. The package is Alpine-first; the happy path is Boolean state in x-data bound to the component's active prop. Keep the state on a wrapper that also contains the target so the target is guaranteed to be in the DOM when the overlay mounts.

Event-driven control for multi-step tours. Rather than threading props through several components, emit a browser event from anywhere (window.dispatchEvent(new CustomEvent('dimmer:show', { detail: { target: '#step-2' } })) or Alpine's $dispatch) and let a single Dimmer instance in the layout listen. Confirm the exact event names in the README before committing — this is the one part of the API worth pinning in a test.

Step sequences. For onboarding, hold an array of selectors in Alpine and advance on "Next":

steps: ['#nav', '#search', '#profile'],
i: 0,
next() { this.i++; this.i < this.steps.length ? this.$dispatch('dimmer:show', { target: this.steps[this.i] }) : this.$dispatch('dimmer:hide') }

Persist completion server-side (a users.onboarded_at column) so you don't re-run the tour on every visit.

Form validation spotlight. After a Livewire/Filament validation round-trip, target the first invalid input:

<x-dimmer :active="$errors->any()" :target="'#' . array_key_first($errors->toArray())" />

This is where Dimmer earns its keep in admin panels — the error summary alone is easy to miss on long forms.

Filament panel integration. Register the package assets on the panel (->assets([...]) in the panel provider) or via a render hook so the overlay exists on every page; then trigger it from a custom action or from $wire after saving. Keeping one Dimmer instance in the panel rather than per-page avoids stacking-context surprises.

Styling without forking. Override the CSS custom properties / classes the package exposes rather than editing published views. If you do publish views, treat them as your code from that point on — vendor:publish --force will silently overwrite your edits on the next upgrade.

Upgrading. Pin ^1.2 in composer.json. v1.2.0 is a non-breaking chore release (it drops an unnecessary illuminate/contracts requirement) — no application code changes are needed to move from 1.1.0. Run composer update awcodes/dimmer and your existing suite is sufficient verification.

Gotchas and Tips

  • Stacking contexts will bite you. An ancestor with transform, filter, perspective, or a z-index creates a new stacking context, and the overlay can end up trapped beneath a sticky header or a Filament topbar. If the dimmer covers everything except the thing you expected it to cover, or covers your nav, look at parent styles before touching the package config.
  • Measure after the DOM settles. If the package positions the overlay against the target's bounding box, opening it in the same tick as a Livewire render gives you stale coordinates. Wrap the toggle in $nextTick() or a requestAnimationFrame.
  • Livewire morphing replaces nodes. A target that gets re-rendered loses its highlighted state. Either add wire:ignore to the target or re-show the overlay on morph.updated. This is the single most common "works once, then breaks" report with overlay packages.
  • Load the JS exactly once. Double-registering the assets (once in a global layout, once in a panel provider) yields duplicate listeners and toggles that appear to do nothing because they fire twice.
  • Accessibility. Trap focus while the overlay is active, support Escape to dismiss, honour prefers-reduced-motion by disabling the fade, and make sure the spotlighted content is still keyboard reachable — a full-screen overlay that swallows Tab is a regression you will ship if you don't test with the keyboard.
  • Transitive dependencies. v1.2.0 no longer pulls illuminate/contracts. If your app was relying on it arriving via Dimmer, that was always an accident — declare it (or better, rely on laravel/framework) explicitly. composer why illuminate/contracts after upgrading will show you whether anything else still provides it.
  • Debugging. Inspect the overlay node in DevTools to see which class/variable is actually applied; temporarily set opacity to 1 and give it a bright background to confirm it is mounting at all. php artisan about plus a published config file is usually enough to confirm the provider registered.
  • Extension points. Prefer the config file and CSS overrides (stable) over published views and internal class names (not part of the public API). Wrap any direct dispatch/event names in a thin Alpine component or Blade partial of your own so a future rename is a one-file change.
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.
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
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core