@@ -30,8 +30,8 @@ export default function RangeSlider(props: RangeSliderProps) {
3030 setProps,
3131 tooltip,
3232 updatemode,
33- min = 0 ,
34- max = 100 ,
33+ min,
34+ max,
3535 marks,
3636 step,
3737 vertical,
@@ -46,7 +46,7 @@ export default function RangeSlider(props: RangeSliderProps) {
4646 } = props ;
4747
4848 // For range slider, we expect an array of values
49- const [ value , setValue ] = useState < number [ ] > ( propValue || [ min , max ] ) ;
49+ const [ value , setValue ] = useState < number [ ] > ( propValue || [ ] ) ;
5050
5151 // Track slider dimension (width for horizontal, height for vertical) for conditional input rendering
5252 const [ sliderWidth , setSliderWidth ] = useState < number | null > ( null ) ;
@@ -60,8 +60,7 @@ export default function RangeSlider(props: RangeSliderProps) {
6060 setValue ( propValue ) ;
6161 } else {
6262 // Default to range from min to max if no value provided
63- const defaultValue = [ min , max ] ;
64- setProps ( { drag_value : defaultValue } ) ;
63+ const defaultValue = [ min ?? ( propValue ? propValue [ 0 ] : 0 ) ] ;
6564 setValue ( defaultValue ) ;
6665 }
6766 } , [ ] ) ;
@@ -80,7 +79,7 @@ export default function RangeSlider(props: RangeSliderProps) {
8079 return ;
8180 }
8281
83- if ( value . length !== 2 ) {
82+ if ( ! value || value . length > 2 ) {
8483 setShowInputs ( false ) ;
8584 return ;
8685 }
@@ -93,8 +92,10 @@ export default function RangeSlider(props: RangeSliderProps) {
9392 if ( dimension > 0 ) {
9493 setSliderWidth ( dimension ) ;
9594
96- const HIDE_AT_WIDTH = 250 ;
97- const SHOW_AT_WIDTH = 450 ;
95+ // eslint-disable-next-line no-magic-numbers
96+ const HIDE_AT_WIDTH = value . length === 1 ? 200 : 250 ;
97+ // eslint-disable-next-line no-magic-numbers
98+ const SHOW_AT_WIDTH = value . length === 1 ? 300 : 450 ;
9899 if ( showInputs && dimension < HIDE_AT_WIDTH ) {
99100 setShowInputs ( false ) ;
100101 } else if ( ! showInputs && dimension >= SHOW_AT_WIDTH ) {
@@ -131,12 +132,17 @@ export default function RangeSlider(props: RangeSliderProps) {
131132
132133 // Check if marks exceed 500 limit for performance
133134 let processedMarks = marks ;
134- if ( marks && Object . keys ( marks ) . length > MAX_MARKS ) {
135- /* eslint-disable no-console */
136- console . warn (
137- `RangeSlider marks exceed ${ MAX_MARKS } limit for performance. Marks have been disabled.`
138- ) ;
139- processedMarks = undefined ;
135+ if ( marks && typeof marks === 'object' && marks !== null ) {
136+ const marksCount = Object . keys ( marks ) . length ;
137+ if ( marksCount > MAX_MARKS ) {
138+ /* eslint-disable no-console */
139+ console . error (
140+ `Slider: Too many marks (${ marksCount } ) provided. ` +
141+ `For performance reasons, marks are limited to 500. ` +
142+ `Using auto-generated marks instead.`
143+ ) ;
144+ processedMarks = undefined ;
145+ }
140146 }
141147
142148 const minMaxValues = useMemo ( ( ) => {
@@ -218,7 +224,7 @@ export default function RangeSlider(props: RangeSliderProps) {
218224 className = "dash-slider-container"
219225 { ...loadingProps }
220226 >
221- { showInputs && ! vertical && (
227+ { showInputs && value . length === 2 && ! vertical && (
222228 < input
223229 type = "number"
224230 className = "dash-input-container dash-range-slider-input dash-range-slider-min-input"
@@ -272,6 +278,7 @@ export default function RangeSlider(props: RangeSliderProps) {
272278 setProps ( { value : newValue } ) ;
273279 }
274280 } }
281+ pattern = "^\\d*\\.?\\d*$"
275282 min = { minMaxValues . min_mark }
276283 max = { value [ 1 ] }
277284 step = { step || undefined }
@@ -378,26 +385,29 @@ export default function RangeSlider(props: RangeSliderProps) {
378385 < input
379386 type = "number"
380387 className = "dash-input-container dash-range-slider-input"
381- value = { value [ 1 ] ?? '' }
388+ value = { value [ value . length - 1 ] ?? '' }
382389 onChange = { e => {
383390 const inputValue = e . target . value ;
384391 // Allow empty string (user is clearing the field)
385392 if ( inputValue === '' ) {
386393 // Don't update props while user is typing, just update local state
387- setValue ( [ value [ 0 ] , null as any ] ) ;
394+ const newValue = [ ...value ] ;
395+ newValue [ newValue . length - 1 ] = '' as any ;
396+ setValue ( newValue ) ;
388397 } else {
389398 const newMax = parseFloat ( inputValue ) ;
390- if ( ! isNaN ( newMax ) ) {
391- const newValue = [ value [ 0 ] , newMax ] ;
392- setValue ( newValue ) ;
393- if ( updatemode === 'drag' ) {
394- setProps ( {
395- value : newValue ,
396- drag_value : newValue ,
397- } ) ;
398- } else {
399- setProps ( { drag_value : newValue } ) ;
400- }
399+ const constrainedMax = Math . max (
400+ minMaxValues . min_mark ,
401+ Math . min ( minMaxValues . max_mark , newMax )
402+ ) ;
403+
404+ if ( newMax === constrainedMax ) {
405+ const newValue = [ ...value ] ;
406+ newValue [ newValue . length - 1 ] = newMax ;
407+ setProps ( {
408+ value : newValue ,
409+ drag_value : newValue ,
410+ } ) ;
401411 }
402412 }
403413 } }
@@ -407,7 +417,9 @@ export default function RangeSlider(props: RangeSliderProps) {
407417
408418 // If empty, default to current value or max_mark
409419 if ( inputValue === '' ) {
410- newMax = value [ 1 ] ?? minMaxValues . max_mark ;
420+ newMax =
421+ value [ value . length - 1 ] ??
422+ minMaxValues . max_mark ;
411423 } else {
412424 newMax = parseFloat ( inputValue ) ;
413425 newMax = isNaN ( newMax )
@@ -422,13 +434,19 @@ export default function RangeSlider(props: RangeSliderProps) {
422434 newMax
423435 )
424436 ) ;
425- const newValue = [ value [ 0 ] , constrainedMax ] ;
437+ const newValue = [ ...value ] ;
438+ newValue [ newValue . length - 1 ] = constrainedMax ;
426439 setValue ( newValue ) ;
427440 if ( updatemode === 'mouseup' ) {
428441 setProps ( { value : newValue } ) ;
429442 }
430443 } }
431- min = { value [ 0 ] }
444+ pattern = "^\\d*\\.?\\d*$"
445+ min = {
446+ value . length === 1
447+ ? minMaxValues . min_mark
448+ : value [ 0 ]
449+ }
432450 max = { minMaxValues . max_mark }
433451 step = { step || undefined }
434452 disabled = { disabled }
0 commit comments