Installation Run:
composer require yepsua/filament-themes
php artisan vendor:publish --tag="yepsua-filament-themes-config"
This publishes the config file (config/filament-themes.php) to customize theme settings.
Publish Assets For CSS/JS assets (if using custom themes):
php artisan vendor:publish --tag="yepsua-filament-themes-assets"
Place your theme CSS (e.g., resources/css/app.css) in the published directory.
Configure Tailwind
Update tailwind.config.js to use CSS variables for dynamic theming:
module.exports = {
theme: {
extend: {
colors: {
primary: withOpacityValue('(--color-primary)'),
// Add other theme colors
}
}
}
}
Define Themes in Config
Edit config/filament-themes.php to define themes (e.g., light, dark, custom):
'themes' => [
'light' => [
'primary' => '#3b82f6', // Tailwind blue-500
'secondary' => '#10b981',
],
'dark' => [
'primary' => '#60a5fa', // Tailwind blue-400
],
],
Set Default Theme
In .env or config/filament.php, set:
FILAMENT_THEME=light
Test
Run npm run dev (or vite) to compile assets, then refresh your Filament admin panel.
Quickly switch between light/dark themes without rebuilding assets:
// Example: Toggle theme via a button click
document.getElementById('theme-toggle').addEventListener('click', () => {
const theme = document.body.classList.contains('dark') ? 'light' : 'dark';
fetch(`/filament-themes/set-theme?theme=${theme}`, { method: 'POST' });
});
setTheme() helper in a Filament action or middleware.config/filament-themes.php under the themes key. Use hex, rgb, or Tailwind color names (e.g., blue-500).
'themes' => [
'brand' => [
'primary' => '#7c3aed', // Indigo-600
'danger' => '#ef4444',
'success' => '#10b981',
],
],
.env:
FILAMENT_THEMES_CUSTOM_PRIMARY=#ec4899 // Overrides 'primary' for 'custom' theme
Frontend Integration:
filament-themes.js (published via assets) to listen for theme changes:
window.addEventListener('filament-themes:updated', (e) => {
document.documentElement.style.setProperty('--color-primary', e.detail.primary);
});
/filament-themes/set-theme).session()->put('filament_theme', 'dark')).Backend Logic:
FilamentThemes facade to manage themes programmatically:
use Yepsua\FilamentThemes\Facades\FilamentThemes;
// Set theme for current user
FilamentThemes::setTheme('dark');
// Get current theme
$currentTheme = FilamentThemes::getTheme();
Vite/Tailwind Setup:
app.css includes CSS variables for dynamic theming:
@layer base {
:root {
--color-primary: rgb(var(--primary));
--color-secondary: rgb(var(--secondary));
}
}
tailwind.config.js:
npm run dev
npm run build.Mix Support:
If using Laravel Mix, replace withOpacityValue in tailwind.config.js with PostCSS variables or use the package’s default setup.
public function handle(Request $request, Closure $next) {
if ($userTheme = session()->get('filament_theme')) {
FilamentThemes::setTheme($userTheme);
}
return $next($request);
}
use Yepsua\FilamentThemes\Facades\FilamentThemes;
public function getThemeOptions(): array {
return collect(config('filament-themes.themes'))
->keys()
->mapWithKeys(fn ($theme) => [$theme => __($theme)])
->toArray();
}
public function updateTheme(string $theme) {
FilamentThemes::setTheme($theme);
session()->put('filament_theme', $theme);
}
'themes' => [
'custom' => [
'extends' => 'light', // Inherit from 'light' theme
'primary' => '#8b5cf6', // Override primary
],
],
Filament::serving(function () {
if (FilamentThemes::getTheme() === 'dark') {
Filament::registerAsset('css', asset('css/filament-dark.css'));
}
});
Filament Panels:
config/filament.php:
'panels' => [
'admin' => [
'theme' => env('FILAMENT_PANEL_THEME', 'light'),
],
],
Dark Mode Detection:
prefers-color-scheme:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
fetch('/filament-themes/set-theme?theme=dark', { method: 'POST' });
}
Localization:
lang/en/json:
{
"themes": {
"light": "Light Mode",
"dark": "Dark Mode"
}
}
Testing:
FilamentThemes::shouldReceive('getTheme')->andReturn('dark');
CSS Variable Conflicts:
@apply sparingly and ensure variables are declared in :root or a higher-specificity layer:
@layer base {
:root {
--color-primary: rgb(var(--primary));
}
}
Asset Caching:
tailwind.config.js or theme colors may not reflect until assets are rebuilt.php artisan cache:clear
npm run dev
Theme Inheritance:
extends in themes may not work as expected if the parent theme’s variables are not properly inherited.@apply for inherited styles.Middleware Order:
app/Providers/AppServiceProvider.php:
public function boot() {
$this->app->booted(fn () => $this->app->make(\Yepsua\FilamentThemes\Http\Middleware\Set
How can I help you explore Laravel packages today?