The Grid component provides a flexible grid layout system for organizing content in rows and columns. It's built on CSS Grid and provides responsive design capabilities with customizable spacing and alignment.
import { Grid } from '@/components/grid'export default function GridExample() {return (<Grid cols={2} gap="md" responsive={true}><div>Item 1</div><div>Item 2</div><div>Item 3</div><div>Item 4</div></Grid>)}
Preview:
| Prop | Type | Default | Description |
|---|---|---|---|
cols | number | 2 | Number of columns in the grid |
gap | 'sm' | 'md' | 'lg' | 'md' | Spacing between grid items |
responsive | boolean | true | Whether to use responsive grid columns |
type | 'default' | 'colored' | 'products' | 'cards' | 'images' | 'gradient' | 'team' | 'stats' | 'default' | Type of default content to display |
className | string | '' | Additional CSS classes for the grid container |
children | ReactNode | - | Grid items to be displayed |
import { Grid } from '@/components/grid'export default function BasicGrid() {return (<Grid cols={2} gap="md"><div className="bg-blue-100 p-4 rounded-lg">Item 1</div><div className="bg-green-100 p-4 rounded-lg">Item 2</div><div className="bg-yellow-100 p-4 rounded-lg">Item 3</div><div className="bg-red-100 p-4 rounded-lg">Item 4</div></Grid>)}
Preview:
// 3-column grid<Grid cols={3} gap="md"><div className="bg-blue-100 p-4 rounded-lg">Item 1</div><div className="bg-green-100 p-4 rounded-lg">Item 2</div><div className="bg-yellow-100 p-4 rounded-lg">Item 3</div><div className="bg-red-100 p-4 rounded-lg">Item 4</div><div className="bg-purple-100 p-4 rounded-lg">Item 5</div><div className="bg-pink-100 p-4 rounded-lg">Item 6</div></Grid>
Preview:
// Small gap<Grid cols={2} gap="sm"><div className="bg-blue-100 p-4 rounded-lg">Item 1</div><div className="bg-green-100 p-4 rounded-lg">Item 2</div><div className="bg-yellow-100 p-4 rounded-lg">Item 3</div><div className="bg-red-100 p-4 rounded-lg">Item 4</div></Grid>// Large gap<Grid cols={2} gap="lg"><div className="bg-blue-100 p-4 rounded-lg">Item 1</div><div className="bg-green-100 p-4 rounded-lg">Item 2</div><div className="bg-yellow-100 p-4 rounded-lg">Item 3</div><div className="bg-red-100 p-4 rounded-lg">Item 4</div></Grid>
Preview Small Gap:
Preview Large Gap:
<Grid cols={4} responsive={false} gap="md"><div className="bg-blue-100 p-4 rounded-lg">Item 1</div><div className="bg-green-100 p-4 rounded-lg">Item 2</div><div className="bg-yellow-100 p-4 rounded-lg">Item 3</div><div className="bg-red-100 p-4 rounded-lg">Item 4</div></Grid>
Preview:
import { Grid } from '@/components/grid'export default function ProductGrid() {const products = [{ id: 1, name: 'Product 1', price: '$29.99' },{ id: 2, name: 'Product 2', price: '$39.99' },{ id: 3, name: 'Product 3', price: '$49.99' },{ id: 4, name: 'Product 4', price: '$59.99' },{ id: 5, name: 'Product 5', price: '$69.99' },{ id: 6, name: 'Product 6', price: '$79.99' },];return (<Grid cols={3} gap="lg">{products.map((product) => (<div key={product.id} className="bg-white p-6 rounded-lg shadow-md border"><h3 className="font-semibold text-lg mb-2">{product.name}</h3><p className="text-2xl font-bold text-blue-600">{product.price}</p></div>))}</Grid>)}
Preview:
Product 1
$29.99
Product 2
$39.99
Product 3
$49.99
Product 4
$59.99
Product 5
$69.99
Product 6
$79.99
import { Grid } from '@/components/grid'export default function CardGrid() {return (<Grid cols={2} gap="md"><div className="bg-white p-6 rounded-lg shadow-md border border-gray-200"><h3 className="text-lg font-semibold mb-2">Card Title 1</h3><p className="text-gray-600">This is a sample card with some content.</p></div><div className="bg-white p-6 rounded-lg shadow-md border border-gray-200"><h3 className="text-lg font-semibold mb-2">Card Title 2</h3><p className="text-gray-600">This is another sample card with content.</p></div><div className="bg-white p-6 rounded-lg shadow-md border border-gray-200"><h3 className="text-lg font-semibold mb-2">Card Title 3</h3><p className="text-gray-600">This is a third sample card with content.</p></div><div className="bg-white p-6 rounded-lg shadow-md border border-gray-200"><h3 className="text-lg font-semibold mb-2">Card Title 4</h3><p className="text-gray-600">This is a fourth sample card with content.</p></div></Grid>)}
Preview:
Card Title 1
This is a sample card with some content.
Card Title 2
This is another sample card with content.
Card Title 3
This is a third sample card with content.
Card Title 4
This is a fourth sample card with content.
import { Grid } from '@/components/grid'export default function ImageGrid() {return (<Grid cols={2} gap="md"><div className="bg-gray-200 p-4 rounded-lg aspect-square flex items-center justify-center"><span className="text-gray-500">Image 1</span></div><div className="bg-gray-200 p-4 rounded-lg aspect-square flex items-center justify-center"><span className="text-gray-500">Image 2</span></div><div className="bg-gray-200 p-4 rounded-lg aspect-square flex items-center justify-center"><span className="text-gray-500">Image 3</span></div><div className="bg-gray-200 p-4 rounded-lg aspect-square flex items-center justify-center"><span className="text-gray-500">Image 4</span></div></Grid>)}
Preview:
import { Grid } from '@/components/grid'export default function CustomGrid() {return (<Grid cols={4} gap="lg" className="grid-cols-1 md:grid-cols-2 lg:grid-cols-4"><div className="bg-gradient-to-r from-blue-500 to-purple-600 text-white p-6 rounded-xl"><h3 className="text-xl font-bold">Feature 1</h3><p className="mt-2">Amazing feature description</p></div><div className="bg-gradient-to-r from-green-500 to-blue-600 text-white p-6 rounded-xl"><h3 className="text-xl font-bold">Feature 2</h3><p className="mt-2">Another amazing feature</p></div><div className="bg-gradient-to-r from-purple-500 to-pink-600 text-white p-6 rounded-xl"><h3 className="text-xl font-bold">Feature 3</h3><p className="mt-2">Yet another feature</p></div><div className="bg-gradient-to-r from-orange-500 to-red-600 text-white p-6 rounded-xl"><h3 className="text-xl font-bold">Feature 4</h3><p className="mt-2">The final feature</p></div></Grid>)}
Preview:
Feature 1
Amazing feature description
Feature 2
Another amazing feature
Feature 3
Yet another feature
Feature 4
The final feature
const portfolioGrid = (<Grid cols={3} gap="lg" className="grid-cols-1 md:grid-cols-2 lg:grid-cols-3">{portfolioItems.map((item) => (<div key={item.id} className="bg-white rounded-lg shadow-lg overflow-hidden"><div className="h-48 bg-gray-200"></div><div className="p-6"><h3 className="text-xl font-semibold mb-2">{item.title}</h3><p className="text-gray-600 mb-4">{item.description}</p><button className="bg-blue-600 text-white px-4 py-2 rounded-lg">View Project</button></div></div>))}</Grid>);
Preview:
Product 1
$29.99
Product 2
$39.99
Product 3
$49.99
Product 4
$59.99
Product 5
$69.99
Product 6
$79.99
const teamGrid = (<Grid cols={4} gap="lg" className="grid-cols-1 md:grid-cols-2 lg:grid-cols-4">{teamMembers.map((member) => (<div key={member.id} className="text-center"><div className="w-24 h-24 bg-gray-300 rounded-full mx-auto mb-4"></div><h3 className="font-semibold">{member.name}</h3><p className="text-gray-600 text-sm">{member.role}</p></div>))}</Grid>);
Preview:
John Doe
CEO
Jane Smith
CTO
Mike Johnson
Designer
Sarah Wilson
Developer
const statsGrid = (<Grid cols={4} gap="md" className="grid-cols-2 md:grid-cols-4">{statistics.map((stat) => (<div key={stat.id} className="bg-white p-6 rounded-lg border border-gray-200 text-center"><div className="text-3xl font-bold text-blue-600">{stat.value}</div><div className="text-gray-600 mt-2">{stat.label}</div></div>))}</Grid>);
Preview:
const galleryGrid = (<Grid cols={4} gap="sm" className="grid-cols-2 md:grid-cols-3 lg:grid-cols-4">{galleryItems.map((item) => (<div key={item.id} className="aspect-square bg-gray-200 rounded-lg overflow-hidden"><img src={item.image} alt={item.alt} className="w-full h-full object-cover" /></div>))}</Grid>);
Preview:
Use responsive grid classes for different screen sizes.
// ✅ Good - Responsive grid<Grid className="grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">// ❌ Avoid - Fixed grid<Grid className="grid-cols-4">
Use consistent gap values across your grid.
// ✅ Good - Consistent spacing<Grid className="gap-4"><Grid className="gap-6"><Grid className="gap-8">// ❌ Avoid - Inconsistent spacing<Grid className="gap-2"><Grid className="gap-12"><Grid className="gap-1">
Use aspect ratio classes for consistent item sizes.
// ✅ Good - Consistent aspect ratios<div className="aspect-square bg-gray-200"><div className="aspect-video bg-gray-200">// ❌ Avoid - Inconsistent sizes<div className="h-48 bg-gray-200"><div className="h-32 bg-gray-200">
Use semantic HTML elements for better accessibility.
// ✅ Good - Semantic elements<Grid><article className="bg-white p-4 rounded-lg"><h3>Article Title</h3><p>Article content</p></article></Grid>// ❌ Avoid - Generic divs<Grid><div className="bg-white p-4 rounded-lg"><div>Article Title</div><div>Article content</div></div></Grid>
Use proper keys for dynamic content.
// ✅ Good - Proper keys<Grid>{items.map((item) => (<div key={item.id}>{item.content}</div>))}</Grid>// ❌ Avoid - Missing or improper keys<Grid>{items.map((item, index) => (<div key={index}>{item.content}</div>))}</Grid>
You can customize the grid layout using CSS classes:
// 2-column grid<Grid className="grid-cols-2 gap-4">// 3-column grid<Grid className="grid-cols-3 gap-6">// 4-column grid<Grid className="grid-cols-4 gap-8">// Auto-fit grid<Grid className="grid-cols-[repeat(auto-fit,minmax(200px,1fr))] gap-4">
Use different themes for different contexts:
// Light theme<Grid className="bg-white border border-gray-200 rounded-lg p-4">// Dark theme<Grid className="bg-gray-900 border border-gray-700 rounded-lg p-4 text-white">// Colorful theme<Grid className="bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg p-4 text-white">
Use different sizes for different emphasis levels:
// Compact grid<Grid className="gap-2"><div className="p-2 text-sm">Compact item</div></Grid>// Standard grid<Grid className="gap-4"><div className="p-4">Standard item</div></Grid>// Spacious grid<Grid className="gap-8"><div className="p-8">Spacious item</div></Grid>
Create grids that change based on content:
const getGridCols = (itemCount: number) => {if (itemCount <= 2) return 'grid-cols-1 md:grid-cols-2';if (itemCount <= 4) return 'grid-cols-2 md:grid-cols-4';return 'grid-cols-2 md:grid-cols-3 lg:grid-cols-4';};<Grid className={getGridCols(items.length)}>{items.map((item) => (<div key={item.id}>{item.content}</div>))}</Grid>
Implement filtering for grid content:
const [filter, setFilter] = useState('all');const filteredItems = items.filter(item =>filter === 'all' || item.category === filter);<Grid>{filteredItems.map((item) => (<div key={item.id}>{item.content}</div>))}</Grid>
Add sorting capabilities to your grid:
const [sortBy, setSortBy] = useState('name');const sortedItems = items.sort((a, b) =>a[sortBy].localeCompare(b[sortBy]));<Grid>{sortedItems.map((item) => (<div key={item.id}>{item.content}</div>))}</Grid>
- Card: For grid items with consistent styling
- Button: For action buttons in grid items
- Image: For images in grid layouts
- Badge: For labels and tags in grid items
- Tooltip: For additional information on hover
For the complete API reference and advanced usage patterns, see the Grid API documentation.
