{
  "generatedFrom": "table.contract.json",
  "component": "Table",
  "slug": "table",
  "group": "Data",
  "tier": "composite-antd",
  "summary": "A data grid — results, leaderboard, participant/admin list — rendered through the shared DataTable.",
  "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/table-theme';",
    "element": null,
    "registers": null
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/table/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/table/table.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/table.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/table.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": "columns",
      "type": "Column[]",
      "default": "[]",
      "desc": "dataIndex / key / title / sorter / filter / fixed / width"
    },
    {
      "name": "dataSource",
      "type": "object[]",
      "default": "[]",
      "desc": "row data"
    },
    {
      "name": "rowKey",
      "type": "string | fn",
      "default": "—",
      "desc": "unique row id"
    },
    {
      "name": "pagination",
      "type": "object | false",
      "default": "—",
      "desc": "brand-outlined page + N/page size changer"
    },
    {
      "name": "reorderable",
      "type": "boolean",
      "default": "false",
      "desc": "drag headers to reorder"
    },
    {
      "name": "freezable",
      "type": "boolean",
      "default": "false",
      "desc": "right-click header to freeze one column"
    }
  ],
  "tokens": [
    "colorPrimary",
    "borderRadius",
    "colorBorderSecondary",
    "Table.headerBg",
    "Table.headerColor",
    "Table.borderColor",
    "Table.rowHoverBg",
    "Table.cellPaddingBlock",
    "Table.cellPaddingInline"
  ],
  "spec": [
    {
      "label": "Container",
      "value": "white surface, 1px #E3E3E3 border, radius 8 — wraps the whole grid"
    },
    {
      "label": "Header",
      "value": "white #fff + secondary-grey #8A8A8A labels (row 60px)"
    },
    {
      "label": "Body",
      "value": "horizontal dividers #E3E3E3 only, no zebra; row 60px"
    },
    {
      "label": "Radius",
      "value": "8"
    },
    {
      "label": "Cell padding",
      "value": "16 (literal)"
    },
    {
      "label": "Row hover",
      "value": "gray-30 #F1F1F1"
    },
    {
      "label": "Customisations (DS V3)",
      "value": "sorting (single arrow) · filtering (checklist/range) · reorder · resize · rows-per-page · freeze · add/remove columns"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "DataTable",
        "when": "any rows×columns grid — results, leaderboard, admin list"
      },
      {
        "what": "never a raw <Table>",
        "when": "a bare antd Table restyled per call site is the drift this replaces"
      }
    ],
    "note": "White header (not antd grey #fafafa), single-arrow sort (not dual caret), Phosphor icons, tokenised colour. The look is theme-driven; call sites pass data + columns only."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "admin"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.\n     Table 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 `tableTheme` the React/Vue wrappers use, so it renders\n     the DS V3 look (white header, grey labels, dividers-only, radius 8, brand hover).\n     No JSX here (JSX needs a compiler) — we use React.createElement via the `h` alias. -->\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, Table } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';\n  import { tableTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/table-theme.js';\n\n  const h = React.createElement;\n\n  const columns = [\n    { key: 'name',      title: 'Name',      dataIndex: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },\n    { key: 'team',      title: 'Team',      dataIndex: 'team' },\n    { key: 'responses', title: 'Responses', dataIndex: 'responses' },\n    { key: 'score',     title: 'Score',     dataIndex: 'score', sorter: (a, b) => a.score - b.score },\n  ];\n  const rows = [\n    { key: '1', name: 'Alex Rivera',   team: 'Growth',  responses: 128, score: 94 },\n    { key: '2', name: 'Priya Nair',    team: 'Product', responses: 112, score: 88 },\n    { key: '3', name: 'Sam Okafor',    team: 'Growth',  responses: 97,  score: 81 },\n  ];\n\n  // Same shared theme the React/Vue DataTable wrappers pass to ConfigProvider.\n  createRoot(document.getElementById('root')).render(\n    h(ConfigProvider, { theme: tableTheme },\n      h(Table, { rowKey: 'key', columns, dataSource: rows, pagination: { pageSize: 5, showSizeChanger: true } })\n    )\n  );\n  // In a real app use the shared DataTable (DS V3 single-arrow sort, filter, freeze, reorder) —\n  // never a raw <Table>. This page shows the paste-and-run form of the same themed grid.\n</script>\n",
    "react": "import { DataTable, Button } from '@aha/ui-react';   // wraps antd v6 <Table> + components.Table theme\n\nconst columns = [\n  { key: 'name',      title: 'Name',      dataIndex: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },\n  { key: 'team',      title: 'Team',      dataIndex: 'team', filter: { type: 'checklist', options: teams } },\n  { key: 'responses', title: 'Responses', dataIndex: 'responses' },\n  { key: 'score',     title: 'Score',     dataIndex: 'score', sorter: (a, b) => a.score - b.score },\n];\n\n<DataTable\n  rowKey=\"key\"\n  columns={columns}\n  dataSource={rows}\n  reorderable\n  freezable\n  pagination={{ pageSize: 5, showSizeChanger: true }}\n/>\n// Never a raw <Table> — DataTable applies the DS V3 look (white header, single-arrow sort, Phosphor icons).\n",
    "vue": "<script setup>\nimport { DataTable } from '@aha/ui-vue';   // wraps ant-design-vue v4 <a-table> + the SAME components.Table theme\n\nconst columns = [\n  { key: 'name',      title: 'Name',      dataIndex: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },\n  { key: 'team',      title: 'Team',      dataIndex: 'team', filter: { type: 'checklist', options: teams } },\n  { key: 'responses', title: 'Responses', dataIndex: 'responses' },\n  { key: 'score',     title: 'Score',     dataIndex: 'score', sorter: (a, b) => a.score - b.score },\n];\n</script>\n\n<template>\n  <DataTable\n    row-key=\"key\"\n    :columns=\"columns\"\n    :data-source=\"rows\"\n    reorderable\n    freezable\n    :pagination=\"{ pageSize: 5, showSizeChanger: true }\"\n  />\n</template>\n",
    "theme": "// theme/index.ts — declared ONCE, mirrored in variables.css. Both tiers read it.\nexport const ahaSlidesTheme = {\n  token: { colorPrimary: '#6A1EBB', borderRadius: 8, fontFamily: '\"Plus Jakarta Sans\", sans-serif',\n           colorText: '#1A1A1A', colorTextSecondary: '#8A8A8A', colorBorderSecondary: '#E3E3E3' },\n  components: {\n    Table: {\n      headerBg: '#ffffff',              // white header — NOT antd's default #fafafa\n      headerColor: '#8A8A8A',           // secondary-grey labels\n      headerSplitColor: 'transparent',  // no vertical separators\n      borderColor: '#E3E3E3',           // horizontal dividers only\n      rowHoverBg: '#F1F1F1',            // gray hover — DS V3 bg-fill-secondary-hover (gray-30)\n      cellPaddingBlock: 16,             // literal 16 (never token.padding → undefined → 0)\n      cellPaddingInline: 16,\n      headerBorderRadius: 0,\n    },\n  },\n};\n"
  }
}
