{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "sales-ai-hero", "type": "registry:ui", "title": "Sales AI Hero", "description": "A SaaS landing hero with floating announcement pill, oversized centered headline, paired square + landscape media tiles, and a divider-flanked trusted-by logo strip.", "dependencies": [ "lucide-react" ], "files": [ { "path": "registry/ruixenui/sales-ai-hero.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport Link from \"next/link\";\nimport { ArrowRight, Zap } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\n/* ── types ───────────────────────────────────────────────────── */\n\ninterface Announcement {\n label: string;\n href?: string;\n /** Override the default lightning glyph */\n icon?: React.ReactNode;\n}\n\ninterface LogoItem {\n name: string;\n /** Optional src for an rendering. Omit to render `name` as text mark. */\n src?: string;\n /** Or supply fully custom JSX (e.g. an inline SVG wordmark) */\n logo?: React.ReactNode;\n href?: string;\n}\n\ninterface TrustedBy {\n /** Headline text, supports inline markup via `highlight` slot below. */\n prefix?: string;\n /** Optional highlighted segment rendered bold next to `prefix`. */\n highlight?: string;\n /** Trailing text after the highlighted segment. */\n suffix?: string;\n logos: LogoItem[];\n}\n\nexport interface SalesAiHeroProps {\n announcement?: Announcement;\n title: React.ReactNode;\n description?: React.ReactNode;\n /** Content for the left (portrait) media tile. Falls back to a placeholder. */\n leftMedia?: React.ReactNode;\n /** Content for the right (landscape) media tile. Falls back to a placeholder. */\n rightMedia?: React.ReactNode;\n /** Trusted-by strip rendered below the media. Omit to hide. */\n trustedBy?: TrustedBy;\n className?: string;\n}\n\n/* ── pieces ──────────────────────────────────────────────────── */\n\nfunction AnnouncementPill({ announcement }: { announcement: Announcement }) {\n const body = (\n <>\n \n {announcement.icon ?? (\n \n )}\n \n {announcement.label}\n \n \n \n \n );\n\n const className = cn(\n \"inline-flex h-11 max-w-full items-center gap-2.5 rounded-full bg-card pl-4 pr-1.5 text-sm font-medium text-foreground shadow-[0_1px_2px_rgba(0,0,0,0.04),0_8px_24px_-12px_rgba(0,0,0,0.18)] ring-1 ring-border/60 transition-colors\",\n \"hover:bg-muted/60\",\n );\n\n return announcement.href ? (\n \n {body}\n \n ) : (\n
{body}
\n );\n}\n\nfunction MediaTile({\n children,\n aspect,\n tone = \"muted\",\n className,\n}: {\n children?: React.ReactNode;\n aspect: string;\n tone?: \"muted\" | \"accent\";\n className?: string;\n}) {\n return (\n \n {children ?? }\n \n );\n}\n\nfunction DefaultPlaceholder({ tone }: { tone: \"muted\" | \"accent\" }) {\n return (\n \n
\n
\n \n Replace media\n \n
\n
\n );\n}\n\nfunction LogoMark({ item }: { item: LogoItem }) {\n if (item.logo) return <>{item.logo};\n if (item.src) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n \n );\n }\n return (\n \n {item.name}\n \n );\n}\n\n/* ── component ───────────────────────────────────────────────── */\n\nexport function SalesAiHero({\n announcement,\n title,\n description,\n leftMedia,\n rightMedia,\n trustedBy,\n className,\n}: SalesAiHeroProps) {\n return (\n \n
\n {/* ── announcement pill ─────────────────────────── */}\n {announcement && (\n
\n \n
\n )}\n\n {/* ── title ─────────────────────────────────────── */}\n \n {title}\n \n\n {/* ── description ───────────────────────────────── */}\n {description && (\n

\n {description}\n

\n )}\n\n {/* ── media row ─────────────────────────────────── */}\n
\n \n {leftMedia}\n \n \n {rightMedia}\n \n
\n\n {/* ── trusted-by ────────────────────────────────── */}\n {trustedBy && (\n
\n
\n
\n

\n {trustedBy.prefix ?? \"Trusted By \"}\n {trustedBy.highlight && (\n \n {trustedBy.highlight}\n \n )}\n {trustedBy.suffix}\n

\n
\n
\n\n {trustedBy.logos.length > 0 && (\n
\n {trustedBy.logos.map((item, idx) => (\n \n
\n {item.href ? (\n \n \n \n ) : (\n \n )}\n
\n {idx < trustedBy.logos.length - 1 && (\n \n )}\n
\n ))}\n
\n )}\n
\n )}\n
\n \n );\n}\n\nexport default SalesAiHero;\n", "type": "registry:ui", "target": "components/ruixen/sales-ai-hero.tsx" } ] }