{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "testimonials-01",
  "type": "registry:block",
  "title": "Editorial Testimonial Wall",
  "description": "An editorial wall of speech-bubble testimonials with a quiet identity row, adapted from Tailark.",
  "author": "Irung",
  "registryDependencies": [],
  "dependencies": [
    "cn@0.2.6"
  ],
  "files": [
    {
      "path": "licenses/testimonials-01/LICENSE.txt",
      "type": "registry:file",
      "target": "@components/uiblocks/testimonials-01/LICENSE.txt",
      "content": "Includes source from Blocks.so and its bundled primitives.\nSource: https://github.com/ephraimduncan/blocks\nRevision: 3f759d5171c2391253ec4c772e9e5b3db2bc7c7f\nUIBlocks modifications (block v0.1.0):\n- Added typed testimonial content, safe controlled defaults and an explicit labeled demo.\n- Replaced Next.js Image and remote sample portraits with host-owned image URLs or text initials.\n- Adapted spacing, theme tokens, and responsive content limits to UIBlocks.\n\nMIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nThird-party design: Tailark\nBlock: testimonials-01 (v0.1.0)\nSource: https://github.com/tailark/blocks\nAuthor: Irung\nRevision: 8139698115c1341bfd2e3e286c04bb4d8146f472\nOriginal files:\n- registry/bases/base/mist/blocks/testimonials/two.tsx\nUIBlocks modifications:\n- Added typed testimonial content, safe controlled defaults and an explicit labeled demo.\n- Replaced Next.js Image and remote sample portraits with host-owned image URLs or text initials.\n- Adapted spacing, theme tokens, and responsive content limits to UIBlocks.\n\nMIT License\n\nCopyright (c) 2025 Irung\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
    },
    {
      "path": "lib/utils.ts",
      "type": "registry:component",
      "target": "@components/uiblocks/testimonials-01/shared/lib/utils.ts",
      "content": "export { cn } from \"cn\";\n"
    },
    {
      "path": "content/components/marketing/testimonials-01.tsx",
      "type": "registry:component",
      "target": "@components/uiblocks/testimonials-01/testimonials-01.tsx",
      "content": "\"use client\";\n\n/**\n * Adapted from Tailark by Irung. Copyright (c) 2025 Irung. MIT licensed.\n * Source: https://github.com/tailark/blocks/blob/8139698115c1341bfd2e3e286c04bb4d8146f472/registry/bases/base/mist/blocks/testimonials/two.tsx\n * Adaptations: portable React images and initials; typed host content; explicit\n * demo mode with fictional quotes; semantic quotations and long-content wrapping.\n */\nimport { useId, useState } from \"react\";\nimport { cn } from \"./shared/lib/utils\";\n\nexport type Testimonial01 = {\n  id: string;\n  quote: string;\n  name: string;\n  role?: string;\n  avatarUrl?: string;\n};\n\nexport type Testimonials01Props = {\n  mode?: \"controlled\" | \"demo\";\n  title?: string;\n  description?: string;\n  testimonials?: readonly Testimonial01[];\n  className?: string;\n};\n\nconst demoTestimonials: readonly Testimonial01[] = [\n  {\n    id: \"demo-design\",\n    name: \"Maya Chen\",\n    role: \"Design lead · Fictional team\",\n    quote:\n      \"A thoughtful starting point lets us spend more time on the details that make a product feel like ours.\",\n  },\n  {\n    id: \"demo-build\",\n    name: \"Alex Morgan\",\n    role: \"Developer · Fictional team\",\n    quote:\n      \"The layout gives our ideas room to breathe. We can start with a clear structure and make it fit our own content.\",\n  },\n  {\n    id: \"demo-product\",\n    name: \"Nia Patel\",\n    role: \"Product lead · Fictional team\",\n    quote:\n      \"Small, consistent choices add up. A calm interface helps our team keep the next step in focus.\",\n  },\n];\n\nfunction PersonAvatar({ name, src }: { name: string; src?: string }) {\n  const [failed, setFailed] = useState(false);\n  const initials = name\n    .trim()\n    .split(/\\s+/u)\n    .slice(0, 2)\n    .map((part) => Array.from(part)[0] ?? \"\")\n    .join(\"\");\n  return (\n    <span className=\"grid size-7 shrink-0 place-items-center overflow-hidden rounded-full border border-transparent bg-muted text-[10px] font-medium text-muted-foreground ring-1 ring-foreground/10\">\n      {src && !failed ? (\n        <img\n          alt=\"\"\n          src={src}\n          width={28}\n          height={28}\n          loading=\"lazy\"\n          className=\"size-full object-cover\"\n          onError={() => setFailed(true)}\n        />\n      ) : (\n        <span aria-hidden=\"true\">{initials || \"?\"}</span>\n      )}\n    </span>\n  );\n}\n\nexport default function Testimonials01({\n  mode = \"controlled\",\n  title = \"Customer stories\",\n  description,\n  testimonials,\n  className,\n}: Testimonials01Props) {\n  const headingId = useId();\n  const rows = testimonials ?? (mode === \"demo\" ? demoTestimonials : []);\n  return (\n    <section\n      aria-labelledby={headingId}\n      className={cn(\"bg-muted py-16 text-foreground sm:py-24\", className)}\n      data-testimonials-mode={mode}\n    >\n      <div className=\"@container mx-auto w-full max-w-5xl px-6\">\n        <div className=\"mb-12 max-w-2xl\">\n          <h2\n            id={headingId}\n            className=\"break-words text-3xl font-semibold tracking-tight sm:text-4xl\"\n          >\n            {title}\n          </h2>\n          {description && (\n            <p className=\"mt-4 text-lg leading-8 text-muted-foreground [overflow-wrap:anywhere]\">\n              {description}\n            </p>\n          )}\n          {mode === \"demo\" && (\n            <p className=\"mt-3 text-xs leading-6 text-muted-foreground\">\n              Sample stories · Fictional people and quotes for this interface\n              demo.\n            </p>\n          )}\n        </div>\n        {rows.length ? (\n          <div className=\"grid gap-6 @lg:grid-cols-2 @3xl:grid-cols-3\">\n            {rows.map((testimonial) => (\n              <figure className=\"min-w-0\" key={testimonial.id}>\n                <blockquote className=\"rounded-2xl rounded-bl border border-transparent bg-background px-4 py-3 leading-7 ring-1 ring-foreground/10 [overflow-wrap:anywhere]\">\n                  <p>{testimonial.quote}</p>\n                </blockquote>\n                <figcaption className=\"mt-4 flex min-w-0 flex-wrap items-center gap-2\">\n                  <PersonAvatar\n                    key={testimonial.avatarUrl ?? testimonial.id}\n                    name={testimonial.name}\n                    src={testimonial.avatarUrl}\n                  />\n                  <span className=\"min-w-0 break-words text-sm font-medium [overflow-wrap:anywhere]\">\n                    {testimonial.name}\n                  </span>\n                  {testimonial.role && (\n                    <>\n                      <span\n                        aria-hidden=\"true\"\n                        className=\"size-1 shrink-0 rounded-full bg-foreground/25\"\n                      />\n                      <span className=\"min-w-0 text-sm text-muted-foreground [overflow-wrap:anywhere]\">\n                        {testimonial.role}\n                      </span>\n                    </>\n                  )}\n                </figcaption>\n              </figure>\n            ))}\n          </div>\n        ) : (\n          <p className=\"rounded-2xl border border-dashed border-border bg-background p-8 text-sm leading-7 text-muted-foreground\">\n            No testimonials supplied. Add approved customer quotes and\n            attribution through the testimonials prop.\n          </p>\n        )}\n      </div>\n    </section>\n  );\n}\n"
    }
  ],
  "categories": [
    "marketing",
    "marketing",
    "clean-saas"
  ],
  "docs": "Import the default component from @components/uiblocks/testimonials-01/testimonials-01.tsx. React 19, Tailwind CSS 4, and the standard shadcn CSS theme variables are required. This block is framework-independent React and works in TanStack Start, Vite, and Next.js projects. Connect links or navigation callbacks to your host application. The live preview opts into mode='demo'; the installed component defaults to controlled data and actions. Supply the host's records and callbacks before enabling service actions. Original design: Tailark by Irung, commit 8139698115c1341bfd2e3e286c04bb4d8146f472, source https://github.com/tailark/blocks. Original paths and local adaptations are recorded in meta.source. The complete upstream MIT notice is bundled in LICENSE.txt; retain it when adapting the component. See https://uiblocks.org/marketing/testimonials-01 for content guidelines and source attribution.",
  "meta": {
    "kind": "block",
    "previewProps": {
      "mode": "demo"
    },
    "defaultMode": "controlled",
    "demoMode": "explicit",
    "includesBackend": false,
    "version": "0.1.0",
    "source": {
      "name": "Tailark",
      "url": "https://github.com/tailark/blocks",
      "license": "MIT",
      "author": "Irung",
      "revision": "8139698115c1341bfd2e3e286c04bb4d8146f472",
      "licenseFile": "licenses/third-party/tailark-MIT.txt",
      "files": [
        "registry/bases/base/mist/blocks/testimonials/two.tsx"
      ],
      "modifications": [
        "Added typed testimonial content, safe controlled defaults and an explicit labeled demo.",
        "Replaced Next.js Image and remote sample portraits with host-owned image URLs or text initials.",
        "Adapted spacing, theme tokens, and responsive content limits to UIBlocks."
      ]
    },
    "license": "MIT",
    "style": "clean-saas",
    "pageType": "marketing",
    "featured": true,
    "tags": [
      "testimonials",
      "reviews",
      "quotes",
      "social proof",
      "trust",
      "评价",
      "客户评价",
      "口碑",
      "推荐语"
    ],
    "contentGuidelines": [
      "Use verified customer quotes and obtain permission for names, roles and portraits.",
      "Pass testimonials to the default controlled mode. Explicit mode='demo' shows fictional sample feedback.",
      "Keep each quote to a few short sentences and test long Chinese names and narrow screens."
    ],
    "recommendedWith": [
      "hero-01",
      "features-02",
      "pricing-02"
    ],
    "entry": "@components/uiblocks/testimonials-01/testimonials-01.tsx",
    "exportName": "default",
    "frameworkIndependent": true,
    "frameworkDependencies": [],
    "compatibleHosts": [
      "react",
      "vite",
      "tanstack-start",
      "nextjs"
    ],
    "requirements": {
      "react": ">=19",
      "tailwind": ">=4"
    },
    "previewUrl": "https://uiblocks.org/preview/testimonials-01"
  }
}
