codewithdennis/filament-theme-inspector
A Filament developer tool for inspecting your panel’s theme in real time. Browse colors, typography, spacing, and component tokens, then copy CSS variables to debug or refine your custom Filament theme.
What it actually does. Despite the marketing copy about "CSS variables and design tokens," the package does one thing: on a Filament panel, hovering any element shows a tooltip with that element's fi-* class string, and clicking copies it to your clipboard. Treat that as the whole feature surface — it is a hover-to-copy class lookup, not a theme token browser. For computed CSS variables you still want DevTools → Computed → filter: --.
Install and register (local only).
composer require codewithdennis/filament-theme-inspector --dev
The vendor namespace follows the usual convention (CodeWithDennis\FilamentThemeInspector\...), but the release notes for v0.0.7 are empty — open vendor/codewithdennis/filament-theme-inspector/src/ and confirm the actual plugin FQCN and whether it is a Filament\Contracts\Plugin or a bare service provider before wiring it up.
// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugins(array_filter([
app()->isLocal() ? ThemeInspectorPlugin::make() : null,
]));
}
If it turns out to be a plain service provider, register it conditionally in bootstrap/providers.php (or config/app.php for older skeletons) instead:
// bootstrap/providers.php
return array_filter([
App\Providers\AppServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
app()->isLocal() ? CodeWithDennis\FilamentThemeInspector\ThemeInspectorServiceProvider::class : null,
]);
Then clear caches and reload: php artisan filament:assets && php artisan optimize:clear.
Where to look first. Open any List/Table page in your panel, hover a table row cell. You should see a tooltip such as fi-ta-cell fi-ta-cell-.... Click it, paste into your editor, and grep -rn "fi-ta-cell" vendor/filament/ — that grep is the actual value of the tool: it collapses "which class is this element?" from a multi-click DevTools excursion into one hover.
First use case. You want to restyle the "Create" button on a resource index page. Hover it, copy fi-btn fi-color-primary fi-btn-size-md ..., grep the Filament vendor tree to find the base .fi-btn rule, then add your override in resources/css/filament/admin/theme.css. Copy → grep → override is the whole loop.
Gate at the panel level, not the environment string alone. app()->isLocal() breaks the moment someone runs a staging design sandbox. Prefer an explicit config flag you can set per-environment:
// config/filament-theme-inspector.php (your own file, not the package's)
'enabled' => env('FILAMENT_THEME_INSPECTOR', false),
->plugins(array_filter([
config('filament-theme-inspector.enabled') ? ThemeInspectorPlugin::make() : null,
]))
Add a CI assertion that the plugin class is absent from the compiled provider list in production builds — php artisan about plus a grep over the built panel is enough. Reviewer memory is not a gate.
Dedicate one design-sandbox panel. Rather than enabling this on the admin panel every engineer uses daily, register a second panel (DesignPanelProvider, path design, guarded by ->authGuard('web') and a policy) that loads your theme under test. Failure modes — CSP blocking the script, a hover overlay stealing clicks — stay away from the panel people actually work in.
The class → source → override workflow.
# 1. paste the copied string
CLASS="fi-ta-cell"
# 2. find where Filament defines it
grep -rn "\.${CLASS}" vendor/filament/tables/resources/css/
# 3. override in your theme
/* resources/css/filament/admin/theme.css */
@import '../../../../vendor/filament/filament/resources/css/theme.css';
.fi-ta-cell {
@apply px-2 py-1 text-xs;
}
Because the tooltip gives you the whole class string, it also tells you about state modifiers (fi-color-primary, fi-btn-size-sm, fi-ta-cell-selected) — those are usually what you actually want to target, not the base class.
Design-QA handoff. This is the strongest non-engineer use case. Give QA/designers the sandbox panel URL and a one-line brief: "hover the thing, click, paste the string into the ticket." It replaces screenshots annotated with "this thing" and materially shortens the designer↔engineer round trip on admin-panel polish. Pair it with a short internal note on Filament's fi- convention; most of the durable value lives in that note, not the package.
Onboarding. New engineers who don't know Filament's class conventions can hover and immediately see them. Half a sprint of this and they stop needing it — plan for usage to drop off, which is fine and is itself the success signal.
Fork-and-own if it sticks. The repo is archived (last release October 2024, ~45 stars, zero dependents). A raw composer require pulls in unmaintained code into your admin toolchain. If the pilot proves value, vendor it into your own namespace as a path or vcs repository and accept the maintenance line item; the surface is genuinely tiny (a service provider, a published asset, a short JS file).
Or just reimplement. The core is roughly this, injected only in dev:
document.addEventListener('mouseover', (e) => {
const fi = [...e.target.classList].filter(c => c.startsWith('fi-'));
if (!fi.length) return;
// position a tooltip with fi.join(' '), click → navigator.clipboard.writeText(...)
});
Thirty lines gets you 90% of the package with zero version coupling. Keep this option on the table — it makes the build-vs-fork call cheap instead of loaded.
Archived means you own every future fix. No security advisory channel, no issue triage, no compatibility matrix. Pin it, name an owner, and pre-commit to a decision (fork / reimplement / discard) before the next Filament major appears on your roadmap — not after.
Filament v4 is unverified and probably broken. A tool keyed to fi- class names is directly exposed to major-version changes, and this was last released in the Filament v3 era. Assume incompatibility until you've tested it; do not put it anywhere a break blocks delivery.
Content-Security-Policy will silently kill it. The inspector injects a script; a strict CSP without a nonce or hash blocks it and you get a hover tooltip that never appears, with only a console warning. If you see "it just doesn't work," check the console for CSP violations before debugging anything else.
Clipboard fails on plain-HTTP hosts. navigator.clipboard.writeText requires a secure context. On an HTTP staging box the copy button does nothing and logs nothing obvious — copy will work on localhost and HTTPS only. Document it or serve staging over TLS.
Don't let the tooltip fool you into targeting the wrong thing. A copied string often includes layout/state classes that are incidental. The class you want is usually the base fi- class plus one modifier; the rest is noise from the current runtime state.
Custom themes can diverge from the fi- prefix. If your theme renames or extends the prefix, or your components are plain Blade/Tailwind without Filament classes, you'll get empty or partial results — that's a convention dependency, not a bug to chase.
Asset publishing after a fresh clone is the most common "broken install." If nothing shows after composer install on a new machine, run php artisan filament:assets and php artisan optimize:clear before suspecting the package. Watch for collisions with your Vite theme build.
Hover overlays can fight Filament's own tooltips and actions. Expect occasional interception on dense tables and icon buttons; that's part of why the sandbox-panel pattern beats enabling it on the working admin panel.
It does not inspect CSS variables or design tokens, whatever the package description claims online. For --fi-* variables, use DevTools Computed styles. Don't promise designers a token browser this doesn't deliver.
Never ship it to production. Not because it's dangerous in itself (it reads classes already rendered to an authenticated admin), but because it's a self-XSS-adjacent surface and a security-review smell, and it degrades the UX for real users. Hard gate + CI assertion, every time.
If it breaks, reach for the reimplement option early. Everything here is a one-commit change with no data, no API, and no migration to unwind. The cost of dropping it is near zero — which should make you aggressive about discarding it the moment it stops working.
How can I help you explore Laravel packages today?