Data Gallery

Gallery grid layout for displaying collections of items with dynamic content via slots. Powered by AlpineJS. Supports client-side data or server-side fetching via URL.

Examples

The Data Gallery component displays items in a responsive grid layout. Each item is rendered using your custom slot, allowing full control over the item appearance. Support for search filtering and pagination.

Basic Gallery

Basic Gallery

Simple gallery layout with card items.

Loading...
blade
<x-plume::data-gallery :data="[
    [
        'id' => 1,
        'name' => 'Product 1',
        'price' => 29.99,
        'description' => 'High quality item',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 2,
        'name' => 'Product 2',
        'price' => 39.99,
        'description' => 'Premium selection',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 3,
        'name' => 'Product 3',
        'price' => 49.99,
        'description' => 'Best seller',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
]" cols="3" gap="4">
    <x-plume::card class="overflow-hidden h-full flex flex-col">
        <img :src="item.image" class="w-full h-48 object-cover" alt="Product image" />
        <div class="p-4 flex flex-col grow">
            <h3 x-text="item.name" class="font-semibold text-lg"></h3>
            <p x-text="item.description" class="text-sm text-foreground/60 grow"></p>
            <span x-text="`$${item.price}`" class="font-bold text-primary mt-2 block"></span>
        </div>
    </x-plume::card>
</x-plume::data-gallery>

Searchable Gallery

With Search

Enable search functionality to filter items.

Loading...
blade
<x-plume::data-gallery :data="[
    [
        'id' => 1,
        'name' => 'Laptop Computer',
        'price' => 999.99,
        'description' => 'High performance',
        'image' =>
            'https://images.unsplash.com/photo-1517694712202-14dd9538aa97?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 2,
        'name' => 'Wireless Mouse',
        'price' => 29.99,
        'description' => 'Ergonomic design',
        'image' =>
            'https://images.unsplash.com/photo-1527814050087-3793815479db?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 3,
        'name' => 'USB Keyboard',
        'price' => 79.99,
        'description' => 'Mechanical switches',
        'image' =>
            'https://images.unsplash.com/photo-1587829191301-4b5ec2b7dba5?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 4,
        'name' => 'Monitor 4K',
        'price' => 399.99,
        'description' => 'Ultra HD display',
        'image' =>
            'https://images.unsplash.com/photo-1593642632823-8f785ba67e45?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
]" searchable cols="3" gap="4">
    <x-plume::card class="overflow-hidden h-full flex flex-col">
        <img :src="item.image" class="w-full h-48 object-cover" />
        <div class="p-4 flex flex-col grow">
            <h3 x-text="item.name" class="font-semibold"></h3>
            <p x-text="item.description" class="text-sm text-foreground/60 grow"></p>
            <span x-text="`$${item.price}`" class="font-bold text-primary mt-2"></span>
        </div>
    </x-plume::card>
</x-plume::data-gallery>

Paginated Gallery

With Pagination

Add pagination to manage large datasets.

Loading...
Showing to of results
blade
<x-plume::data-gallery :data="[
    [
        'id' => 1,
        'name' => 'Item 1',
        'price' => 19.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 2,
        'name' => 'Item 2',
        'price' => 24.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 3,
        'name' => 'Item 3',
        'price' => 29.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 4,
        'name' => 'Item 4',
        'price' => 34.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 5,
        'name' => 'Item 5',
        'price' => 39.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 6,
        'name' => 'Item 6',
        'price' => 44.99,
        'description' => 'Description',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
]" paginated :per-page="4" cols="3" gap="4">
    <x-plume::card class="overflow-hidden">
        <img :src="item.image" class="w-full h-40 object-cover" />
        <div class="p-4">
            <h3 x-text="item.name" class="font-semibold"></h3>
            <p x-text="item.description" class="text-xs text-foreground/50"></p>
            <span x-text="`$${item.price}`" class="font-bold text-primary mt-2 block"></span>
        </div>
    </x-plume::card>
</x-plume::data-gallery>

Responsive Columns

Different Column Layouts

Use cols property to adjust the grid layout.

2 Columns

Loading...

4 Columns

Loading...
blade
<x-plume::data-gallery :data="[
    [
        'id' => 1,
        'name' => 'Wide Item 1',
        'price' => 29.99,
        'description' => 'Item',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 2,
        'name' => 'Wide Item 2',
        'price' => 39.99,
        'description' => 'Item',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 3,
        'name' => 'Wide Item 3',
        'price' => 49.99,
        'description' => 'Item',
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
]" cols="2" gap="4">
    <x-plume::card class="overflow-hidden">
        <img :src="item.image" class="w-full h-48 object-cover" />
        <div class="p-4">
            <h3 x-text="item.name" class="font-semibold"></h3>
            <span x-text="`$${item.price}`"
                class="font-bold text-primary mt-2 block"></span>
        </div>
    </x-plume::card>
</x-plume::data-gallery>

<x-plume::data-gallery :data="[
    [
        'id' => 1,
        'name' => 'Item 1',
        'price' => 19.99,
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 2,
        'name' => 'Item 2',
        'price' => 19.99,
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 3,
        'name' => 'Item 3',
        'price' => 19.99,
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
    [
        'id' => 4,
        'name' => 'Item 4',
        'price' => 19.99,
        'image' =>
            'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&auto=format&fit=crop&w=400&q=80',
    ],
]" cols="4" gap="4">
    <x-plume::card class="overflow-hidden">
        <img :src="item.image" class="w-full h-32 object-cover" />
        <div class="p-3">
            <h3 x-text="item.name" class="font-semibold text-sm"></h3>
            <span x-text="`$${item.price}`"
                class="text-primary text-sm font-bold mt-1 block"></span>
        </div>
    </x-plume::card>
</x-plume::data-gallery>
Prop Type Default Description
data array|string [] Array of objects to display (client-side data).
searchable bool false Whether to show a search input for filtering.
paginated bool false Whether to enable pagination.
perPage int 10 Number of items per page.
url string null API endpoint URL for server-side fetching.
cols int 3 Shortcut to set responsive column distribution.
gap int 4 Gap spacing between items.
minCols int null Minimum number of grid columns on mobile.
maxCols int null Maximum number of grid columns on large screens.
onSort string null Callback expression for when the gallery is sorted.
onFilter string null Callback expression for when the data is filtered.
onPageChange string null Callback expression for when the page is changed.
onLoad string null Callback expression for when data is loaded.

Usage

blade
<x-plume::data-gallery :data="[['name' => 'Item 1'], ['name' => 'Item 2']]">
    <x-plume::card>
        <h3 x-text="item.name"></h3>
    </x-plume::card>
</x-plume::data-gallery>