From adb8d104f2ebc29890b8c578e34a412e8c5c3fc2 Mon Sep 17 00:00:00 2001 From: austinw-fineart <40481873+austinw-fineart@users.noreply.github.com> Date: Tue, 2 Sep 2025 17:40:25 +0800 Subject: [PATCH 1/2] fix(radio): move root assignment to mirror hostDisconnected Fixes a regression caused by 688ab3c where calling hostConnected / hostDisconnected in rapid succession can cause root to become null. --- radio/internal/single-selection-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/internal/single-selection-controller.ts b/radio/internal/single-selection-controller.ts index 052dc3057..4c006bc24 100644 --- a/radio/internal/single-selection-controller.ts +++ b/radio/internal/single-selection-controller.ts @@ -74,7 +74,6 @@ export class SingleSelectionController implements ReactiveController { constructor(private readonly host: SingleSelectionElement) {} hostConnected() { - this.root = this.host.getRootNode() as ParentNode; this.host.addEventListener('keydown', this.handleKeyDown); this.host.addEventListener('focusin', this.handleFocusIn); this.host.addEventListener('focusout', this.handleFocusOut); @@ -90,6 +89,7 @@ export class SingleSelectionController implements ReactiveController { // connected at the same time. queueMicrotask(() => { // Update for the newly added host. + this.root = this.host.getRootNode() as ParentNode; this.updateTabIndices(); }); } From 6010e52c8fcd53577a8cf2cee53095033f329d2a Mon Sep 17 00:00:00 2001 From: austinw-fineart <40481873+austinw-fineart@users.noreply.github.com> Date: Wed, 3 Sep 2025 09:52:27 +0800 Subject: [PATCH 2/2] fix(radio): also move sibling uncheck logic after root assignment --- radio/internal/single-selection-controller.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/radio/internal/single-selection-controller.ts b/radio/internal/single-selection-controller.ts index 4c006bc24..e1bdc667d 100644 --- a/radio/internal/single-selection-controller.ts +++ b/radio/internal/single-selection-controller.ts @@ -77,11 +77,6 @@ export class SingleSelectionController implements ReactiveController { this.host.addEventListener('keydown', this.handleKeyDown); this.host.addEventListener('focusin', this.handleFocusIn); this.host.addEventListener('focusout', this.handleFocusOut); - if (this.host.checked) { - // Uncheck other siblings when attached if already checked. This mimics - // native behavior. - this.uncheckSiblings(); - } // Update siblings after a microtask to allow other synchronous connected // callbacks to settle before triggering additional Lit updates. This avoids @@ -90,6 +85,12 @@ export class SingleSelectionController implements ReactiveController { queueMicrotask(() => { // Update for the newly added host. this.root = this.host.getRootNode() as ParentNode; + if (this.host.checked) { + // Uncheck other siblings when attached if already checked. This mimics + // native behavior. + this.uncheckSiblings(); + } + this.updateTabIndices(); }); }