From d5b2d56e5cb68efe5d6ccdec113b4fec8aae047e Mon Sep 17 00:00:00 2001 From: phranck Date: Fri, 6 Feb 2026 20:04:44 +0100 Subject: [PATCH] Fix: Reset RadioButtonGroup focusedIndex to selected item on focus loss - isFocused now requires both focusedIndex match AND groupHasFocus - Prevents focused items from appearing dimmed after group loses focus - onFocusLost() resets focusedIndex to selected button for correct state - Fixes visual state inconsistency when tabbing between groups --- Sources/TUIkit/Views/RadioButton.swift | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Sources/TUIkit/Views/RadioButton.swift b/Sources/TUIkit/Views/RadioButton.swift index 64b1c6c..9da7aac 100644 --- a/Sources/TUIkit/Views/RadioButton.swift +++ b/Sources/TUIkit/Views/RadioButton.swift @@ -195,6 +195,17 @@ final class RadioButtonGroupHandler: Focusable { } } +// MARK: - Focus Lifecycle + +extension RadioButtonGroupHandler { + func onFocusLost() { + // Reset focusedIndex to the selected item when the group loses focus + if let selectedIndex = itemValues.firstIndex(of: selection.wrappedValue) { + focusedIndex = selectedIndex + } + } +} + // MARK: - Key Event Handling extension RadioButtonGroupHandler { @@ -315,7 +326,7 @@ extension RadioButtonGroup: Renderable { renderRadioButton( index: index, item: item, - isFocused: handler.focusedIndex == index, + isFocused: handler.focusedIndex == index && groupHasFocus, groupHasFocus: groupHasFocus, isSelected: selection.wrappedValue == item.value, context: context, @@ -334,7 +345,7 @@ extension RadioButtonGroup: Renderable { renderRadioButton( index: index, item: item, - isFocused: handler.focusedIndex == index, + isFocused: handler.focusedIndex == index && groupHasFocus, groupHasFocus: groupHasFocus, isSelected: selection.wrappedValue == item.value, context: context,