From f9aceb3d02bd1eefd5037a664472456c9769e74f Mon Sep 17 00:00:00 2001 From: Robert Knight <95928279+microbit-robert@users.noreply.github.com> Date: Thu, 2 Apr 2026 18:10:27 +0100 Subject: [PATCH 1/3] Add ariaDisabled prop to button (#11236) aria-disabled uses the ariaDisabled or disabled props to inform screen readers that the button is dimmed or unavailable etc. Remove title from undo / redo buttons as aria-label is present. Co-authored-by: Richard Knoll --- webapp/src/editortoolbar.tsx | 4 ++-- webapp/src/sui.tsx | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/webapp/src/editortoolbar.tsx b/webapp/src/editortoolbar.tsx index 909a045c575c..270c05df45ca 100644 --- a/webapp/src/editortoolbar.tsx +++ b/webapp/src/editortoolbar.tsx @@ -172,8 +172,8 @@ export class EditorToolbar extends data.Component, - + , + ]; } diff --git a/webapp/src/sui.tsx b/webapp/src/sui.tsx index 1754b0e033b6..460a0493ed51 100644 --- a/webapp/src/sui.tsx +++ b/webapp/src/sui.tsx @@ -511,6 +511,7 @@ export interface ButtonProps extends UiProps, TooltipUIProps { id?: string; title?: string; ariaLabel?: string; + ariaDisabled?: boolean; ariaExpanded?: boolean; onClick?: (e: React.MouseEvent) => void; disabled?: boolean; @@ -539,6 +540,7 @@ export class Button extends StatelessUIElement { tabIndex={this.props.tabIndex || 0} aria-label={this.props.ariaLabel} aria-expanded={this.props.ariaExpanded} + aria-disabled={this.props.ariaDisabled ?? disabled} onClick={this.props.onClick} onKeyDown={this.props.onKeyDown} autoFocus={this.props.autoFocus} From 5c0d7d17d007ba9b4a3c36cffbf68d2e9cc0db8f Mon Sep 17 00:00:00 2001 From: Sarah Rietkerk <49178322+srietkerk@users.noreply.github.com> Date: Thu, 2 Apr 2026 10:50:46 -0700 Subject: [PATCH 2/3] only use new spatial audio if new apis are available (#11235) Co-authored-by: Richard Knoll --- pxtsim/sound/audioContextManager.ts | 12 ++++++-- pxtsim/sound/spatialAudioPlayer.ts | 46 +++++++++++++++++++---------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/pxtsim/sound/audioContextManager.ts b/pxtsim/sound/audioContextManager.ts index 80f44d22ba0a..bcbe36f90532 100644 --- a/pxtsim/sound/audioContextManager.ts +++ b/pxtsim/sound/audioContextManager.ts @@ -348,9 +348,15 @@ namespace pxsim.AudioContextManager { export function setListenerPosition(x: number, y: number, z: number) { const ctx = context(); if (ctx) { - ctx.listener.positionX.setTargetAtTime(x, 0, 0.02); - ctx.listener.positionY.setTargetAtTime(y, 0, 0.02); - ctx.listener.positionZ.setTargetAtTime(z, 0, 0.02); + // Firefox does not support AudioParam-based positionX/Y/Z on AudioListener. + // Fall back to the deprecated setPosition() method. + if (ctx.listener.positionX) { + ctx.listener.positionX.setTargetAtTime(x, 0, 0.02); + ctx.listener.positionY.setTargetAtTime(y, 0, 0.02); + ctx.listener.positionZ.setTargetAtTime(z, 0, 0.02); + } else { + ctx.listener.setPosition(x, y, z); + } } } } \ No newline at end of file diff --git a/pxtsim/sound/spatialAudioPlayer.ts b/pxtsim/sound/spatialAudioPlayer.ts index 5cca0eff1d15..e83ac427001f 100644 --- a/pxtsim/sound/spatialAudioPlayer.ts +++ b/pxtsim/sound/spatialAudioPlayer.ts @@ -35,26 +35,20 @@ namespace pxsim.AudioContextManager { this.panner = new PannerNode(context, { panningModel: 'HRTF', distanceModel: "linear", - positionX: 0, - positionY: 0, - positionZ: 0, - orientationX: 0, - orientationY: 0, - orientationZ: -1, }); + // Set initial position/orientation using the compat helpers + // (Firefox doesn't support AudioParam-based position/orientation properties) + setPannerPosition(this.panner, 0, 0, 0); + setPannerOrientation(this.panner, 0, 0, -1); this.panner.connect(destination); } setPosition(x: number, y: number, z: number) { - this.panner.positionX.setTargetAtTime(x, 0, 0.02); - this.panner.positionY.setTargetAtTime(y, 0, 0.02); - this.panner.positionZ.setTargetAtTime(z, 0, 0.02); + setPannerPosition(this.panner, x, y, z); } setOrientation(x: number, y: number, z: number) { - this.panner.orientationX.setTargetAtTime(x, 0, 0.02); - this.panner.orientationY.setTargetAtTime(y, 0, 0.02); - this.panner.orientationZ.setTargetAtTime(z, 0, 0.02); + setPannerOrientation(this.panner, x, y, z); } setCone(innerAngle: number, outerAngle: number, outerGain: number) { @@ -83,9 +77,9 @@ namespace pxsim.AudioContextManager { } } - get x(): number { return this.panner.positionX.value; } - get y(): number { return this.panner.positionY.value; } - get z(): number { return this.panner.positionZ.value; } + get x(): number { return this.panner.positionX?.value ?? 0; } + get y(): number { return this.panner.positionY?.value ?? 0; } + get z(): number { return this.panner.positionZ?.value ?? 0; } dispose() { this.panner.disconnect(); @@ -110,4 +104,26 @@ namespace pxsim.AudioContextManager { await this.audioWorkletSource.playInstructionsAsync(b); } } + + // Firefox does not support AudioParam-based positionX/Y/Z and orientationX/Y/Z + // on PannerNode or AudioListener. Fall back to the deprecated setPosition()/setOrientation() methods. + function setPannerPosition(panner: PannerNode, x: number, y: number, z: number) { + if (panner.positionX) { + panner.positionX.setTargetAtTime(x, 0, 0.02); + panner.positionY.setTargetAtTime(y, 0, 0.02); + panner.positionZ.setTargetAtTime(z, 0, 0.02); + } else { + panner.setPosition(x, y, z); + } + } + + function setPannerOrientation(panner: PannerNode, x: number, y: number, z: number) { + if (panner.orientationX) { + panner.orientationX.setTargetAtTime(x, 0, 0.02); + panner.orientationY.setTargetAtTime(y, 0, 0.02); + panner.orientationZ.setTargetAtTime(z, 0, 0.02); + } else { + panner.setOrientation(x, y, z); + } + } } \ No newline at end of file From 400e42f406ec6190c50a6d254fc0938d4b486f34 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Thu, 2 Apr 2026 11:02:29 -0700 Subject: [PATCH 3/3] [pxt-cli] bump version to v12.3.5 (#11244) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1d1b11348267..899751a5a6d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pxt-core", - "version": "12.3.4", + "version": "12.3.5", "description": "Microsoft MakeCode provides Blocks / JavaScript / Python tools and editors", "keywords": [ "TypeScript",