1 estrella en GitHub = 1 componente nuevo.

Dar una estrella
Tablas de Precios

Pricing Comparison Matrix

Matriz detallada de comparación de precios con desglose exhaustivo de funcionalidades por plan.

pricingmatrixcomparisontogglesaas
Vista Previa en Vivo
Flexible Plans

Transparent Pricing for High-Growth Teams

Choose the right plan to scale your digital products. No hidden fees, cancel anytime.

MonthlyAnnual Save 20%
Starter

For indie developers and personal experiments.

$19/mo
Get Started
  • ✓ Up to 3 React Projects
  • ✓ All 200+ UI Components
  • ✓ Community Discord Support
  • ✕ Private Component Registry
  • ✕ Dedicated Priority Support
Enterprise

For organizations requiring custom SLAs and bespoke design systems.

$149/mo
Contact Sales
  • ✓ Everything in Pro Plan
  • ✓ Custom Component Engineering
  • ✓ 99.99% Guaranteed SLA
  • ✓ Dedicated Security Audit Support
  • ✓ Dedicated Account Manager

Uso

Copia y pega este código directamente en tu componente React:

tsx
import { PricingComparisonMatrix } from 'react-component-kit-ui/sections';

<PricingComparisonMatrix />

Instalación Manual

Si no estás usando el paquete npm, crea un archivo nuevo y pega el siguiente código: src/components/sections/PricingComparisonMatrix.tsx + PricingComparisonMatrix.css:

PricingComparisonMatrix.tsx
'use client';

import { useEffect, useRef } from 'react';
import './PricingComparisonMatrix.css';

/**
 * PricingComparisonMatrix — Full-page interactive pricing matrix with billing toggle and feature comparison.
 * 
 * @param {string} badge - Eyebrow badge text.
 * @param {string} title - Section main heading.
 * @param {string} subtitle - Supporting description text.
 */
export interface PricingComparisonMatrixProps {
  badge?: string;
  title?: string;
  subtitle?: string;
  className?: string;
}

