{
  "generatedFrom": "qr-code.contract.json",
  "component": "QR code",
  "slug": "qr-code",
  "group": "Data Display",
  "tier": "composite-antd",
  "summary": "A scannable QR code — a join link, a deck URL, a Wi-Fi handoff — rendered through the shared QRCode.",
  "install": {
    "package": "@ahaslides-product/design",
    "registry": "https://npm.pkg.github.com",
    "scope": "@ahaslides-product",
    "auth": "Published to GitHub Packages — needs a GitHub token with read:packages. Configure the @ahaslides-product scope in .npmrc before installing.",
    "npmrc": "@ahaslides-product:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}   # a GitHub token with read:packages",
    "command": "npm i @ahaslides-product/design",
    "tokenLayer": "import '@ahaslides-product/design/tokens.css';",
    "import": "import '@ahaslides-product/design/qr-code-theme';",
    "element": null,
    "registers": null
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/qr-code/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/qr-code/qr-code.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/qr-code.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/qr-code.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — a CDN-React runnable page (React + antd loaded from a CDN, no build step) — React/Vue use the same shared-themed DataTable via your bundler. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "package": "antd",
      "major": 6
    },
    "vue": {
      "package": "ant-design-vue",
      "major": 4
    },
    "html": {
      "via": "cdn-react",
      "runnable": "paste-and-run — React + antd loaded from a CDN, no build step"
    }
  },
  "props": [
    {
      "name": "value",
      "type": "string",
      "default": "—",
      "desc": "The URL or text to encode"
    },
    {
      "name": "size",
      "type": "number",
      "default": "160",
      "desc": "Rendered pixel size"
    },
    {
      "name": "errorLevel",
      "type": "L | M | Q | H",
      "default": "M",
      "desc": "Error-correction level"
    },
    {
      "name": "status",
      "type": "active | expired | loading | scanned",
      "default": "active",
      "desc": "Render state — expired/scanned overlay a mask, loading shows a spinner"
    },
    {
      "name": "icon",
      "type": "string",
      "default": "—",
      "desc": "Optional centre logo URL"
    },
    {
      "name": "color",
      "type": "string",
      "default": "#1A1A1A",
      "desc": "Module colour (defaults to ink)"
    },
    {
      "name": "bgColor",
      "type": "string",
      "default": "#FFFFFF",
      "desc": "Module background (kept white per DS)"
    },
    {
      "name": "bordered",
      "type": "boolean",
      "default": "false",
      "desc": "antd's own 1px frame — off, so the .aha-qr container owns the DS frame"
    }
  ],
  "tokens": [
    "colorPrimary",
    "borderRadius",
    "colorText",
    "colorBorderSecondary"
  ],
  "spec": [
    {
      "label": "Modules",
      "value": "ink #1A1A1A on white #FFFFFF (color / bgColor)"
    },
    {
      "label": "Frame",
      "value": "1px #E3E3E3 border · radius 8 · padding 16"
    },
    {
      "label": "Size",
      "value": "160 default (set via size)"
    },
    {
      "label": "Error level",
      "value": "M default (L / M / Q / H)"
    },
    {
      "label": "Status",
      "value": "active default (active / expired / loading / scanned)"
    },
    {
      "label": "Bordered",
      "value": "off — the .aha-qr frame supplies the DS border (antd's own bordered defaults on)"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "QR code",
        "when": "a link people scan from a screen with a phone — a join code, a deck URL, an app download"
      },
      {
        "what": "a plain link",
        "when": "the destination is clicked, not scanned"
      }
    ],
    "note": "Keep the encoded value short so the code stays low-density and scans fast. Always show the human-readable link or join code beside it as a fallback.",
    "dsv3": "COVERED — antd v6 QRCode (ant-design-vue v4 in Vue), framed once by the shared qrCodeTheme; matrix: value · size (120/160/200) · errorLevel (L/M/Q/H) · status (active/expired/loading/scanned) · color + bgColor · icon · bordered (off — the .aha-qr container owns the DS frame). The DS keeps ink modules on white in a 1px radius-8 padding-16 frame; verified via Figma search_design_system against the DS V3 system-qr-code component (key 74513a3c66281fccc173cf04ebed74f404a7995e)."
  },
  "surfaces": [
    "audience",
    "editor",
    "dashboard"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.\n     QR code is a COMPOSITE (antd, no framework-free element), so its HTML form is a\n     CDN-React page — React + antd load from a CDN (esm.sh) and mount on open. It\n     consumes the SAME shared `qrCodeTheme` the React/Vue wrappers use, so it renders\n     the DS V3 look (ink modules on white, 1px radius-8 frame).\n     No JSX here (JSX needs a compiler) — we use React.createElement via the `h` alias. -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css\">\n<style>\n  .aha-qr { display:inline-block; box-sizing:border-box; padding:16px; background:var(--aha-bg-container);\n    border:1px solid var(--aha-border); border-radius:var(--aha-radius-default); }\n</style>\n<div id=\"root\"></div>\n<script type=\"module\">\n  import React from 'https://esm.sh/react@18';\n  import { createRoot } from 'https://esm.sh/react-dom@18/client';\n  import { ConfigProvider, QRCode } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';\n  import { qrCodeTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/qr-code-theme.js';\n\n  const h = React.createElement;\n\n  // Same shared theme the React/Vue wrappers pass to ConfigProvider.\n  // Matrix: size 120/160/200 · errorLevel L/M/Q/H · status active/expired/loading/scanned · bordered off.\n  createRoot(document.getElementById('root')).render(\n    h(ConfigProvider, { theme: qrCodeTheme },\n      h('div', { className: 'aha-qr' },\n        h(QRCode, {\n          value: 'https://ahaslides.com/join',\n          size: 160,\n          errorLevel: 'M',\n          status: 'active',\n          bordered: false,        // the .aha-qr container owns the DS frame\n          color: '#1A1A1A',\n          bgColor: '#FFFFFF'\n        })\n      )\n    )\n  );\n</script>\n",
    "react": "import { ConfigProvider, QRCode } from 'antd';   // antd v6\nimport { qrCodeTheme } from '@ahaslides-product/design/qr-code-theme';\n\n<ConfigProvider theme={qrCodeTheme}>\n  <div className=\"aha-qr\">\n    <QRCode\n      value=\"https://ahaslides.com/join\"\n      size={160}                 // 120 / 160 / 200\n      errorLevel=\"M\"             // L / M / Q / H — raise for a logo overlay\n      status=\"active\"            // active / expired / loading / scanned\n      bordered={false}           // the .aha-qr container owns the DS frame\n      color=\"#1A1A1A\"            // ink modules\n      bgColor=\"#FFFFFF\"          // on white, per DS\n    />\n  </div>\n</ConfigProvider>\n// One shared qrCodeTheme → the DS V3 look. Frame the code with the .aha-qr container\n// (1px --aha-border, radius --aha-radius-default) and show the join link/code alongside.\n// Add a centre logo with icon=\"…\" and bump errorLevel to Q/H so it still scans.\n",
    "vue": "<script setup>\nimport { ConfigProvider, QRCode } from 'ant-design-vue';   // ant-design-vue v4\nimport { qrCodeTheme } from '@ahaslides-product/design/qr-code-theme';\n</script>\n\n<template>\n  <a-config-provider :theme=\"qrCodeTheme\">\n    <div class=\"aha-qr\">\n      <a-qrcode\n        value=\"https://ahaslides.com/join\"\n        :size=\"160\"\n        error-level=\"M\"\n        status=\"active\"\n        :bordered=\"false\"\n        color=\"#1A1A1A\"\n        bg-color=\"#FFFFFF\"\n      />\n    </div>\n  </a-config-provider>\n</template>\n<!-- The SAME qrCodeTheme as React → one DS V3 look across both vendor libraries.\n     Matrix: size 120/160/200 · error-level L/M/Q/H · status active/expired/loading/scanned. -->\n",
    "theme": "// @ahaslides-product/design/qr-code-theme — declared ONCE, consumed by both tiers.\nimport { qrCodeTheme } from '@ahaslides-product/design/qr-code-theme';\n\nexport const qrCodeTheme = {\n  token: {\n    colorPrimary: '#6A1EBB',\n    borderRadius: 8,\n    colorText: '#1A1A1A',              // QR module ink\n    colorBorderSecondary: '#E3E3E3',   // framing border\n    fontFamily: 'var(--aha-font-product, \"Plus Jakarta Sans\", sans-serif)',\n  },\n};\n"
  }
}
