{
  "generatedFrom": "slider.contract.json",
  "component": "Slider",
  "slug": "slider",
  "group": "Data Entry",
  "tier": "composite-antd",
  "summary": "Drag to set a value across a known range — volume, opacity, thresholds, ranges — rendered through the shared Slider.",
  "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/slider-theme';",
    "element": null,
    "registers": null
  },
  "feeds": {
    "doc": "https://ahaslides-product.github.io/ahaslides-design/slider/index.html",
    "md": "https://ahaslides-product.github.io/ahaslides-design/slider/slider.md",
    "agentJson": "https://ahaslides-product.github.io/ahaslides-design/slider.agent.json",
    "llms": "https://ahaslides-product.github.io/ahaslides-design/slider.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": "number | [number, number]",
      "default": "—",
      "desc": "Position(s); a pair renders a range slider"
    },
    {
      "name": "min",
      "type": "number",
      "default": "0",
      "desc": "Range floor"
    },
    {
      "name": "max",
      "type": "number",
      "default": "100",
      "desc": "Range ceiling"
    },
    {
      "name": "step",
      "type": "number | null",
      "default": "1",
      "desc": "Increment; null with marks to snap to marks only"
    },
    {
      "name": "marks",
      "type": "{ [value]: label }",
      "default": "—",
      "desc": "Labelled tick positions"
    },
    {
      "name": "range",
      "type": "boolean",
      "default": "false",
      "desc": "Two thumbs — select a [low, high] span"
    },
    {
      "name": "vertical",
      "type": "boolean",
      "default": "false",
      "desc": "Orient the rail vertically"
    },
    {
      "name": "disabled",
      "type": "boolean",
      "default": "false",
      "desc": "Non-interactive, dimmed track + handle"
    },
    {
      "name": "onChange",
      "type": "(value) => void",
      "default": "—",
      "desc": "Fires with the new value(s)"
    }
  ],
  "tokens": [
    "colorPrimary",
    "Slider.railBg",
    "Slider.trackBg",
    "Slider.handleColor",
    "Slider.railSize",
    "Slider.handleSize"
  ],
  "spec": [
    {
      "label": "Rail",
      "value": "4px · #F1F1F1 (gray-30)"
    },
    {
      "label": "Track",
      "value": "brand #6A1EBB"
    },
    {
      "label": "Handle",
      "value": "14px · brand ring"
    },
    {
      "label": "Hover rail",
      "value": "#E3E3E3 (gray-40)"
    },
    {
      "label": "Range",
      "value": "two thumbs when value is a [min,max] pair"
    }
  ],
  "opinion": {
    "whenToUse": [
      {
        "what": "Slider",
        "when": "an approximate value across a continuous range where feel beats an exact number"
      },
      {
        "what": "InputNumber",
        "when": "the exact number matters — a precise limit or count"
      },
      {
        "what": "Slider range",
        "when": "a span with a low and high bound — a price or time window"
      }
    ],
    "note": "Pair a slider with a live value readout (or an InputNumber) when the exact number matters. Use marks and step to snap to meaningful positions rather than an arbitrary continuum.",
    "dsv3": "COVERED — antd v6 Slider themed by the shared sliderTheme; matrix: Type (single / range · two thumbs) × Marks (labelled ticks on/off, with step/dots) × Orientation (horizontal / vertical) × Disabled, plus min/max/step and tooltip formatting. The preview exposes Type · Marks · Orientation · Disabled as live React controls; the default render (single · no marks · horizontal · enabled) is the conformance measure target (brand #6A1EBB track, gray-30 rail, 14px handle). Verified via Figma search_design_system against the DS V3 Slider set (Slider, Slider-Mark, Range-Slider, Slider-Icon, Handle, Marks, system-sliders-horizontal)."
  },
  "surfaces": [
    "editor",
    "dashboard",
    "settings"
  ],
  "snippets": {
    "html": "<!-- Paste-and-run: save as .html and open in a browser. No build step, no bundler.\n     Slider is a COMPOSITE (antd, no framework-free element), so its HTML form is a CDN-React\n     page — React + antd load from a CDN (esm.sh) and mount on open. It consumes the SAME shared\n     `sliderTheme` the React/Vue wrappers use, so it renders the DS V3 look (brand track + handle,\n     gray-30 rail).\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, Slider } from 'https://esm.sh/antd@6?deps=react@18,react-dom@18';\n  import { sliderTheme } from 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/slider-theme.js';\n\n  const h = React.createElement;\n\n  const marks = { 0: '0', 50: '50', 100: '100' };\n\n  createRoot(document.getElementById('root')).render(\n    h(ConfigProvider, { theme: sliderTheme },\n      h('div', { style: { width: 280 } },\n        h(Slider, { defaultValue: 40 }),                              // single\n        h(Slider, { range: true, defaultValue: [20, 70] }),          // range · two thumbs\n        h(Slider, { defaultValue: 50, marks: marks, step: null }),   // marks, snap\n        h('div', { style: { height: 200 } }, h(Slider, { vertical: true, defaultValue: 40 })), // vertical\n        h(Slider, { defaultValue: 40, disabled: true })              // disabled\n      )\n    )\n  );\n</script>\n",
    "react": "import { ConfigProvider, Slider } from 'antd';   // antd v6\nimport { sliderTheme } from '@ahaslides-product/design/slider-theme';\n\nconst marks = { 0: '0', 50: '50', 100: '100' };\n\n<ConfigProvider theme={sliderTheme}>\n  <Slider defaultValue={40} onChange={setVolume} />          {/* single */}\n  <Slider range defaultValue={[20, 70]} onChange={setWindow} /> {/* range · two thumbs */}\n  <Slider defaultValue={50} marks={marks} step={null} />     {/* marks, snap to marks */}\n  <div style={{ height: 200 }}><Slider vertical defaultValue={40} /></div> {/* vertical */}\n  <Slider defaultValue={40} disabled />                      {/* disabled */}\n</ConfigProvider>\n// One shared sliderTheme → the DS V3 look; pair with a value readout when the exact number matters.\n",
    "vue": "<script setup>\nimport { ref } from 'vue';\nimport { ConfigProvider, Slider } from 'ant-design-vue';   // ant-design-vue v4\nimport { sliderTheme } from '@ahaslides-product/design/slider-theme';\n\nconst volume = ref(40);\nconst window = ref([20, 70]);\nconst snapped = ref(50);\nconst marks = { 0: '0', 50: '50', 100: '100' };\n</script>\n\n<template>\n  <a-config-provider :theme=\"sliderTheme\">\n    <a-slider v-model:value=\"volume\" />                    <!-- single -->\n    <a-slider v-model:value=\"window\" range />              <!-- range · two thumbs -->\n    <a-slider v-model:value=\"snapped\" :marks=\"marks\" :step=\"null\" /> <!-- marks, snap -->\n    <div style=\"height: 200px\"><a-slider v-model:value=\"volume\" vertical /></div> <!-- vertical -->\n    <a-slider v-model:value=\"volume\" disabled />           <!-- disabled -->\n  </a-config-provider>\n</template>\n<!-- The SAME sliderTheme as React → one DS V3 look across both vendor libraries. -->\n",
    "theme": "// @ahaslides-product/design/slider-theme — declared ONCE, consumed by both tiers.\nimport { sliderTheme } from '@ahaslides-product/design/slider-theme';\n\nexport const sliderTheme = {\n  token: {\n    colorPrimary: '#6A1EBB',\n    borderRadius: 8,\n    fontFamily: 'var(--aha-font-product, \"Plus Jakarta Sans\", sans-serif)',\n  },\n  components: {\n    Slider: {\n      railBg: '#F1F1F1',            // gray-30 rest rail\n      railHoverBg: '#E3E3E3',       // gray-40 hover rail\n      trackBg: '#6A1EBB',           // brand track\n      trackHoverBg: '#5715A0',      // purple-80 hover track\n      handleColor: '#6A1EBB',       // brand handle ring\n      handleActiveColor: '#5715A0',\n      dotActiveBorderColor: '#6A1EBB',\n      railSize: 4,\n      handleSize: 14,\n      handleSizeHover: 16,\n    },\n  },\n};\n"
  }
}
