{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "pricing",
  "title": "Pricing",
  "description": "Flexible pricing component with customizable features and options.",
  "files": [
    {
      "path": "registry/ecommerce/pricing/index.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { Switch } from '@/components/systaliko-ui/shadcn/switch';\nimport { cva, VariantProps } from 'class-variance-authority';\nimport { CheckIcon, PlusIcon, XIcon } from 'lucide-react';\nimport React from 'react';\ninterface Price {\n  amount: number;\n  currency: string;\n  interval?: 'month' | 'year' | 'week' | 'day' | 'one-time';\n  discount?: number;\n}\n\ninterface PriceFormatOptions {\n  locale?: string;\n  showCurrency?: boolean;\n  showDecimals?: boolean;\n  compact?: boolean;\n  notation?: 'standard' | 'compact' | 'scientific' | 'engineering';\n}\n\nfunction formatPrice(price: Price, options: PriceFormatOptions = {}): string {\n  const {\n    locale = 'en-US',\n    showCurrency = true,\n    showDecimals = true,\n    compact = false,\n    notation = 'standard',\n  } = options;\n\n  const formatter = new Intl.NumberFormat(locale, {\n    style: showCurrency ? 'currency' : 'decimal',\n    currency: price.currency,\n    minimumFractionDigits: showDecimals ? 2 : 0,\n    maximumFractionDigits: showDecimals ? 2 : 0,\n    notation: compact ? 'compact' : notation,\n  });\n\n  return formatter.format(price.amount);\n}\n\nfunction calculateFinalPrice(price: Price): number {\n  if (price.discount) {\n    return price.amount * (1 - price.discount / 100);\n  }\n  return price.amount;\n}\n\nexport interface PriceProps extends React.HTMLAttributes<HTMLDivElement> {\n  price: Price;\n  options?: PriceFormatOptions;\n  animated?: boolean;\n}\n\nexport function Price({\n  price,\n  options,\n  className,\n  children,\n  animated = false,\n  ...props\n}: PriceProps) {\n  const finalPrice = calculateFinalPrice(price);\n  const [displayValue, setDisplayValue] = React.useState(finalPrice);\n  const [isAnimating, setIsAnimating] = React.useState(false);\n  const prevValueRef = React.useRef(finalPrice);\n\n  React.useEffect(() => {\n    if (animated && prevValueRef.current !== finalPrice) {\n      setIsAnimating(true);\n      const duration = 400;\n      const steps = 20;\n      const stepDuration = duration / steps;\n      const diff = finalPrice - prevValueRef.current;\n      const stepValue = diff / steps;\n\n      let currentStep = 0;\n      const timer = setInterval(() => {\n        currentStep++;\n        if (currentStep === steps) {\n          setDisplayValue(finalPrice);\n          setIsAnimating(false);\n          clearInterval(timer);\n        } else {\n          setDisplayValue(prevValueRef.current + stepValue * currentStep);\n        }\n      }, stepDuration);\n\n      prevValueRef.current = finalPrice;\n      return () => clearInterval(timer);\n    } else if (!animated) {\n      setDisplayValue(finalPrice);\n    }\n  }, [finalPrice, animated]);\n\n  const displayPrice = animated ? displayValue : finalPrice;\n\n  return (\n    <div className={cn('tabular-nums', className)} {...props}>\n      {price.discount ? (\n        <div className=\"flex items-baseline gap-2\">\n          <span className=\"text-muted-foreground/60 line-through text-sm\">\n            {formatPrice(price, options)}\n          </span>\n          <span\n            className={cn(\n              'transition-transform duration-300',\n              isAnimating && 'scale-105',\n            )}\n          >\n            {formatPrice({ ...price, amount: displayPrice }, options)}\n          </span>\n        </div>\n      ) : (\n        <span\n          className={cn(\n            'transition-transform duration-300',\n            isAnimating && 'scale-105',\n          )}\n        >\n          {formatPrice({ ...price, amount: displayPrice }, options)}\n        </span>\n      )}\n      {children}\n    </div>\n  );\n}\n\nconst pricingCardVariants = cva(\n  'group relative border-2 p-6 flex flex-col space-y-6 bg-card transition-all duration-300 hover:shadow-[0_8px_40px_-12px_rgba(0,0,0,0.1)]',\n  {\n    variants: {\n      variant: {\n        default: 'border-border/20 hover:border-border/50 ',\n        featured: 'border-primary/50 z-2 hover:border-primary',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n);\ntype PricingInterval = 'monthly' | 'yearly';\ninterface PricingDuration {\n  monthly: number;\n  yearly: number;\n}\n\ninterface PricingContextValue {\n  interval: PricingInterval;\n  toggleInterval: () => void;\n  savings?: number;\n}\nconst PricingContext = React.createContext<PricingContextValue | undefined>(\n  undefined,\n);\nfunction usePricingContext() {\n  const context = React.useContext(PricingContext);\n  if (context === undefined) {\n    throw new Error('usePricingContext must be used within a PricingProvider');\n  }\n  return context;\n}\nexport function calculateYearlySavings(pricing: PricingDuration): number {\n  const yearlyTotal = pricing.monthly * 12;\n  const savings = yearlyTotal - pricing.yearly;\n  return Math.round((savings / yearlyTotal) * 100);\n}\n\nexport function Pricing({ ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  const [interval, setInterval] = React.useState<PricingInterval>('monthly');\n\n  const toggleInterval = () => {\n    setInterval((prevState) =>\n      prevState === 'monthly' ? 'yearly' : 'monthly',\n    );\n  };\n  return (\n    <PricingContext.Provider value={{ interval, toggleInterval }}>\n      <div {...props} />\n    </PricingContext.Provider>\n  );\n}\n\nexport function PricingCard({\n  className,\n  variant,\n  ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof pricingCardVariants>) {\n  return (\n    <div\n      className={cn(pricingCardVariants({ variant, className }))}\n      {...props}\n    />\n  );\n}\n\nexport function PricingFeature({\n  children,\n  className,\n  ...props\n}: React.HtmlHTMLAttributes<HTMLDivElement>) {\n  return (\n    <div className={cn('inline-flex items-center gap-3', className)} {...props}>\n      <div className=\"shrink-0 size-5 rounded-full inline-flex items-center justify-center\">\n        <CheckIcon className=\"size-3.5\" />\n      </div>\n      {children}\n    </div>\n  );\n}\nexport function PricingIncludesPrevious({\n  children,\n  className,\n  ...props\n}: React.HtmlHTMLAttributes<HTMLDivElement>) {\n  return (\n    <div className={cn('inline-flex items-center gap-3', className)} {...props}>\n      <div className=\"shrink-0 size-5 rounded-full inline-flex items-center justify-center\">\n        <PlusIcon className=\"size-3.5\" />\n      </div>\n      {children}\n    </div>\n  );\n}\nexport function PricingExclude({\n  children,\n  className,\n  ...props\n}: React.HtmlHTMLAttributes<HTMLDivElement>) {\n  return (\n    <div className={cn('inline-flex items-center gap-3', className)} {...props}>\n      <div className=\"shrink-0 size-5 rounded-full inline-flex items-center justify-center\">\n        <XIcon className=\"size-3.5\" />\n      </div>\n      {children}\n    </div>\n  );\n}\nexport function PricingPackage({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      className={cn('inline-flex items-center gap-1', className)}\n      {...props}\n    />\n  );\n}\nexport function PricingIntervalSwitch({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLButtonElement>) {\n  const { toggleInterval } = usePricingContext();\n  return (\n    <Switch\n      className={cn('inline-flex items-center gap-1', className)}\n      id=\"yearly-pricing\"\n      onCheckedChange={toggleInterval}\n      {...props}\n    />\n  );\n}\ninterface PricingValueProps extends React.HTMLAttributes<HTMLDivElement> {\n  monthlyValue: number;\n  yearlyValue: number;\n}\nexport function PricingValue({\n  monthlyValue,\n  yearlyValue,\n  className,\n  ...props\n}: PricingValueProps) {\n  const { interval } = usePricingContext();\n  const currentPrice = interval === 'monthly' ? monthlyValue : yearlyValue;\n\n  return (\n    <Price\n      {...props}\n      price={{\n        amount: currentPrice,\n        currency: 'USD',\n        interval: interval === 'monthly' ? 'month' : 'year',\n      }}\n      options={{ showDecimals: false }}\n      animated={true}\n      className={cn(\n        'inline-flex gap-1 tracking-tighter items-center text-4xl',\n        className,\n      )}\n    >\n      <span className=\"text-muted-foreground text-sm font-normal tracking-normal\">\n        /{interval === 'monthly' ? 'per month' : 'per year'}\n      </span>\n    </Price>\n  );\n}\n",
      "type": "registry:block",
      "target": "components/systaliko-ui/pricing.tsx"
    }
  ],
  "type": "registry:block"
}