UIPackage
Menu

Framework

Change language

Boilerplate repo

Conversion CTA

blockmarketing

Interactive developer CTA section with live framework switcher, interactive CLI installation terminal, 1-click clipboard copy, and production guarantees.

Also available for Vue ->

Installation

$npx shadcn@latest add https://uipkge.dev/r/react/cta-01.json
Named registry:npx shadcn@latest add @uipkge-react/cta-01Installs to:components/blocks/

Variants

Loading interactive previews…

npm dependencies

Files installed (1)

  • components/blocks/Cta01.tsx8 kB
    'use client'
    
    import * as React from 'react'
    import { ArrowRight, Check, CheckCircle2, Code2, Copy, Download, Globe, Layers, ShieldCheck, Zap } from 'lucide-react'
    import { Badge } from '@/components/ui/badge'
    import { Button } from '@/components/ui/button'
    import { Card } from '@/components/ui/card'
    import { cn } from '@/lib/utils'
    
    type Framework = 'vue' | 'react' | 'nuxt'
    
    const installCommands: Record<Framework, { command: string; subtitle: string }> = {
      vue: {
        command: 'npx shadcn-vue@latest add https://uipkge.dev/r/vue/init.json -y',
        subtitle: 'Zero-config Vue 3.5 + Tailwind v4 + Reka UI primitives',
      },
      react: {
        command: 'npx shadcn@latest add https://uipkge.dev/r/react/init.json -y',
        subtitle: 'Production-ready React 19 + Radix primitives + CVA variants',
      },
      nuxt: {
        command: 'npx shadcn-vue@latest add https://uipkge.dev/r/vue/init.json -y',
        subtitle: 'Nuxt 4 auto-imports, SSR hydration-safe, unbundled ownership',
      },
    }
    
    export function Cta01() {
      const [activeFramework, setActiveFramework] = React.useState<Framework>('vue')
      const [copied, setCopied] = React.useState(false)
      const [pingMs] = React.useState(14)
    
      const copyCommand = () => {
        navigator.clipboard.writeText(installCommands[activeFramework].command)
        setCopied(true)
        setTimeout(() => setCopied(false), 2000)
      }
    
      return (
        <section
          data-slot="cta-01"
          className="bg-background border-border relative w-full overflow-hidden border-y py-16 lg:py-24"
        >
          <div className="mx-auto max-w-5xl space-y-10 px-4 text-center sm:px-6 lg:px-8">
            {/* Eyebrow Pill */}
            <div className="inline-flex items-center gap-2">
              <Badge
                variant="outline"
                className="border-primary/30 text-primary bg-primary/5 gap-1.5 px-3 py-1 font-mono text-xs tracking-wide uppercase"
              >
                <Zap className="size-3.5" />
                Unbundled Registry Distribution
              </Badge>
              <div className="text-muted-foreground flex items-center gap-1.5 font-mono text-xs">
                <span className="bg-success size-2 rounded-full" />
                <span>CDN Edge: {pingMs}ms P99</span>
              </div>
            </div>
    
            {/* Main Headline & Narrative */}
            <div className="mx-auto max-w-3xl space-y-4">
              <h2 className="text-foreground text-3xl leading-[1.15] font-bold tracking-tight sm:text-5xl">
                Own Your UI. No Semver Lock-in. Zero Bloat.
              </h2>
              <p className="text-muted-foreground text-base leading-relaxed sm:text-lg">
                The components are the product. Source files are copied directly into your workspace. Modify, compose, and
                refactor without fighting external package boundaries.
              </p>
            </div>
    
            {/* Interactive Developer Terminal Box */}
            <Card className="mx-auto max-w-2xl overflow-hidden border-zinc-800 bg-zinc-950 text-left text-zinc-100 shadow-sm">
              {/* Terminal Titlebar */}
              <div className="flex items-center justify-between border-b border-zinc-800 bg-zinc-900/70 px-4 py-3">
                <div className="flex items-center gap-2">
                  <div className="flex gap-1.5">
                    <div className="bg-destructive/80 size-3 rounded-full" />
                    <div className="bg-warning/80 size-3 rounded-full" />
                    <div className="bg-success/80 size-3 rounded-full" />
                  </div>
                  <span className="text-muted-foreground ml-2 font-mono text-xs">terminal — bootstrap workspace</span>
                </div>
    
                {/* Framework selector tabs */}
                <div className="flex items-center gap-1 rounded-md border border-zinc-800 bg-zinc-950 p-0.5">
                  {[
                    { id: 'vue', label: 'Vue 3.5' },
                    { id: 'react', label: 'React 19' },
                    { id: 'nuxt', label: 'Nuxt 4' },
                  ].map((fw) => (
                    <button
                      key={fw.id}
                      type="button"
                      className={cn(
                        'rounded px-2 py-0.5 font-mono text-xs transition-colors',
                        activeFramework === fw.id
                          ? 'bg-zinc-800 font-semibold text-zinc-100 shadow-xs'
                          : 'text-muted-foreground hover:text-zinc-200',
                      )}
                      onClick={() => setActiveFramework(fw.id as any)}
                    >
                      {fw.label}
                    </button>
                  ))}
                </div>
              </div>
    
              {/* Terminal Command Runner Body */}
              <div className="space-y-3 p-4 font-mono text-xs sm:p-5">
                <div className="flex items-center justify-between gap-3 rounded-lg border border-zinc-800 bg-zinc-900/90 p-3">
                  <div className="text-success flex items-center gap-2.5 overflow-x-auto select-all">
                    <span className="text-muted-foreground shrink-0">$</span>
                    <span className="whitespace-nowrap">{installCommands[activeFramework].command}</span>
                  </div>
                  <Button
                    size="sm"
                    variant="outline"
                    className="h-7 shrink-0 gap-1.5 border-zinc-700 bg-zinc-800 px-2.5 font-mono text-xs text-zinc-200 hover:bg-zinc-700"
                    onClick={copyCommand}
                  >
                    {copied ? <Check className="text-success size-3.5" /> : <Copy className="size-3.5" />}
                    <span>{copied ? 'Copied' : 'Copy'}</span>
                  </Button>
                </div>
    
                <p className="text-muted-foreground flex items-center gap-1.5 text-xs">
                  <span>{installCommands[activeFramework].subtitle}</span>
                </p>
              </div>
            </Card>
    
            {/* Primary Action Buttons */}
            <div className="flex flex-wrap items-center justify-center gap-3.5 pt-2">
              <Button size="lg" className="h-11 gap-2 px-6 font-semibold shadow-sm" onClick={copyCommand}>
                <Download className="size-4" />
                {copied ? 'Command Copied to Clipboard' : 'Install Components'}
              </Button>
              <Button size="lg" variant="outline" className="h-11 gap-2 px-6 font-semibold" asChild>
                <a href="https://github.com/uday-a/uipkge" target="_blank" rel="noreferrer">
                  <Code2 className="size-4" />
                  Explore Source Registry
                  <ArrowRight className="size-4" />
                </a>
              </Button>
            </div>
    
            {/* Trust Badges & Guarantees Grid */}
            <div className="border-border grid grid-cols-2 gap-4 border-t pt-8 text-left sm:grid-cols-4">
              <div className="flex items-start gap-2.5">
                <CheckCircle2 className="text-success mt-0.5 size-4 shrink-0" />
                <div>
                  <p className="text-foreground text-xs font-semibold">100% Code Ownership</p>
                  <p className="text-muted-foreground mt-0.5 text-xs">Files live in your repository</p>
                </div>
              </div>
              <div className="flex items-start gap-2.5">
                <ShieldCheck className="text-success mt-0.5 size-4 shrink-0" />
                <div>
                  <p className="text-foreground text-xs font-semibold">Zero Runtime Bloat</p>
                  <p className="text-muted-foreground mt-0.5 text-xs">No opaque wrapper dependencies</p>
                </div>
              </div>
              <div className="flex items-start gap-2.5">
                <Layers className="text-success mt-0.5 size-4 shrink-0" />
                <div>
                  <p className="text-foreground text-xs font-semibold">Tailwind CSS v4</p>
                  <p className="text-muted-foreground mt-0.5 text-xs">OKLCH color system & tokens</p>
                </div>
              </div>
              <div className="flex items-start gap-2.5">
                <Globe className="text-success mt-0.5 size-4 shrink-0" />
                <div>
                  <p className="text-foreground text-xs font-semibold">Dual Framework</p>
                  <p className="text-muted-foreground mt-0.5 text-xs">Strict Vue 3.5 & React 19 parity</p>
                </div>
              </div>
            </div>
          </div>
        </section>
      )
    }
    export default Cta01
    

Raw manifest:https://uipkge.dev/r/react/cta-01.json