{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "slider",
  "title": "Slider",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A single or range slider with a name per thumb, a live value bubble, vertical orientation and full keyboard control, built on Radix.",
  "dependencies": [
    "radix-ui"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/direction.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/slider.tsx",
      "content": "// Ballmac UI: Slider. https://ui.ballmac.com/components/slider\n// Based on shadcn/ui Slider (MIT, Copyright (c) 2023 shadcn), adding per-thumb labels, a live value bubble, and vertical support.\n\"use client\";\n\nimport * as React from \"react\";\nimport { Slider as Primitive } from \"radix-ui\";\nimport { useDirection } from \"@/lib/ballmac/direction\";\nimport { cn } from \"@/lib/utils\";\n\ntype SliderProps = Omit<\n  React.ComponentProps<typeof Primitive.Root>,\n  \"value\" | \"defaultValue\"\n> & {\n  /** Controlled value. One number per thumb. */\n  value?: number[];\n  /** Initial value when uncontrolled. One number per thumb; two numbers make a range. */\n  defaultValue?: number[];\n  /** Accessible name for each thumb, in order, for example `[\"Minimum\", \"Maximum\"]`. A single-thumb slider can use `aria-label` or `aria-labelledby`, which are passed to the thumb. */\n  thumbLabels?: string[];\n  /** Show a value bubble above the thumb while it is hovered, focused or dragged. */\n  showValue?: boolean;\n  /** Format the number shown in the bubble and announced as `aria-valuetext`. */\n  formatValue?: (value: number) => string;\n};\n\nfunction Slider({\n  className,\n  value,\n  defaultValue,\n  min = 0,\n  max = 100,\n  thumbLabels,\n  showValue = false,\n  formatValue,\n  onValueChange,\n  orientation = \"horizontal\",\n  \"aria-label\": ariaLabel,\n  \"aria-labelledby\": ariaLabelledby,\n  ...props\n}: SliderProps) {\n  const [inner, setInner] = React.useState<number[]>(defaultValue ?? [min]);\n  const values = value ?? inner;\n  const vertical = orientation === \"vertical\";\n  const dir = useDirection(props.dir);\n  return (\n    <Primitive.Root\n      data-slot=\"slider\"\n      dir={dir}\n      value={value}\n      defaultValue={defaultValue}\n      min={min}\n      max={max}\n      orientation={orientation}\n      onValueChange={(next) => {\n        setInner(next);\n        onValueChange?.(next);\n      }}\n      className={cn(\n        \"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-44 data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col\",\n        className,\n      )}\n      {...props}\n    >\n      <Primitive.Track\n        data-slot=\"slider-track\"\n        className=\"relative grow overflow-hidden rounded-full bg-muted data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5\"\n      >\n        <Primitive.Range\n          data-slot=\"slider-range\"\n          className=\"absolute bg-primary data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full\"\n        />\n      </Primitive.Track>\n      {values.map((v, i) => (\n        <Primitive.Thumb\n          key={i}\n          data-slot=\"slider-thumb\"\n          aria-label={thumbLabels?.[i] ?? (values.length === 1 ? ariaLabel : undefined)}\n          aria-labelledby={\n            !thumbLabels?.[i] && values.length === 1 ? ariaLabelledby : undefined\n          }\n          aria-valuetext={formatValue ? formatValue(v) : undefined}\n          className=\"group/thumb relative block size-5 shrink-0 rounded-full border-2 border-primary bg-background shadow-sm outline-none transition-[box-shadow,transform] duration-150 hover:ring-4 hover:ring-ring/30 focus-visible:ring-4 focus-visible:ring-ring/50 active:scale-110 disabled:pointer-events-none motion-reduce:transition-none motion-reduce:active:scale-100\"\n        >\n          {showValue && (\n            <span\n              aria-hidden=\"true\"\n              className={cn(\n                \"pointer-events-none absolute rounded-md bg-foreground px-1.5 py-0.5 text-xs font-medium tabular-nums text-background opacity-0 shadow transition-opacity duration-150 group-hover/thumb:opacity-100 group-focus-visible/thumb:opacity-100 group-active/thumb:opacity-100 motion-reduce:transition-none\",\n                vertical\n                  ? \"top-1/2 start-full ms-2 -translate-y-1/2\"\n                  : \"bottom-full left-1/2 mb-2 -translate-x-1/2\",\n              )}\n            >\n              {formatValue ? formatValue(v) : v}\n            </span>\n          )}\n        </Primitive.Thumb>\n      ))}\n    </Primitive.Root>\n  );\n}\n\nexport { Slider, type SliderProps };\n",
      "type": "registry:ui",
      "target": "@components/ballmac/slider.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "input",
      "range",
      "form",
      "radix"
    ],
    "version": "1.0.0",
    "updated": "2026-09-30",
    "ai": {
      "summary": "Drag or use the keyboard to pick a number or a range. Give every thumb a name with thumbLabels; showValue adds a bubble on hover, focus and drag.",
      "whenToUse": [
        "Volume, brightness and zoom",
        "Price and date ranges with two thumbs",
        "Any bounded numeric choice where precision is not critical"
      ],
      "whenNotToUse": [
        "Exact numeric entry; use number-input",
        "A styled range with marks or steps shown; use slider-range"
      ],
      "composesWith": [
        "label",
        "field"
      ],
      "a11y": [
        {
          "keys": "ArrowLeft / ArrowRight / ArrowUp / ArrowDown",
          "action": "Changes the value by one step"
        },
        {
          "keys": "PageUp / PageDown",
          "action": "Changes by a larger step"
        },
        {
          "keys": "Home / End",
          "action": "Jumps to min or max"
        },
        {
          "keys": "Tab",
          "action": "Moves between thumbs"
        }
      ],
      "customization": [
        "min, max, step",
        "thumbLabels for range sliders",
        "showValue and formatValue",
        "orientation: horizontal | vertical"
      ]
    },
    "source": {
      "name": "shadcn/ui Slider",
      "url": "https://github.com/shadcn-ui/ui",
      "license": "MIT",
      "copyright": "Copyright (c) 2023 shadcn",
      "modified": true
    },
    "examples": [
      "slider-demo",
      "slider-states"
    ],
    "url": "https://ui.ballmac.com/components/slider"
  },
  "categories": [
    "forms"
  ],
  "type": "registry:ui"
}