{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "slider",
  "type": "registry:ui",
  "title": "Slider",
  "description": "Range input with an optional mono value readout beside its label.",
  "categories": [
    "forms"
  ],
  "registryDependencies": [
    "https://whiskeyjack.net/r/utils.json"
  ],
  "files": [
    {
      "path": "components/ui/slider.tsx",
      "type": "registry:ui",
      "target": "components/ui/slider.tsx",
      "content": "import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface SliderProps\n  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"type\" | \"value\"> {\n  /** Optional label shown above the slider. */\n  label?: React.ReactNode;\n  value: number;\n  onChange: (value: number) => void;\n  /**\n   * Optional formatter for the value display shown to the right of the label.\n   * If `label` is present and `formatValue` is provided (or the value is a\n   * finite number), the formatted value is rendered as a mono / tabular hint.\n   */\n  formatValue?: (value: number) => string;\n}\n\n/**\n * A thin, accent-themed range slider. Uses a native `<input type=\"range\">`\n * with styling injected via Tailwind arbitrary variants for both the WebKit\n * and Firefox thumb pseudo-elements. The label + value-readout row above the\n * track follows the design-system \"field label\" pattern (small caps, mono).\n */\nconst Slider = React.forwardRef<HTMLInputElement, SliderProps>(\n  ({ label, value, onChange, formatValue, className, min, max, step, id: idProp, ...props }, ref) => {\n    const autoId = React.useId();\n    const id = idProp ?? (label !== undefined ? autoId : undefined);\n    const display = formatValue ? formatValue(value) : String(value);\n    return (\n      <div className=\"flex flex-col gap-2.5\">\n        {label !== undefined && (\n          <div className=\"flex items-baseline justify-between gap-2\">\n            <label\n              htmlFor={id}\n              className=\"text-xs text-[var(--color-text-muted-light)] dark:text-[var(--color-text-muted-dark)]\"\n            >\n              {label}\n            </label>\n            {formatValue && (\n              <span className=\"text-xs tabular-nums text-[var(--color-text-secondary-light)] dark:text-[var(--color-text-secondary-dark)]\">\n                {display}\n              </span>\n            )}\n          </div>\n        )}\n        <input\n          ref={ref}\n          type=\"range\"\n          id={id}\n          value={value}\n          min={min}\n          max={max}\n          step={step}\n          aria-valuetext={display}\n          onChange={e => onChange(Number(e.target.value))}\n          className={cn(\n            \"appearance-none w-full h-1.5 rounded-full cursor-pointer\",\n            // Track: neutral-700 in dark (NOT neutral-800, which equals\n            // --color-surface-dark #27272a -- the track would vanish on a Card).\n            \"bg-[var(--color-warm-200)] dark:bg-[var(--color-neutral-700)]\",\n            \"wj-focus-ring\",\n            // WebKit thumb\n            \"[&::-webkit-slider-thumb]:appearance-none\",\n            \"[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4\",\n            \"[&::-webkit-slider-thumb]:rounded-full\",\n            \"[&::-webkit-slider-thumb]:bg-[var(--color-accent-500)]\",\n            \"[&::-webkit-slider-thumb]:shadow-md-bevel-accent\",\n            // Hover and press are the SAME size: the thumb grows while the\n            // pointer is on it or dragging it, and only returns once both end.\n            // A separate press size made a click read as shrink-then-grow,\n            // since releasing over the thumb lands back in the hover state.\n            \"[&::-webkit-slider-thumb]:transition-transform\",\n            \"hover:[&::-webkit-slider-thumb]:scale-110\",\n            \"active:[&::-webkit-slider-thumb]:scale-110\",\n            // Firefox thumb\n            \"[&::-moz-range-thumb]:appearance-none\",\n            \"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4\",\n            \"[&::-moz-range-thumb]:rounded-full\",\n            \"[&::-moz-range-thumb]:bg-[var(--color-accent-500)]\",\n            \"[&::-moz-range-thumb]:border-0\",\n            \"[&::-moz-range-thumb]:shadow-md-bevel-accent\",\n            \"[&::-moz-range-thumb]:transition-transform\",\n            \"hover:[&::-moz-range-thumb]:scale-110\",\n            \"active:[&::-moz-range-thumb]:scale-110\",\n            \"disabled:opacity-50 disabled:cursor-not-allowed\",\n            className,\n          )}\n          {...props}\n        />\n      </div>\n    );\n  },\n);\nSlider.displayName = \"Slider\";\n\nexport { Slider };\n"
    }
  ],
  "docs": "The control for a value along a continuum: a target, a threshold, a volume. It wraps a native range input, so `min`, `max` and `step` are passed straight through and do not appear in the props table below -- they arrive via the inherited input attributes. Add `formatValue` for a live readout next to the label. It styles the native thumb across browsers and exposes aria-valuetext.",
  "meta": {
    "group": "forms",
    "related": [
      "input"
    ],
    "exports": [
      "Slider"
    ],
    "siteSlug": "slider"
  }
}
