{
  "generatedFrom": "descriptions.contract.json",
  "component": "Descriptions",
  "slug": "descriptions",
  "group": "Data Display",
  "tier": "leaf-lit",
  "summary": "A read-only label/value grid summarising one entity's fields — N columns, bordered or plain, horizontal or vertical, with per-item span.",
  "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-descriptions';",
    "element": "aha-descriptions",
    "registers": "aha-descriptions"
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/descriptions/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/descriptions/descriptions.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/descriptions.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/descriptions.llms.txt",
    "index": "https://ahaslides-product.github.io/ahaslides-design/llms.txt"
  },
  "recommendedSnippet": "html",
  "vibeCode": "Emit the HTML snippet by default — <aha-descriptions> 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-descriptions"
    },
    "vue": {
      "via": "web-component",
      "ref": "aha-descriptions"
    },
    "html": {
      "via": "web-component",
      "ref": "aha-descriptions",
      "runnable": "paste-and-run — no build step, renders on open"
    }
  },
  "props": [
    {
      "name": "items",
      "type": "JSON [{label,value,span?}]",
      "default": "—",
      "desc": "The items, as a JSON tree. Alternative to light-DOM children"
    },
    {
      "name": "desc-title",
      "type": "string",
      "default": "—",
      "desc": "Renders an optional header row"
    },
    {
      "name": "column",
      "type": "number",
      "default": "2 (vertical 3)",
      "desc": "Label/value pairs per row"
    },
    {
      "name": "bordered",
      "type": "boolean attr",
      "default": "false",
      "desc": "Ruled table with cell borders + tinted label column"
    },
    {
      "name": "size",
      "type": "'default' | 'small' | 'large'",
      "default": "default",
      "desc": "Cell padding scale"
    },
    {
      "name": "layout",
      "type": "'horizontal' | 'vertical'",
      "default": "horizontal",
      "desc": "Label : value side-by-side, or label stacked over value"
    },
    {
      "name": "label",
      "type": "string (on children)",
      "default": "—",
      "desc": "Each child's label attribute names its item"
    },
    {
      "name": "span",
      "type": "number (items/children)",
      "default": "1",
      "desc": "How many columns the item spans"
    },
    {
      "name": "(children)",
      "type": "slot",
      "default": "—",
      "desc": "Each child's content is the item value (when not using items)"
    }
  ],
  "tokens": [
    "bg-container",
    "bg-container-secondary",
    "border",
    "split",
    "radius-default",
    "text-default",
    "text-secondary",
    "font-product"
  ],
  "spec": [
    {
      "label": "Container",
      "value": "border 1px #E3E3E3 · radius 8px · bg #FFFFFF"
    },
    {
      "label": "Title",
      "value": "padding 12/16 · 15/22 SemiBold #1A1A1A · divider #F1F1F1"
    },
    {
      "label": "Label cell",
      "value": "SemiBold #4A4A4A · bordered → bg #F7F7F7 + tinted column"
    },
    {
      "label": "Value cell",
      "value": "#1A1A1A · 14/22 · rows/cells ruled #F1F1F1"
    },
    {
      "label": "Column",
      "value": "N label/value pairs flow per row; an item spans several (default 2 · vertical 3)"
    },
    {
      "label": "Bordered",
      "value": "ruled table — cell borders #F1F1F1 + tinted label column; plain = row dividers only"
    },
    {
      "label": "Size",
      "value": "padding scale — default 12/16 · small 8/12 · large 16/20"
    },
    {
      "label": "Layout",
      "value": "horizontal (label : value) · vertical (label over value)"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Descriptions",
        "when": "read-only label/value facts about one entity (a plan, an account)"
      },
      {
        "what": "Form",
        "when": "the same fields need to be edited"
      },
      {
        "what": "Table",
        "when": "the same fields across many records"
      }
    ],
    "note": "Labels are sentence case nouns — 'Billing cycle', not 'BILLING CYCLE'. Keep to the facts that matter; a long grid reads like a form nobody can fill in.",
    "dsv3": "COVERED — DS V3's measured set has no Descriptions cell (confirmed via Figma search on fileKey MwjvUjVI0HnfwD9EwPXRAy — no Descriptions/Detail component-set); the variant matrix (column · bordered vs plain · size default/small/large · layout horizontal/vertical · per-item span) is enumerated from antd Descriptions conventions, bound to the token layer (radius-default, border, split, bg-container-secondary, text-default/secondary). A deliberate, documented extension — not a measured match."
  },
  "surfaces": [
    "dashboard",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step.\n     <aha-descriptions> is the SAME shared custom element React and Vue consume — here in\n     its 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-descriptions.js';   // registers <aha-descriptions>\n</script>\n\n<!-- items = [{label, value, span?}]; bordered | column=\"N\" | size=\"default|small|large\" | layout=\"horizontal|vertical\" -->\n<aha-descriptions desc-title=\"Account\" bordered column=\"2\" size=\"default\" layout=\"horizontal\" style=\"max-width:520px\"\n  items='[\n    {\"label\":\"Plan\",\"value\":\"Pro\"},\n    {\"label\":\"Status\",\"value\":\"Active\"},\n    {\"label\":\"Seats\",\"value\":\"25 of 50\"},\n    {\"label\":\"Billing cycle\",\"value\":\"Yearly\"},\n    {\"label\":\"Renews\",\"value\":\"9 Sep 2027\",\"span\":2}\n  ]'>\n</aha-descriptions>\n\n<!-- …or feed rows as light-DOM children (each child's label attr + content = one item): -->\n<aha-descriptions desc-title=\"Plan\" style=\"max-width:360px; margin-top:16px\">\n  <div label=\"Tier\">Pro</div>\n  <div label=\"Notes\" span=\"2\">Renews yearly · 25 of 50 seats used</div>\n</aha-descriptions>\n",
    "react": "import '@ahaslides-product/design/aha-descriptions';   // registers <aha-descriptions>\n\n// Feed an items tree ([{label, value, span?}]) — bordered, N columns, sized, laid out.\nfunction AccountFacts({ title, items }) {\n  return (\n    <aha-descriptions\n      desc-title={title}\n      bordered\n      column=\"2\"\n      size=\"default\"\n      layout=\"horizontal\"\n      items={JSON.stringify(items)}\n    />\n  );\n}\n\n// usage\n<AccountFacts\n  title=\"Account\"\n  items={[\n    { label: 'Plan', value: 'Pro' },\n    { label: 'Status', value: 'Active' },\n    { label: 'Seats', value: '25 of 50' },\n    { label: 'Renews', value: '9 Sep 2027', span: 2 },\n  ]}\n/>\n",
    "vue": "// main.ts — register the element + mark aha-* as custom elements\nimport '@ahaslides-product/design/aha-descriptions';\napp.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');\n\n// Component.vue\n<script setup>\nimport { ref, computed } from 'vue';\nconst items = ref([\n  { label: 'Plan', value: 'Pro' },\n  { label: 'Status', value: 'Active' },\n  { label: 'Seats', value: '25 of 50' },\n  { label: 'Renews', value: '9 Sep 2027', span: 2 },\n]);\nconst itemsJson = computed(() => JSON.stringify(items.value));\n</script>\n\n<template>\n  <!-- bordered | column=\"N\" | size=\"default|small|large\" | layout=\"horizontal|vertical\" -->\n  <aha-descriptions desc-title=\"Account\" bordered column=\"2\" layout=\"horizontal\" :items=\"itemsJson\" />\n</template>\n"
  }
}
