Pricing Tier Comparison Matrix
blockmarketingComprehensive pricing tier comparison matrix with billing cycle discount toggles, prominent recommended plan, and granular capability matrix table.
Installation
$pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/pricing-tier-comparison-matrix.json$npx shadcn-vue@latest add https://uipkge.dev/r/vue/pricing-tier-comparison-matrix.json$yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/pricing-tier-comparison-matrix.json$bunx shadcn-vue@latest add https://uipkge.dev/r/vue/pricing-tier-comparison-matrix.jsonNamed registry:
npx shadcn-vue@latest add @uipkge/pricing-tier-comparison-matrixInstalls to:app/components/blocks/Variants
Loading interactive previews…
Loading interactive previews…
Schema
Type aliases exported from this item's source. Use these to shape the data you pass in.
Planinterface Plan {
id: string
name: string
description: string
monthlyPrice: number
annualPrice: number
highlight: boolean
badge?: string
ctaText: string
ctaVariant: 'default' | 'outline' | 'secondary'
}FeatureComparisonRowinterface FeatureComparisonRow {
category: string
features: {
name: string
tooltip: string
community: boolean | string
pro: boolean | string
enterprise: boolean | string
}[]
}npm dependencies
Files installed (1)
app/components/blocks/PricingTierComparisonMatrix.vue11.3 kB
<script setup lang="ts"> import { ref } from 'vue' import { ArrowRight, Check, Minus, ShieldCheck } from 'lucide-vue-next' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card } from '@/components/ui/card' type BillingCycle = 'monthly' | 'annual' const billing = ref<BillingCycle>('annual') interface Plan { id: string name: string description: string monthlyPrice: number annualPrice: number highlight: boolean badge?: string ctaText: string ctaVariant: 'default' | 'outline' | 'secondary' } const plans: Plan[] = [ { id: 'community', name: 'Community OSS', description: 'For indie hackers and developers building open source products.', monthlyPrice: 0, annualPrice: 0, highlight: false, ctaText: 'Start Building Free', ctaVariant: 'outline', }, { id: 'pro', name: 'Pro Team', description: 'For growing startup engineering teams that require high velocity.', monthlyPrice: 29, annualPrice: 24, highlight: true, badge: 'Most Popular', ctaText: 'Claim Pro License', ctaVariant: 'default', }, { id: 'enterprise', name: 'Enterprise Scale', description: 'Dedicated registry syncing, SSO, SOC2 compliance audits, and SLA.', monthlyPrice: 119, annualPrice: 99, highlight: false, ctaText: 'Talk to Sales', ctaVariant: 'outline', }, ] interface FeatureComparisonRow { category: string features: { name: string tooltip: string community: boolean | string pro: boolean | string enterprise: boolean | string }[] } const comparisonData: FeatureComparisonRow[] = [ { category: 'Registry & Core Primitives', features: [ { name: 'Full AST Component Source Access', tooltip: 'Raw SFC and TSX source files copied directly into your repository.', community: true, pro: true, enterprise: true, }, { name: 'Dual-Framework Parity (Vue + React)', tooltip: 'Identical DOM semantics and CVA tokens across both ecosystems.', community: true, pro: true, enterprise: true, }, { name: 'Curated Marketing & SaaS Blocks', tooltip: 'Access to 450+ production-grade unbundled layout blocks.', community: '100+ Blocks', pro: 'All 450+ Blocks', enterprise: 'All Blocks + Custom', }, { name: 'Tailwind CSS v4 OKLCH Token System', tooltip: 'Hardware-calibrated color spaces and spring curves.', community: true, pro: true, enterprise: true, }, ], }, { category: 'Enterprise & Security Compliance', features: [ { name: 'Private Registry Mirroring', tooltip: 'Host your organization’s customized internal registry behind a firewall.', community: false, pro: '1 Private Repo', enterprise: 'Unlimited Private Hubs', }, { name: 'SOC2 & ISO 27001 Audit Packs', tooltip: 'Pre-certified security documentation and architecture proofs.', community: false, pro: false, enterprise: true, }, { name: 'Guaranteed 99.99% Registry CDN SLA', tooltip: 'Global multi-region edge distribution uptime guarantee.', community: false, pro: '99.9% SLA', enterprise: '99.99% High Availability', }, { name: 'Dedicated Design Engineering Support', tooltip: 'Direct Slack / Discord channel with core design system maintainers.', community: false, pro: 'Priority Email', enterprise: 'Dedicated Slack Channel', }, ], }, ] </script> <template> <section data-slot="pricing-tier-comparison-matrix" class="bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8" > <div class="mx-auto max-w-7xl space-y-16"> <!-- Header --> <div class="mx-auto max-w-3xl space-y-4 text-center"> <Badge variant="secondary" class="gap-1.5 px-3 py-1 font-mono text-xs shadow-xs"> <ShieldCheck class="text-primary size-3.5" /> Predictable Pricing </Badge> <h2 class="text-foreground text-3xl font-bold tracking-tight sm:text-4xl"> Zero seat taxes. Own your source code forever. </h2> <p class="text-muted-foreground text-base"> Choose the tier that fits your engineering team's delivery scale and compliance needs. </p> <!-- Billing Toggle --> <div class="flex items-center justify-center gap-3 pt-4"> <span class="font-mono text-xs" :class="billing === 'monthly' ? 'text-foreground font-bold' : 'text-muted-foreground'" > Monthly </span> <div class="border-border bg-card relative flex items-center rounded-full border p-1"> <button type="button" class="relative z-10 rounded-full px-3 py-1 font-mono text-xs transition-colors" :class=" billing === 'monthly' ? 'bg-primary text-primary-foreground font-semibold shadow-xs' : 'text-muted-foreground' " @click="billing = 'monthly'" > Monthly </button> <button type="button" class="relative z-10 flex items-center gap-1.5 rounded-full px-3 py-1 font-mono text-xs transition-colors" :class=" billing === 'annual' ? 'bg-primary text-primary-foreground font-semibold shadow-xs' : 'text-muted-foreground' " @click="billing = 'annual'" > <span>Annual</span> <span class="bg-success rounded-full px-1.5 py-0.5 text-xs font-bold text-white">Save 20%</span> </button> </div> </div> </div> <!-- Pricing Plan Cards Grid (3 Columns) --> <div class="grid grid-cols-1 items-stretch gap-6 md:grid-cols-3"> <Card v-for="plan in plans" :key="plan.id" class="border-border bg-card relative flex flex-col justify-between space-y-6 rounded-2xl p-6 text-left shadow-xl transition-colors sm:p-8" :class=" plan.highlight ? 'border-primary/80 ring-primary/20 scale-[1.02] shadow-sm ring-2' : 'hover:border-border/80' " > <!-- Top Badge --> <div v-if="plan.badge" class="absolute -top-3 left-1/2 -translate-x-1/2"> <Badge class="px-3 py-0.5 font-mono text-xs tracking-wider uppercase shadow-md"> {{ plan.badge }} </Badge> </div> <div class="space-y-4"> <div> <h3 class="text-foreground font-mono text-xl font-bold">{{ plan.name }}</h3> <p class="text-muted-foreground mt-1 min-h-[36px] text-xs">{{ plan.description }}</p> </div> <!-- Price display --> <div class="flex items-baseline gap-1.5 font-mono"> <span class="text-foreground text-4xl font-bold"> ${{ billing === 'annual' ? plan.annualPrice : plan.monthlyPrice }} </span> <span class="text-muted-foreground text-xs">/ month</span> </div> <p class="text-muted-foreground font-mono text-xs"> {{ billing === 'annual' && plan.annualPrice > 0 ? 'Billed annually ($' + plan.annualPrice * 12 + '/yr)' : 'Billed monthly' }} </p> </div> <Button :variant="plan.ctaVariant" class="h-10 w-full gap-1.5 font-mono text-xs shadow-xs"> <span>{{ plan.ctaText }}</span> <ArrowRight class="size-3.5" /> </Button> </Card> </div> <!-- Deep Feature Comparison Matrix Table --> <div class="space-y-6"> <div class="text-center"> <h3 class="text-foreground font-mono text-xl font-bold">Detailed Feature Comparison</h3> <p class="text-muted-foreground mt-1 text-xs">Full granular matrix of capabilities and entitlements.</p> </div> <Card class="border-border bg-card overflow-hidden rounded-2xl text-left shadow-sm"> <div class="overflow-x-auto"> <table class="w-full border-collapse text-left text-xs"> <thead> <tr class="border-border bg-muted/40 text-muted-foreground border-b font-mono"> <th class="w-1/2 p-4 font-semibold">Capability</th> <th class="p-4 text-center font-semibold">Community</th> <th class="text-primary p-4 text-center font-bold font-semibold">Pro Team</th> <th class="p-4 text-center font-semibold">Enterprise</th> </tr> </thead> <tbody> <template v-for="(section, sIdx) in comparisonData" :key="sIdx"> <tr class="bg-muted/20 border-border/80 border-b"> <td colspan="4" class="text-muted-foreground p-3 px-4 font-mono text-xs font-bold tracking-wider uppercase" > {{ section.category }} </td> </tr> <tr v-for="(row, rIdx) in section.features" :key="rIdx" class="border-border/60 hover:bg-muted/10 border-b transition-colors" > <td class="p-4"> <div class="text-foreground font-medium">{{ row.name }}</div> <div class="text-muted-foreground mt-0.5 text-xs">{{ row.tooltip }}</div> </td> <td class="p-4 text-center font-mono"> <template v-if="typeof row.community === 'boolean'"> <Check v-if="row.community" class="text-success mx-auto size-4" /> <Minus v-else class="text-muted-foreground/40 mx-auto size-4" /> </template> <span v-else class="text-muted-foreground">{{ row.community }}</span> </td> <td class="p-4 text-center font-mono font-semibold"> <template v-if="typeof row.pro === 'boolean'"> <Check v-if="row.pro" class="text-success mx-auto size-4" /> <Minus v-else class="text-muted-foreground/40 mx-auto size-4" /> </template> <span v-else class="text-primary">{{ row.pro }}</span> </td> <td class="p-4 text-center font-mono"> <template v-if="typeof row.enterprise === 'boolean'"> <Check v-if="row.enterprise" class="text-success mx-auto size-4" /> <Minus v-else class="text-muted-foreground/40 mx-auto size-4" /> </template> <span v-else class="text-foreground font-semibold">{{ row.enterprise }}</span> </td> </tr> </template> </tbody> </table> </div> </Card> </div> </div> </section> </template>
Raw manifest:https://uipkge.dev/r/vue/pricing-tier-comparison-matrix.json