{
  "generatedFrom": "flex.contract.json",
  "component": "Flex",
  "slug": "flex",
  "group": "Layout",
  "tier": "leaf-lit",
  "summary": "A flexbox container with the DS spacing scale baked into `gap` — direction, align, justify, wrap.",
  "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/aha-flex';",
    "element": "aha-flex",
    "registers": "aha-flex"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/flex/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/flex/flex.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/flex.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/flex.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-flex> is a standard custom element that renders on open — React/Vue are thin adapters over the same element. Paste into an .html file and it renders with no build step.",
  "frameworks": {
    "react": {
      "via": "web-component",
      "ref": "aha-flex"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-flex"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-flex",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "gap",
      "type": "small | middle | large | number",
      "default": "0",
      "desc": "Space between items — named DS step (8/16/24) or a raw pixel number"
    },
    {
      "name": "vertical",
      "type": "boolean",
      "default": "false",
      "desc": "Stack in a column — AntD's boolean shorthand for direction=column (direction wins if both set)"
    },
    {
      "name": "direction",
      "type": "row | row-reverse | column | column-reverse",
      "default": "row",
      "desc": "Main-axis direction (flex-direction) — the full matrix; overrides `vertical`"
    },
    {
      "name": "align",
      "type": "start | center | end | baseline | stretch",
      "default": "stretch",
      "desc": "Cross-axis alignment (align-items)"
    },
    {
      "name": "justify",
      "type": "start | center | end | space-between | space-around | space-evenly",
      "default": "start",
      "desc": "Main-axis distribution (justify-content)"
    },
    {
      "name": "wrap",
      "type": "boolean",
      "default": "false",
      "desc": "Allow items to wrap onto multiple lines"
    }
  ],
  "tokens": [
    "text-default"
  ],
  "spec": [
    {
      "label": "Display",
      "value": "flex"
    },
    {
      "label": "Gap scale",
      "value": "small 8 · middle 16 · large 24 (or a raw px number)"
    },
    {
      "label": "Direction",
      "value": "row · row-reverse · column · column-reverse (or `vertical` for column)"
    },
    {
      "label": "Align",
      "value": "start · center · end · baseline · stretch (align-items)"
    },
    {
      "label": "Justify",
      "value": "start · center · end · space-between/around/evenly"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Flex",
        "when": "arranging a block of items in one dimension with consistent DS spacing"
      },
      {
        "what": "Grid",
        "when": "you need two-dimensional rows-and-columns, not a single flow"
      },
      {
        "what": "Space",
        "when": "you only need even gaps between a small inline set of items"
      }
    ],
    "note": "Keep gaps on the named scale (small/middle/large) so spacing stays consistent across surfaces — reach for a raw pixel number only for a genuine one-off. Flex is layout, never decoration: it paints no background.",
    "dsv3": "COVERED — DS V3 has no measured Flex cell; spec derived from the DS spacing scale (8/16/24) + AntD Flex conventions (gap steps, direction/align/justify/wrap). A deliberate, documented layout extension; the only visual token it binds is inherited text colour."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings",
    "audience"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-flex> is the SAME shared custom element React and Vue consume — here in its\n     native form. Theming comes only from the --aha-* tokens in tokens.css. -->\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css\">\n<script type=\"module\">\n  import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-flex.js';   // registers <aha-flex>\n</script>\n\n<!-- gap takes a named DS step (small 8 / middle 16 / large 24) or a raw pixel number -->\n<aha-flex gap=\"middle\" align=\"center\">\n  <button>Save</button>\n  <button>Cancel</button>\n  <button>More</button>\n</aha-flex>\n\n<!-- column: `vertical` is the shorthand; `direction` unlocks the full row/column-reverse matrix -->\n<aha-flex vertical gap=\"large\" style=\"margin-top:24px\">\n  <div>Row one</div>\n  <div>Row two</div>\n</aha-flex>\n\n<!-- push items apart, cross-align centred -->\n<aha-flex justify=\"space-between\" align=\"center\" style=\"margin-top:24px\">\n  <strong>Title</strong>\n  <a href=\"#\">Action</a>\n</aha-flex>\n\n<!-- wrap onto multiple lines with a small gap -->\n<aha-flex wrap gap=\"small\" style=\"margin-top:24px\">\n  <span>Poll</span><span>Quiz</span><span>Word cloud</span><span>Q&amp;A</span><span>Brainstorm</span>\n</aha-flex>\n",
    "react": "import '@ahaslides-product/design/aha-flex';   // registers <aha-flex>\n\n// A static layout primitive — the custom element renders identically in React, no wrapper needed.\n<aha-flex gap=\"middle\" align=\"center\">\n  <Button>Save</Button>\n  <Button variant=\"secondary\">Cancel</Button>\n</aha-flex>\n\n{/* `vertical` is the column shorthand; `direction` unlocks row/column-reverse */}\n<aha-flex vertical gap=\"large\">\n  <Card />\n  <Card />\n</aha-flex>\n\n<aha-flex justify=\"space-between\" align=\"center\">\n  <strong>Title</strong>\n  <a href=\"#\">Action</a>\n</aha-flex>\n\n<aha-flex wrap gap=\"small\">\n  {tags.map((t) => <Tag key={t}>{t}</Tag>)}\n</aha-flex>\n",
    "vue": "// main.ts — register the element + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-flex';\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<template>\n  <aha-flex gap=\"middle\" align=\"center\">\n    <button>Save</button>\n    <button>Cancel</button>\n  </aha-flex>\n\n  <!-- `vertical` is the column shorthand; `direction` unlocks row/column-reverse -->\n  <aha-flex vertical gap=\"large\">\n    <Card />\n    <Card />\n  </aha-flex>\n\n  <aha-flex justify=\"space-between\" align=\"center\">\n    <strong>Title</strong>\n    <a href=\"#\">Action</a>\n  </aha-flex>\n\n  <aha-flex wrap gap=\"small\">\n    <span v-for=\"t in tags\" :key=\"t\">{{ t }}</span>\n  </aha-flex>\n</template>\n"
  }
}
