Weave Code
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

Filament Cards Laravel Package

harvirsidhu/filament-cards

Turn any Filament page into a card-based navigation hub. Auto-discovers Cluster/Resource pages, respects navigation config, checks authorization, and supports grouping, columns/spans, visibility rules, manual links, and optional search—ideal for settings hubs and dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Installation: Run composer require harvirsidhu/filament-cards and add the Tailwind source to your theme.css:

    @source '../../../../vendor/harvirsidhu/filament-cards/resources/views';
    

    Then rebuild assets with npm run build.

  2. First Use Case: Create a minimal CardsPage for a Cluster front page:

    use Harvirsidhu\FilamentCards\Filament\Pages\CardsPage;
    
    class SettingsHub extends CardsPage {
        protected static ?string $cluster = Settings::class;
        protected static ?int $navigationSort = -1;
    
        protected static function getCards(): array {
            return static::discoverClusterCards();
        }
    }
    

    This auto-generates cards for all pages/resources in the Settings cluster, respecting Filament's built-in authorization.


Implementation Patterns

1. Auto-Discovery Workflow

  • Cluster Front Page: Use discoverClusterCards() to auto-populate cards from all pages/resources in a cluster. Customize visibility with showInFilamentCards() or $excludedClusterComponents.
    protected static function getCards(): array {
        return [
            ...static::discoverClusterCards(),
            CardItem::make('https://docs.example.com')->label('Documentation'),
        ];
    }
    
  • Resource Hub: Use discoverResourceCards() for resource-specific hubs. Exclude pages with $excludedResourcePages.
    protected static function getCards(): array {
        return static::discoverResourceCards();
    }
    

2. Manual Card Customization

  • Grouping: Organize cards into collapsible groups with CardGroup:
    CardGroup::make('Finance')
        ->icon('heroicon-o-currency-dollar')
        ->schema([
            CardItem::make(BillingSettings::class)->color('success'),
        ]),
    
  • Dynamic Properties: Use closures for dynamic labels, visibility, or badges:
    CardItem::make(CompanySettings::class)
        ->label(fn () => __('settings.company'))
        ->visible(fn () => auth()->user()->can('edit_company')),
    

3. Integration with Filament Pages/Resources

  • Auto-Resolve Properties: Add $navigationDescription, $filamentCardsGroup, or getNavigationBadge() to your existing pages/resources to auto-populate card fields.
    class CompanySettings extends Page {
        public static ?string $navigationDescription = 'Manage company details.';
        public static ?string $filamentCardsGroup = 'Business';
    }
    
  • Override Defaults: Manually set properties on CardItem to override auto-resolved values:
    CardItem::make(CompanySettings::class)
        ->description('Custom description')
        ->badge('Updated')->badgeColor('primary'),
    

4. Search and Layout

  • Enable Search: Set $searchable = true on the CardsPage to add a search bar:
    class SettingsHub extends CardsPage {
        protected static bool $searchable = true;
    }
    
  • Responsive Grid: Use columnSpan() for responsive layouts:
    CardItem::make(CompanySettings::class)
        ->columnSpan(['default' => 1, 'lg' => 2]),
    

5. Dynamic Registration

  • Service Provider Registration: Register cards from packages/modules:
    public function boot(): void {
        FilamentCards::registerCard(
            CardItem::make('https://example.com/docs')
                ->label('Docs')
                ->icon('heroicon-o-book-open'),
        );
    }
    

Gotchas and Tips

Pitfalls

  1. Missing Theme Setup: Forgetting to add the Tailwind source to theme.css will break styling. Always run npm run build after installation.
  2. Authorization Bypass: Auto-discovery respects canAccess(), but manually added CardItems (e.g., for URLs) bypass this. Use visible() closures to enforce checks:
    CardItem::make('https://example.com')
        ->visible(fn () => auth()->user()->can('view_external_docs')),
    
  3. Circular References: Auto-discovery may include the CardsPage itself if not excluded. The package skips the current page by default, but verify with $excludedClusterComponents if needed.
  4. Search Indexing: Custom searchKeywords() are case-sensitive. Use lowercase or normalize terms for consistency:
    ->searchKeywords(['invoice', 'payment']),
    

Debugging

  • Hidden Cards: Use dd(static::discoverClusterCards()) to inspect auto-discovered cards and debug visibility issues.
  • Styling Issues: Check for Tailwind class conflicts. The package uses utility classes like filament-cards-*, so avoid overriding these in your theme.
  • URL Resolution: Verify URLs for manually added CardItems. Internal URLs (e.g., /path) are resolved via Filament’s router, while external URLs (e.g., https://) open in the same tab by default.

Extension Points

  1. Custom Discovery Logic: Override discoverClusterCards() or discoverResourceCards() in a child class to filter or transform discovered cards:
    protected static function getCards(): array {
        return collect(static::discoverClusterCards())
            ->reject(fn ($card) => str_contains($card->getUrl(), 'hidden'))
            ->values()
            ->toArray();
    }
    
  2. Dynamic Card Groups: Use closures to conditionally create groups:
    CardGroup::make(fn () => auth()->user()->isAdmin() ? 'Admin Tools' : 'Tools')
        ->schema([...]),
    
  3. Plugin Registration: Extend the package by publishing config or views:
    php artisan vendor:publish --tag="filament-cards-config"
    
  4. Custom Badges: Extend badge colors by modifying the package’s Tailwind config or using inline styles via extraAttributes():
    CardItem::make(DangerZone::class)
        ->badge('Critical')
        ->extraAttributes(['style' => 'background-color: #dc2626;']),
    

Performance Tips

  • Lazy-Load Groups: For large clusters, use collapsible groups (CardGroup::make()->collapsible()) to reduce initial load time.
  • Memoization: Cache auto-discovered cards in a service provider if the cluster/pages are static:
    static::cache(fn () => static::discoverClusterCards(), 'cluster-cards-cache', now()->addHours(1));
    
  • Avoid Overriding Auto-Resolve: Prefer adding properties to pages/resources (e.g., $navigationDescription) over manually setting them on every CardItem to reduce boilerplate.

Config Quirks

  • Navigation Icon: Ensure $navigationIcon is set on the CardsPage for proper sidebar integration. Use Heroicons (e.g., 'heroicon-o-squares-2x2') for consistency.
  • Cluster/Resource Hooks: Auto-discovery relies on Filament’s built-in hooks (shouldRegisterNavigation(), canAccess()). Override these carefully to avoid breaking card visibility.
  • URL Generation: For manually added CardItems, use absolute paths (e.g., /settings/company) or full URLs (e.g., https://example.com). Relative paths may fail to resolve.
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata