Describe the bug
The Shadcn Slider component does not correctly parse single numeric values for the value or defaultValue props. It incorrectly falls back to a dual-thumb state [min, max] when it should render a single-thumb state [value].
Furthermore, because of an unstable dependency check in React.useMemo, wrapping the value in an array (e.g., value={[field.value]}) causes infinite re-renders during drag interactions, making the component unusable in controlled forms (like react-hook-form).
🔍 Technical Root Cause
The bug resides in https://github.com/shadcn-ui/ui/blob/main/apps/v4/registry/bases/base/ui/slider.tsx#L13 within the calculation of the internal _values array:
// Current Buggy Implementation
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max],
);
Incorrect Logic: If value is a number (e.g. 0.5), the Array.isArray(value) check fails, and it defaults to [min, max].
Reference Instability: When developers pass [field.value], a new array reference is created on every render. Because value is a dependency of useMemo, the internal _values array is recalculated constantly, causing the primitive to lose its internal transition/drag state.
Proposed Fix: Update the useMemo block to explicitly check for undefined and properly wrap single values in an array:
const _values = React.useMemo(() => {
if (Array.isArray(value)) return value;
if (value !== undefined) return [value];
if (Array.isArray(defaultValue)) return defaultValue;
if (defaultValue !== undefined) return [defaultValue];
return [max]; // Default to single thumb
}, [value, defaultValue, max]);
This change allows the component to support the standard API expected by Shadcn users while maintaining stable references for single-thumb sliders.
Affected component/components
Slider
How to reproduce
- Use the component in a controlled form.
- Pass a single number to the value prop:
- Observed Behavior: The slider renders two thumbs (one at 0, one at 100).
- Attempt to fix it by passing an array:
Observed Behavior: The slider "stutters" or remains frozen because the internal useMemo triggers a re-render on every mouse movement, dropping the active drag state of the primitive.
Codesandbox/StackBlitz link
No response
Logs
System Info
Before submitting
Describe the bug
The Shadcn Slider component does not correctly parse single numeric values for the value or defaultValue props. It incorrectly falls back to a dual-thumb state [min, max] when it should render a single-thumb state [value].
Furthermore, because of an unstable dependency check in React.useMemo, wrapping the value in an array (e.g., value={[field.value]}) causes infinite re-renders during drag interactions, making the component unusable in controlled forms (like react-hook-form).
🔍 Technical Root Cause
The bug resides in https://github.com/shadcn-ui/ui/blob/main/apps/v4/registry/bases/base/ui/slider.tsx#L13 within the calculation of the internal _values array:
// Current Buggy Implementation
Incorrect Logic: If value is a number (e.g. 0.5), the Array.isArray(value) check fails, and it defaults to [min, max].
Reference Instability: When developers pass [field.value], a new array reference is created on every render. Because value is a dependency of useMemo, the internal _values array is recalculated constantly, causing the primitive to lose its internal transition/drag state.
Proposed Fix: Update the useMemo block to explicitly check for undefined and properly wrap single values in an array:
This change allows the component to support the standard API expected by Shadcn users while maintaining stable references for single-thumb sliders.
Affected component/components
Slider
How to reproduce
Observed Behavior: The slider "stutters" or remains frozen because the internal useMemo triggers a re-render on every mouse movement, dropping the active drag state of the primitive.
Codesandbox/StackBlitz link
No response
Logs
System Info
Before submitting