Skip to content

Commit 04ed4ba

Browse files
authored
V2 Slider Test (#296)
* update slider to vitest * fix: types * refactor: streamline slider tests by removing unnecessary wait statements * feat: add SliderLabel component and enhance accessibility
1 parent fb12cd8 commit 04ed4ba

File tree

8 files changed

+574
-588
lines changed

8 files changed

+574
-588
lines changed

libs/components/src/slider/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { SliderRoot as Root } from "./slider-root";
2+
export { SliderLabel as Label } from "./slider-label";
23
export { SliderTrack as Track } from "./slider-track";
34
export { SliderRange as Range } from "./slider-range";
45
export { SliderThumb as Thumb } from "./slider-thumb";

libs/components/src/slider/slider-context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface SliderContext {
1818
thumbType: Signal<ThumbType | undefined>;
1919
onChange$?: (value: SliderValue) => void;
2020
onChangeEnd$?: (value: SliderValue) => void;
21+
localId: string;
2122
}
2223

2324
export const sliderContextId = createContextId<SliderContext>("slider-context");
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { type PropsOf, Slot, component$, useContext } from "@qwik.dev/core";
2+
import { Render } from "../render/render";
3+
import { sliderContextId } from "./slider-context";
4+
5+
type PublicLabelProps = PropsOf<"span">;
6+
7+
/** Label component for slider that automatically connects to the slider via aria-labelledby */
8+
export const SliderLabel = component$((props: PublicLabelProps) => {
9+
const context = useContext(sliderContextId);
10+
const labelId = `${context.localId}-label`;
11+
12+
return (
13+
<Render {...props} id={labelId} data-qds-slider-label fallback="span">
14+
<Slot />
15+
</Render>
16+
);
17+
});

libs/components/src/slider/slider-root.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
component$,
88
useComputed$,
99
useContextProvider,
10+
useId,
1011
useSignal,
1112
useStyles$,
1213
useTask$
@@ -50,6 +51,9 @@ export const SliderRoot = component$<PublicRootProps>((props) => {
5051
...divProps
5152
} = props;
5253

54+
const localId = useId();
55+
const labelId = `${localId}-label`;
56+
5357
const isRangeSignal = useSignal(isRange);
5458

5559
const valueSignal = useSignal<SliderValue>(
@@ -143,7 +147,8 @@ export const SliderRoot = component$<PublicRootProps>((props) => {
143147
calculateValue,
144148
onChange$,
145149
onChangeEnd$,
146-
thumbType: useSignal<ThumbType | undefined>(undefined)
150+
thumbType: useSignal<ThumbType | undefined>(undefined),
151+
localId
147152
};
148153

149154
useContextProvider(sliderContextId, context);
@@ -163,6 +168,7 @@ export const SliderRoot = component$<PublicRootProps>((props) => {
163168
aria-valuemin={min.value}
164169
aria-valuemax={max.value}
165170
aria-valuenow={ariaValueNow.value}
171+
aria-labelledby={labelId}
166172
>
167173
<Slot />
168174
</div>

libs/components/src/slider/slider-thumb.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ export const SliderThumb = component$((props: PublicThumbProps) => {
184184
}
185185
});
186186

187+
const thumbLabelId = `${context.localId}-label`;
188+
187189
return (
188190
<div
189191
{...rest}
@@ -209,6 +211,7 @@ export const SliderThumb = component$((props: PublicThumbProps) => {
209211
aria-valuemax={ariaValueMax.value}
210212
aria-valuenow={ariaValueNow.value}
211213
aria-disabled={context.disabled.value}
214+
aria-labelledby={thumbLabelId}
212215
>
213216
<Slot />
214217
</div>

0 commit comments

Comments
 (0)