Slider: Adjusts input to enforce min/max values on blur (#40524) (#40637)

* [cr] adjusts slider input to enfore min/max values on blur

* [cr] additional test for blur action, min/max readability

(cherry picked from commit 70f68289f5)

Co-authored-by: Coleman Rollins <crollins199@gmail.com>
This commit is contained in:
Grot (@grafanabot)
2021-10-19 17:15:27 +02:00
committed by GitHub
co-authored by Coleman Rollins
parent 7def66fdb6
commit d70d30c31e
2 changed files with 43 additions and 5 deletions
@@ -26,4 +26,29 @@ describe('Slider', () => {
expect(wrapper.html()).not.toContain('aria-valuenow="20"');
expect(wrapper.html()).not.toContain('aria-valuenow="10"');
});
it('allows for custom values to be set in the input', () => {
const wrapper = mount(<Slider {...sliderProps} value={10} min={10} max={100} />);
const sliderInput = wrapper.find('input');
sliderInput.simulate('focus');
sliderInput.simulate('change', { target: { value: 50 } });
sliderInput.simulate('blur');
expect(wrapper.html()).toContain('aria-valuenow="50"');
});
it('defaults after blur if input value is outside of range', () => {
const wrapper = mount(<Slider {...sliderProps} value={10} min={10} max={100} />);
const sliderInput = wrapper.find('input');
sliderInput.simulate('focus');
sliderInput.simulate('change', { target: { value: 200 } });
// re-grab to check value is out of range before blur
const sliderInputIncorrect = wrapper.find('input');
expect(sliderInputIncorrect.get(0).props.value).toEqual('200');
sliderInput.simulate('blur');
expect(wrapper.html()).toContain('aria-valuenow="100"');
// re-grab to check value is back inside range
const sliderInputCorrect = wrapper.find('input');
expect(sliderInputCorrect.get(0).props.value).toEqual('100');
});
});
@@ -1,4 +1,4 @@
import React, { useState, useCallback, ChangeEvent, FunctionComponent } from 'react';
import React, { useState, useCallback, ChangeEvent, FunctionComponent, FocusEvent } from 'react';
import SliderComponent from 'rc-slider';
import { cx } from '@emotion/css';
import { Global } from '@emotion/react';
@@ -45,9 +45,6 @@ export const Slider: FunctionComponent<SliderProps> = ({
v = 0;
}
v > max && (v = max);
v < min && (v = min);
setSliderValue(v);
if (onChange) {
@@ -58,7 +55,22 @@ export const Slider: FunctionComponent<SliderProps> = ({
onAfterChange(v);
}
},
[max, min, onChange, onAfterChange]
[onChange, onAfterChange]
);
// Check for min/max on input blur so user is able to enter
// custom values that might seem above/below min/max on first keystroke
const onSliderInputBlur = useCallback(
(e: FocusEvent<HTMLInputElement>) => {
const v = +e.target.value;
if (v > max) {
setSliderValue(max);
} else if (v < min) {
setSliderValue(min);
}
},
[max, min]
);
const sliderInputClassNames = !isHorizontal ? [styles.sliderInputVertical] : [];
@@ -86,6 +98,7 @@ export const Slider: FunctionComponent<SliderProps> = ({
className={cx(styles.sliderInputField, ...sliderInputFieldClassNames)}
value={`${sliderValue}`} // to fix the react leading zero issue
onChange={onSliderInputChange}
onBlur={onSliderInputBlur}
min={min}
max={max}
/>