diff --git a/studio/frontend/src/components/ui/slider.tsx b/studio/frontend/src/components/ui/slider.tsx index 4a235e674d..f65b3ffa71 100644 --- a/studio/frontend/src/components/ui/slider.tsx +++ b/studio/frontend/src/components/ui/slider.tsx @@ -1,57 +1,76 @@ -import { Slider as SliderPrimitive } from "radix-ui"; -import * as React from "react"; - -import { cn } from "@/lib/utils"; - -function Slider({ - className, - defaultValue, - value, - min = 0, - max = 100, - ...props -}: React.ComponentProps) { - const _values = React.useMemo( - () => - Array.isArray(value) - ? value - : Array.isArray(defaultValue) - ? defaultValue - : [min, max], - [value, defaultValue, min, max], - ); - - return ( - - - - - {Array.from({ length: _values.length }, (_, index) => ( - - ))} - - ); -} - -export { Slider }; +import { Slider as SliderPrimitive } from "radix-ui"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +function Slider({ + className, + defaultValue, + value, + min = 0, + max = 100, + ...props +}: React.ComponentProps) { + const _values = React.useMemo( + () => + Array.isArray(value) + ? value + : Array.isArray(defaultValue) + ? defaultValue + : [min, max], + [value, defaultValue, min, max], + ); + + // For single-thumb horizontal sliders, render the fill bar as a sibling of + // the track (outside its overflow-hidden container) so it can align flush + // with the thumb center without being clipped. The Range inside the track + // is hidden in this case to avoid double-painting. + const isSingleThumb = _values.length === 1; + const fillPercent = isSingleThumb + ? Math.min(100, Math.max(0, (((_values[0] ?? min) - min) / (max - min)) * 100)) + : null; + + return ( + + + + + {isSingleThumb && ( +
+ )} + {Array.from({ length: _values.length }, (_, index) => ( + + ))} + + ); +} + +export { Slider };