Skip to content

Apply BitChoiceGroup improvements (#12740)#12743

Open
msynk wants to merge 2 commits into
bitfoundation:developfrom
msynk:12740-blazorui-choicegroup-improvements
Open

Apply BitChoiceGroup improvements (#12740)#12743
msynk wants to merge 2 commits into
bitfoundation:developfrom
msynk:12740-blazorui-choicegroup-improvements

Conversation

@msynk

@msynk msynk commented Jul 21, 2026

Copy link
Copy Markdown
Member

closes #12740

Summary by CodeRabbit

  • New Features
    • ChoiceGroup now supports per-item/option secondary descriptions, rendered under the option text and linked for screen readers.
    • Added AutoFocus, Gap, and ItemDescription styling customization.
  • Accessibility Improvements
    • ChoiceGroup ARIA now reflects Required/ReadOnly/Disabled and horizontal/vertical orientation.
  • Demos/Documentation
    • Expanded ChoiceGroup demos to cover descriptions, prefixes, events, dynamic items, styling, icons, sizing, and RTL.
  • Tests
    • Added coverage for focus/tab behavior, read-only accessibility, description linking (aria-describedby), Required/orientation, and custom gap styling.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3fc2c4eb-c526-4812-a37d-d10f053f2baa

📥 Commits

Reviewing files that changed from the base of the PR and between 5066e53 and 904f917.

📒 Files selected for processing (22)
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs

Walkthrough

BitChoiceGroup now supports descriptions, one-time autofocus, configurable item gaps, expanded ARIA attributes, accessible focusable inputs, description styling, and item-description class customization. Demos, samples, and tests were expanded accordingly.

Changes

ChoiceGroup component behavior

Layer / File(s) Summary
Accessible rendering and component parameters
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/*
Adds descriptions, autofocus, configurable gaps, ARIA attributes, focus registration, accessible input styling, and description rendering.
Validation coverage
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs
Tests focus behavior, read-only tab order, descriptions, gap styling, required state, and orientation attributes.

Demo coverage

Layer / File(s) Summary
Custom demo and metadata updates
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/*CustomDemo*, BitChoiceGroupDemo*, Order.cs
Documents the expanded API and adds descriptions, read-only, gap, prefix, event, dynamic-item, icon, size, styling, and RTL examples.
Item and option demo updates
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroup{Item,Option}Demo*
Adds matching item- and option-based examples, state handlers, dynamic collection operations, validation updates, and reorganized samples.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: yasmoradi, cyrus-sushiant

Sequence Diagram(s)

sequenceDiagram
  participant ChoiceGroup
  participant ChoiceGroupItem
  participant RadioInput
  ChoiceGroupItem->>ChoiceGroup: Register rendered input
  ChoiceGroup->>RadioInput: Select checked or first item
  ChoiceGroup->>RadioInput: Focus once when AutoFocus is enabled
Loading

Poem

A rabbit hops through radios bright,
Adds descriptions tied just right.
Gaps stretch wide and focus stays,
ARIA guides the keyboard’s ways.
New demos bloom with helpful wings.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the BitChoiceGroup improvements in this PR.
Linked Issues check ✅ Passed The changes add missing ChoiceGroup features, demos, descriptions, and demo page copy requested by #12740.
Out of Scope Changes check ✅ Passed No clearly unrelated code changes stand out; the added tests, demo data, and styling support the ChoiceGroup work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 374-397: Update SetInputElement’s AutoFocus branch to wrap
InputElement.FocusAsync() in defensive catches for InvalidOperationException and
JSException, preventing interop or disconnected-element failures from escaping
during rendering while preserving the existing autofocus conditions and state
updates.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs`:
- Around line 566-646: Update the second Small/Medium/Large trio in
example18RazorCode to match the live “ChoiceGroup with icon” demo: retain
Horizontal but remove Inline from each BitChoiceGroup declaration, leaving the
first inline trio unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d67c0345-34a4-4b60-8f99-9c941fefb8bb

📥 Commits

Reviewing files that changed from the base of the PR and between 5066e53 and 951e505.

📒 Files selected for processing (22)
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs

@msynk

msynk commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full-review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

@msynk: Starting a complete review of #12743, including the BitChoiceGroup implementation, accessibility behavior, tests, and demo updates.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)

376-396: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add defensive exception handling for FocusAsync.

In Blazor, calling FocusAsync can throw an InvalidOperationException (if the element is disconnected before the call completes) or a JSException (if the interop fails, e.g., due to a closed circuit). It is highly recommended to wrap FocusAsync in a try/catch block to prevent unhandled exceptions from terminating the Blazor circuit during rendering.

🛠️ Proposed fix
     internal async Task SetInputElement(TItem item, ElementReference inputElement)
     {
         var isChecked = GetIsCheckedItem(item);
 
         if (isChecked is false)
         {
             if (_items.Any(GetIsCheckedItem)) return;
             if (ReferenceEquals(_items.FirstOrDefault(), item) is false) return;
         }
 
         InputElement = inputElement;
 
         if (AutoFocus && _autoFocusDone is false && IsEnabled && ReadOnly is false && GetIsEnabled(item))
         {
             _autoFocusDone = true;
-            await InputElement.FocusAsync();
+            try
+            {
+                await InputElement.FocusAsync();
+            }
+            catch (Exception ex) when (ex is JSException || ex is InvalidOperationException)
+            {
+                // Ignore focus failures (e.g., element disconnected or hidden)
+            }
         }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`
around lines 376 - 396, Update SetInputElement so the AutoFocus FocusAsync call
is wrapped in defensive handling for InvalidOperationException and JSException,
preventing disconnected-element or failed-interop errors from escaping during
rendering while preserving the existing autofocus conditions and _autoFocusDone
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 376-396: Update SetInputElement so the AutoFocus FocusAsync call
is wrapped in defensive handling for InvalidOperationException and JSException,
preventing disconnected-element or failed-interop errors from escaping during
rendering while preserving the existing autofocus conditions and _autoFocusDone
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 621312aa-e975-4df1-a8af-117b126ddf09

📥 Commits

Reviewing files that changed from the base of the PR and between 5066e53 and 904f917.

📒 Files selected for processing (22)
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cs
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor
  • src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs

@msynk

msynk commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full-review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

@msynk: Starting a complete re-review of #12743, including the BitChoiceGroup implementation, accessibility behavior, tests, and demo updates.

✅ Action performed

Full review finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The BitChoiceGroup improvements

2 participants