irajul/filament-shadcn-theme
A configurable shadcn-inspired theme plugin for Filament v5 panels.
The package maps shadcn-style tokens onto Filament's generated HTML, so it can theme navigation, topbar, cards, forms, tables, pagination, checkboxes, empty states, modals, dropdowns, widgets, and light/dark mode without requiring a Vite asset build.
Install the package with Composer:
composer require irajul/filament-shadcn-theme
php artisan vendor:publish --tag=filament-shadcn-theme-config
The package is auto-discovered by Laravel. Register the plugin on each Filament panel that should use the theme.
<?php
namespace App\Providers\Filament;
use Filament\Enums\ThemeMode;
use Filament\Panel;
use Filament\PanelProvider;
use Irajul\FilamentShadcnTheme\Enums\BaseColor;
use Irajul\FilamentShadcnTheme\Enums\MenuAccent;
use Irajul\FilamentShadcnTheme\Enums\Radius;
use Irajul\FilamentShadcnTheme\Enums\SidebarVariant;
use Irajul\FilamentShadcnTheme\Enums\StyleVariant;
use Irajul\FilamentShadcnTheme\Enums\SurfaceShadow;
use Irajul\FilamentShadcnTheme\Enums\ThemeColor;
use Irajul\FilamentShadcnTheme\FilamentShadcnThemePlugin;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->defaultThemeMode(ThemeMode::Dark)
->darkMode(true)
->plugin(
FilamentShadcnThemePlugin::make()
->style(StyleVariant::Lyra)
->baseColor(BaseColor::Taupe)
->themeColor(ThemeColor::Taupe)
->chartColor(ThemeColor::Taupe)
->font('inter')
->headingFont('inherit')
->radius(Radius::None)
->menuAccent(MenuAccent::Subtle)
->sidebarVariant(SidebarVariant::Sidebar)
->surfaceShadow(SurfaceShadow::ExtraSmall)
);
}
}
The default package look is intentionally sharp and shadcn-like:
[
'style' => 'lyra',
'base_color' => 'taupe',
'theme_color' => 'taupe',
'chart_color' => null,
'font' => 'inter',
'heading_font' => 'inherit',
'icon_library' => 'lucide',
'css_mode' => 'inline',
'radius' => 'none',
'menu_color' => 'default',
'menu_accent' => 'subtle',
'sidebar_variant' => 'sidebar',
'surface_shadow' => 'xs',
]
You may change defaults in config/filament-shadcn-theme.php, or override them fluently in the panel provider.
Controls density, spacing, table rhythm, sidebar spacing, card padding, and radius personality.
Available values:
StyleVariant::Vega
StyleVariant::Nova
StyleVariant::Maia
StyleVariant::Lyra
StyleVariant::Mira
StyleVariant::Luma
StyleVariant::Sera
String values: vega, nova, maia, lyra, mira, luma, sera.
Controls neutral surfaces, borders, text, sidebar background, muted text, and table backgrounds.
Available values:
BaseColor::Neutral
BaseColor::Stone
BaseColor::Zinc
BaseColor::Mauve
BaseColor::Olive
BaseColor::Mist
BaseColor::Taupe
String values: neutral, stone, zinc, mauve, olive, mist, taupe.
Controls primary buttons, active navigation, focus rings, and primary accents.
Available values:
ThemeColor::Neutral
ThemeColor::Stone
ThemeColor::Zinc
ThemeColor::Mauve
ThemeColor::Olive
ThemeColor::Mist
ThemeColor::Taupe
ThemeColor::Amber
ThemeColor::Blue
ThemeColor::Cyan
ThemeColor::Emerald
ThemeColor::Fuchsia
ThemeColor::Green
ThemeColor::Indigo
ThemeColor::Lime
ThemeColor::Orange
ThemeColor::Pink
ThemeColor::Purple
ThemeColor::Red
ThemeColor::Rose
ThemeColor::Sky
ThemeColor::Teal
ThemeColor::Violet
ThemeColor::Yellow
String values: neutral, stone, zinc, mauve, olive, mist, taupe, amber, blue, cyan, emerald, fuchsia, green, indigo, lime, orange, pink, purple, red, rose, sky, teal, violet, yellow.
Controls --chart-* tokens. If omitted, the chart palette follows theme_color.
->chartColor(ThemeColor::Emerald)
Controls the generated --font-sans and --font-heading tokens. The panel font is also applied through Filament by default.
Built-in font keys:
inter
geist
figtree
manrope
dm-sans
public-sans
noto-sans
nunito-sans
space-grotesk
montserrat
ibm-plex-sans
jetbrains-mono
geist-mono
Any custom font family string is accepted:
->font('Geist')
->headingFont('Space Grotesk')
Use heading_font => inherit or ->headingFont('inherit') to keep headings on the body font stack.
Controls shadcn radius tokens and component corners.
Available values:
Radius::Default // 0.625rem
Radius::None // 0
Radius::Small // 0.45rem
Radius::Medium // 0.625rem
Radius::Large // 0.875rem
String values: default, none, small, medium, large.
For the sharp Lyra look, use Radius::None.
Currently stored as a CSS metadata token so the same config can support icon-library-specific styling later.
Available values:
IconLibrary::Lucide
IconLibrary::Heroicons
IconLibrary::Tabler
IconLibrary::Phosphor
IconLibrary::Radix
String values: lucide, heroicons, tabler, phosphor, radix.
Controls how generated CSS is delivered.
Available values:
CssMode::Inline
CssMode::CachedAsset
String values: inline, cached-asset.
inline injects a generated <style> tag into the Filament panel and is the default because it requires no writable public directory. cached-asset writes a hashed stylesheet to public/vendor/filament-shadcn-theme and injects a <link> tag instead.
FilamentShadcnThemePlugin::make()
->cssMode('cached-asset')
You can warm or clear cached CSS assets from Artisan:
php artisan filament-shadcn-theme:cache --panel=admin
php artisan filament-shadcn-theme:clear --panel=admin
Controls sidebar color treatment.
Available values:
MenuColor::Default
MenuColor::Inverted
MenuColor::DefaultTranslucent
MenuColor::InvertedTranslucent
String values: default, inverted, default-translucent, inverted-translucent.
Controls active navigation intensity.
Available values:
MenuAccent::Subtle
MenuAccent::Bold
String values: subtle, bold.
Controls sidebar offset, border, radius, and shadow.
Available values:
SidebarVariant::Sidebar
SidebarVariant::Floating
SidebarVariant::Inset
String values: sidebar, floating, inset.
Controls shared panel and floating surface shadow tokens.
Available values:
SurfaceShadow::None
SurfaceShadow::ExtraSmall
SurfaceShadow::Small
SurfaceShadow::Medium
String values: none, xs, sm, md.
Use token overrides when you want to change shadcn tokens directly.
FilamentShadcnThemePlugin::make()
->tokens(
light: [
'background' => 'oklch(1 0 0)',
'primary' => 'oklch(0.55 0.18 140)',
],
dark: [
'background' => 'oklch(0.16 0.01 90)',
'primary' => 'oklch(0.78 0.2 140)',
],
);
Use style variables for layout and density adjustments.
FilamentShadcnThemePlugin::make()
->styleVariables([
'fs-sidebar-width' => '18rem',
'fs-main-padding-y' => '1rem',
'fs-table-cell-padding-y' => '0.35rem',
'fs-table-edge-padding-x' => '0.875rem',
]);
Use selector overrides if your Filament build or custom plugin outputs a different class.
FilamentShadcnThemePlugin::make()
->selectorMap([
'card' => '.fi-section, .custom-admin-card',
'button' => '.fi-btn, .custom-admin-button',
]);
After publishing config, edit config/filament-shadcn-theme.php:
return [
'style' => 'lyra',
'base_color' => 'taupe',
'theme_color' => 'taupe',
'chart_color' => 'emerald',
'font' => 'inter',
'heading_font' => 'inherit',
'icon_library' => 'lucide',
'css_mode' => 'inline',
'radius' => 'none',
'menu_color' => 'default',
'menu_accent' => 'subtle',
'sidebar_variant' => 'sidebar',
'surface_shadow' => 'xs',
'apply_panel_font' => true,
'default_theme_mode' => 'dark',
'dark_mode' => true,
'force_dark_mode' => false,
'token_overrides' => [
'light' => [],
'dark' => [],
],
'style_overrides' => [],
'selector_map' => [],
];
Then register the plugin with no extra arguments:
->plugin(FilamentShadcnThemePlugin::make())
Package tests live inside this package, not in the host Laravel app.
composer validate --strict
composer install
composer test
The tests are intentionally standalone. They exercise configuration hydration, fluent plugin configuration, shadcn token rendering, Filament selector coverage, light/dark token output, and the exposed option enums without relying on a host application's test case.
Issues and pull requests are welcome. Please read CONTRIBUTING.md before opening larger changes so setup, tests, and release expectations stay predictable.
Please do not open public issues for suspected vulnerabilities. Follow the private reporting process in SECURITY.md.
Before tagging a release:
composer validate --strict
composer test
git tag v1.0.0
git push origin main --tags
Then create the GitHub release and publish the tag to Packagist. Packagist reads versions from Git tags, so keep the version field out of composer.json.
For Packagist, submit the public GitHub repository URL once and enable the Packagist GitHub hook or application sync. No GitHub Action is required for Packagist updates; the hook updates the package when tags are pushed.
composer.json package metadata updated before publishing.How can I help you explore Laravel packages today?