{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "qr-code",
  "type": "registry:component",
  "title": "QR Code",
  "description": "Styled, accessible QR code with download buttons: colors, gradients, patterns, logos and frame templates.",
  "author": "bucharitesh <https://qrdx.dev>",
  "dependencies": ["qrdx", "lucide-react"],
  "registryDependencies": ["button"],
  "files": [
    {
      "path": "registry/qrdx/qr-code.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport { Download } from \"lucide-react\";\nimport {\n  type BodyPattern,\n  type ColorConfig,\n  type CornerEyeDotPattern,\n  type CornerEyePattern,\n  type DownloadFormat,\n  downloadQRCode,\n  type ErrorLevel,\n  getQRData,\n  QRCode as QRCodeImage,\n} from \"qrdx\";\nimport { type ComponentProps, type ReactNode, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\nexport interface QrCodeProps\n  extends Omit<ComponentProps<\"figure\">, \"children\"> {\n  /** Text or URL to encode. */\n  value: string;\n  /**\n   * Rendered width and height in pixels.\n   * @default 200\n   */\n  size?: number;\n  /**\n   * Module color: any CSS color or a qrdx gradient.\n   * @default \"#000000\"\n   */\n  fgColor?: ColorConfig;\n  /**\n   * Background color: any CSS color or a qrdx gradient.\n   * @default \"#FFFFFF\"\n   */\n  bgColor?: ColorConfig;\n  /** Corner eye color. Defaults to `fgColor`. */\n  eyeColor?: ColorConfig;\n  /** Color of the dot inside each corner eye. Defaults to `fgColor`. */\n  dotColor?: ColorConfig;\n  /**\n   * Shape of the data modules.\n   * @default \"circle\"\n   */\n  bodyPattern?: BodyPattern;\n  /**\n   * Shape of the corner eye frames.\n   * @default \"gear\"\n   */\n  cornerEyePattern?: CornerEyePattern;\n  /**\n   * Shape of the dot inside each corner eye.\n   * @default \"circle\"\n   */\n  cornerEyeDotPattern?: CornerEyeDotPattern;\n  /**\n   * Error correction level. Use \"H\" with a logo.\n   * @default \"Q\"\n   */\n  level?: ErrorLevel;\n  /**\n   * Quiet zone around the code, in modules.\n   * @default 2\n   */\n  margin?: number;\n  /** qrdx frame template id, e.g. \"Arrow\" or \"StandardBox\". */\n  templateId?: string;\n  /** Center logo: a data URL or an image URL served with CORS headers. */\n  logo?: string;\n  /** Accessible name. Defaults to \"QR code: <value>\". */\n  label?: string;\n  /** Visible caption under the code. */\n  caption?: ReactNode;\n  /**\n   * Download buttons to show. Pass `[]` to hide them. \"pdf\" needs the\n   * optional `jspdf` package.\n   * @default [\"png\", \"svg\"]\n   */\n  downloadFormats?: DownloadFormat[];\n  /**\n   * Width and height of downloaded files in pixels (50 to 5000).\n   * @default 1024\n   */\n  downloadSize?: number;\n  /**\n   * Download file name without extension.\n   * @default \"qr-code\"\n   */\n  filename?: string;\n}\n\nexport function QrCode({\n  value,\n  size = 200,\n  fgColor,\n  bgColor,\n  eyeColor,\n  dotColor,\n  bodyPattern,\n  cornerEyePattern,\n  cornerEyeDotPattern,\n  level,\n  margin = 2,\n  templateId,\n  logo,\n  label,\n  caption,\n  downloadFormats = [\"png\", \"svg\"],\n  downloadSize = 1024,\n  filename = \"qr-code\",\n  className,\n  ...props\n}: QrCodeProps) {\n  const [pending, setPending] = useState<DownloadFormat | null>(null);\n  const [status, setStatus] = useState(\"\");\n  const [error, setError] = useState(\"\");\n\n  const style = {\n    fgColor,\n    bgColor,\n    eyeColor,\n    dotColor,\n    bodyPattern,\n    cornerEyePattern,\n    cornerEyeDotPattern,\n    level,\n    margin,\n    templateId,\n  };\n\n  async function download(format: DownloadFormat) {\n    setPending(format);\n    setStatus(\"\");\n    setError(\"\");\n    try {\n      // getQRData lays the logo out for 1024px; scale it to the file size.\n      const data = getQRData({ ...style, value, logo });\n      const ratio = downloadSize / data.size;\n      await downloadQRCode(\n        {\n          ...data,\n          size: downloadSize,\n          imageSettings: data.imageSettings && {\n            ...data.imageSettings,\n            width: data.imageSettings.width * ratio,\n            height: data.imageSettings.height * ratio,\n          },\n        },\n        {\n          format,\n          size: { width: downloadSize, height: downloadSize },\n          filename: `${filename}.${format}`,\n        },\n      );\n      setStatus(`Downloaded ${filename}.${format}`);\n    } catch (cause) {\n      setError(\n        cause instanceof Error ? cause.message : \"Could not download the file.\",\n      );\n    } finally {\n      setPending(null);\n    }\n  }\n\n  return (\n    <figure\n      className={cn(\"inline-flex flex-col items-center gap-3\", className)}\n      data-slot=\"qr-code\"\n      {...props}\n    >\n      <div\n        aria-label={label ?? `QR code: ${value}`}\n        className=\"overflow-hidden rounded-[10px]\"\n        role=\"img\"\n        style={{ width: size, height: size }}\n      >\n        <QRCodeImage {...style} logo={logo} size={size} value={value} />\n      </div>\n      {caption ? (\n        <figcaption className=\"text-center text-muted-foreground text-sm\">\n          {caption}\n        </figcaption>\n      ) : null}\n      {downloadFormats.length > 0 ? (\n        <fieldset className=\"flex flex-wrap justify-center gap-2\">\n          <legend className=\"sr-only\">Download QR code</legend>\n          {downloadFormats.map((format) => (\n            <Button\n              aria-busy={pending === format}\n              disabled={pending !== null}\n              key={format}\n              onClick={() => download(format)}\n              size=\"sm\"\n              type=\"button\"\n              variant=\"outline\"\n            >\n              <Download aria-hidden=\"true\" />\n              {format.toUpperCase()}\n            </Button>\n          ))}\n        </fieldset>\n      ) : null}\n      {error ? (\n        <p\n          className=\"max-w-xs text-center text-destructive text-xs\"\n          role=\"alert\"\n        >\n          {error}\n        </p>\n      ) : null}\n      <p aria-live=\"polite\" className=\"sr-only\">\n        {status}\n      </p>\n    </figure>\n  );\n}\n"
    }
  ],
  "docs": "Import it with `import { QrCode } from \"@/components/qr-code\"`. Props and examples: https://qrdx.dev/docs/components/qr-code",
  "categories": ["qr-code"]
}
