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.
No items found
Try adjusting your search or filters.
<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.
No items found
Try adjusting your search or filters.
<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.
No items found
Try adjusting your search or filters.
<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
No items found
Try adjusting your search or filters.
4 Columns
No items found
Try adjusting your search or filters.
<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
<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>