solaceui
blockbento-grid-1source: ok · hit
Bento Grid 1
Solace UI bento grid block variation 1.
npx shadcn add "https://www.solaceui.com/r/bento-grid-1.json"free
Where it goes
bento-grid
Visual style
bento
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · mediumanimationmotion
Files2 · source cached 10/15/2026, 7:41:32 AM
src/registry/blocks/bento-grid/one/index.tsx
import {
BentoGrid,
BentoItem,
ChatMessaging,
CompanyLogos,
} from "@/registry/blocks/bento-grid/one/bento-grid-template-one";
export default function BentoGridOne() {
const items: BentoItem[] = [
{
id: "1",
type: "feature",
title: "World-Class Information Design",
description:
"Transform complex data into crisp visuals that quickly tell your story.",
image:
"https://assets.solaceui.com/solaceui-hero-video.jpg",
},
{
id: "2",
type: "chat",
content: <ChatMessaging />,
},
{
id: "3",
type: "partners",
title: "Connected Everywhere",
description:
"Embed your work seamlessly across your favorite platforms for instant sharing.",
content: <CompanyLogos />,
},
];
return (
<main className="flex min-h-screen flex-col items-center justify-center p-4 md:p-24 ">
<BentoGrid items={items} />
</main>
);
}
src/registry/blocks/bento-grid/one/bento-grid-template-one.tsx
"use client";
import type { ReactNode } from "react";
import { motion } from "motion/react";
import Image from "next/image";
import { cn } from "@/lib/utils";
// Types for our bento grid items
export type BentoItem = {
id: string;
type: "feature" | "chat" | "partners";
title?: string;
description?: string;
image?: string;
className?: string;
content?: ReactNode;
};
// Props for our base BentoGrid component
interface BentoGridProps {
items: BentoItem[];
className?: string;
}
// Props for each bento item
interface BentoItemProps {
item: BentoItem;
className?: string;
}
// Base BentoGrid component
export function BentoGrid({ items, className }: BentoGridProps) {
return (
<div
className={cn(
"grid grid-cols-1 md:grid-cols-2 gap-4 max-w-7xl mx-auto",
className
)}
>
{items.map((item) => {
return (
<div
key={item.id}
className={cn(
"row-span-1",
item.type === "feature" && "col-span-1 md:col-span-2",
item.className
)}
>
<BentoGridItem item={item} />
</div>
);
})}
</div>
);
}
// Individual BentoGridItem component
function BentoGridItem({ item, className }: BentoItemProps) {
const { type, title, description, image, content } = item;
// Different layouts based on item type
switch (type) {
case "feature":
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className={cn(
"group relative overflow-hidden rounded-xl bg-[#19ffc2ec] dark:bg-neutral-900 p-8 h-[400px] flex flex-col md:flex-row shadow-md",
className
)}
>
<div className="flex flex-col justify-center z-10 md:w-1/2">
<span className="text-xs uppercase dark:text-[#1DCD9F] text-black font-medium mb-2">
Visualise Info
</span>
<h2 className="text-3xl md:text-4xl font-bold dark:text-white text-black mb-4 text-balance">
{title}
</h2>
<p className="text-sm text-neutral-600 max-w-md text-balance">
{description}
</p>
</div>
{image && (
<div className=" md:w-1/2 h-full right-0 top-0 flex items-center justify-center">
<div className="relative w-full h-full">
<motion.div
initial={{ rotate: 0 }}
animate={{ scale: 1.1 }}
transition={{ duration: 0.7 }}
className="absolute inset-0 z-0"
>
<div className="relative w-full h-full top-10 left-10">
<Image
src={image || "/placeholder.svg"}
alt="visualise"
fill
className="object-cover rounded-md shadow-xl dark:shadow-[#1DCD9F] shadow-white"
unoptimized
/>
</div>
</motion.div>
</div>
</div>
)}
<div className="absolute bottom-0 z-50 inset-x-0 h-[2rem] bg-gradient-to-t dark:from-neutral-900 from-[#1DCD9F] to-transparent w-full pointer-events-none" />
</motion.div>
);
case "chat":
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.1 }}
className={cn(
"group relative overflow-hidden rounded-xl bg-[#222222] dark:bg-neutral-900 p-8 h-[400px] flex flex-col shadow-md",
className
)}
>
<div className="z-10">
<span className="text-xs uppercase text-[#1DCD9F] font-medium mb-2 flex items-center justify-center p-2">
Customise
</span>
</div>
<div className="flex-1 relative">{content}</div>
<div className="absolute bottom-0 z-50 inset-x-0 h-[2rem] bg-gradient-to-t from-neutral-900 to-transparent w-full pointer-events-none" />
</motion.div>
);
case "partners":
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }}
className={cn(
"group relative overflow-hidden rounded-xl bg-neutral-900 p-8 h-[400px] flex flex-col shadow-md",
className
)}
>
<div className="flex-1 relative flex items-center justify-center">
{content}
<div className="absolute left-0 z-[100] inset-y-0 w-10 bg-gradient-to-r from-neutral-900 to-transparent h-full pointer-events-none" />
<div className="absolute right-0 z-[100] inset-y-0 w-10 bg-gradient-to-l from-neutral-900 to-transparent h-full pointer-events-none" />
</div>
<div className="mt-4 z-10">
<span className="text-xs uppercase text-[#1DCD9F] font-medium ">
Embed
</span>
<h3 className="text-2xl font-bold text-white mb-2 text-balance">
{title}
</h3>
<p className="text-sm dark:text-neutral-600 text-neutral-700 text-balance">
{description}
</p>
</div>
</motion.div>
);
default:
return null;
}
}
// Company logos component for the partners section
export function CompanyLogos() {
const logos = [
{
name: "Spotify",
url: "https://assets.solaceui.com/solaceui-Spotify.png",
},
{
name: "Notion",
url: "https://assets.solaceui.com/solaceui-Notion.png",
},
{
name: "Slack",
url: "https://assets.solaceui.com/solaceui-Slack.png",
},
{
name: "Twitter",
url: "https://assets.solaceui.com/solaceui-Twitter.png",
},
{
name: "Apple",
url: "https://assets.solaceui.com/solaceui-Apple.png",
},
];
return (
<div className="w-full overflow-hidden">
<motion.div
className="flex gap-8 items-center justify-center"
animate={{ x: [0, -1000] }}
transition={{
x: {
repeat: Number.POSITIVE_INFINITY,
repeatType: "loop",
duration: 20,
ease: "linear",
},
}}
>
{/* First set of logos */}
{logos.map((logo) => (
<div
key={logo.name}
className="flex-shrink-0 w-16 h-16 bg-neutral-800 rounded-lg flex items-center justify-center p-2"
>
<Image
src={logo.url || "/placeholder.svg"}
alt={logo.name}
width={40}
height={40}
className="w-10 h-10 object-contain"
unoptimized
/>
</div>
))}
{/* Duplicate set for seamless looping */}
{logos.map((logo) => (
<div
key={`${logo.name}-dup`}
className="flex-shrink-0 w-16 h-16 bg-neutral-800 rounded-lg flex items-center justify-center p-2"
>
<Image
src={logo.url || "/placeholder.svg"}
alt={logo.name}
width={40}
height={40}
className="w-10 h-10 object-contain"
unoptimized
/>
</div>
))}
</motion.div>
</div>
);
}
// Chat messaging component with iPhone mockup
export function ChatMessaging() {
return (
<div className="relative w-full h-full flex items-center justify-center">
<div className="relative w-[280px] h-[500px] bg-neutral-800 rounded-[36px] p-3 border-4 border-neutral-700 overflow-hidden">
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 w-1/3 h-6 bg-neutral-700 rounded-b-xl z-10" />
<div className="w-full h-full bg-neutral-900 rounded-[28px] p-4 overflow-hidden">
<div className="flex items-center mb-4">
<div className="w-8 h-8 rounded-full bg-[#1DCD9F] mr-3" />
<div>
<div className="text-white text-xs font-medium">Assistant</div>
<div className="text-neutral-400 text-[10px]">Online</div>
</div>
</div>
<div className="space-y-3">
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5 }}
className="bg-neutral-800 p-2 rounded-lg rounded-tl-none max-w-[80%] text-[10px] text-white"
>
How can I help you today?
</motion.div>
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.3 }}
className="bg-[#1DCD9F] p-2 rounded-lg rounded-tr-none max-w-[80%] ml-auto text-[10px] text-white"
>
I need help with my project
</motion.div>
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.6 }}
className="bg-neutral-800 p-2 rounded-lg rounded-tl-none max-w-[80%] text-[10px] text-white"
>
I'd be happy to help! What kind of project are you working
on?
</motion.div>
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5, delay: 0.9 }}
className="bg-[#1DCD9F] p-2 rounded-lg rounded-tr-none max-w-[80%] ml-auto text-[10px] text-white"
>
I'm building a component library with Next.js and Tailwind
</motion.div>
</div>
</div>
</div>
</div>
);
}