Product Card Grid
A responsive grid of product cards with images, ratings, and prices.
Data View
Card
Badge
Button
Rating
Preview
Sale
Wireless Headphones
Premium noise-cancelling over-ear headphones with 30hr battery.
$79.99$99.99
Mechanical Keyboard
RGB backlit mechanical keyboard with Cherry MX switches.
$129.99
Sale
USB-C Hub
7-in-1 USB-C adapter with HDMI, USB 3.0, and SD card reader.
$49.99$59.99
Laptop Stand
Adjustable aluminum laptop stand for ergonomic viewing.
$34.99
Wireless Mouse
Ergonomic wireless mouse with silent click and 3 DPI modes.
$24.99
Sale
Webcam HD
1080p HD webcam with built-in microphone and auto-focus.
$59.99$79.99
Code
<BbDataView TItem="Product" Data="@products" Layout="DataViewLayout.Grid"
GridClass="grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"
InitialPageSize="6">
<Fields>
<BbDataViewColumn TItem="Product" TValue="string"
Property="@(p => p.Name)"
Header="Name"
Sortable
Filterable />
<BbDataViewColumn TItem="Product" TValue="double"
Property="@(p => p.Price)"
Header="Price"
Sortable />
<BbDataViewColumn TItem="Product" TValue="double"
Property="@(p => p.Rating)"
Header="Rating"
Sortable />
<BbDataViewListTemplate TItem="Product" Context="product">
<BbCard class="overflow-hidden">
<div class="flex gap-4 p-4">
<div class="relative h-24 w-24 shrink-0 bg-muted rounded-lg flex items-center justify-center">
<!-- shopping-bag icon SVG -->
@if (product.OnSale)
{
<BbBadge class="absolute top-1 right-1 text-[10px] px-1"
Variant="BadgeVariant.Destructive">Sale</BbBadge>
}
</div>
<div class="flex-1 min-w-0 space-y-1">
<div class="flex items-start justify-between gap-2">
<p class="font-medium">@product.Name</p>
<div class="flex items-center gap-2 shrink-0">
<span class="font-bold">[email protected]("F2")</span>
@if (product.OriginalPrice.HasValue)
{
<span class="text-muted-foreground line-through text-sm">
[email protected]("F2")
</span>
}
</div>
</div>
<p class="text-sm text-muted-foreground line-clamp-1">@product.Description</p>
<BbRating Value="@product.Rating" Max="5" ReadOnly="true" Size="RatingSize.Small" />
</div>
<BbButton class="self-center shrink-0">
<!-- shopping-cart icon SVG -->
Add to Cart
</BbButton>
</div>
</BbCard>
</BbDataViewListTemplate>
<BbDataViewGridTemplate TItem="Product" Context="product">
<BbCard class="overflow-hidden">
<div class="relative h-48 bg-muted flex items-center justify-center">
<!-- shopping-bag icon SVG -->
@if (product.OnSale)
{
<BbBadge class="absolute top-2 right-2"
Variant="BadgeVariant.Destructive">Sale</BbBadge>
}
</div>
<BbCardContent class="pt-4 space-y-2">
<p class="font-medium">@product.Name</p>
<p class="text-sm text-muted-foreground line-clamp-2">@product.Description</p>
<BbRating Value="@product.Rating" Max="5" ReadOnly="true" Size="RatingSize.Small" />
<div class="flex items-center gap-2">
<span class="font-bold">[email protected]("F2")</span>
@if (product.OriginalPrice.HasValue)
{
<span class="text-muted-foreground line-through text-sm">
[email protected]("F2")
</span>
}
</div>
</BbCardContent>
<BbCardFooter>
<BbButton class="w-full">
<!-- shopping-cart icon SVG -->
Add to Cart
</BbButton>
</BbCardFooter>
</BbCard>
</BbDataViewGridTemplate>
</Fields>
</BbDataView>
@code {
private class Product
{
public string Name { get; set; } = "";
public string Description { get; set; } = "";
public double Price { get; set; }
public double? OriginalPrice { get; set; }
public double Rating { get; set; }
public bool OnSale { get; set; }
}
private List<Product> products = new()
{
new() { Name = "Wireless Headphones", Description = "Premium noise-cancelling over-ear headphones with 30hr battery.", Price = 79.99, OriginalPrice = 99.99, Rating = 4.5, OnSale = true },
new() { Name = "Mechanical Keyboard", Description = "RGB backlit mechanical keyboard with Cherry MX switches.", Price = 129.99, Rating = 4.8 },
new() { Name = "USB-C Hub", Description = "7-in-1 USB-C adapter with HDMI, USB 3.0, and SD card reader.", Price = 49.99, OriginalPrice = 59.99, Rating = 4.2, OnSale = true },
new() { Name = "Laptop Stand", Description = "Adjustable aluminum laptop stand for ergonomic viewing.", Price = 34.99, Rating = 4.6 },
new() { Name = "Wireless Mouse", Description = "Ergonomic wireless mouse with silent click and 3 DPI modes.", Price = 24.99, Rating = 4.3 },
new() { Name = "Webcam HD", Description = "1080p HD webcam with built-in microphone and auto-focus.", Price = 59.99, OriginalPrice = 79.99, Rating = 4.1, OnSale = true }
};
}