diff --git a/components/dash-core-components/src/components/RangeSlider.tsx b/components/dash-core-components/src/components/RangeSlider.tsx index 35f0f00845..b1d8175bf8 100644 --- a/components/dash-core-components/src/components/RangeSlider.tsx +++ b/components/dash-core-components/src/components/RangeSlider.tsx @@ -18,9 +18,16 @@ export default function RangeSlider({ persistence_type = PersistenceTypes.local, // eslint-disable-next-line no-magic-numbers verticalHeight = 400, - step = 1, + step = undefined, ...props }: RangeSliderProps) { + // Some considerations for the default value of `step`: + // If the range consists of integers, default to a value of `1` + // Otherwise, leave it undefined + if (Number.isInteger(props.min) && Number.isInteger(props.max)) { + step = 1; + } + return ( )} + {showInputs && !vertical && ( + { + const inputValue = e.target.value; + // Allow empty string (user is clearing the field) + if (inputValue === '') { + // Don't update props while user is typing, just update local state + const newValue = [...value]; + newValue[newValue.length - 1] = '' as any; + setValue(newValue); + } else { + const newMax = parseFloat(inputValue); + const constrainedMax = Math.max( + minMaxValues.min_mark, + Math.min(minMaxValues.max_mark, newMax) + ); + + if (newMax === constrainedMax) { + const newValue = [...value]; + newValue[newValue.length - 1] = newMax; + setProps({ + value: newValue, + drag_value: newValue, + }); + } + } + }} + onBlur={e => { + const inputValue = e.target.value; + let newMax: number; + + // If empty, default to current value or max_mark + if (inputValue === '') { + newMax = + value[value.length - 1] ?? + minMaxValues.max_mark; + } else { + newMax = parseFloat(inputValue); + newMax = isNaN(newMax) + ? minMaxValues.max_mark + : newMax; + } + + const constrainedMax = Math.min( + minMaxValues.max_mark, + Math.max( + value[0] ?? minMaxValues.min_mark, + newMax + ) + ); + const newValue = [...value]; + newValue[newValue.length - 1] = constrainedMax; + setValue(newValue); + if (updatemode === 'mouseup') { + setProps({value: newValue}); + } + }} + pattern="^\\d*\\.?\\d*$" + min={ + value.length === 1 + ? minMaxValues.min_mark + : value[0] + } + max={minMaxValues.max_mark} + step={step || undefined} + disabled={disabled} + /> + )}
e.preventDefault()} // prevent interactions from "clicking" the parent, particularly when slider is inside a label tag @@ -334,77 +405,6 @@ export default function RangeSlider(props: RangeSliderProps) { })}
- {showInputs && !vertical && ( - { - const inputValue = e.target.value; - // Allow empty string (user is clearing the field) - if (inputValue === '') { - // Don't update props while user is typing, just update local state - const newValue = [...value]; - newValue[newValue.length - 1] = '' as any; - setValue(newValue); - } else { - const newMax = parseFloat(inputValue); - const constrainedMax = Math.max( - minMaxValues.min_mark, - Math.min(minMaxValues.max_mark, newMax) - ); - - if (newMax === constrainedMax) { - const newValue = [...value]; - newValue[newValue.length - 1] = newMax; - setProps({ - value: newValue, - drag_value: newValue, - }); - } - } - }} - onBlur={e => { - const inputValue = e.target.value; - let newMax: number; - - // If empty, default to current value or max_mark - if (inputValue === '') { - newMax = - value[value.length - 1] ?? - minMaxValues.max_mark; - } else { - newMax = parseFloat(inputValue); - newMax = isNaN(newMax) - ? minMaxValues.max_mark - : newMax; - } - - const constrainedMax = Math.min( - minMaxValues.max_mark, - Math.max( - value[0] ?? minMaxValues.min_mark, - newMax - ) - ); - const newValue = [...value]; - newValue[newValue.length - 1] = constrainedMax; - setValue(newValue); - if (updatemode === 'mouseup') { - setProps({value: newValue}); - } - }} - pattern="^\\d*\\.?\\d*$" - min={ - value.length === 1 - ? minMaxValues.min_mark - : value[0] - } - max={minMaxValues.max_mark} - step={step || undefined} - disabled={disabled} - /> - )} )} diff --git a/components/dash-core-components/tests/integration/misc/test_dcc_components_as_props.py b/components/dash-core-components/tests/integration/misc/test_dcc_components_as_props.py index 6145477636..df9191ae03 100644 --- a/components/dash-core-components/tests/integration/misc/test_dcc_components_as_props.py +++ b/components/dash-core-components/tests/integration/misc/test_dcc_components_as_props.py @@ -54,6 +54,7 @@ def test_mdcap001_dcc_components_as_props(dash_dcc): search_input = dash_dcc.find_element("#dropdown .dash-dropdown-search") search_input.send_keys("4") + sleep(0.25) options = dash_dcc.find_elements("#dropdown .dash-dropdown-option") wait.until(lambda: len(options) == 1, 1)