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

To begin using harvirsidhu/filament-cards, install the package via Composer:

composer require harvirsidhu/filament-cards

Add the package's views to your Filament theme by updating theme.css:

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

Rebuild assets:

npm run build

First Use Case: Create a simple CardsPage to display a grid of cards linking to other Filament pages:

use Harvirsidhu\FilamentCards\Filament\Pages\CardsPage;
use Harvirsidhu\FilamentCards\CardItem;

class ControlPanel extends CardsPage
{
    protected static ?string $navigationIcon = 'heroicon-o-squares-2x2';

    protected static function getCards(): array
    {
        return [
            CardItem::make(CompanySettings::class),
            CardItem::make(BillingSettings::class),
        ];
    }
}

Implementation Patterns

1. Auto-Discovery for Clusters

Use discoverClusterCards() to automatically generate cards for all pages/resources in a Cluster:

class SettingsHub extends CardsPage
{
    protected static ?string $cluster = Settings::class;
    protected static ?int $navigationSort = -1;

    protected static function getCards(): array
    {
        return static::discoverClusterCards();
    }
}

Key Methods:

  • showInFilamentCards(): Override to exclude a page/resource from auto-discovery.
  • $navigationDescription: Auto-populated in card descriptions.
  • $filamentCardsGroup: Custom group name (defaults to $navigationGroup).

2. Manual Card Customization

Combine auto-discovered cards with manually crafted ones (e.g., external links):

protected static function getCards(): array
{
    return [
        ...static::discoverClusterCards(),
        CardGroup::make('External Links')
            ->schema([
                CardItem::make('https://docs.example.com')
                    ->label('Documentation')
                    ->icon('heroicon-o-book-open')
                    ->openUrlInNewTab(),
            ]),
    ];
}

3. Dynamic Registration

Register cards from service providers (ideal for modular apps):

// In a ServiceProvider
FilamentCards::registerCard(
    CardItem::make(ExternalTool::class)
        ->label('External Tool')
        ->icon('heroicon-o-external-link')
);

4. Resource-Specific Hubs

Auto-generate cards for a Resource’s pages:

class UserSettingsHub extends CardsPage
{
    protected static string $resource = UserResource::class;

    protected static function getCards(): array
    {
        return static::discoverResourceCards();
    }
}

5. Conditional Visibility

Use closures for dynamic card visibility:

CardItem::make(BillingSettings::class)
    ->visible(fn () => auth()->user()->can('manage-billing'))
    ->hidden(fn () => !auth()->user()->isAdmin());

6. Grouping and Layout

Organize cards into collapsible groups with custom icons/descriptions:

CardGroup::make('Finance')
    ->icon('heroicon-o-currency-dollar')
    ->description('Billing and invoices')
    ->schema([
        CardItem::make(BillingSettings::class),
        CardItem::make(InvoicesResource::class),
    ]);

7. Search Functionality

Enable live search with keywords:

class SettingsHub extends CardsPage
{
    protected static bool $searchable = true;

    protected static function getCards(): array
    {
        return [
            CardItem::make(BillingSettings::class)
                ->searchKeywords(['invoices', 'payments']),
        ];
    }
}

Gotchas and Tips

Pitfalls

  1. Auto-Discovery Conflicts:

    • Pages/resources with shouldRegisterNavigation(): false won’t appear unless showInFilamentCards(): true is explicitly set.
    • Fix: Use $excludedClusterComponents or $excludedResourcePages in CardsPage to exclude specific items.
  2. Styling Issues:

    • Forgetting to add @source for the package’s views to theme.css will break card layouts.
    • Fix: Rebuild assets (npm run build) after updating theme.css.
  3. Authorization Bypass:

    • Auto-discovered cards respect canAccess(), but manually added CardItems (e.g., for URLs) bypass this.
    • Fix: Wrap manual CardItems in visibility checks:
      CardItem::make('/admin/tools')
          ->visible(fn () => auth()->user()->isAdmin())
      
  4. Group Sorting:

    • Groups default to sorting by $navigationSort. Omitting this may lead to unpredictable ordering.
    • Fix: Explicitly set sort() on CardItems or use getFilamentCardsGroup() to control group order.

Debugging Tips

  • Check Auto-Discovery: Temporarily log the output of discoverClusterCards() or discoverResourceCards() to verify included/excluded items:

    dd(static::discoverClusterCards());
    
  • Inspect Card Properties: Use ->toArray() on a CardItem to debug its resolved attributes:

    dd(CardItem::make(CompanySettings::class)->toArray());
    
  • Search Bar Not Working: Ensure $searchable = true on the CardsPage and that searchKeywords() is populated for relevant cards.


Extension Points

  1. Custom Discovery Logic: Override discoverClusterCards() or discoverResourceCards() in a subclass to filter items dynamically:

    protected static function discoverClusterCards(): array
    {
        return parent::discoverClusterCards()
            ->reject(fn ($card) => str_contains($card->getUrl(), 'legacy'));
    }
    
  2. Dynamic Card Registration: Extend the FilamentCards facade to add cards from packages:

    FilamentCards::extend(function (FilamentCards $cards) {
        $cards->registerCard(
            CardItem::make('https://example.com/docs')
                ->label('Docs')
                ->icon('heroicon-o-document-text')
        );
    });
    
  3. Custom Card Rendering: Publish the package’s views and modify them to change the card template:

    php artisan vendor:publish --tag="filament-cards-views"
    
  4. Responsive Grid Control: Use columnSpan() with responsive arrays for adaptive layouts:

    CardItem::make(CompanySettings::class)
        ->columnSpan([
            'default' => 1,
            'md' => 2,
            'lg' => 3,
        ]);
    

Config Quirks

  • Default Grouping: Cards without a $filamentCardsGroup fall back to $navigationGroup. Set this explicitly to avoid misplaced cards.

  • Icon Fallback: If a CardItem lacks an icon, it defaults to the page/resource’s $navigationIcon. Provide a fallback:

    CardItem::make('/path')
        ->icon('heroicon-o-question-mark-circle')
    
  • URL Resolution: For external URLs, always use openUrlInNewTab() to avoid breaking navigation:

    CardItem::make('https://example.com')
        ->openUrlInNewTab();
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope