From 84012a0f4aead32cc9f63478f608a58bbd4b6bec Mon Sep 17 00:00:00 2001 From: Dante Date: Wed, 21 Oct 2026 22:12:03 +0800 Subject: [PATCH] fix(player): include visible playback rate in accessible name --- packages/player/src/controls.test.ts | 27 +++++++++++++++++++++++++++ packages/player/src/controls.ts | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/player/src/controls.test.ts b/packages/player/src/controls.test.ts index afa75a7c126..ffc86f83a51 100644 --- a/packages/player/src/controls.test.ts +++ b/packages/player/src/controls.test.ts @@ -76,3 +76,30 @@ describe("createControls host listeners", () => { host.remove(); }); }); + +describe("createControls playback speed name", () => { + it("includes the visible rate initially and after menu and API updates", () => { + const host = document.createElement("div"); + const onSpeedChange = vi.fn(); + const api = createControls(host, { ...noopCallbacks(), onSpeedChange }); + const speedButton = host.querySelector(".hfp-speed-btn"); + + expect(speedButton?.textContent).toBe("1x"); + expect(speedButton?.getAttribute("aria-label")).toBe("Playback speed: 1x"); + + const option = host.querySelector('[data-speed="1.5"]'); + expect(option).not.toBeNull(); + option?.click(); + + expect(speedButton?.textContent).toBe("1.5x"); + expect(speedButton?.getAttribute("aria-label")).toBe("Playback speed: 1.5x"); + expect(onSpeedChange).toHaveBeenCalledWith(1.5); + + api.updateSpeed(2); + + expect(speedButton?.textContent).toBe("2x"); + expect(speedButton?.getAttribute("aria-label")).toBe("Playback speed: 2x"); + + api.destroy(); + }); +}); diff --git a/packages/player/src/controls.ts b/packages/player/src/controls.ts index 7b9da6343ed..2cef825a689 100644 --- a/packages/player/src/controls.ts +++ b/packages/player/src/controls.ts @@ -101,7 +101,7 @@ export function createControls( speedBtn.className = "hfp-speed-btn"; speedBtn.type = "button"; speedBtn.textContent = "1x"; - speedBtn.setAttribute("aria-label", "Playback speed"); + speedBtn.setAttribute("aria-label", "Playback speed: 1x"); const speedMenu = document.createElement("div"); speedMenu.className = "hfp-speed-menu"; @@ -273,6 +273,7 @@ export function createControls( const newSpeed = parseFloat(target.dataset.speed!); speedIndex = presets.indexOf(newSpeed); speedBtn.textContent = formatSpeed(newSpeed); + speedBtn.setAttribute("aria-label", `Playback speed: ${formatSpeed(newSpeed)}`); setActiveOption(newSpeed); speedMenu.classList.remove("hfp-open"); speedBtn.setAttribute("aria-expanded", "false"); @@ -374,6 +375,7 @@ export function createControls( const idx = presets.indexOf(speed); if (idx !== -1) speedIndex = idx; speedBtn.textContent = formatSpeed(speed); + speedBtn.setAttribute("aria-label", `Playback speed: ${formatSpeed(speed)}`); setActiveOption(speed); }, updateMuted(muted: boolean) {