# Hero Tiles

A pair of promotional hero tiles, each with a title, tagline, two actions, and a product image.

Hero Tiles is an open-source block from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.

Source: https://ui.suiss.app/docs/blocks/hero-tiles

**React**

**Example**

```tsx title="components/blocks/hero-tiles.tsx"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

const photo = (id: string) =>
  `https://images.unsplash.com/photo-${id}?w=1600&q=80&auto=format&fit=crop`

const tiles = [
  {
    title: "Book Air",
    text: "So thin. So capable. Now with S5.",
    image: photo("1750056393331-82e69d28c9d9"),
    alt: "A laptop between plants on a wooden desk",
    dark: false,
  },
  {
    title: "Watch",
    text: "Series 11. Smarter. Brighter. Mightier.",
    image: photo("1696688713460-de12ac76ebc6"),
    alt: "A smartwatch on a dark table",
    dark: true,
  },
]

export function HeroTiles() {
  return (
    <section className="grid gap-3 bg-background p-3 md:grid-cols-2">
      {tiles.map((tile) => (
        <article
          key={tile.title}
          className={cn(
            "flex min-w-0 flex-col items-center overflow-hidden bg-muted pt-11 text-center text-foreground",
            tile.dark && "dark bg-background"
          )}
        >
          <div className="flex flex-col items-center gap-1 px-6">
            <h2 className="text-4xl font-semibold tracking-tight">
              {tile.dark && <span className="me-1.5">suiss</span>}
              {tile.title}
            </h2>
            <p className="text-xl text-balance">{tile.text}</p>
          </div>
          <div className="mt-4.5 flex flex-wrap justify-center gap-3.5 px-6">
            <Button>Learn more</Button>
            <Button
              variant="outline"
              className="border-primary bg-transparent text-primary hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:bg-transparent"
            >
              Buy
            </Button>
          </div>
          <img
            src={tile.image}
            alt={tile.alt}
            className="mt-4.5 aspect-[1.4] w-full bg-secondary object-cover"
          />
        </article>
      ))}
    </section>
  )
}
```

Two promotional tiles, each with a title, tagline, Learn more and Buy buttons and a product image, one of them rendered in the dark palette. The tiles stack on mobile and sit side by side on desktop. It is a static server component for promoting two products or offers on a home page.

## Installation

### CLI

```bash title="Terminal"
npx shadcn@latest add @esuiss/hero-tiles
```

Works in any project with a `components.json`. See [Installation](https://ui.suiss.app/docs/installation#add-components) for the one-line registry setup. Or use the suiss/ui CLI:

```bash title="Terminal"
npx @esuiss/ui@latest add blocks hero-tiles
```

### Manual

1. Add the [`cn` helper](https://ui.suiss.app/docs/installation#the-cn-helper).

2. Add the pieces it builds on: [Button](https://ui.suiss.app/docs/components/button).

3. Copy the source into `components/blocks/hero-tiles.tsx`:

```tsx title="components/blocks/hero-tiles.tsx"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

const photo = (id: string) =>
  `https://images.unsplash.com/photo-${id}?w=1600&q=80&auto=format&fit=crop`

const tiles = [
  {
    title: "Book Air",
    text: "So thin. So capable. Now with S5.",
    image: photo("1750056393331-82e69d28c9d9"),
    alt: "A laptop between plants on a wooden desk",
    dark: false,
  },
  {
    title: "Watch",
    text: "Series 11. Smarter. Brighter. Mightier.",
    image: photo("1696688713460-de12ac76ebc6"),
    alt: "A smartwatch on a dark table",
    dark: true,
  },
]

export function HeroTiles() {
  return (
    <section className="grid gap-3 bg-background p-3 md:grid-cols-2">
      {tiles.map((tile) => (
        <article
          key={tile.title}
          className={cn(
            "flex min-w-0 flex-col items-center overflow-hidden bg-muted pt-11 text-center text-foreground",
            tile.dark && "dark bg-background"
          )}
        >
          <div className="flex flex-col items-center gap-1 px-6">
            <h2 className="text-4xl font-semibold tracking-tight">
              {tile.dark && <span className="me-1.5">suiss</span>}
              {tile.title}
            </h2>
            <p className="text-xl text-balance">{tile.text}</p>
          </div>
          <div className="mt-4.5 flex flex-wrap justify-center gap-3.5 px-6">
            <Button>Learn more</Button>
            <Button
              variant="outline"
              className="border-primary bg-transparent text-primary hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:bg-transparent"
            >
              Buy
            </Button>
          </div>
          <img
            src={tile.image}
            alt={tile.alt}
            className="mt-4.5 aspect-[1.4] w-full bg-secondary object-cover"
          />
        </article>
      ))}
    </section>
  )
}
```

4. Update the import paths to match your project.

## Usage

```tsx
import { HeroTiles } from "@/components/blocks/hero-tiles"
```

```tsx
<HeroTiles />
```

Edit the `tiles` array; each tile has a title, text, image, alt text and a `dark` flag. Dark tiles prefix their title with suiss, so remove that span if it doesn't fit your brand. Connect the buttons to your product pages.

## Notes

Images are Unsplash placeholders.

