{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "testimonials-grid",
  "type": "registry:block",
  "title": "Testimonials grid",
  "description": "A social proof section: a grid of customer quotes and reviews. It can use columns of uneven height and still be read in the order you give.",
  "categories": [
    "section"
  ],
  "registryDependencies": [
    "https://facadeui.dev/r/container.json",
    "https://facadeui.dev/r/section.json",
    "https://facadeui.dev/r/section-header.json",
    "https://facadeui.dev/r/testimonial.json",
    "https://facadeui.dev/r/types.json",
    "https://facadeui.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "src/sections/testimonials-grid.tsx",
      "type": "registry:component",
      "target": "components/sections/testimonials-grid.tsx",
      "content": "/**\n * TestimonialsGrid — a wall of customer quotes.\n *\n * `columns=\"masonry\"` uses CSS multi-column, which keeps ragged quote lengths\n * from leaving a row of tall gaps. That is safe here in a way `grid-auto-flow:\n * dense` is not: multi-column flows items in document order down each column,\n * so reading order and visual order still agree.\n *\n * a11y: a `<ul>` of `<li>`s, each holding a `Testimonial` — which is a\n * `<figure>` with the quote in a `<blockquote>` and the attribution in a\n * `<figcaption>` outside it, because the person's name is not part of what they\n * said. Ratings are announced as \"Rated 5 out of 5\", not as five star icons.\n *\n * Dependencies: react, @/lib/types, @/lib/utils,\n * @/components/ui/container, @/components/ui/section, @/components/ui/section-header,\n * @/components/ui/testimonial.\n */\n\nimport type { ElementType } from \"react\"\n\nimport type { ImageComponent, ListSlotProps, SectionBaseProps } from \"@/lib/types\"\nimport { cn, slugId } from \"@/lib/utils\"\nimport { Container } from \"@/components/ui/container\"\nimport { Section } from \"@/components/ui/section\"\nimport { SectionHeader } from \"@/components/ui/section-header\"\nimport { Testimonial, type TestimonialItem } from \"@/components/ui/testimonial\"\n\nexport interface TestimonialsGridProps extends SectionBaseProps, ListSlotProps {\n  items: TestimonialItem[]\n  title?: string\n  eyebrow?: string\n  description?: string\n  image?: ImageComponent\n  /**\n   * `masonry` lets columns have uneven heights, so quotes of different lengths leave no\n   * gaps.\n   */\n  columns?: 2 | 3 | \"masonry\"\n  variant?: \"card\" | \"plain\"\n  align?: \"start\" | \"center\"\n}\n\nexport function TestimonialsGrid({\n  items,\n  title,\n  eyebrow,\n  description,\n  image,\n  columns = 3,\n  variant = \"card\",\n  align = \"center\",\n  listAs,\n  itemAs,\n  headingLevel = 2,\n  as,\n  spacing = \"md\",\n  className,\n  id,\n}: TestimonialsGridProps) {\n  const List = (listAs ?? \"ul\") as ElementType\n  const Item = (itemAs ?? \"li\") as ElementType\n  const titleId = title ? (id ? `${id}-title` : slugId(title)) : undefined\n  const masonry = columns === \"masonry\"\n\n  return (\n    <Section\n      as={as ?? (title ? \"section\" : \"div\")}\n      spacing={spacing}\n      labelledBy={titleId}\n      id={id}\n      className={className}\n    >\n      <Container className=\"flex flex-col gap-14\">\n        {title ? (\n          <SectionHeader\n            align={align}\n            eyebrow={eyebrow}\n            title={title}\n            description={description}\n            headingLevel={headingLevel}\n            titleId={titleId}\n          />\n        ) : null}\n\n        <List\n          className={cn(\n            masonry\n              ? \"gap-6 sm:columns-2 lg:columns-3 [&>*]:mb-6 [&>*]:break-inside-avoid\"\n              : \"grid gap-6\",\n            !masonry && columns === 2 && \"sm:grid-cols-2\",\n            !masonry && columns === 3 && \"sm:grid-cols-2 lg:grid-cols-3\",\n          )}\n        >\n          {items.map((item, index) => (\n            <Item key={item.id ?? `${item.author.name}-${index}`}>\n              <Testimonial {...item} image={image} variant={variant} />\n            </Item>\n          ))}\n        </List>\n      </Container>\n    </Section>\n  )\n}\n"
    }
  ],
  "docs": "Import styles/facade-tokens.css in your global stylesheet, after @import \"tailwindcss\". Set headingLevel to fit the page outline (sections default to h2). Pass next/link and next/image through the link and image props. Docs: https://facadeui.dev/components/testimonials-grid"
}
