{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "price",
  "files": [
    {
      "path": "src/components/ui/price/price.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div class={cn(\"flex flex-wrap items-center gap-x-2\", className)} {...props}>\n  <slot />\n</div>\n",
      "type": "registry:ui"
    },
    {
      "path": "src/components/ui/price/price-unit.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"span\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<span\n  class={cn(\"text-muted-foreground text-sm leading-tight\", className)}\n  {...props}\n>\n  / <slot />\n</span>\n",
      "type": "registry:ui"
    },
    {
      "path": "src/components/ui/price/price-value.astro",
      "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport {\n  formatPriceDiscount,\n  formatPriceValue,\n  type DiscountFormat,\n  type PriceValue,\n} from \"./format-price-value\"\n\ntype Props = VariantProps<typeof variants> &\n  HTMLAttributes<\"span\"> & {\n    price?: PriceValue\n    compareAt?: PriceValue\n    currency?: string\n    locale?: string\n    variant?: \"default\" | \"sale\"\n    discountFormat?: DiscountFormat\n    showDiscount?: boolean\n  }\n\nconst variants = cva(\"leading-tight\", {\n  variants: {\n    variant: {\n      default: \"text-foreground\",\n      sale: \"text-muted-foreground line-through\",\n    },\n  },\n})\n\nconst {\n  class: className,\n  price,\n  compareAt,\n  currency = \"USD\",\n  locale = \"en-US\",\n  variant = \"default\",\n  discountFormat = \"percentage\",\n  showDiscount = true,\n  ...props\n} = Astro.props\n\nconst formattedPrice = formatPriceValue(price, { currency, locale })\nconst formattedCompareAt = formatPriceValue(compareAt, { currency, locale })\nconst formattedDiscount =\n  showDiscount && compareAt\n    ? formatPriceDiscount(price, compareAt, {\n        currency,\n        locale,\n        format: discountFormat,\n      })\n    : null\nconst hasDiscount = Boolean(formattedCompareAt && formattedDiscount)\n---\n\n{\n  formattedPrice && (\n    <span\n      class={cn(\n        \"inline-flex flex-wrap items-center gap-x-2 gap-y-1\",\n        className\n      )}\n      {...props}\n    >\n      <span class={cn(variants({ variant }))}>{formattedPrice}</span>\n      {formattedCompareAt && (\n        <span class=\"text-muted-foreground text-sm leading-tight line-through\">\n          {formattedCompareAt}\n        </span>\n      )}\n      {hasDiscount && (\n        <span class=\"bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs font-medium\">\n          Save {formattedDiscount}\n        </span>\n      )}\n    </span>\n  )\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "src/components/ui/price/format-price-value.ts",
      "content": "export interface FormatPriceValueOptions {\n  currency: string\n  locale: string\n}\n\nexport type PriceValue = number | string | [number, number]\nexport type DiscountFormat = \"percentage\" | \"amount\"\n\nfunction formatCurrency(value: number, options: FormatPriceValueOptions) {\n  return new Intl.NumberFormat(options.locale, {\n    style: \"currency\",\n    currency: options.currency,\n  }).format(value)\n}\n\nexport function parseSinglePriceValue(price: PriceValue | null | undefined) {\n  if (price === null || price === undefined || price === \"\") {\n    return null\n  }\n\n  if (typeof price === \"number\") {\n    return Number.isFinite(price) ? price : null\n  }\n\n  if (Array.isArray(price)) {\n    return null\n  }\n\n  const numericValue = Number(price)\n\n  if (!Number.isNaN(numericValue) && Number.isFinite(numericValue)) {\n    return numericValue\n  }\n\n  return null\n}\n\nexport function formatPriceDiscount(\n  price: PriceValue | null | undefined,\n  compareAt: PriceValue | null | undefined,\n  options: FormatPriceValueOptions & {\n    format?: DiscountFormat\n  }\n) {\n  const currentPrice = parseSinglePriceValue(price)\n  const originalPrice = parseSinglePriceValue(compareAt)\n\n  if (\n    currentPrice === null ||\n    originalPrice === null ||\n    originalPrice <= currentPrice ||\n    originalPrice <= 0\n  ) {\n    return null\n  }\n\n  if (options.format === \"amount\") {\n    return formatCurrency(originalPrice - currentPrice, options)\n  }\n\n  return `${Math.round(((originalPrice - currentPrice) / originalPrice) * 100)}%`\n}\n\nexport function formatPriceValue(\n  price: PriceValue | null | undefined,\n  options: FormatPriceValueOptions\n) {\n  if (price === null || price === undefined || price === \"\") {\n    return null\n  }\n\n  if (typeof price === \"number\") {\n    return formatCurrency(price, options)\n  }\n\n  if (Array.isArray(price)) {\n    const [minimum, maximum] = price\n    return `${formatCurrency(minimum, options)} - ${formatCurrency(maximum, options)}`\n  }\n\n  const rangeMatch = price.match(\n    /^\\s*(-?\\d+(?:\\.\\d+)?)\\s*-\\s*(-?\\d+(?:\\.\\d+)?)\\s*$/\n  )\n\n  if (!rangeMatch) {\n    return price\n  }\n\n  const [, minimum, maximum] = rangeMatch\n  return `${formatCurrency(Number(minimum), options)} - ${formatCurrency(Number(maximum), options)}`\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "src/components/ui/price/index.ts",
      "content": "export { default as Price } from \"./price.astro\"\nexport { default as PriceUnit } from \"./price-unit.astro\"\nexport { default as PriceValue } from \"./price-value.astro\"\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}