{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "preview-switch-hero", "type": "registry:ui", "title": "Preview Switch Hero", "description": "A split hero with an icon-rail that switches the product preview, a lead-capture column (badge, ratings, email form, CTAs, avatars), and a full-width logo strip. Responsive and theme-aware.", "dependencies": [ "lucide-react" ], "files": [ { "path": "registry/ruixenui/preview-switch-hero.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport { ArrowUpRight, Mail, Star } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── types ───────────────────────────────────────────────────── */\n\nexport interface PreviewTab {\n id: string;\n /** Text label shown in the switcher rail. */\n label: string;\n /** Panel shown when this tab is active. All panels should share one size. */\n media: React.ReactNode;\n}\n\nexport interface HeroRating {\n source: string;\n score: string;\n /** Defaults to a filled star. */\n icon?: React.ReactNode;\n}\n\nexport interface HeroLogo {\n name: string;\n /** Optional custom mark; falls back to the name as a text wordmark. */\n logo?: React.ReactNode;\n}\n\nexport interface HeroAvatar {\n initials?: string;\n src?: string;\n}\n\nexport interface Cta {\n label: string;\n href?: string;\n}\n\nexport interface PreviewSwitchHeroProps {\n /** Small pill above the title, e.g. `{ tag: \"NEW\", label: \"…\" }`. */\n badge?: { tag?: string; label: React.ReactNode };\n title: React.ReactNode;\n description?: React.ReactNode;\n ratings?: HeroRating[];\n /**\n * Show the email-capture field above the CTAs. When `false`, the CTAs render\n * on their own as plain actions (no form/input). Default `true`.\n */\n showEmail?: boolean;\n /** Label above the email field. */\n emailLabel?: React.ReactNode;\n emailPlaceholder?: string;\n /** Called with the email on submit. */\n onSubmit?: (email: string) => void;\n /** Submits the form when no `href`; otherwise renders as a link. */\n primaryCta?: Cta;\n secondaryCta?: Cta;\n avatars?: HeroAvatar[];\n socialProof?: React.ReactNode;\n /** Text tabs that switch the preview. */\n tabs: PreviewTab[];\n /** Logo strip rendered full-width below the split. */\n logos?: HeroLogo[];\n className?: string;\n}\n\n/* ── pieces ──────────────────────────────────────────────────── */\n\nfunction TabRail({\n tabs,\n active,\n onSelect,\n}: {\n tabs: PreviewTab[];\n active: number;\n onSelect: (i: number) => void;\n}) {\n return (\n
\n {description}\n
\n )}\n\n {ratings && ratings.length > 0 && (\n