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

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

* [cr] additional test for blur action, min/max readability
geomap-multiple-layers
Coleman Rollins 4 years ago committed by GitHub
parent e48d77b1eb
commit 70f68289f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      packages/grafana-ui/src/components/Slider/Slider.test.tsx
  2. 23
      packages/grafana-ui/src/components/Slider/Slider.tsx

@ -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';
@ -46,9 +46,6 @@ export const Slider: FunctionComponent<SliderProps> = ({
v = 0;
}
v > max && (v = max);
v < min && (v = min);
setSliderValue(v);
if (onChange) {
@ -59,7 +56,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] : [];
@ -88,6 +100,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}
/>

Loading…
Cancel
Save