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 }
    };
}