Slider: Make inputId a required param and fix minor a11y violations (#112006)
* make inputId a required param for <Slider>, fix a11y violations * differentiate between slider and rangeslider
This commit is contained in:
@@ -833,16 +833,6 @@
|
||||
"count": 13
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx": {
|
||||
"no-restricted-syntax": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Slider/Slider.story.tsx": {
|
||||
"no-restricted-syntax": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Table/Cells/TableCell.tsx": {
|
||||
"@typescript-eslint/consistent-type-assertions": {
|
||||
"count": 3
|
||||
|
||||
@@ -9,8 +9,6 @@ const meta: Meta<typeof RangeSlider> = {
|
||||
controls: {
|
||||
exclude: ['tooltipAlwaysVisible'],
|
||||
},
|
||||
// TODO fix a11y issue in story and remove this
|
||||
a11y: { test: 'off' },
|
||||
},
|
||||
argTypes: {
|
||||
orientation: { control: { type: 'select', options: ['horizontal', 'vertical'] } },
|
||||
|
||||
@@ -3,6 +3,8 @@ import { Global } from '@emotion/react';
|
||||
import Slider, { SliderProps } from 'rc-slider';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
|
||||
import HandleTooltip from './HandleTooltip';
|
||||
@@ -44,6 +46,7 @@ export const RangeSlider = ({
|
||||
|
||||
const isHorizontal = orientation === 'horizontal';
|
||||
const styles = useStyles2(getStyles, isHorizontal);
|
||||
const dragHandleAriaLabel = t('grafana-ui.range-slider.drag-handle-aria-label', 'Use arrow keys to change the value');
|
||||
|
||||
const tipHandleRender: SliderProps['handleRender'] = (node, handleProps) => {
|
||||
return (
|
||||
@@ -73,6 +76,7 @@ export const RangeSlider = ({
|
||||
vertical={!isHorizontal}
|
||||
reverse={reverse}
|
||||
handleRender={tipHandleRender}
|
||||
ariaLabelForHandle={dragHandleAriaLabel}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import { useId } from 'react';
|
||||
|
||||
import { Field } from '../Forms/Field';
|
||||
|
||||
import { Slider } from './Slider';
|
||||
|
||||
@@ -12,8 +15,6 @@ const meta: Meta<typeof Slider> = {
|
||||
knobs: {
|
||||
disabled: true,
|
||||
},
|
||||
// TODO fix a11y issue in story and remove this
|
||||
a11y: { test: 'off' },
|
||||
},
|
||||
argTypes: {
|
||||
orientation: { control: { type: 'select', options: ['horizontal', 'vertical'] } },
|
||||
@@ -31,17 +32,25 @@ const meta: Meta<typeof Slider> = {
|
||||
};
|
||||
|
||||
export const Basic: StoryFn<typeof Slider> = (args) => {
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<div style={{ width: '300px', height: '300px' }}>
|
||||
<Slider {...args} />
|
||||
<Field label="Slider">
|
||||
<Slider {...args} inputId={id} />
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithMarks: StoryFn<typeof Slider> = (args) => {
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<div style={{ width: '300px', height: '300px' }}>
|
||||
<Slider {...args} />
|
||||
<Field label="Slider">
|
||||
<Slider {...args} inputId={id} />
|
||||
</Field>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { SliderProps } from './types';
|
||||
const sliderProps: SliderProps = {
|
||||
min: 10,
|
||||
max: 20,
|
||||
inputId: 'slider-test',
|
||||
};
|
||||
|
||||
describe('Slider', () => {
|
||||
|
||||
@@ -3,6 +3,8 @@ import { Global } from '@emotion/react';
|
||||
import SliderComponent from 'rc-slider';
|
||||
import { useState, useCallback, ChangeEvent, FocusEvent } from 'react';
|
||||
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
import { Input } from '../Input/Input';
|
||||
|
||||
@@ -24,11 +26,14 @@ export const Slider = ({
|
||||
ariaLabelForHandle,
|
||||
marks,
|
||||
included,
|
||||
inputId,
|
||||
}: SliderProps) => {
|
||||
const isHorizontal = orientation === 'horizontal';
|
||||
const styles = useStyles2(getStyles, isHorizontal, Boolean(marks));
|
||||
const SliderWithTooltip = SliderComponent;
|
||||
const [sliderValue, setSliderValue] = useState<number>(value ?? min);
|
||||
const dragHandleAriaLabel =
|
||||
ariaLabelForHandle ?? t('grafana-ui.slider.drag-handle-aria-label', 'Use arrow keys to change the value');
|
||||
|
||||
const onSliderChange = useCallback(
|
||||
(v: number | number[]) => {
|
||||
@@ -102,7 +107,7 @@ export const Slider = ({
|
||||
onChangeComplete={handleChangeComplete}
|
||||
vertical={!isHorizontal}
|
||||
reverse={reverse}
|
||||
ariaLabelForHandle={ariaLabelForHandle}
|
||||
ariaLabelForHandle={dragHandleAriaLabel}
|
||||
marks={marks}
|
||||
included={included}
|
||||
/>
|
||||
@@ -116,6 +121,7 @@ export const Slider = ({
|
||||
onBlur={onSliderInputBlur}
|
||||
min={min}
|
||||
max={max}
|
||||
id={inputId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface SliderProps extends CommonSliderProps {
|
||||
onAfterChange?: (value?: number) => void;
|
||||
formatTooltipResult?: (value: number) => number;
|
||||
ariaLabelForHandle?: string;
|
||||
inputId: string;
|
||||
}
|
||||
|
||||
export interface RangeSliderProps extends CommonSliderProps {
|
||||
|
||||
@@ -8697,6 +8697,9 @@
|
||||
"tooltip-hide": "Hide password",
|
||||
"tooltip-show": "Show password"
|
||||
},
|
||||
"range-slider": {
|
||||
"drag-handle-aria-label": "Use arrow keys to change the value"
|
||||
},
|
||||
"row-expander": {
|
||||
"aria-label-expand": "Expand row",
|
||||
"collapse": "Collapse row",
|
||||
@@ -8725,6 +8728,9 @@
|
||||
"series-color-picker-popover": {
|
||||
"y-axis-usage": "Use right y-axis"
|
||||
},
|
||||
"slider": {
|
||||
"drag-handle-aria-label": "Use arrow keys to change the value"
|
||||
},
|
||||
"spinner": {
|
||||
"aria-label": "Loading"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user