agenticmorf/fluxui-theme
FluxUI theme and appearance settings for Laravel apps using Livewire Flux. Offers light/dark/system mode, accent and base color swatch pickers, and stores user preferences in an appearance_preferences JSON field on the User model.
Installation:
composer require agenticmorf/fluxui-theme
php artisan migrate
CSS Setup (in resources/css/app.css):
@import 'tailwindcss';
@import '../../vendor/livewire/flux/dist/flux.css';
@source '../../vendor/livewire/flux/stubs/**/*.blade.php';
@custom-variant dark (&:where(.dark, .dark *));
Add to Layout Head (before @fluxAppearance):
<x-fluxui-theme::appearance />
Wrap App Shell (in app.blade.php or similar):
@php
$appearance = app(\AgenticMorf\FluxuiTheme\AppearanceService::class)->getEffective(auth()->user());
@endphp
<flux:accent id="flux-accent" :color="$appearance['accent']">
<!-- Your app content -->
</flux:accent>
Add Settings Link (in your settings nav):
<flux:navlist.item :href="route('appearance.edit')" wire:navigate>{{ __('Appearance') }}</flux:navlist.item>
A user visits the appearance settings page (/settings/appearance), selects a new accent color (e.g., "blue"), and sees the UI update in real-time. The change persists for their session.
User Preferences Storage:
appearance_preferences JSON column on the users table.{
"accent": "blue",
"base": "slate",
"theme": "system"
}
Dynamic CSS Injection:
<x-fluxui-theme::appearance /> component injects inline CSS to override Flux’s base colors (e.g., --color-zinc-* → --color-slate-*).<flux:accent> wrapper.Theme Mode Handling:
@fluxAppearance to toggle between light/dark/system themes.theme: "system".Live Preview:
id="flux-accent" as a target for CSS injection.For Multi-Tenant Apps:
Override the appearance_resolver in config/fluxui-theme.php to fetch tenant-specific defaults:
'appearance_resolver' => [App\Services\TenantSettings::class, 'getAppearance'],
For Admin Overrides: Combine user preferences with admin defaults:
$appearance = app(\AgenticMorf\FluxuiTheme\AppearanceService::class)->getEffective(auth()->user(), [
'accent' => 'green', // Admin override
'base' => 'zinc',
'theme' => 'light'
]);
For Dark Mode Detection:
Use @fluxAppearance in your layout to handle theme switching:
@fluxAppearance
<div class="dark:bg-gray-900 dark:text-white">
<!-- Your content -->
</div>
For Custom Base Colors:
Extend Flux’s CSS variables in app.css:
:root {
--color-mist-50: #f8fafc;
--color-mist-100: #f1f5f9;
/* ... other custom base colors ... */
}
Missing id="flux-accent":
<flux:accent> has id="flux-accent" in your layout.CSS Variable Conflicts:
--color-zinc-* variables, they may override the package’s dynamic CSS.!important in your injected CSS or scope variables (e.g., --fluxui-zinc-*).Migration Issues:
appearance_preferences already exists in your users table, the package’s migration will skip it. However, if the column is missing at runtime, the app may throw an error.php artisan migrate in production or add the column manually:
Schema::table('users', function (Blueprint $table) {
$table->json('appearance_preferences')->nullable();
});
Theme Mode Not Updating:
@fluxAppearance is placed after <x-fluxui-theme::appearance />, the theme may not apply correctly.<x-fluxui-theme::appearance /> before @fluxAppearance in your <head>.Base Color Switching:
--color-zinc-* variables. If you use custom base colors (e.g., --color-mist-*), ensure they are defined in Flux’s CSS or your app’s CSS.app.css.Check User Preferences:
dd(auth()->user()->appearance_preferences);
Ensure the JSON structure matches the expected format.
Inspect Injected CSS:
Use browser dev tools to verify that the package injects CSS for base colors and accent colors. Look for dynamically generated --color-* variables.
Verify Route Configuration:
If the appearance page doesn’t load, check config/fluxui-theme.php for correct route and route_name values.
Custom Swatches: Extend the available accent or base colors by overriding the package’s assets or adding custom CSS variables.
Additional Preferences:
Store extra appearance settings (e.g., font size, corner radius) in appearance_preferences and extend the settings page:
// In your User model
protected $casts = [
'appearance_preferences' => 'array',
];
Custom Appearance Service:
Override the AppearanceService to add logic (e.g., team-wide defaults):
class CustomAppearanceService extends \AgenticMorf\FluxuiTheme\AppearanceService
{
public function getEffective(?User $user, ?array $defaults = null): array
{
$teamDefaults = $this->getTeamDefaults();
return parent::getEffective($user, $teamDefaults ?? $defaults);
}
}
Dark Mode Detection: Extend the theme logic to support custom dark mode rules (e.g., based on time of day):
// In your AppearanceService
public function resolveTheme(?User $user): string
{
if ($user->appearance_preferences['theme'] === 'system') {
return \Carbon\Carbon::now()->hour < 8 || \Carbon\Carbon::now()->hour > 20 ? 'dark' : 'light';
}
return $user->appearance_preferences['theme'] ?? 'light';
}
Localization: Translate swatch names and settings labels by publishing the language files:
php artisan vendor:publish --tag=fluxui-theme-lang
How can I help you explore Laravel packages today?