export function PricingComparisonMatrix({
  badge = "Flexible Plans",
  title = "Transparent Pricing for High-Growth Teams",
  subtitle = "Choose the right plan to scale your digital products. No hidden fees, cancel anytime.",
  className = ""
}: PricingComparisonMatrixProps) {

  // Ported from the Astro <script>: runs once after mount (DOM logic kept as in the Astro kit).
  const mounted = useRef(false);
  useEffect(() => {
    if (mounted.current) return;
    mounted.current = true;
    const toggleBtn = document.getElementById('billingToggleBtn');
      const priceVals = document.querySelectorAll('.price-val');
    
      if (toggleBtn) {
        toggleBtn.addEventListener('click', () => {
          const isAnnual = toggleBtn.getAttribute('aria-checked') === 'true';
          const newState = !isAnnual;
          toggleBtn.setAttribute('aria-checked', String(newState));
    
          priceVals.forEach((el) => {
            const val = newState ? el.getAttribute('data-annual') : el.getAttribute('data-monthly');
            if (val) el.textContent = val;
          });
        });
      }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      <div className="cq-pricing-comparison-matrix-cq" data-rk-4ae18a="">
      <section className={`pricing-section ${className}`} aria-labelledby="pricing-title" data-rk-4ae18a="">
        <div className="pricing-bg" aria-hidden="true" data-rk-4ae18a="">
          <div className="pricing-glow" data-rk-4ae18a=""></div>
        </div>
      
        <div className="container" data-rk-4ae18a="">
          {/* Header */}
          <div className="section-header" data-rk-4ae18a="">
            {badge && <span className="section-badge" data-rk-4ae18a="">{badge}</span>}
            <h2 id="pricing-title" className="section-title" data-rk-4ae18a="">{title}</h2>
            <p className="section-subtitle" data-rk-4ae18a="">{subtitle}</p>
      
            {/* Interactive Billing Toggle */}
            <div className="billing-toggle-wrap" data-rk-4ae18a="">
              <span className="toggle-label" id="label-monthly" data-rk-4ae18a="">Monthly</span>
              <button type="button" className="billing-toggle" id="billingToggleBtn" role="switch" aria-checked="false" aria-label="Toggle annual billing" data-rk-4ae18a="">
                <span className="toggle-slider" data-rk-4ae18a=""></span>
              </button>
              <span className="toggle-label" id="label-annual" data-rk-4ae18a="">
                Annual <span className="discount-pill" data-rk-4ae18a="">Save 20%</span>
              </span>
            </div>
          </div>
      
          {/* Pricing Cards Grid */}
          <div className="pricing-cards" data-rk-4ae18a="">
            {/* 1. Starter Tier */}
            <div className="plan-card" data-rk-4ae18a="">
              <div className="plan-card__header" data-rk-4ae18a="">
                <span className="plan-name" data-rk-4ae18a="">Starter</span>
                <p className="plan-desc" data-rk-4ae18a="">For indie developers and personal experiments.</p>
                <div className="plan-price" data-rk-4ae18a="">
                  <span className="price-currency" data-rk-4ae18a="">$</span>
                  <span className="price-val" data-monthly="19" data-annual="15" data-rk-4ae18a="">19</span>
                  <span className="price-period" data-rk-4ae18a="">/mo</span>
                </div>
                <a href="#get-started" className="plan-btn plan-btn--ghost" data-rk-4ae18a="">Get Started</a>
              </div>
              <div className="plan-divider" data-rk-4ae18a=""></div>
              <ul className="plan-features" aria-label="Starter Plan Features" data-rk-4ae18a="">
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Up to 3 React Projects</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> All 200+ UI Components</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Community Discord Support</li>
                <li className="feature-disabled" data-rk-4ae18a=""><span className="cross-icon" data-rk-4ae18a="">✕</span> Private Component Registry</li>
                <li className="feature-disabled" data-rk-4ae18a=""><span className="cross-icon" data-rk-4ae18a="">✕</span> Dedicated Priority Support</li>
              </ul>
            </div>
      
            {/* 2. Pro Tier (Featured / Most Popular) */}
            <div className="plan-card plan-card--popular" data-rk-4ae18a="">
              <div className="popular-ribbon" data-rk-4ae18a="">Most Popular</div>
              <div className="plan-card__header" data-rk-4ae18a="">
                <span className="plan-name plan-name--popular" data-rk-4ae18a="">Professional</span>
                <p className="plan-desc" data-rk-4ae18a="">For fast-moving teams and production web applications.</p>
                <div className="plan-price" data-rk-4ae18a="">
                  <span className="price-currency" data-rk-4ae18a="">$</span>
                  <span className="price-val" data-monthly="49" data-annual="39" data-rk-4ae18a="">49</span>
                  <span className="price-period" data-rk-4ae18a="">/mo</span>
                </div>
                <a href="#get-pro" className="plan-btn plan-btn--primary" data-rk-4ae18a="">Start 14-Day Free Trial</a>
              </div>
              <div className="plan-divider" data-rk-4ae18a=""></div>
              <ul className="plan-features" aria-label="Professional Plan Features" data-rk-4ae18a="">
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Unlimited React Projects</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> All 200+ UI & 3D Components</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Figma UI Kit & Design Tokens</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Private NPM Team Access</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Priority Email & Chat Support</li>
              </ul>
            </div>
      
            {/* 3. Enterprise Tier */}
            <div className="plan-card" data-rk-4ae18a="">
              <div className="plan-card__header" data-rk-4ae18a="">
                <span className="plan-name" data-rk-4ae18a="">Enterprise</span>
                <p className="plan-desc" data-rk-4ae18a="">For organizations requiring custom SLAs and bespoke design systems.</p>
                <div className="plan-price" data-rk-4ae18a="">
                  <span className="price-currency" data-rk-4ae18a="">$</span>
                  <span className="price-val" data-monthly="149" data-annual="119" data-rk-4ae18a="">149</span>
                  <span className="price-period" data-rk-4ae18a="">/mo</span>
                </div>
                <a href="#contact-sales" className="plan-btn plan-btn--ghost" data-rk-4ae18a="">Contact Sales</a>
              </div>
              <div className="plan-divider" data-rk-4ae18a=""></div>
              <ul className="plan-features" aria-label="Enterprise Plan Features" data-rk-4ae18a="">
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Everything in Pro Plan</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Custom Component Engineering</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> 99.99% Guaranteed SLA</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Dedicated Security Audit Support</li>
                <li data-rk-4ae18a=""><span className="check-icon" data-rk-4ae18a="">✓</span> Dedicated Account Manager</li>
              </ul>
            </div>
          </div>
      
          {/* Money-back guarantee footer note */}
          <div className="pricing-footer" data-rk-4ae18a="">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="guarantee-icon" data-rk-4ae18a=""><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" data-rk-4ae18a="" /><path d="m9 12 2 2 4-4" data-rk-4ae18a="" /></svg>
            <span data-rk-4ae18a="">30-Day unconditional money-back guarantee. No questions asked.</span>
          </div>
        </div>
      </section>
      </div>
    </>
  );
}

export default PricingComparisonMatrix;
PricingComparisonMatrix.css
/* PricingComparisonMatrix — ported from astro-component-kit (sections/PricingComparisonMatrix.astro) */

.cq-pricing-comparison-matrix-cq:where([data-rk-4ae18a]) { container-type: inline-size; }
.pricing-section:where([data-rk-4ae18a]) {
  position: relative;
  padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
  background: var(--c-bg-primary, #030712);
  overflow: hidden;
}

.pricing-bg:where([data-rk-4ae18a]) {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

.pricing-glow:where([data-rk-4ae18a]) {
  position: absolute;
  top: 20%;
  left: 50%;
  transform: translateX(-50%);
  width: 600px;
  height: 500px;
  background: radial-gradient(circle, color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent), transparent 70%);
  filter: blur(100px);
}

.container:where([data-rk-4ae18a]) {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
}

.section-header:where([data-rk-4ae18a]) {
  text-align: center;
  max-width: 760px;
  margin: 0 auto var(--sp-12, 3rem);
}

.section-badge:where([data-rk-4ae18a]) {
  display: inline-flex;
  padding: 0.35rem 0.9rem;
  border-radius: 9999px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
  color: #eab308;
  border: 1px solid rgba(234, 179, 8, 0.25);
  margin-bottom: var(--sp-4, 1rem);
}

.section-title:where([data-rk-4ae18a]) {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 900;
  color: #fff;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 var(--sp-4, 1rem);
}

.section-subtitle:where([data-rk-4ae18a]) {
  font-size: 1.1rem;
  color: #94a3b8;
  line-height: 1.6;
  margin: 0 0 2rem;
}

/* Billing Toggle */
.billing-toggle-wrap:where([data-rk-4ae18a]) {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.4rem 0.8rem;
  background: rgba(15, 23, 42, 0.8);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
  border-radius: 9999px;
}

.toggle-label:where([data-rk-4ae18a]) {
  font-size: 0.88rem;
  font-weight: 600;
  color: #cbd5e1;
}

.discount-pill:where([data-rk-4ae18a]) {
  padding: 0.15rem 0.5rem;
  background: rgba(16, 185, 129, 0.15);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.3);
  border-radius: 9999px;
  font-size: 0.72rem;
  font-weight: 700;
}

.billing-toggle:where([data-rk-4ae18a]) {
  width: 44px;
  height: 24px;
  border-radius: 9999px;
  background: rgb(var(--ink-rgb, 255 255 255) / 0.15);
  border: none;
  position: relative;
  cursor: pointer;
  padding: 2px;
  transition: background 0.3s ease;
}

.toggle-slider:where([data-rk-4ae18a]) {
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.billing-toggle[aria-checked="true"]:where([data-rk-4ae18a]) {
  background: #eab308;
}

.billing-toggle[aria-checked="true"]:where([data-rk-4ae18a]) .toggle-slider:where([data-rk-4ae18a]) {
  transform: translateX(20px);
}

/* Pricing Cards */
.pricing-cards:where([data-rk-4ae18a]) {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  align-items: stretch;
}

.plan-card:where([data-rk-4ae18a]) {
  position: relative;
  background: rgba(15, 23, 42, 0.6);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
  border-radius: var(--r-xl, 20px);
  padding: 2.25rem 2rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.plan-card:hover:where([data-rk-4ae18a]) {
  transform: translateY(-4px);
  border-color: rgb(var(--ink-rgb, 255 255 255) / 0.18);
}

.plan-card--popular:where([data-rk-4ae18a]) {
  background: rgba(20, 25, 45, 0.85);
  border-color: rgba(234, 179, 8, 0.4);
  box-shadow: 0 0 30px -10px rgba(234, 179, 8, 0.25);
  transform: scale(1.03);
}

.plan-card--popular:hover:where([data-rk-4ae18a]) {
  transform: scale(1.03) translateY(-4px);
}

.popular-ribbon:where([data-rk-4ae18a]) {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.25rem 0.85rem;
  background: linear-gradient(135deg, #eab308, #ca8a04);
  color: #000;
  font-weight: 800;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: 9999px;
  box-shadow: 0 4px 12px rgba(234, 179, 8, 0.4);
}

.plan-name:where([data-rk-4ae18a]) {
  font-size: 1.25rem;
  font-weight: 800;
  color: #fff;
}

.plan-name--popular:where([data-rk-4ae18a]) {
  color: #facc15;
}

.plan-desc:where([data-rk-4ae18a]) {
  font-size: 0.88rem;
  color: #94a3b8;
  line-height: 1.5;
  margin: 0.4rem 0 1.5rem;
  min-height: 40px;
}

.plan-price:where([data-rk-4ae18a]) {
  display: flex;
  align-items: baseline;
  gap: 0.2rem;
  margin-bottom: 1.5rem;
}

.price-currency:where([data-rk-4ae18a]) {
  font-size: 1.5rem;
  font-weight: 700;
  color: #94a3b8;
}

.price-val:where([data-rk-4ae18a]) {
  font-size: 3rem;
  font-weight: 900;
  color: #fff;
  line-height: 1;
}

.price-period:where([data-rk-4ae18a]) {
  font-size: 0.9rem;
  color: #64748b;
}

.plan-btn:where([data-rk-4ae18a]) {
  display: block;
  text-align: center;
  padding: 0.85rem 1.5rem;
  border-radius: var(--r-md, 10px);
  font-size: 0.95rem;
  font-weight: 700;
  text-decoration: none;
  transition: all 0.25s ease;
}

.plan-btn--primary:where([data-rk-4ae18a]) {
  background: linear-gradient(135deg, #eab308, #d97706);
  color: #000;
  box-shadow: 0 4px 15px rgba(234, 179, 8, 0.3);
}

.plan-btn--primary:hover:where([data-rk-4ae18a]) {
  filter: brightness(1.1);
  box-shadow: 0 6px 20px rgba(234, 179, 8, 0.45);
}

.plan-btn--ghost:where([data-rk-4ae18a]) {
  background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
  color: #fff;
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12);
}

.plan-btn--ghost:hover:where([data-rk-4ae18a]) {
  background: rgb(var(--ink-rgb, 255 255 255) / 0.1);
  border-color: rgb(var(--ink-rgb, 255 255 255) / 0.25);
}

.plan-divider:where([data-rk-4ae18a]) {
  height: 1px;
  background: rgb(var(--ink-rgb, 255 255 255) / 0.08);
  margin: 1.5rem 0;
}

.plan-features:where([data-rk-4ae18a]) {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.plan-features:where([data-rk-4ae18a]) li:where([data-rk-4ae18a]) {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.88rem;
  color: #cbd5e1;
}

.check-icon:where([data-rk-4ae18a]) {
  color: #10b981;
  font-weight: 900;
}

.cross-icon:where([data-rk-4ae18a]) {
  color: #64748b;
  font-weight: 700;
}

.feature-disabled:where([data-rk-4ae18a]) {
  color: #64748b;
}

.pricing-footer:where([data-rk-4ae18a]) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  margin-top: 3rem;
  color: #94a3b8;
  font-size: 0.9rem;
}

.guarantee-icon:where([data-rk-4ae18a]) {
  color: #10b981;
}

@container (max-width: 960px) {
  .pricing-cards:where([data-rk-4ae18a]) {
    grid-template-columns: 1fr;
  }
  .plan-card--popular:where([data-rk-4ae18a]) {
    transform: none;
  }
  .plan-card--popular:hover:where([data-rk-4ae18a]) {
    transform: translateY(-4px);
  }
}