{ "name": "bento-grid", "type": "registry:component", "dependencies": [ "lucide-react", "motion" ], "files": [ { "type": "registry:component", "content": "\"use client\";\n\n/**\n * @author: @dorianbaffier\n * @description: Bento Grid\n * @version: 1.0.0\n * @date: 2025-06-26\n * @license: MIT\n * @website: https://kokonutui.com\n * @github: https://github.com/kokonut-labs/kokonutui\n */\n\nimport {\n ArrowUpRight,\n CheckCircle2,\n Clock,\n Mic,\n Plus,\n Sparkles,\n Zap,\n} from \"lucide-react\";\nimport {\n motion,\n useMotionValue,\n useTransform,\n type Variants,\n} from \"motion/react\";\nimport Link from \"next/link\";\nimport { useEffect, useRef, useState } from \"react\";\nimport Anthropic from \"@/components/icons/anthropic\";\nimport AnthropicDark from \"@/components/icons/anthropic-dark\";\nimport DeepSeek from \"@/components/icons/deepseek\";\nimport Google from \"@/components/icons/gemini\";\nimport MistralAI from \"@/components/icons/mistral\";\nimport OpenAI from \"@/components/icons/open-ai\";\nimport OpenAIDark from \"@/components/icons/open-ai-dark\";\nimport { cn } from \"@/lib/utils\";\n\ninterface BentoItem {\n id: string;\n title: string;\n description: string;\n icons?: boolean;\n href?: string;\n feature?:\n | \"chart\"\n | \"counter\"\n | \"code\"\n | \"timeline\"\n | \"spotlight\"\n | \"icons\"\n | \"typing\"\n | \"metrics\";\n spotlightItems?: string[];\n timeline?: Array<{ year: string; event: string }>;\n code?: string;\n codeLang?: string;\n typingText?: string;\n metrics?: Array<{\n label: string;\n value: number;\n suffix?: string;\n color?: string;\n }>;\n statistic?: {\n value: string;\n label: string;\n start?: number;\n end?: number;\n suffix?: string;\n };\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst bentoItems: BentoItem[] = [\n {\n id: \"main\",\n title: \"Building tomorrow's technology\",\n description:\n \"We architect and develop enterprise-grade applications that scale seamlessly with cloud-native technologies and microservices.\",\n href: \"#\",\n feature: \"spotlight\",\n spotlightItems: [\n \"Microservices architecture\",\n \"Serverless computing\",\n \"Container orchestration\",\n \"API-first design\",\n \"Event-driven systems\",\n ],\n size: \"lg\",\n className: \"col-span-2 row-span-1 md:col-span-2 md:row-span-1\",\n },\n {\n id: \"stat1\",\n title: \"AI Agents & Automation\",\n description:\n \"Intelligent agents that learn, adapt, and automate complex workflows\",\n href: \"#\",\n feature: \"typing\",\n typingText:\n \"const createAgent = async () => {\\n const agent = new AIAgent({\\n model: 'gpt-4-turbo',\\n tools: [codeAnalysis, dataProcessing],\\n memory: new ConversationalMemory()\\n });\\n\\n // Train on domain knowledge\\n await agent.learn(domainData);\\n\\n return agent;\\n};\",\n size: \"md\",\n className: \"col-span-2 row-span-1 col-start-1 col-end-3\",\n },\n {\n id: \"partners\",\n title: \"Trusted partners\",\n description:\n \"Working with the leading AI and cloud providers to deliver cutting-edge solutions\",\n icons: true,\n href: \"#\",\n feature: \"icons\",\n size: \"md\",\n className: \"col-span-1 row-span-1\",\n },\n {\n id: \"innovation\",\n title: \"Innovation timeline\",\n description:\n \"Pioneering the future of AI and cloud computing with breakthrough innovations\",\n href: \"#\",\n feature: \"timeline\",\n timeline: [\n { year: \"2020\", event: \"Launch of Cloud-Native Platform\" },\n { year: \"2021\", event: \"Advanced AI Integration & LLM APIs\" },\n { year: \"2022\", event: \"Multi-Agent Systems & RAG Architecture\" },\n { year: \"2023\", event: \"Autonomous AI Agents & Neural Networks\" },\n {\n year: \"2024\",\n event: \"AGI-Ready Infrastructure & Edge Computing\",\n },\n ],\n size: \"sm\",\n className: \"col-span-1 row-span-1\",\n },\n];\n\nconst fadeInUp: Variants = {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: {\n duration: 0.5,\n ease: \"easeOut\",\n },\n },\n};\n\nconst staggerContainer: Variants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.15,\n delayChildren: 0.3,\n },\n },\n};\n\nconst SpotlightFeature = ({ items }: { items: string[] }) => (\n \n);\n\nconst CounterAnimation = ({\n start,\n end,\n suffix = \"\",\n}: {\n start: number;\n end: number;\n suffix?: string;\n}) => {\n const [count, setCount] = useState(start);\n\n useEffect(() => {\n const duration = 2000;\n const frameRate = 1000 / 60;\n const totalFrames = Math.round(duration / frameRate);\n\n let currentFrame = 0;\n const counter = setInterval(() => {\n currentFrame++;\n const progress = currentFrame / totalFrames;\n const easedProgress = 1 - (1 - progress) ** 3;\n const current = start + (end - start) * easedProgress;\n\n setCount(Math.min(current, end));\n\n if (currentFrame === totalFrames) {\n clearInterval(counter);\n }\n }, frameRate);\n\n return () => clearInterval(counter);\n }, [start, end]);\n\n return (\n
\n \n {count.toFixed(1).replace(/\\.0$/, \"\")}\n \n \n {suffix}\n \n
\n );\n};\n\nconst ChartAnimation = ({ value }: { value: number }) => (\n
\n \n
\n);\n\nconst IconsFeature = () => (\n
\n \n
\n \n \n
\n \n OpenAI\n \n
\n \n
\n \n \n
\n \n Anthropic\n \n
\n \n
\n \n
\n \n Google\n \n
\n \n
\n \n
\n \n Mistral\n \n
\n \n
\n \n
\n \n DeepSeek\n \n
\n \n
\n \n
\n \n More\n \n
\n
\n);\n\nconst TimelineFeature = ({\n timeline,\n}: {\n timeline: Array<{ year: string; event: string }>;\n}) => (\n
\n
\n {timeline.map((item) => (\n \n
\n
\n
\n {item.year}\n
\n
\n {item.event}\n
\n
\n \n ))}\n
\n);\n\nconst TypingCodeFeature = ({ text }: { text: string }) => {\n const [displayedText, setDisplayedText] = useState(\"\");\n const [currentIndex, setCurrentIndex] = useState(0);\n const terminalRef = useRef(null);\n\n useEffect(() => {\n if (currentIndex < text.length) {\n const timeout = setTimeout(\n () => {\n setDisplayedText((prev) => prev + text[currentIndex]);\n setCurrentIndex((prev) => prev + 1);\n\n if (terminalRef.current) {\n terminalRef.current.scrollTop = terminalRef.current.scrollHeight;\n }\n },\n Math.random() * 30 + 10\n ); // Random typing speed for realistic effect\n\n return () => clearTimeout(timeout);\n }\n }, [currentIndex, text]);\n\n // Reset animation when component unmounts and remounts\n useEffect(() => {\n setDisplayedText(\"\");\n setCurrentIndex(0);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n
\n
\n
\n server.ts\n
\n
\n \n
\n          {displayedText}\n          |\n        
\n
\n
\n );\n};\n\nconst MetricsFeature = ({\n metrics,\n}: {\n metrics: Array<{\n label: string;\n value: number;\n suffix?: string;\n color?: string;\n }>;\n}) => {\n const getColorClass = (color = \"emerald\") => {\n const colors = {\n emerald: \"bg-emerald-500 dark:bg-emerald-400\",\n blue: \"bg-blue-500 dark:bg-blue-400\",\n violet: \"bg-violet-500 dark:bg-violet-400\",\n amber: \"bg-amber-500 dark:bg-amber-400\",\n rose: \"bg-rose-500 dark:bg-rose-400\",\n };\n return colors[color as keyof typeof colors] || colors.emerald;\n };\n\n return (\n
\n {metrics.map((metric, index) => (\n \n
\n
\n {metric.label === \"Uptime\" && }\n {metric.label === \"Response time\" && (\n \n )}\n {metric.label === \"Cost reduction\" && (\n \n )}\n {metric.label}\n
\n
\n {metric.value}\n {metric.suffix}\n
\n
\n
\n \n
\n \n ))}\n
\n );\n};\n\nfunction AIInput_Voice() {\n const [submitted, setSubmitted] = useState(false);\n const [time, setTime] = useState(0);\n const [isClient, setIsClient] = useState(false);\n const [isDemo, setIsDemo] = useState(true);\n\n useEffect(() => {\n setIsClient(true);\n }, []);\n\n useEffect(() => {\n let intervalId: NodeJS.Timeout;\n\n if (submitted) {\n intervalId = setInterval(() => {\n setTime((t) => t + 1);\n }, 1000);\n } else {\n setTime(0);\n }\n\n return () => clearInterval(intervalId);\n }, [submitted]);\n\n const formatTime = (seconds: number) => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins.toString().padStart(2, \"0\")}:${secs\n .toString()\n .padStart(2, \"0\")}`;\n };\n\n useEffect(() => {\n if (!isDemo) return;\n\n let timeoutId: NodeJS.Timeout;\n const runAnimation = () => {\n setSubmitted(true);\n timeoutId = setTimeout(() => {\n setSubmitted(false);\n timeoutId = setTimeout(runAnimation, 1000);\n }, 3000);\n };\n\n const initialTimeout = setTimeout(runAnimation, 100);\n return () => {\n clearTimeout(timeoutId);\n clearTimeout(initialTimeout);\n };\n }, [isDemo]);\n\n const handleClick = () => {\n if (isDemo) {\n setIsDemo(false);\n setSubmitted(false);\n } else {\n setSubmitted((prev) => !prev);\n }\n };\n\n return (\n
\n
\n \n {submitted ? (\n \n ) : (\n \n )}\n \n\n \n {formatTime(time)}\n \n\n
\n {[...Array(48)].map((_, i) => (\n \n ))}\n
\n\n

\n {submitted ? \"Listening...\" : \"Click to speak\"}\n

\n
\n
\n );\n}\n\nconst BentoCard = ({ item }: { item: BentoItem }) => {\n const [isHovered, setIsHovered] = useState(false);\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n const rotateX = useTransform(y, [-100, 100], [2, -2]);\n const rotateY = useTransform(x, [-100, 100], [-2, 2]);\n\n function handleMouseMove(event: React.MouseEvent) {\n const rect = event.currentTarget.getBoundingClientRect();\n const width = rect.width;\n const height = rect.height;\n const mouseX = event.clientX - rect.left;\n const mouseY = event.clientY - rect.top;\n const xPct = mouseX / width - 0.5;\n const yPct = mouseY / height - 0.5;\n x.set(xPct * 100);\n y.set(yPct * 100);\n }\n\n function handleMouseLeave() {\n x.set(0);\n y.set(0);\n setIsHovered(false);\n }\n\n return (\n setIsHovered(true)}\n onMouseMove={handleMouseMove}\n style={{\n rotateX,\n rotateY,\n transformStyle: \"preserve-3d\",\n }}\n transition={{ type: \"spring\", stiffness: 300, damping: 20 }}\n variants={fadeInUp}\n whileHover={{ y: -5 }}\n >\n \n \n
\n
\n

\n {item.title}\n

\n
\n \n
\n
\n\n

\n {item.description}\n

\n\n {/* Feature specific content */}\n {item.feature === \"spotlight\" && item.spotlightItems && (\n \n )}\n\n {item.feature === \"counter\" && item.statistic && (\n
\n \n
\n )}\n\n {item.feature === \"chart\" && item.statistic && (\n
\n
\n \n {item.statistic.label}\n \n \n {item.statistic.end}\n {item.statistic.suffix}\n \n
\n \n
\n )}\n\n {item.feature === \"timeline\" && item.timeline && (\n \n )}\n\n {item.feature === \"icons\" && }\n\n {item.feature === \"typing\" && item.typingText && (\n \n )}\n\n {item.feature === \"metrics\" && item.metrics && (\n \n )}\n\n {item.icons && !item.feature && (\n
\n \n \n \n \n \n \n \n
\n )}\n
\n
\n \n \n );\n};\n\nexport default function BentoGrid() {\n return (\n
\n
\n {/* Bento Grid */}\n \n
\n \n \n \n \n \n \n
\n
\n \n \n \n \n
\n
\n

\n Voice Assistant\n

\n
\n

\n Interact with our AI using natural voice commands. Experience\n seamless voice-driven interactions with advanced speech\n recognition.\n

\n \n
\n \n
\n \n
\n
\n );\n}\n", "path": "/components/kokonutui/bento-grid.tsx", "target": "components/kokonutui/bento-grid.tsx" }, { "type": "registry:component", "content": "const Anthropic = (props: React.SVGProps) => (\n \n {\"Anthropic\"}\n \n \n);\nexport default Anthropic;\n", "path": "/components/icons/anthropic.tsx", "target": "components/kokonutui/anthropic.tsx" }, { "type": "registry:component", "content": "import type { SVGProps } from \"react\";\n\nconst AnthropicDark = (props: SVGProps) => (\n \n {\"Anthropic\"}\n \n \n);\nexport default AnthropicDark;\n", "path": "/components/icons/anthropic-dark.tsx", "target": "components/kokonutui/anthropic-dark.tsx" }, { "type": "registry:component", "content": "const Gemini = (props: React.SVGProps) => (\n \n {\"Gemini\"}\n \n \n \n \n \n \n \n \n \n);\nexport default Gemini;\n", "path": "/components/icons/gemini.tsx", "target": "components/kokonutui/gemini.tsx" }, { "type": "registry:component", "content": "const OpenAI = (props: React.SVGProps) => (\n \n OpenAI\n \n \n);\n\nexport default OpenAI;\n", "path": "/components/icons/open-ai.tsx", "target": "components/kokonutui/open-ai.tsx" }, { "type": "registry:component", "content": "import type { SVGProps } from \"react\";\n\nconst OpenAIDark = (props: SVGProps) => (\n \n OpenAI\n \n \n);\nexport default OpenAIDark;\n", "path": "/components/icons/open-ai-dark.tsx", "target": "components/kokonutui/open-ai-dark.tsx" }, { "type": "registry:component", "content": "const MistralAI = (props: React.SVGProps) => (\n \n Mistral AI\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n);\nexport default MistralAI;\n", "path": "/components/icons/mistral.tsx", "target": "components/kokonutui/mistral.tsx" }, { "type": "registry:component", "content": "const DeepSeek = (props: React.SVGProps) => (\n \n DeepSeek\n \n \n);\nexport default DeepSeek;\n", "path": "/components/icons/deepseek.tsx", "target": "components/kokonutui/deepseek.tsx" } ] }