WebberUI

Editorial Interleave Grid

An editorial interleave grid — a product grid that automatically inserts a full-width image, pull quote, or video section every N cards, giving it a magazine-like rhythm.

Loading preview…
npx shadcn@latest add https://webberui.com/r/editorial-interleave-grid.json

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

3
3
16
0.06
<EditorialInterleaveGrid />

Installation

npx shadcn@latest add https://webberui.com/r/editorial-interleave-grid.json

Or, once registries are configured in components.json, install it as @webberui/editorial-interleave-grid.

Usage

Product cards go in as children and editorial sections go in through the editorials array. The grid inserts one editorial section every cadence product cards, cycling through editorials.

import {
  EditorialInterleaveGrid,
  ProductCard,
  EditorialBlock,
} from "@/components/ui/editorial-interleave-grid";

<EditorialInterleaveGrid
  columns={3}
  cadence={3}
  editorials={[
    <EditorialBlock
      key="hero"
      variant="image"
      kicker="Autumn 2026"
      title="A return to natural tones"
      cta="Explore the collection"
      href="/collections/autumn"
      media={<img src="/hero.jpg" alt="" />}
    />,
    <EditorialBlock
      key="quote"
      variant="quote"
      quote="Good design leaves the noise outside the door."
      author="— Brand director"
    />,
    <EditorialBlock
      key="film"
      variant="video"
      kicker="Behind the seams"
      title="A day in the workshop"
      media={<img src="/poster.jpg" alt="" />}
    />,
  ]}
>
  {items.map((item) => (
    <ProductCard
      key={item.id}
      title={item.name}
      price={item.price}
      tag={item.tag}
      href={item.url}
      image={<img src={item.image} alt="" />}
    />
  ))}
</EditorialInterleaveGrid>

Props

EditorialInterleaveGrid

PropTypeDefaultDescription
childrenReact.ReactNodeProduct card children (put ProductCards here)
editorialsReact.ReactNode[][]Editorial sections interleaved on the cadence, cycled through in order
cadencenumber3How many product cards go between each inserted editorial section
columnsnumber3Number of product columns (1–6)
gapnumber16Grid gap (px)
staggernumber0.06Interval between product cards on reveal (seconds)
delaynumber0Delay before the reveal starts (seconds)
oncebooleantruePlays only the first time the element enters the viewport
classNamestringAppended to the grid container's className

ProductCard

PropTypeDefaultDescription
titleReact.ReactNodeProduct name
priceReact.ReactNodePrice text
tagReact.ReactNodeCorner tag (such as "New" or "Limited")
imageReact.ReactNodeProduct image node; a neutral placeholder shows when it is not supplied
hrefstringLink URL; when supplied the whole card is an <a>
onSelect() => voidClick callback; without an href the whole card is a <button>
childrenReact.ReactNodeOverride the content of the image area
classNamestringAppended to the card's className

EditorialBlock

PropTypeDefaultDescription
variant"image" | "quote" | "video""image"Style: full-width image / brand pull quote / video poster
kickerReact.ReactNodeKicker (a small label)
titleReact.ReactNodeMain title (image / video styles)
quoteReact.ReactNodeQuote content (quote style)
authorReact.ReactNodeQuote attribution / brand signature
mediaReact.ReactNodeBackground media node; a gradient shows when it is not supplied
ctaReact.ReactNodeCall-to-action text
hrefstringCall-to-action link; when supplied the whole block is clickable
childrenReact.ReactNodeOverride all of the content
classNamestringAppended to the block's className

Animation details

  • Editorial sections: they reveal by expanding a clip-path outward from a horizontal seam in the middle (inset(46%)inset(0%)); once the frame is open the text rises slightly into view, creating the rhythm of a magazine gatefold opening.
  • Product cards: staggered fade in (opacity plus offset), with the interval controlled by stagger; the image scales up slightly on hover.
  • Video style: the play button carries a soft pulsing glow, hinting that it is playable.
  • Interleave logic: it walks the product cards and inserts the next editorial section every time cadence is reached; nothing is inserted at the very end, so the sequence never closes on an orphaned section.

Accessibility

  • When the user has "reduce motion" enabled at the system level, a static grid renders with no clip-path expansion, no fade in, and no pulsing
  • Product names are rendered as <h3>, and the quote style uses the semantic <blockquote> and <cite> tags
  • A product card with an href renders as an <a> and one with only onSelect renders as a <button>, both keyboard focusable with a focus-visible outline
  • Decorative icons in the editorial sections (quote mark, play, glow) are all marked aria-hidden

On this page