{ "name": "pricing-card-two", "type": "registry:ui", "registryDependencies": [], "dependencies": [], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "pricing-card-two.tsx", "content": "'use client';\n\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\n\ntype AnchorOrButton =\n | ({\n href: string;\n onClick?: never;\n } & React.AnchorHTMLAttributes)\n | ({\n href?: undefined;\n onClick?: React.MouseEventHandler;\n } & React.ButtonHTMLAttributes);\n\ntype Tone = 'pink' | 'blue' | 'amber' | 'emerald' | 'zinc';\n\nexport type PricingFeature = {\n label: React.ReactNode;\n included?: boolean; // default true\n};\n\nexport type PricingCardTwoProps = {\n icon?: React.ReactNode;\n name: string;\n subtitle?: string;\n\n price: number | string;\n currency?: string;\n periodLabel?: string;\n\n features: PricingFeature[];\n\n cta?: AnchorOrButton & { label?: string; 'aria-label'?: string };\n\n /** Visuals */\n tone?: Tone;\n className?: string;\n\n /** Slot overrides */\n iconClassName?: string;\n nameClassName?: string;\n subtitleClassName?: string;\n priceClassName?: string;\n periodClassName?: string;\n featureListClassName?: string;\n featureItemClassName?: string;\n ctaClassName?: string;\n};\n\nconst toneMap: Record<\n Tone,\n {\n /** gradient frame */\n frame: string;\n /** accent text (icon + price) */\n accent: string;\n /** CTA */\n btn: string;\n btnHover: string;\n /** tick / cross badges */\n okBg: string;\n okRing: string;\n okFg: string;\n noBg: string;\n noRing: string;\n noFg: string;\n }\n> = {\n pink: {\n frame: 'bg-gradient-to-b from-pink-400 to-fuchsia-600',\n accent: 'text-pink-600',\n btn: 'bg-pink-600 text-white',\n btnHover: 'hover:bg-pink-700',\n okBg: 'bg-pink-50 dark:bg-pink-950/40',\n okRing: 'ring-pink-200 dark:ring-pink-900/50',\n okFg: 'text-pink-600 dark:text-pink-400',\n noBg: 'bg-amber-50 dark:bg-amber-950/40',\n noRing: 'ring-amber-200 dark:ring-amber-900/40',\n noFg: 'text-amber-500',\n },\n blue: {\n frame: 'bg-gradient-to-b from-blue-400 to-indigo-600',\n accent: 'text-blue-600',\n btn: 'bg-blue-600 text-white',\n btnHover: 'hover:bg-blue-700',\n okBg: 'bg-blue-50 dark:bg-blue-950/40',\n okRing: 'ring-blue-200 dark:ring-blue-900/50',\n okFg: 'text-blue-600 dark:text-blue-400',\n noBg: 'bg-amber-50 dark:bg-amber-950/40',\n noRing: 'ring-amber-200 dark:ring-amber-900/40',\n noFg: 'text-amber-500',\n },\n amber: {\n frame: 'bg-gradient-to-b from-amber-400 to-orange-500',\n accent: 'text-amber-600',\n btn: 'bg-amber-500 text-white',\n btnHover: 'hover:bg-amber-600',\n okBg: 'bg-amber-50 dark:bg-amber-950/40',\n okRing: 'ring-amber-200 dark:ring-amber-900/50',\n okFg: 'text-amber-600 dark:text-amber-400',\n noBg: 'bg-rose-50 dark:bg-rose-950/40',\n noRing: 'ring-rose-200 dark:ring-rose-900/40',\n noFg: 'text-rose-500',\n },\n emerald: {\n frame: 'bg-gradient-to-b from-emerald-400 to-teal-600',\n accent: 'text-emerald-600',\n btn: 'bg-emerald-600 text-white',\n btnHover: 'hover:bg-emerald-700',\n okBg: 'bg-emerald-50 dark:bg-emerald-950/40',\n okRing: 'ring-emerald-200 dark:ring-emerald-900/50',\n okFg: 'text-emerald-600 dark:text-emerald-400',\n noBg: 'bg-amber-50 dark:bg-amber-950/40',\n noRing: 'ring-amber-200 dark:ring-amber-900/40',\n noFg: 'text-amber-500',\n },\n zinc: {\n frame: 'bg-gradient-to-b from-zinc-300 to-zinc-500',\n accent: 'text-zinc-900 dark:text-zinc-50',\n btn: 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900',\n btnHover: 'hover:bg-black/80 dark:hover:bg-white',\n okBg: 'bg-zinc-100 dark:bg-zinc-800/60',\n okRing: 'ring-zinc-200 dark:ring-zinc-700',\n okFg: 'text-zinc-700 dark:text-zinc-300',\n noBg: 'bg-amber-50 dark:bg-amber-950/40',\n noRing: 'ring-amber-200 dark:ring-amber-900/40',\n noFg: 'text-amber-500',\n },\n};\n\nfunction priceParts(price: number | string, currency?: string) {\n if (typeof price === 'number')\n return { main: `${currency ?? '$'}${price}`, raw: price };\n return { main: price, raw: price };\n}\n\nexport default function PricingCardTwo({\n icon,\n name,\n subtitle = 'the starter choise',\n price,\n currency = '$',\n periodLabel = '/month',\n features,\n cta,\n tone = 'blue',\n className,\n iconClassName,\n nameClassName,\n subtitleClassName,\n priceClassName,\n periodClassName,\n featureListClassName,\n featureItemClassName,\n ctaClassName,\n}: PricingCardTwoProps) {\n const t = toneMap[tone];\n const pp = priceParts(price, currency);\n\n return (\n
\n {/* colored frame */}\n
\n {/* card surface */}\n
\n {/* icon */}\n {icon && (\n \n {icon}\n
\n )}\n\n {/* title + subtitle */}\n \n {name}\n \n {subtitle && (\n \n {subtitle}\n

\n )}\n\n {/* price */}\n
\n {pp.main}\n \n {periodLabel}\n \n
\n\n {/* features */}\n
    \n {features.map((f, i) => {\n const ok = f.included !== false;\n return (\n \n \n {ok ? (\n \n \n \n ) : (\n \n \n \n )}\n \n {f.label}\n \n );\n })}\n
\n\n {/* CTA */}\n {cta && (\n <>\n {cta.href ? (\n \n {cta.label ?? 'Choose Plan'}\n \n ) : (\n \n {cta.label ?? 'Choose Plan'}\n \n )}\n \n )}\n
\n \n
\n );\n}\n", "type": "registry:ui" } ] }