Skip to main content

Overview

The Content Grid component is a powerful and flexible solution for displaying collections of items in either grid or list layouts. It provides smooth transitions between view modes, responsive column configurations, and complete control over item rendering.

Installation

npx shadcn@latest add https://rigidui.com/r/content-grid.json

Usage

"use client";

import { ContentGrid } from "@/components/content-grid";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Star, Eye, Download } from "lucide-react";

export default function MyComponent() {
  const sampleItems = [
    {
      id: 1,
      title: "Dashboard Template",
      description: "A comprehensive dashboard template with charts and analytics.",
      category: "Template",
      price: "$49",
      rating: 4.9,
      views: 1234,
      downloads: 892,
    },
    {
      id: 2,
      title: "UI Kit Pro",
      description: "Complete UI kit with modern components and layouts.",
      category: "UI Kit",
      price: "$29",
      rating: 4.8,
      views: 956,
      downloads: 643,
    },
  ];

  const renderCard = (item: any, viewMode: "grid" | "list") => {
    const isListMode = viewMode === "list";

    return (
      <Card
        key={item.id}
        className={`hover:shadow-md transition-shadow ${
          isListMode ? "flex items-center gap-4" : ""
        }`}
      >
        <div className={`flex-1 ${isListMode ? "mr-4" : ""}`}>
          <CardHeader className="pb-2">
            <div className="flex items-start justify-between">
              <div>
                <CardTitle className="text-base">{item.title}</CardTitle>
                <Badge variant="outline" className="mt-1 text-xs">
                  {item.category}
                </Badge>
              </div>
              <div className="text-right">
                <div className="font-bold text-primary">{item.price}</div>
                <div className="flex items-center gap-1 text-sm text-muted-foreground">
                  <Star className="h-3 w-3 fill-yellow-400 text-yellow-400" />
                  {item.rating}
                </div>
              </div>
            </div>
          </CardHeader>
          <CardContent className="pt-0">
            <p className="text-muted-foreground text-sm mb-3 line-clamp-2">
              {item.description}
            </p>
            <div className="flex items-center gap-4 text-sm text-muted-foreground mb-3">
              <div className="flex items-center gap-1">
                <Eye className="h-4 w-4" />
                {item.views.toLocaleString()}
              </div>
              <div className="flex items-center gap-1">
                <Download className="h-4 w-4" />
                {item.downloads.toLocaleString()}
              </div>
            </div>
            <Button size="sm" className="w-full">
              <Download className="h-4 w-4 mr-2" />
              Download
            </Button>
          </CardContent>
        </div>
      </Card>
    );
  };

  return (
    <ContentGrid
      items={sampleItems}
      renderCard={renderCard}
      defaultViewMode="grid"
      gridColumns={2}
      className="w-full"
    />
  );
}

Features

The Content Grid component automatically handles the item count display and provides smooth transitions between view modes.
  • Grid & List Views: Seamlessly switch between grid and list layouts with smooth transitions and optimized rendering
  • Flexible Rendering: Complete control over card rendering with custom render functions that adapt to view modes
  • Responsive Design: Built-in responsive breakpoints ensure optimal display across all device sizes
  • Customizable Columns: Configure exact column counts or use auto-responsive layouts that adapt to screen size
  • View Mode Toggle: Built-in UI controls for switching between grid and list views
  • Empty State Handling: Automatic display of empty state messages when no items are present

API Reference

ContentGridProps

items
ContentItem[]
required
Array of items to display in the grid/list. Each item must have an id property (string or number) and can contain any additional properties.
renderCard
(item: ContentItem, viewMode: ViewMode) => React.ReactNode
required
Function to render each card item. Receives the item data and the current view mode (‘grid’ or ‘list’) as parameters. Use the viewMode parameter to conditionally adjust the card layout.
defaultViewMode
'grid' | 'list'
default:"'grid'"
Default view mode when the component first loads.
gridColumns
'auto' | 1 | 2 | 3 | 4 | 5 | 6
default:"'auto'"
Number of columns in grid view. When set to 'auto', provides responsive columns:
  • Mobile: 1 column
  • Small screens: 2 columns
  • Large screens: 3 columns
  • Extra large: 4 columns
When set to a specific number, the layout adapts with responsive breakpoints.
className
string
Additional CSS classes for the container element.
onViewModeChange
(mode: ViewMode) => void
Callback function called when the view mode changes. Useful for persisting user preferences or triggering analytics.

Types

ContentItem

export interface ContentItem {
  id: string | number
  [key: string]: unknown
}

ViewMode

export type ViewMode = 'grid' | 'list'

Advanced Usage

Persisting View Mode

"use client";

import { useState, useEffect } from "react";
import { ContentGrid } from "@/components/content-grid";

export default function MyComponent() {
  const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');

  // Load saved preference
  useEffect(() => {
    const saved = localStorage.getItem('contentViewMode');
    if (saved) setViewMode(saved as 'grid' | 'list');
  }, []);

  const handleViewModeChange = (mode: 'grid' | 'list') => {
    setViewMode(mode);
    localStorage.setItem('contentViewMode', mode);
  };

  return (
    <ContentGrid
      items={items}
      renderCard={renderCard}
      defaultViewMode={viewMode}
      onViewModeChange={handleViewModeChange}
    />
  );
}

Adapting Card Layout to View Mode

const renderCard = (item: any, viewMode: 'grid' | 'list') => {
  if (viewMode === 'list') {
    return (
      <div className="flex items-center gap-4 p-4 border rounded-lg">
        <img src={item.image} className="w-24 h-24 object-cover rounded" />
        <div className="flex-1">
          <h3 className="text-lg font-semibold">{item.title}</h3>
          <p className="text-sm text-muted-foreground">{item.description}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="p-4 border rounded-lg">
      <img src={item.image} className="w-full h-48 object-cover rounded mb-4" />
      <h3 className="text-lg font-semibold">{item.title}</h3>
      <p className="text-sm text-muted-foreground line-clamp-2">{item.description}</p>
    </div>
  );
};
Use the viewMode parameter in your renderCard function to optimize the layout for each display mode. List mode typically works better with horizontal layouts, while grid mode suits vertical card designs.

Responsive Behavior

The grid columns automatically adapt to screen size:
Grid ColumnsMobileSmallMediumLargeXL2XL
auto122344
1111111
2122222
3122333
4122344
5122345
6122345
The Content Grid component requires items to have a unique id property. This is used for React’s key prop during rendering.

Build docs developers (and LLMs) love