{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "slider",
  "title": "Slider",
  "description": "A thin track and a solid thumb, with its label and value above.",
  "dependencies": [
    "@base-ui/react",
    "@stylexjs/stylex"
  ],
  "registryDependencies": [
    "https://constella.aayush.cv/r/base.json",
    "https://constella.aayush.cv/r/label.json"
  ],
  "files": [
    {
      "path": "src/components/primitives/slider.tsx",
      "content": "\"use client\";\n\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\";\nimport * as stylex from \"@stylexjs/stylex\";\n\nimport { labelStyles } from \"@/components/primitives/label\";\nimport type { Sx } from \"@/lib/constella/styles\";\nimport { typeStyles } from \"@/lib/constella/styles\";\nimport {\n  colors,\n  durations,\n  easings,\n  opacities,\n  presses,\n  radii,\n  shadows,\n  sizes,\n  space,\n  strokes,\n} from \"@/lib/constella/tokens.stylex\";\n\ntype Styled<T> = Omit<T, \"className\" | \"style\"> & {\n  sx?: Sx;\n};\n\nconst halfThumb = `calc(${sizes.thumb} / 2)`;\nconst halfThumbOut = `calc(${sizes.thumb} / -2)`;\nconst vertical = \":is([data-orientation='vertical'])\";\n\nconst styles = stylex.create({\n  // Label and value share the first row; the control spans the second.\n  slider: {\n    alignItems: \"center\",\n    columnGap: space.sm,\n    display: \"grid\",\n    gridTemplateColumns: \"minmax(0, 1fr) auto\",\n    opacity: { default: 1, \":is([data-disabled])\": opacities.disabled },\n    width: { default: \"100%\", [vertical]: \"auto\" },\n  },\n  value: {\n    color: colors.textSecondary,\n    fontVariantNumeric: \"tabular-nums\",\n    gridColumn: 2,\n  },\n  control: {\n    alignItems: \"center\",\n    cursor: { default: \"pointer\", \":is([data-disabled])\": \"not-allowed\" },\n    display: \"flex\",\n    flexDirection: { default: \"row\", [vertical]: \"column\" },\n    gridColumn: \"1 / -1\",\n    height: { default: sizes.controlXxs, [vertical]: \"100%\" },\n    // Centered thumbs need no measuring, so they render before hydration; Base UI maps the\n    // pointer inside this padding, so the thumb stays within the bar and still tracks the pointer.\n    paddingBlock: { default: 0, [vertical]: halfThumb },\n    paddingInline: { default: halfThumb, [vertical]: 0 },\n    touchAction: \"none\",\n    userSelect: \"none\",\n    width: { default: null, [vertical]: sizes.controlXxs },\n  },\n  // The bar reaches past the track into the control's padding, under the thumb at either end.\n  track: {\n    height: { default: strokes.track, [vertical]: \"100%\" },\n    position: \"relative\",\n    width: { default: \"100%\", [vertical]: strokes.track },\n    \"::before\": {\n      backgroundColor: colors.fillOpaque,\n      borderStartStartRadius: radii.full,\n      borderStartEndRadius: radii.full,\n      borderEndStartRadius: radii.full,\n      borderEndEndRadius: radii.full,\n      content: \"''\",\n      insetBlockEnd: { default: 0, [vertical]: halfThumbOut },\n      insetBlockStart: { default: 0, [vertical]: halfThumbOut },\n      insetInlineEnd: { default: halfThumbOut, [vertical]: 0 },\n      insetInlineStart: { default: halfThumbOut, [vertical]: 0 },\n      position: \"absolute\",\n    },\n  },\n  // Base UI sizes the indicator along the track; the bar reaches back under the start thumb.\n  indicator: {\n    height: { default: \"100%\", [vertical]: null },\n    width: { default: null, [vertical]: \"100%\" },\n    \"::before\": {\n      backgroundColor: colors.accentSolid,\n      borderStartStartRadius: radii.full,\n      borderStartEndRadius: radii.full,\n      borderEndStartRadius: radii.full,\n      borderEndEndRadius: radii.full,\n      content: \"''\",\n      insetBlockEnd: { default: 0, [vertical]: halfThumbOut },\n      insetBlockStart: 0,\n      insetInlineEnd: 0,\n      insetInlineStart: { default: halfThumbOut, [vertical]: 0 },\n      position: \"absolute\",\n    },\n  },\n  thumb: {\n    backgroundColor: colors.accentSolid,\n    borderStartStartRadius: radii.full,\n    borderStartEndRadius: radii.full,\n    borderEndStartRadius: radii.full,\n    borderEndEndRadius: radii.full,\n    boxShadow: shadows.defaultRing,\n    height: sizes.thumb,\n    // Base UI positions the thumb with `translate`, so `transform` is free for the press.\n    transform: { default: null, \":is([data-dragging])\": presses.icon },\n    transitionDuration: durations.press,\n    transitionProperty: \"transform\",\n    transitionTimingFunction: easings.out,\n    width: sizes.thumb,\n    \"::before\": {\n      content: \"''\",\n      insetBlockEnd: `calc((${sizes.thumb} - ${sizes.hitArea}) / 2)`,\n      insetBlockStart: `calc((${sizes.thumb} - ${sizes.hitArea}) / 2)`,\n      insetInlineEnd: `calc((${sizes.thumb} - ${sizes.hitArea}) / 2)`,\n      insetInlineStart: `calc((${sizes.thumb} - ${sizes.hitArea}) / 2)`,\n      position: \"absolute\",\n    },\n  },\n});\n\nfunction Slider<Value extends number | readonly number[]>({\n  sx,\n  ...props\n}: Styled<SliderPrimitive.Root.Props<Value>>) {\n  return (\n    <SliderPrimitive.Root\n      data-slot=\"slider\"\n      {...props}\n      {...stylex.props(styles.slider, sx)}\n    />\n  );\n}\n\nfunction SliderLabel({ sx, ...props }: Styled<SliderPrimitive.Label.Props>) {\n  return (\n    <SliderPrimitive.Label\n      data-slot=\"slider-label\"\n      {...props}\n      {...stylex.props(labelStyles(), sx)}\n    />\n  );\n}\n\nfunction SliderValue({ sx, ...props }: Styled<SliderPrimitive.Value.Props>) {\n  return (\n    <SliderPrimitive.Value\n      data-slot=\"slider-value\"\n      {...props}\n      {...stylex.props([typeStyles.textSm, styles.value], sx)}\n    />\n  );\n}\n\n/** Renders the track, the filled indicator and one thumb. For a range, compose the parts. */\nfunction SliderControl({\n  children,\n  sx,\n  ...props\n}: Styled<SliderPrimitive.Control.Props>) {\n  return (\n    <SliderPrimitive.Control\n      data-slot=\"slider-control\"\n      {...props}\n      {...stylex.props(styles.control, sx)}\n    >\n      {children ?? (\n        <SliderTrack>\n          <SliderIndicator />\n          <SliderThumb />\n        </SliderTrack>\n      )}\n    </SliderPrimitive.Control>\n  );\n}\n\nfunction SliderTrack({ sx, ...props }: Styled<SliderPrimitive.Track.Props>) {\n  return (\n    <SliderPrimitive.Track\n      data-slot=\"slider-track\"\n      {...props}\n      {...stylex.props(styles.track, sx)}\n    />\n  );\n}\n\nfunction SliderIndicator({\n  sx,\n  ...props\n}: Styled<SliderPrimitive.Indicator.Props>) {\n  return (\n    <SliderPrimitive.Indicator\n      data-slot=\"slider-indicator\"\n      {...props}\n      {...stylex.props(styles.indicator, sx)}\n    />\n  );\n}\n\nfunction SliderThumb({ sx, ...props }: Styled<SliderPrimitive.Thumb.Props>) {\n  return (\n    <SliderPrimitive.Thumb\n      data-slot=\"slider-thumb\"\n      {...props}\n      {...stylex.props(styles.thumb, sx)}\n    />\n  );\n}\n\nexport {\n  Slider,\n  SliderControl,\n  SliderIndicator,\n  SliderLabel,\n  SliderThumb,\n  SliderTrack,\n  SliderValue,\n};\n",
      "type": "registry:component"
    }
  ],
  "docs": "Usage: https://constella.aayush.cv/docs/components/slider/index.md",
  "type": "registry:ui"
}