mirror of
https://github.com/captbaritone/webamp.git
synced 2026-11-07 10:25:59 -10:00
Add aria-valuetext to the seeking, volume and balance sliders
Screen readers announced these range inputs as bare numbers (e.g. "26" for the seeking bar). Describe their values instead: - Seeking Bar: "0:32 of 2:00" (the scrub position while dragging) - Volume Bar: "75%" - Balance: "Center", "20% Left" or "20% Right"
This commit is contained in:
1 parent
504eea5288
commit
7794463bfc
5 files changed
+42
-4
No files matched your search
@@ -0,0 +1,9 @@
|
||||
import { balanceValueText } from "./Balance";
|
||||
|
||||
describe("balanceValueText", () => {
|
||||
it("describes the balance", () => {
|
||||
expect(balanceValueText(0)).toBe("Center");
|
||||
expect(balanceValueText(-20)).toBe("20% Left");
|
||||
expect(balanceValueText(100)).toBe("100% Right");
|
||||
});
|
||||
});
|
||||
@@ -4,6 +4,14 @@ import * as Actions from "../actionCreators";
|
||||
import * as Selectors from "../selectors";
|
||||
import { useTypedSelector, useActionCreator } from "../hooks";
|
||||
|
||||
// E.g. "Center" or "20% Left"
|
||||
export function balanceValueText(balance: number): string {
|
||||
if (balance === 0) {
|
||||
return "Center";
|
||||
}
|
||||
return `${Math.abs(balance)}% ${balance > 0 ? "Right" : "Left"}`;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
id?: string;
|
||||
style?: React.CSSProperties;
|
||||
@@ -29,6 +37,7 @@ export default function Balance({ style, className, id }: Props) {
|
||||
onPointerDown={() => setFocus("balance")}
|
||||
onPointerUp={unsetFocus}
|
||||
title="Balance"
|
||||
aria-valuetext={balanceValueText(balance)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -125,4 +125,14 @@ describe("Position", () => {
|
||||
pointer("pointerup");
|
||||
expect(seeks()).toEqual([60]);
|
||||
});
|
||||
|
||||
it("describes the position as elapsed time of total time", () => {
|
||||
expect(input.getAttribute("aria-valuetext")).toBe("0:30 of 2:00");
|
||||
});
|
||||
|
||||
it("describes the scrub position while dragging", () => {
|
||||
pointer("pointerdown");
|
||||
changeValue("50");
|
||||
expect(input.getAttribute("aria-valuetext")).toBe("1:00 of 2:00");
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import { FormEvent, KeyboardEvent, memo, useCallback, useRef } from "react";
|
||||
import * as Selectors from "../../selectors";
|
||||
import * as Actions from "../../actionCreators";
|
||||
import { getTimeStr } from "../../utils";
|
||||
import { useTypedSelector, useTypedDispatch } from "../../hooks";
|
||||
|
||||
function usePosition() {
|
||||
@@ -10,14 +11,21 @@ function usePosition() {
|
||||
const scrubPosition = useTypedSelector(Selectors.getUserInputScrubPosition);
|
||||
const userInputFocus = useTypedSelector(Selectors.getUserInputFocus);
|
||||
|
||||
const displayedPosition =
|
||||
userInputFocus === "position" ? scrubPosition : position;
|
||||
const scrubbing = userInputFocus === "position";
|
||||
const displayedPosition = scrubbing ? scrubPosition : position;
|
||||
|
||||
return [position, displayedPosition];
|
||||
// E.g. "0:32 of 2:00"
|
||||
let valueText;
|
||||
if (duration != null) {
|
||||
const time = scrubbing ? (duration * scrubPosition) / 100 : timeElapsed;
|
||||
valueText = `${getTimeStr(time)} of ${getTimeStr(duration)}`;
|
||||
}
|
||||
|
||||
return [position, displayedPosition, valueText] as const;
|
||||
}
|
||||
|
||||
const Position = memo(() => {
|
||||
const [position, displayedPosition] = usePosition();
|
||||
const [position, displayedPosition, valueText] = usePosition();
|
||||
const dispatch = useTypedDispatch();
|
||||
|
||||
const seekToPercentComplete = useCallback(
|
||||
@@ -124,6 +132,7 @@ const Position = memo(() => {
|
||||
onPointerUp={handlePointerUp}
|
||||
onPointerDown={handlePointerDown}
|
||||
title="Seeking Bar"
|
||||
aria-valuetext={valueText}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ export default function Volume({ id, style, className }: Props) {
|
||||
onPointerDown={() => setFocus("volume")}
|
||||
onPointerUp={unsetFocus}
|
||||
title="Volume Bar"
|
||||
aria-valuetext={`${volume}%`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user