/** * Bento Grid Layout Template * * Features: * - Responsive asymmetric grid * - Glass card components * - Hover animations * - Flexible span configurations */ import React from 'react'; import { motion } from 'framer-motion'; // ============================================ // TYPES // ============================================ export interface BentoCardProps { children: React.ReactNode; className?: string; // Grid span colSpan?: 1 | 2 | 3 | 4; rowSpan?: 1 | 2 | 3; // Appearance hover?: boolean; glowColor?: string; noBorder?: boolean; } export interface BentoGridProps { children: React.ReactNode; className?: string; // Grid configuration cols?: 1 | 2 | 3 | 4; gap?: 'sm' | 'md' | 'lg'; } // ============================================ // BENTO CARD // ============================================ export const BentoCard: React.FC = ({ children, className = '', colSpan = 1, rowSpan = 1, hover = true, glowColor = 'rgba(255, 77, 0, 0.3)', noBorder = false, }) => { const colSpanClasses = { 1: 'col-span-1', 2: 'col-span-1 md:col-span-2', 3: 'col-span-1 md:col-span-2 lg:col-span-3', 4: 'col-span-1 md:col-span-2 lg:col-span-4', }; const rowSpanClasses = { 1: 'row-span-1', 2: 'row-span-1 md:row-span-2', 3: 'row-span-1 md:row-span-2 lg:row-span-3', }; return ( {children} ); }; // ============================================ // BENTO GRID // ============================================ export const BentoGrid: React.FC = ({ children, className = '', cols = 4, gap = 'md', }) => { const colClasses = { 1: 'grid-cols-1', 2: 'grid-cols-1 md:grid-cols-2', 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3', 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4', }; const gapClasses = { sm: 'gap-2', md: 'gap-4', lg: 'gap-6', }; return (
{children}
); }; // ============================================ // STAT CARD (common bento item) // ============================================ export interface StatCardProps { icon: React.ReactNode; label: string; value: string | number; change?: string; changeType?: 'positive' | 'negative' | 'neutral'; accentColor?: string; } export const StatCard: React.FC = ({ icon, label, value, change, changeType = 'neutral', accentColor = '#ff4d00', }) => { const changeColors = { positive: 'text-green-400', negative: 'text-red-400', neutral: 'text-zinc-400', }; return (
{icon}
{change && ( {change} )}
{value}
{label}
); }; // ============================================ // CHART CARD (wrapper for charts) // ============================================ export const ChartCard: React.FC<{ title: string; icon: React.ReactNode; children: React.ReactNode; colSpan?: 1 | 2 | 3 | 4; accentColor?: string; }> = ({ title, icon, children, colSpan = 2, accentColor = '#ff4d00' }) => (
{icon} {title}
{children}
); // ============================================ // USAGE EXAMPLE // ============================================ /* import { BentoGrid, BentoCard, StatCard, ChartCard } from './bento-grid'; import { Cpu, Database, Activity } from 'lucide-react'; function Dashboard() { return ( } label="CPU Load" value="67.3%" change="+2.4%" changeType="positive" /> } label="Memory" value="12.4 GB" change="-0.8%" changeType="negative" accentColor="#00f3ff" /> } colSpan={2} > ); } */ export default { BentoGrid, BentoCard, StatCard, ChartCard };