{
  "schemaVersion": 1,
  "name": "slider",
  "useFor": "Use to set a number in a known range where the rough value matters more than the exact one (a per-order budget, a retry count). Show the current value beside it in the platform mono. Pass two values for a range, and set step for whole units.",
  "constraints": [
    "A slider for an exact amount the user must type",
    "A round blue knob",
    "Animating the key between values"
  ],
  "documentation": "",
  "source": "Extrapolated from opencommerce (the switch key and the speed bars in speed.feature)",
  "exports": [
    "Slider"
  ],
  "client": true,
  "docsUrl": "https://opencommerce-ds.vercel.app/components/slider",
  "markdownUrl": "https://opencommerce-ds.vercel.app/r/slider.md",
  "examples": [
    {
      "path": "examples/slider.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Label } from \"@/components/ui/label\";\nimport { Slider } from \"@/components/ui/slider\";\n\nexport function Site() {\n  const [budget, setBudget] = React.useState([200]);\n  return (\n    <div className=\"grid max-w-110 gap-3\">\n      <div className=\"flex items-baseline justify-between\">\n        <Label htmlFor=\"budget\">Per-order budget</Label>\n        <span className=\"font-mono text-caption text-fg\">${budget[0]}</span>\n      </div>\n      <Slider id=\"budget\" value={budget} onValueChange={setBudget} min={0} max={1000} step={10} aria-label=\"Per-order budget\" />\n    </div>\n  );\n}\n\nexport function Range() {\n  const [range, setRange] = React.useState([40, 240]);\n  return (\n    <div className=\"grid max-w-110 gap-3\">\n      <div className=\"flex items-baseline justify-between\">\n        <Label>Price filter</Label>\n        <span className=\"font-mono text-caption text-fg\">\n          ${range[0]} to ${range[1]}\n        </span>\n      </div>\n      <Slider value={range} onValueChange={setRange} min={0} max={500} step={5} aria-label=\"Price filter\" />\n    </div>\n  );\n}\n\nexport function States() {\n  return (\n    <div className=\"flex max-w-110 items-start gap-10\">\n      <div className=\"grid flex-1 gap-3\">\n        <Label>Retries (disabled)</Label>\n        <Slider defaultValue={[3]} max={10} step={1} disabled aria-label=\"Retries\" />\n      </div>\n      <Slider defaultValue={[60]} orientation=\"vertical\" aria-label=\"Volume\" className=\"h-32\" />\n    </div>\n  );\n}\n",
      "exports": [
        "Site",
        "Range",
        "States"
      ],
      "requires": [
        "slider",
        "label"
      ],
      "packages": [],
      "previews": [
        {
          "name": "Site",
          "url": "https://opencommerce-ds.vercel.app/preview/slider/Site"
        },
        {
          "name": "Range",
          "url": "https://opencommerce-ds.vercel.app/preview/slider/Range"
        },
        {
          "name": "States",
          "url": "https://opencommerce-ds.vercel.app/preview/slider/States"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Slider",
  "description": "A 4px rule filled with the blue up to the value, with a small white key you drag or step with the arrow keys.",
  "surface": "site",
  "kinds": [],
  "requires": [
    "theme",
    "utils"
  ],
  "packages": [
    "@radix-ui/react-slider"
  ],
  "files": [
    {
      "path": "components/ui/slider.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SliderPrimitive from \"@radix-ui/react-slider\";\n\nimport { cn } from \"@/lib/utils\";\n\n// Extrapolated from the brand's switch and the speed bars in speed.feature: a 4px track in the 9 percent ink rule, filled\n// with the blue up to the value, and an 18px white key with 5px corners on the 16 percent ink edge with the switch key's\n// faint drop. Focus draws the outline ring; the key follows the pointer and never animates its position. Pass two values\n// for a range.\nfunction Slider({ className, defaultValue, value, min = 0, max = 100, ...props }: React.ComponentProps<typeof SliderPrimitive.Root>) {\n  const values = React.useMemo(() => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]), [value, defaultValue, min, max]);\n  return (\n    <SliderPrimitive.Root\n      data-slot=\"slider\"\n      defaultValue={defaultValue}\n      value={value}\n      min={min}\n      max={max}\n      className={cn(\n        \"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col\",\n        className,\n      )}\n      {...props}\n    >\n      <SliderPrimitive.Track\n        data-slot=\"slider-track\"\n        className=\"relative grow overflow-hidden rounded-chip bg-line data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1\"\n      >\n        <SliderPrimitive.Range data-slot=\"slider-range\" className=\"absolute bg-primary data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full\" />\n      </SliderPrimitive.Track>\n      {Array.from({ length: values.length }, (_, index) => (\n        <SliderPrimitive.Thumb\n          data-slot=\"slider-thumb\"\n          key={index}\n          aria-label={props[\"aria-label\"] ? undefined : values.length > 1 ? (index === 0 ? \"Minimum\" : \"Maximum\") : undefined}\n          className=\"block size-4.5 shrink-0 cursor-grab rounded-menu border border-hairline bg-white shadow-tile outline-none transition-[border-color] duration-160 ease-out hover:border-line-field-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus-ring active:cursor-grabbing disabled:pointer-events-none motion-reduce:transition-none\"\n        />\n      ))}\n    </SliderPrimitive.Root>\n  );\n}\n\nexport { Slider };\n"
    }
  ]
}
