Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Then open `http://localhost:8000`.
| `ariaLabelledByForHandle` | string \| string[] | - | `aria-labelledby` for handle elements. |
| `ariaDescribedByForHandle` | string \| string[] | - | `aria-describedby` for handle elements. |
| `ariaRequired` | boolean | - | `aria-required` for handle elements. |
| `ariaInvalid` | `AriaInvalid` | - | `aria-invalid` for handle elements. |
| `ariaInvalidForHandle` | `AriaInvalid \| AriaInvalid[]` | - | `aria-invalid` for handle elements. Omitted entries fall back to `ariaInvalid`. |
| `ariaValueTextFormatterForHandle` | `((value: number) => string) \| ((value: number) => string)[]` | - | Formatter for `aria-valuetext`. |
| `autoFocus` | boolean | - | Focus the slider on mount. |
| `className` | string | - | Additional class name. |
Expand Down
2 changes: 2 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ npm start
| `ariaLabelledByForHandle` | string \| string[] | - | `aria-labelledby` for handle elements. |
| `ariaDescribedByForHandle` | string \| string[] | - | 句柄元素的 `aria-describedby`。 |
| `ariaRequired` | boolean | - | 句柄元素的 `aria-required`。 |
| `ariaInvalid` | boolean | - | 句柄元素的 `aria-invalid`。 |
| `ariaInvalidForHandle` | `AriaInvalid \| AriaInvalid[]` | - | 句柄元素的 `aria-invalid`。 |
| `ariaValueTextFormatterForHandle` | `((value: number) => string) \| ((value: number) => string)[]` | - | `aria-valuetext` 格式化函数。 |
| `autoFocus` | boolean | - | 挂载后自动聚焦滑块。 |
| `className` | string | - | 附加 className。 |
Expand Down
3 changes: 3 additions & 0 deletions src/Handles/Handle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
ariaLabelledByForHandle,
ariaDescribedByForHandle,
ariaRequired,
ariaInvalid,
ariaInvalidForHandle,
ariaValueTextFormatterForHandle,
styles,
classNames,
Expand Down Expand Up @@ -176,6 +178,7 @@ const Handle = React.forwardRef<HTMLDivElement, HandleProps>((props, ref) => {
'aria-labelledby': getIndex(ariaLabelledByForHandle, valueIndex),
'aria-describedby': getIndex(ariaDescribedByForHandle, valueIndex),
'aria-required': getIndex(ariaRequired, valueIndex),
'aria-invalid': getIndex(ariaInvalidForHandle, valueIndex) ?? ariaInvalid,
'aria-valuetext': getIndex(ariaValueTextFormatterForHandle, valueIndex)?.(value),
'aria-orientation': direction === 'ltr' || direction === 'rtl' ? 'horizontal' : 'vertical',
onMouseDown: onInternalStartMove,
Expand Down
9 changes: 9 additions & 0 deletions src/Slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import useDrag from './hooks/useDrag';
import useOffset, { getClosestEnabledHandleIndex } from './hooks/useOffset';
import useRange from './hooks/useRange';
import type {
AriaInvalid,
AriaValueFormat,
Direction,
OnStartMove,
Expand Down Expand Up @@ -115,6 +116,8 @@ export interface SliderProps<ValueType = number | number[]> {
ariaLabelledByForHandle?: string | string[];
ariaDescribedByForHandle?: string | string[];
ariaRequired?: boolean;
ariaInvalid?: AriaInvalid;
ariaInvalidForHandle?: AriaInvalid | AriaInvalid[];
ariaValueTextFormatterForHandle?: AriaValueFormat | AriaValueFormat[];
}

Expand Down Expand Up @@ -184,6 +187,8 @@ const Slider = React.forwardRef<SliderRef, SliderProps<number | number[]>>((prop
ariaLabelledByForHandle,
ariaDescribedByForHandle,
ariaRequired,
ariaInvalid,
ariaInvalidForHandle,
ariaValueTextFormatterForHandle,
} = props;

Expand Down Expand Up @@ -594,6 +599,8 @@ const Slider = React.forwardRef<SliderRef, SliderProps<number | number[]>>((prop
ariaLabelledByForHandle,
ariaDescribedByForHandle,
ariaRequired,
ariaInvalid,
ariaInvalidForHandle,
ariaValueTextFormatterForHandle,
styles: styles || {},
classNames: classNames || {},
Expand All @@ -615,6 +622,8 @@ const Slider = React.forwardRef<SliderRef, SliderProps<number | number[]>>((prop
ariaLabelledByForHandle,
ariaDescribedByForHandle,
ariaRequired,
ariaInvalid,
ariaInvalidForHandle,
ariaValueTextFormatterForHandle,
styles,
classNames,
Expand Down
4 changes: 3 additions & 1 deletion src/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import type { AriaValueFormat, Direction, SliderClassNames, SliderStyles } from './interface';
import type { AriaInvalid, AriaValueFormat, Direction, SliderClassNames, SliderStyles } from './interface';

export interface SliderContextProps {
min: number;
Expand All @@ -17,6 +17,8 @@ export interface SliderContextProps {
ariaLabelledByForHandle?: string | string[];
ariaDescribedByForHandle?: string | string[];
ariaRequired?: boolean;
ariaInvalid?: AriaInvalid;
ariaInvalidForHandle?: AriaInvalid | AriaInvalid[];
ariaValueTextFormatterForHandle?: AriaValueFormat | AriaValueFormat[];
classNames: SliderClassNames;
styles: SliderStyles;
Expand Down
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Slider, { type SliderProps, type SliderRef } from './Slider';
export { UnstableContext } from './context';

export type { AriaInvalid } from './interface';
export type { SliderProps, SliderRef };

export default Slider;
2 changes: 2 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export type OnStartMove = (

export type AriaValueFormat = (value: number) => string;

export type AriaInvalid = boolean | 'grammar' | 'spelling';

export type SemanticName = 'tracks' | 'track' | 'rail' | 'handle';

export type SliderClassNames = Partial<Record<SemanticName, string>>;
Expand Down
35 changes: 35 additions & 0 deletions tests/Range.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,32 @@ describe('Range', () => {
);
});

it('sets aria-invalid on the handles', () => {
const { container } = render(
<Slider range ariaInvalidForHandle={[true, false]} />,
);
expect(container.getElementsByClassName('rc-slider-handle')[0]).toHaveAttribute(
'aria-invalid',
'true',
);
expect(container.getElementsByClassName('rc-slider-handle')[1]).toHaveAttribute(
'aria-invalid',
'false',
);
});

it('sets aria-invalid on the handles using ariaInvalid prop', () => {
const { container } = render(<Slider range ariaInvalid={true} />);
expect(container.getElementsByClassName('rc-slider-handle')[0]).toHaveAttribute(
'aria-invalid',
'true',
);
expect(container.getElementsByClassName('rc-slider-handle')[1]).toHaveAttribute(
'aria-invalid',
'true',
);
});

it('sets aria-valuetext on the handles', () => {
const { container } = render(
<Slider
Expand Down Expand Up @@ -1181,3 +1207,12 @@ describe('Range', () => {
});
});
});

it('falls back to global aria-invalid for omitted range entries', () => {
const { container } = render(
<Slider range ariaInvalid="grammar" ariaInvalidForHandle={[false]} />,
);
const handles = container.getElementsByClassName('rc-slider-handle');
expect(handles[0]).toHaveAttribute('aria-invalid', 'false');
expect(handles[1]).toHaveAttribute('aria-invalid', 'grammar');
});
16 changes: 16 additions & 0 deletions tests/Slider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,22 @@ describe('Slider', () => {
);
});

it('sets aria-invalid on the handle', () => {
const { container } = render(<Slider ariaInvalid={true} />);
expect(container.getElementsByClassName('rc-slider-handle')[0]).toHaveAttribute(
'aria-invalid',
'true',
);
});

it('sets aria-invalid on the handle with ariaInvalidForHandle', () => {
const { container } = render(<Slider ariaInvalidForHandle="grammar" />);
expect(container.getElementsByClassName('rc-slider-handle')[0]).toHaveAttribute(
'aria-invalid',
'grammar',
);
});

it('sets aria-valuetext on the handle', () => {
const { container } = render(
<Slider
Expand Down