shadimage

Bento Grid 1

Bento grid section 1 with cards, media, two-column layout, three-column grid, bento-style grid.

components/pro-blocks/landing-page/bento-grids/bento-grid-1.tsx

import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { Media } from "@/components/ui/media"

type BentoImage = {
  src: string
  alt: string
  width: number
  height: number
}

type BentoGrid1Item = {
  className?: string
  imageClassName: string
  description: string
}

type Props = {
  taglineText?: string
  title?: string
  description?: string
  featureTitle?: string
  image?: BentoImage
  items?: BentoGrid1Item[]
}

const defaultImage = {
  src: "/image.png",
  alt: "Placeholder",
  width: 1000,
  height: 1000,
} satisfies BentoImage

const defaultProps = {
  taglineText: "Bento grid 1",
  title: "Feature-rich layout that captures attention",
  description:
    "Add a concise value statement that highlights your product's key features and benefits in a visually dynamic grid.",
  featureTitle: "Feature title",
  image: defaultImage,
  items: [
    {
      className: "lg:row-span-2",
      imageClassName: "h-full w-full object-cover",
      description:
        "Shortly describe how this feature solves a specific user problem.",
    },
    {
      imageClassName: "h-full w-full object-cover md:aspect-[4/3]",
      description:
        "Shortly describe how this feature solves a specific user problem.",
    },
    {
      className: "lg:col-start-2",
      imageClassName: "h-full w-full object-cover md:aspect-[4/3]",
      description:
        "Shortly describe how this feature solves a specific user problem.",
    },
    {
      className: "lg:col-start-3 lg:row-span-2 lg:row-start-1",
      imageClassName: "h-full w-full object-cover",
      description:
        "Shortly describe how this feature solves a specific user problem.",
    },
  ] satisfies BentoGrid1Item[],
}

export function BentoGrid1({
  taglineText = defaultProps.taglineText,
  title = defaultProps.title,
  description = defaultProps.description,
  featureTitle = defaultProps.featureTitle,
  image = defaultProps.image,
  items = defaultProps.items,
}: Props) {
  return (
    <section className="bg-background" aria-labelledby="bento-grid-1-heading">
      <div className="wrapper">
        <div className="mx-auto mb-10 flex max-w-xl flex-col items-center text-center md:mb-12">
          <div className="tagline">{taglineText}</div>
          <h2 id="bento-grid-1-heading" className="heading-lg">
            {title}
          </h2>
          <p className="paragraph">{description}</p>
        </div>

        <div className="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
          {items.map((feature, index) => (
            <Card
              key={index}
              className={`gap-0 pt-3 pb-0 ${feature.className ?? ""}`}
            >
              <CardHeader className="gap-0 py-3">
                <h3 className="heading-sm">{featureTitle}</h3>
                <p className="paragraph-sm">{feature.description}</p>
              </CardHeader>
              <CardContent className="flex h-full flex-col p-3">
                <Media
                  type="image"
                  src={image.src}
                  alt={image.alt}
                  width={image.width}
                  height={image.height}
                  className={feature.imageClassName}
                />
              </CardContent>
            </Card>
          ))}
        </div>
      </div>
    </section>
  )
}
Where it goes
bento-grid
Visual style
bento3d