Apply BitChoiceGroup improvements (#12740) - #12743
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughBitChoiceGroup adds ARIA metadata, descriptions, autofocus, label positioning, suffix/title customization, synchronized selection state, revised styling, expanded demonstrations, and broad accessibility, interaction, content, options, state, and styling tests. ChangesChoiceGroup component and rendering
Demo coverage
Estimated code review effort: 4 (Complex) | ~60 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (22)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
376-396: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winAdd defensive exception handling for
FocusAsync.In Blazor, calling
FocusAsynccan throw anInvalidOperationException(if the element is disconnected before the call completes) or aJSException(if the interop fails, e.g., due to a closed circuit). It is highly recommended to wrapFocusAsyncin atry/catchblock 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
📒 Files selected for processing (22)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStylelint:
.scssextension in@import.Flagged by Stylelint (
scss/load-partial-extension). Since this convention likely repeats elsewhere in the codebase, consider a broader cleanup rather than a one-off fix here.🤖 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.scss` at line 1, Remove the .scss extension from the `@import` in BitChoiceGroup styles, and apply the same extensionless partial-import convention to other SCSS imports in the affected codebase where applicable.Source: Linters/SAST tools
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
30-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAutoFocus doc says "first item", but implementation skips disabled ones.
GetTabTargetItem()(Line 422) resolves to the first enabled item, falling back to the first item only when none are enabled. The XML doc here doesn't mention the "enabled" qualifier, which could mislead consumers about which item receives focus when the first item is disabled.📝 Proposed doc fix
/// <summary> - /// Determines if the ChoiceGroup is auto focused on first render, focusing its checked item (or its first item). + /// Determines if the ChoiceGroup is auto focused on first render, focusing its checked item (or its first enabled item). /// </summary> [Parameter] public bool AutoFocus { get; set; }🤖 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 30 - 34, Update the AutoFocus XML documentation to state that first render focuses the checked item, or the first enabled item when no checked item is available, with the existing fallback behavior for all-disabled groups reflected accurately. Keep the implementation, parameter, and GetTabTargetItem() behavior unchanged.
🤖 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.
Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 30-34: Update the AutoFocus XML documentation to state that first
render focuses the checked item, or the first enabled item when no checked item
is available, with the existing fallback behavior for all-disabled groups
reflected accurately. Keep the implementation, parameter, and GetTabTargetItem()
behavior unchanged.
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss`:
- Line 1: Remove the .scss extension from the `@import` in BitChoiceGroup styles,
and apply the same extensionless partial-import convention to other SCSS imports
in the affected codebase where applicable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: dbcaec9c-9a44-490e-ae98-ceb340cb9601
📒 Files selected for processing (31)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razor
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
31-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAutoFocus doc doesn't match actual targeting behavior.
Doc says autofocus lands on the checked item "or its first item", but
GetTabTargetItem()(Line 468) actually picks the first enabled item, falling back to the first item only when none are enabled. Worth tightening the wording so consumers aren't surprised when a disabled first item is skipped.📝 Proposed doc fix
/// <summary> - /// Determines if the ChoiceGroup is auto focused on first render, focusing its checked item (or its first item). + /// Determines if the ChoiceGroup is auto focused on first render, focusing its checked item (or its first enabled item, when none is checked). /// </summary> [Parameter] public bool AutoFocus { get; set; }🤖 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 31 - 35, Update the AutoFocus XML documentation to accurately describe that focus targets the first enabled item, falling back to the first item only when no enabled items exist; ensure the wording remains consistent with GetTabTargetItem().src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs (1)
133-148: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThe autofocus tests only count focus interop calls, not the target.
BitChoiceGroupShouldAutoFocusTheFirstEnabledItemWhenNothingIsCheckedwould pass even if the focus landed on the disabled first input — exactly the regression the comment says it guards against. Consider asserting on the invocation arguments (the element reference / id) so the intended target is actually verified.Also applies to: 163-166
🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs` around lines 133 - 148, Update BitChoiceGroupShouldAutoFocusTheFirstEnabledItemWhenNothingIsChecked and the related test at the alternate location to assert the focus interop invocation targets the first enabled item, using its element reference or id, rather than only checking FocusInvocationCount(). Preserve the existing setup and ensure the disabled first item is not the autofocus target.src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor (1)
32-42: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueGuidance contradicts the sample data.
The lead says images are decorative and
ImageAltshould only be set "when the picture says something the text does not", butimageItems/inlineImageItemsset placeholder alts like"alt for Bar image", which duplicates the item text. Consider droppingImageAltfrom these demo items (or using it on just one item to illustrate the exception) so the example matches the advice.🤖 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/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor` around lines 32 - 42, Align the demo data used by imageItems and inlineImageItems with the accessibility guidance by removing placeholder ImageAlt values that duplicate each item’s text. Leave ImageAlt set only on an item where the image conveys information not present in the label, if demonstrating that exception is needed.src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor (1)
22-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueProse mixes "item" and "option" on the options page.
These rewritten leads say "items" while the rest of this page (and the rendered API,
BitChoiceGroupOption) says "options" — e.g. line 22 "individual items", line 47 "the item is checked … the item text", line 108 "Lays out the items in a row". Same wording appears at lines 566, 762 and 856. Worth normalizing to "option" except where the text names an actual parameter (ItemTemplate,ItemPrefixTemplate, per-itemStyle/Class).Also applies to: 47-47, 108-108
🤖 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/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor` at line 22, Normalize the prose in _BitChoiceGroupOptionDemo to use “option” instead of “item” when referring to ChoiceGroup options, including the descriptions around the disabled state, checked state/text, and layout. Preserve “item” only when it names actual API parameters such as ItemTemplate, ItemPrefixTemplate, or per-item Style/Class, and apply the same wording consistently to the other noted occurrences.
🤖 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 451-466: Add defensive exception handling around FocusAsync in
SetInputElement, catching the expected JSException and InvalidOperationException
so failures from disconnected elements or closed circuits do not propagate to
the caller. Preserve the existing autofocus conditions and _autoFocusDone state
behavior.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs`:
- Around line 555-556: Correct the copied Razor sample in example20RazorCode by
inserting a space between the Label attribute and DefaultValue attribute,
keeping the rest of the BitChoiceGroup example unchanged.
---
Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 31-35: Update the AutoFocus XML documentation to accurately
describe that focus targets the first enabled item, falling back to the first
item only when no enabled items exist; ensure the wording remains consistent
with GetTabTargetItem().
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor`:
- Around line 32-42: Align the demo data used by imageItems and inlineImageItems
with the accessibility guidance by removing placeholder ImageAlt values that
duplicate each item’s text. Leave ImageAlt set only on an item where the image
conveys information not present in the label, if demonstrating that exception is
needed.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor`:
- Line 22: Normalize the prose in _BitChoiceGroupOptionDemo to use “option”
instead of “item” when referring to ChoiceGroup options, including the
descriptions around the disabled state, checked state/text, and layout. Preserve
“item” only when it names actual API parameters such as ItemTemplate,
ItemPrefixTemplate, or per-item Style/Class, and apply the same wording
consistently to the other noted occurrences.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs`:
- Around line 133-148: Update
BitChoiceGroupShouldAutoFocusTheFirstEnabledItemWhenNothingIsChecked and the
related test at the alternate location to assert the focus interop invocation
targets the first enabled item, using its element reference or id, rather than
only checking FocusInvocationCount(). Preserve the existing setup and ensure the
disabled first item is not the autofocus target.
🪄 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 Plus
Run ID: a55cbb71-16b8-42d6-96bc-e668b3c64d36
📒 Files selected for processing (31)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razor
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
452-467: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winStill missing defensive exception handling around
FocusAsync.This was flagged on two prior commits and remains unresolved.
await InputElement.FocusAsync();can throwJSException/JSDisconnectedException/InvalidOperationException(disconnected element, closed circuit, prerendering, etc.), and since_BitChoiceGroupItem.razor.cs'sOnAfterRenderAsyncawaits this method unguarded, an uncaught exception here will propagate out of the render lifecycle and can crash the circuit. The file already uses a similar guarded pattern for JS interop elsewhere (seeOnAfterRenderAsync's reorder call catchingJSDisconnectedException/JSException).🛠️ Proposed fix
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 JSDisconnectedException || ex is InvalidOperationException) + { + // Ignore focus failures (e.g., element disconnected, circuit closed, or invalid element ref) + } }🤖 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 452 - 467, Wrap the InputElement.FocusAsync call in SetInputElement with defensive exception handling for JSDisconnectedException, JSException, and InvalidOperationException, matching the existing guarded JS interop pattern in OnAfterRenderAsync. Ensure these expected lifecycle failures are handled locally so they do not propagate through the render lifecycle.
🧹 Nitpick comments (1)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs (1)
121-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert which input got focused. The test name says "the checked item", but only the invocation count is checked — it would pass if the first item were focused.
FocusedElementId()is already available.💚 Proposed tightening
- RenderComponent<BitChoiceGroup<BitChoiceGroupItem<string>, string>>(parameters => + var component = RenderComponent<BitChoiceGroup<BitChoiceGroupItem<string>, string>>(parameters => { parameters.Add(p => p.Items, GetItems()); parameters.Add(p => p.DefaultValue, "B"); parameters.Add(p => p.AutoFocus, true); }); Assert.AreEqual(1, FocusInvocationCount()); + Assert.AreEqual(component.FindAll(".bit-chg-icn input")[1].GetAttribute("blazor:elementreference"), FocusedElementId());🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs` around lines 121 - 132, Strengthen BitChoiceGroupShouldAutoFocusTheCheckedItem by asserting that FocusedElementId() matches the input associated with the checked/default-value item "B", in addition to the existing FocusInvocationCount assertion. Use the existing item identifiers from GetItems() rather than only verifying that some input received focus.
🤖 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 154-172: Add an explicit changelog or migration note for the
removed BitChoiceGroup Reversed parameter, documenting its replacement with
LabelPosition and specifying that Reversed=true in horizontal choice groups maps
to the corresponding LabelPosition value. Reference the BitChoiceGroup API and
preserve the migration guidance for existing bindings.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor`:
- Around line 313-314: Update the Prefix description in
_BitChoiceGroupCustomDemo.razor at lines 313-314 and
_BitChoiceGroupItemDemo.razor at lines 196-197 to state that Prefix renders
before the item text inside the item label, replacing the inaccurate “in front
of the radio circle” wording while keeping both pages consistent.
---
Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 452-467: Wrap the InputElement.FocusAsync call in SetInputElement
with defensive exception handling for JSDisconnectedException, JSException, and
InvalidOperationException, matching the existing guarded JS interop pattern in
OnAfterRenderAsync. Ensure these expected lifecycle failures are handled locally
so they do not propagate through the render lifecycle.
---
Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs`:
- Around line 121-132: Strengthen BitChoiceGroupShouldAutoFocusTheCheckedItem by
asserting that FocusedElementId() matches the input associated with the
checked/default-value item "B", in addition to the existing FocusInvocationCount
assertion. Use the existing item identifiers from GetItems() rather than only
verifying that some input received focus.
🪄 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 Plus
Run ID: 66a0f41d-3608-41de-bc33-3cb37def787d
📒 Files selected for processing (31)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razor
|
@coderabbitai re-review |
…into 12740-blazorui-choicegroup-improvements
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs (1)
526-546: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
DescriptionTemplatesnippet references.custom-descriptionwithout defining it.Other template examples in this file ship an inline
<style>block; this one doesn't, so copy-pasting yields unstyled markup.🤖 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/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs` around lines 526 - 546, Update the example16RazorCode sample to include an inline style definition for the custom-description class used by DescriptionTemplate, matching the pattern of the other styled template examples while preserving the existing markup and 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.
Inline comments:
In `@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scss`:
- Around line 214-216: Insert a blank line immediately before the comment
describing the focus ring in the ChoiceGroup styles, without changing the
comment or surrounding selectors.
---
Nitpick comments:
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cs`:
- Around line 526-546: Update the example16RazorCode sample to include an inline
style definition for the custom-description class used by DescriptionTemplate,
matching the pattern of the other styled template examples while preserving the
existing markup and behavior.
🪄 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 Plus
Run ID: c8a18261-e55c-4a39-9c6c-8c9fe9e9f0ac
📒 Files selected for processing (8)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cs
🚧 Files skipped from review as they are similar to previous changes (6)
- 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/_BitChoiceGroupOptionDemo.razor
- 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/_BitChoiceGroupOptionDemo.razor.samples.cs
- src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cs
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs (1)
169-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPrefer bUnit's built-in
VerifyFocusAsyncInvoke/ShouldBeElementReferenceToover manual identifier string-matching.
FocusInvocationCount()/FocusedElementId()reinvent functionality bUnit ships out of the box specifically for testingElementReference.FocusAsync(). Per bUnit's docs, the idiomatic pattern isJSInterop.VerifyFocusAsyncInvoke().Arguments[0].ShouldBeElementReferenceTo(inputElement), andVerifyFocusAsyncInvoke(0)/JSInterop.VerifyNotInvoke(...)-style checks cover the "not called" case. This avoids depending on an undocumentedIdentifiersubstring ("focus") and on reading the internalblazor:elementreferenceattribute directly.♻️ Suggested refactor using bUnit's official API
- // "B" is the checked item, so the focus has to land on it and not on the first one. - Assert.AreEqual(1, FocusInvocationCount()); - Assert.AreEqual(component.FindAll(".bit-chg-icn input")[items.FindIndex(i => i.Value == "B")].GetAttribute("blazor:elementreference"), FocusedElementId()); + // "B" is the checked item, so the focus has to land on it and not on the first one. + var expectedInput = component.FindAll(".bit-chg-icn input")[items.FindIndex(i => i.Value == "B")]; + Context.JSInterop.VerifyFocusAsyncInvoke().Arguments[0].ShouldBeElementReferenceTo(expectedInput);- private int FocusInvocationCount() - { - return Context.JSInterop.Invocations.Count(i => i.Identifier.Contains("focus", System.StringComparison.OrdinalIgnoreCase)); - } - - // The id of the element the focus interop was called with, so a test can assert which input was focused - // and not only that something was. It matches the blazor:elementreference attribute bUnit renders on the - // elements captured with `@ref`. - private string FocusedElementId() - { - var invocation = Context.JSInterop.Invocations.Single(i => i.Identifier.Contains("focus", System.StringComparison.OrdinalIgnoreCase)); - - return ((ElementReference)invocation.Arguments[0]!).Id; - }🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs` around lines 169 - 182, Replace the manual FocusInvocationCount and FocusedElementId helpers with bUnit’s built-in JSInterop verification APIs. Update the affected ChoiceGroup tests to use VerifyFocusAsyncInvoke, VerifyNotInvoke, and ShouldBeElementReferenceTo for focus-call and target assertions, removing Identifier substring matching and direct ElementReference ID inspection.
🤖 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/BitChoiceGroupItem.cs`:
- Around line 93-97: Revise the Title XML documentation for BitChoiceGroupItem
and BitChoiceGroupOption to state that AriaLabel provides an alternative
accessible name, not visible content; direct required information to
Text/templates or Description. Align the corresponding item and option API
metadata in BitChoiceGroupDemo.razor.cs at the specified ranges with the same
guidance.
---
Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs`:
- Around line 169-182: Replace the manual FocusInvocationCount and
FocusedElementId helpers with bUnit’s built-in JSInterop verification APIs.
Update the affected ChoiceGroup tests to use VerifyFocusAsyncInvoke,
VerifyNotInvoke, and ShouldBeElementReferenceTo for focus-call and target
assertions, removing Identifier substring matching and direct ElementReference
ID inspection.
🪄 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 Plus
Run ID: c02e5ac6-920d-4ebd-a225-7fe21258c4db
📒 Files selected for processing (32)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cs (1)
37-55: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueCoverage gap: in-place property mutation without a count change.
This test only proves the group detects an item added to the same list reference. It doesn't cover mutating an existing item's property (e.g.,
Text) in place with the same count/reference — a scenario that's easy to miss if the underlying change-detection compares list length/reference rather than content.Consider adding a test that mutates an existing item's property in place (no add/remove) and re-renders, asserting the DOM reflects the change.
🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cs` around lines 37 - 55, The existing BitChoiceGroupShouldDetectInPlaceMutationOfTheSameItemsCollection test only covers adding an item. Add a separate test for mutating an existing item’s property, such as Text, while preserving the same collection reference and item count; re-render the BitChoiceGroup and assert the DOM displays the updated text.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs (1)
198-214: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate test coverage for item-description → aria-describedby wiring. Both files add a test asserting the same behavior: an item's
Descriptionrenders exactly once and the input'saria-describedbypoints to it. One root cause — the same scenario was added twice in this PR across two different test classes.
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs#L198-L214: keep this as the canonical test — it's in the purpose-built accessibility test class described by the file's own doc comment.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs#L285-L306: removeBitChoiceGroupShouldRenderDescriptions(or repurpose it to assert something not already covered, e.g. multiple descriptions across items) since it duplicates the accessibility-test assertion.🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs` around lines 198 - 214, The accessibility test in src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs lines 198-214 should remain the canonical coverage for item descriptions wiring to aria-describedby. In src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs lines 285-306, remove BitChoiceGroupShouldRenderDescriptions or repurpose it to cover distinct behavior, such as multiple item descriptions.
🤖 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.scss`:
- Line 1: Update the partial import in BitChoiceGroup.scss to reference the
functions partial without its .scss extension, preserving the existing relative
import path.
---
Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs`:
- Around line 198-214: The accessibility test in
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cs
lines 198-214 should remain the canonical coverage for item descriptions wiring
to aria-describedby. In
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs
lines 285-306, remove BitChoiceGroupShouldRenderDescriptions or repurpose it to
cover distinct behavior, such as multiple item descriptions.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cs`:
- Around line 37-55: The existing
BitChoiceGroupShouldDetectInPlaceMutationOfTheSameItemsCollection test only
covers adding an item. Add a separate test for mutating an existing item’s
property, such as Text, while preserving the same collection reference and item
count; re-render the BitChoiceGroup and assert the DOM displays the updated
text.
🪄 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 Plus
Run ID: ca0f2fee-0458-4b80-b953-4c8ccf216434
📒 Files selected for processing (32)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs (1)
81-101: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
RefreshInventoryonly toleratesIOException, notUnauthorizedAccessException.
UnauthorizedAccessExceptiondoesn't derive fromIOExceptionin .NET, so a read-only source checkout (common in hardened CI images) would let this throw uncaught instead of being absorbed like the documented concurrent-write race. The test would still fail, but with a raw exception instead of the intendedAssert.Failguidance message at Line 40-44.🩹 Proposed fix
- catch (IOException) + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { }🤖 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/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs` around lines 81 - 101, Update RefreshInventory to also absorb UnauthorizedAccessException alongside IOException when writing or replacing the inventory file, preserving the existing cleanup behavior and allowing the caller’s intended Assert.Fail guidance to handle the failure.
🤖 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.
Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs`:
- Around line 81-101: Update RefreshInventory to also absorb
UnauthorizedAccessException alongside IOException when writing or replacing the
inventory file, preserving the existing cleanup behavior and allowing the
caller’s intended Assert.Fail guidance to handle the failure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7cf76ade-4b8d-40f1-9a46-34715ef60c95
📒 Files selected for processing (34)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (1)
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 2 minutes. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
642-646: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
GetIsItemEnabledinHandleClick,HandleChange, andSetInputElement.This new helper centralizes "group enabled AND item enabled", but the three call sites below still inline the same check, so a future change to the enablement rule risks drifting out of sync.
♻️ Proposed consolidation
internal async Task HandleClick(TItem item) { - if (IsEnabled is false || ReadOnly || GetIsEnabled(item) is false) return; + if (GetIsItemEnabled(item) is false || ReadOnly) return; await OnClick.InvokeAsync(item); } internal void HandleChange(TItem item) { - if (IsEnabled is false || ReadOnly || GetIsEnabled(item) is false) return; + if (GetIsItemEnabled(item) is false || ReadOnly) return;- if (AutoFocus && _autoFocusDone is false && IsEnabled && ReadOnly is false && GetIsEnabled(item)) + if (AutoFocus && _autoFocusDone is false && ReadOnly is false && GetIsItemEnabled(item))🤖 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 642 - 646, Replace the duplicated group-and-item enablement checks in HandleClick, HandleChange, and SetInputElement with calls to GetIsItemEnabled(item). Keep each method’s existing behavior unchanged while routing all three decisions through the centralized helper.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs (1)
13-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid hard-coding the internal JSInterop focus identifier.
VerifyNotInvoke(FocusAsyncIdentifier)only fails for that exact identifier; if the Blazor/bUnit focus identifier changes, this negative assertion can silently pass even ifAutoFocusfires whileReadOnly. Use a focus-call shape check instead, such as asserting no JSInterop invocation ends with.focuswas recorded.🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs` around lines 13 - 16, Replace the hard-coded FocusAsyncIdentifier usage in the ReadOnly/AutoFocus negative assertion with a JSInterop invocation shape check that verifies no recorded invocation ends with “.focus”. Remove the identifier constant if it is no longer needed, while preserving the existing positive focus verification.
🤖 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.
Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 642-646: Replace the duplicated group-and-item enablement checks
in HandleClick, HandleChange, and SetInputElement with calls to
GetIsItemEnabled(item). Keep each method’s existing behavior unchanged while
routing all three decisions through the centralized helper.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs`:
- Around line 13-16: Replace the hard-coded FocusAsyncIdentifier usage in the
ReadOnly/AutoFocus negative assertion with a JSInterop invocation shape check
that verifies no recorded invocation ends with “.focus”. Remove the identifier
constant if it is no longer needed, while preserving the existing positive focus
verification.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8cb0e771-09b4-48e9-be19-678fdbb30b58
📒 Files selected for processing (35)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (2)
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razor
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor (1)
23-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider a non-
labelelement for the group caption.A
<label>with neitherfornor a wrapped form control is semantically inert; the accessible name comes solely fromaria-labelledby. Adiv/span(orlegendinside afieldset) conveys intent better and avoids browsers/AT treating it as an orphan label. Purely cosmetic given the ARIA wiring already works.🤖 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` around lines 23 - 37, Replace the orphan label element in the HasLabel block of BitChoiceGroup with a non-label caption element, such as a div or span, while preserving its id, styles, classes, and existing LabelTemplate/Label rendering.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs (1)
94-100: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winGuard the cleanup in
finally.The
trybody deliberately toleratesIOException/UnauthorizedAccessException, but thefinallycleanup does not: a concurrent sibling or a read-only checkout can makeFile.Deletethrow, which would surface instead of the intendedAssert.Failmessage and turn a documented drift failure into a confusing IO error.🛠️ Proposed fix
finally { - if (File.Exists(tempPath)) - { - File.Delete(tempPath); - } + try + { + if (File.Exists(tempPath)) + { + File.Delete(tempPath); + } + } + catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { } }🤖 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/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs` around lines 94 - 100, Update the finally cleanup in the relevant contract test to guard File.Delete against IOException and UnauthorizedAccessException, preserving the original Assert.Fail result when cleanup cannot remove the temporary file. Keep the existing File.Exists check and ensure cleanup exceptions do not escape the test.src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs (1)
449-454: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value
GetInputIdrescans_itemsper item; the index is already tracked.
GetItemIndexis a linearFindIndexinvoked once per item per render (O(n²) overall), and it yields-1(producing...-Input--1) for an item that is not in_items.SetIndexItems/SetIndexalready stamps the position onto each item, so reading it back is both cheaper and consistent.🤖 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 449 - 454, The GetInputId method should use the index assigned by SetIndexItems/SetIndex instead of calling GetItemIndex, eliminating the per-item FindIndex scan and avoiding -1 for tracked items. Remove or stop using GetItemIndex and read the existing stamped position from the item when constructing the fallback input ID.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs (1)
13-16: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winNegative focus assertion relies on an undocumented Blazor internal JS identifier.
VerifyNotInvoke(FocusAsyncIdentifier)only proves that specific hardcoded string wasn't invoked. If Blazor's internalFocusAsyncinterop identifier ever changes (it's a private implementation detail, not a public contract), this assertion would keep passing trivially even if a real autofocus regression is introduced, since the real invocation would use a different identifier.Consider strengthening this to something identifier-agnostic, e.g. asserting
Context.JSInterop.Invocationsis empty, so the test still catches a regression even if the internal identifier string changes.♻️ Suggested more robust assertion
- Context.JSInterop.VerifyNotInvoke(FocusAsyncIdentifier); + Assert.AreEqual(0, Context.JSInterop.Invocations.Count);Also applies to: 159-170
🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs` around lines 13 - 16, Replace the negative focus assertion in the relevant ChoiceGroup event tests with an identifier-agnostic check that Context.JSInterop.Invocations is empty, and remove the FocusAsyncIdentifier constant and related comments if no longer used. Preserve the existing positive focus verification.
🤖 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/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md`:
- Around line 4-13: Document the removal of --bit-chg-clr-brd as a breaking
public-API change in the project’s release notes or breaking-changes
documentation, noting that ChoiceGroup no longer defines or consumes it and that
consumers must remove or migrate related CSS and Style overrides.
---
Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor`:
- Around line 23-37: Replace the orphan label element in the HasLabel block of
BitChoiceGroup with a non-label caption element, such as a div or span, while
preserving its id, styles, classes, and existing LabelTemplate/Label rendering.
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs`:
- Around line 449-454: The GetInputId method should use the index assigned by
SetIndexItems/SetIndex instead of calling GetItemIndex, eliminating the per-item
FindIndex scan and avoiding -1 for tracked items. Remove or stop using
GetItemIndex and read the existing stamped position from the item when
constructing the fallback input ID.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cs`:
- Around line 13-16: Replace the negative focus assertion in the relevant
ChoiceGroup event tests with an identifier-agnostic check that
Context.JSInterop.Invocations is empty, and remove the FocusAsyncIdentifier
constant and related comments if no longer used. Preserve the existing positive
focus verification.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs`:
- Around line 94-100: Update the finally cleanup in the relevant contract test
to guard File.Delete against IOException and UnauthorizedAccessException,
preserving the original Assert.Fail result when cleanup cannot remove the
temporary file. Keep the existing File.Exists check and ensure cleanup
exceptions do not escape the test.
🪄 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 Plus
Run ID: 65aaf4eb-c917-4952-bb9a-5cb0b10c68c2
📒 Files selected for processing (35)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (2)
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razor
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cs (1)
148-161: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueName says "empty suffix", but the item has no suffix at all.
Item A leaves
Suffixnull, whereas the prefix counterpart (Line 112) usesstring.Empty. SettingSuffix = string.Emptyhere would actually exercise the empty-string fallback and match the method name.♻️ Proposed tweak
- new() { Text = "A", Value = "A" }, + new() { Text = "A", Value = "A", Suffix = string.Empty },🤖 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/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cs` around lines 148 - 161, Update BitChoiceGroupShouldFallBackToTheItemSuffixTemplateForAnEmptySuffix so item A explicitly sets Suffix to string.Empty instead of leaving it null, ensuring the test covers the empty-string fallback described by its name and matching the prefix counterpart’s setup.src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs (1)
29-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSelf-healing inventory makes the drift signal non-repeatable, and the failure message can lie.
Two related consequences of rewriting the checked-in file from inside the test:
- On CI, a retry of the same job passes because the first run already rewrote the file (and the rewrite is discarded with the workspace), so intentional-vs-accidental drift can slip through unnoticed.
- If the write is swallowed at Line 91, the message still claims the file "has been refreshed in place".
Consider gating the rewrite behind an env var /
--update-snapshots-style switch, keeping the default path assert-only, and only claiming a refresh when the move actually succeeded.♻️ Sketch
- RefreshInventory(inventoryPath, generated); - - Assert.Fail( - "The component CSS variable inventory had drifted from the SCSS sources and has been " + - $"refreshed in place ({inventoryPath}). These names are documented public API: if the " + - "change is intentional, review the diff, commit it and note the change in the release " + - "notes; otherwise revert the SCSS rename."); + var refreshed = Environment.GetEnvironmentVariable("BIT_UPDATE_CSS_INVENTORY") == "1" + && RefreshInventory(inventoryPath, generated); + + Assert.Fail( + "The component CSS variable inventory has drifted from the SCSS sources " + + $"({inventoryPath}){(refreshed ? " and was refreshed in place" : string.Empty)}. " + + "These names are documented public API: if the change is intentional, re-run with " + + "BIT_UPDATE_CSS_INVENTORY=1, review the diff, commit it and note the change in the " + + "release notes; otherwise revert the SCSS rename.");
RefreshInventorywould returnbool(trueafter a successfulFile.Move,falsein the swallowed catch).Also applies to: 81-109
🤖 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/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs` around lines 29 - 45, Update the inventory drift handling in the contract test and RefreshInventory so the default execution only compares and fails without rewriting the checked-in file. Gate updates behind an explicit environment variable or equivalent update switch, make RefreshInventory return whether the move succeeded, and only include “refreshed in place” in the failure message when it returns true; otherwise report that the refresh failed or was not performed.
🤖 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.
Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cs`:
- Around line 148-161: Update
BitChoiceGroupShouldFallBackToTheItemSuffixTemplateForAnEmptySuffix so item A
explicitly sets Suffix to string.Empty instead of leaving it null, ensuring the
test covers the empty-string fallback described by its name and matching the
prefix counterpart’s setup.
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cs`:
- Around line 29-45: Update the inventory drift handling in the contract test
and RefreshInventory so the default execution only compares and fails without
rewriting the checked-in file. Gate updates behind an explicit environment
variable or equivalent update switch, make RefreshInventory return whether the
move succeeded, and only include “refreshed in place” in the failure message
when it returns true; otherwise report that the refresh failed or was not
performed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 446fb48c-ac06-451e-8e62-496b1a5a6c10
📒 Files selected for processing (35)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (2)
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razor
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cs (1)
11-16: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valuePer-render fan-out cost scales with item count.
Calling
SetInputElementfrom every item'sOnAfterRenderAsyncon every render is needed to keepInputElement/autofocus tracking correct when the checked item changes, but per the referencedSetInputElementimplementation this does O(n) work (_items.Any(...),GetTabTargetItem()) per call, so a full re-render costs O(n²) across all items. Likely negligible for typical group sizes; worth keeping in mind if ChoiceGroup is used with many options.🤖 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/_BitChoiceGroupItem.razor.cs` around lines 11 - 16, Optimize the interaction between OnAfterRenderAsync and ChoiceGroup.SetInputElement to avoid repeating the O(n) group scan for every item during a render; coordinate the update so the checked-item/input-element tracking work runs once per group render while preserving correct autofocus and InputElement updates when the checked item changes.
🤖 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 408-409: The BitChoiceGroup.TryParseValueFromString override
currently throws when EditContext binding supplies a string value. Replace the
throwing behavior with a safe handling path that prevents string-value updates
from crashing while preserving the component’s TValue binding and validation
behavior; keep CurrentValueAsString unsupported only if that remains enforced
without reaching this method.
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cs`:
- Around line 17-22: Update the AutoFocus parameter Description in
BitChoiceGroupDemo to state that autofocus is skipped when the ChoiceGroup is
ReadOnly, while preserving the existing checked-item and first-enabled-item
fallback behavior.
---
Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cs`:
- Around line 11-16: Optimize the interaction between OnAfterRenderAsync and
ChoiceGroup.SetInputElement to avoid repeating the O(n) group scan for every
item during a render; coordinate the update so the checked-item/input-element
tracking work runs once per group render while preserving correct autofocus and
InputElement updates when the checked item changes.
🪄 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 Plus
Run ID: 25b7adb2-e102-4f3d-b65d-a6aa149cf61c
📒 Files selected for processing (35)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (2)
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razor
|
@coderabbitai full-review |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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`:
- Around line 6-21: The explicit aria-describedby attributes in
BitChoiceGroup.razor and _BitChoiceGroupItem.razor override consumer values from
HtmlAttributes; update the code-behind for both the group and item to resolve
the final aria-describedby value, using the caller-supplied value when present
and generating the internal ID only when absent, then bind the markup to that
resolved value.
🪄 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 Plus
Run ID: 27275b5b-9aa1-4a58-b705-f9f0bd8cb042
📒 Files selected for processing (35)
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.scsssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupClassStyles.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupItem.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupNameSelectors.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroupOption.cssrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razorsrc/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/BitChoiceGroupDemo.razor.scsssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/Order.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupCustomDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupItemDemo.razor.samples.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razorsrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.cssrc/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Inputs/ChoiceGroup/_BitChoiceGroupOptionDemo.razor.samples.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csprojsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupAccessibilityTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupEventsTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupItemContentTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsApiTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStateTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupStyleClassTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupUncontrolledOptionsTest.razorsrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/BitComponentCssVariablesContractTests.cssrc/BlazorUI/Tests/Bit.BlazorUI.Tests/Utils/Theme/component-css-variables.md
💤 Files with no reviewable changes (2)
- src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/DemoPage.razor
- src/BlazorUI/Tests/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj
| @* The invalid state belongs to the choice as a whole, not to the option that happens to be focused, | ||
| so the group carries the aria-invalid too and not only the individual radio inputs of the base class. *@ | ||
| <div @ref="RootElement" @attributes="HtmlAttributes" | ||
| id="@_Id" | ||
| role="radiogroup" | ||
| style="@StyleBuilder.Value" | ||
| class="@ClassBuilder.Value" | ||
| dir="@Dir?.ToString().ToLower()" | ||
| aria-label="@AriaLabel" | ||
| aria-labelledby="@GetAriaLabelledBy()"> | ||
| aria-labelledby="@GetAriaLabelledBy()" | ||
| aria-describedby="@GetAriaDescribedBy()" | ||
| aria-required="@(Required ? "true" : null)" | ||
| aria-invalid="@(ValueInvalid is true ? "true" : null)" | ||
| aria-readonly="@(ReadOnly ? "true" : null)" | ||
| aria-disabled="@(IsEnabled ? null : "true")" | ||
| aria-orientation="@(Horizontal ? "horizontal" : "vertical")"> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate files =="
git ls-files | rg 'BitChoiceGroup\.razor|_BitChoiceGroupItem\.razor|BitChoiceGroup\.cs|\.csproj$' | sed -n '1,120p'
echo
echo "== BitChoiceGroup.razor =="
sed -n '1,80p' src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor
echo
echo "== _BitChoiceGroupItem.razor =="
sed -n '1,90p' src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor
echo
echo "== relevant occurrences in code-behind =="
rg -n "GetAriaDescribedBy|aria-describedby|HtmlAttributes|InputHtmlAttributes|HasDescription|IsEnabled|ReadOnly|Required" src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup -S
echo
echo "== git diff stat/name =="
git diff --stat | sed -n '1,80p'
git diff --name-only | sed -n '1,80p'
git diff -- BitChoiceGroup.razor src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor | sed -n '1,160p' || true
git diff -- _BitChoiceGroupItem.razor src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor | sed -n '1,160p' || true
echo
echo "== runtime Blazor duplicate attribute semantics probe via generated RenderTreeBuilder? not available; inspect available tooling =="
rg -n "Multiple attributes with the same name|override|duplicate attribute" $(find . -path ./bin -prune -o -path ./obj -prune -o -type f \( -name '*.cs' -o -name '*.md' \) -print) -S | sed -n '1,120p' || trueRepository: bitfoundation/bitplatform
Length of output: 48675
🌐 Web query:
Blazor rendering duplicate attribute names rightmost attribute wins @attributes explicit attribute duplicate name behavior
💡 Result:
In Blazor, when multiple attributes with the same name are present on a markup element—including those provided via explicit declaration and those "splatted" using the @attributes directive—the precedence is determined by the order in which they are processed [1][2]. The framework processes attributes from right to left (last to first) [1][3][4]. Because the framework evaluates these attributes in this order, the first attribute encountered (which is the rightmost attribute in your code) wins [1][5]. This behavior is effectively equivalent to "last one wins" when reading the code from left to right [2][5]. Key behaviors to remember: * If you place an attribute to the right of @attributes, that attribute will take precedence because it is processed first [1][6]. * If you place an attribute to the left of @attributes, the attribute contained within the @attributes collection will take precedence because it is processed after the explicit attribute [1][2]. Example: If you have <input @attributes="MyAttributes" class="my-class" />, the class attribute "my-class" is to the right of @attributes. It will be processed first, making "my-class" the final value, even if the "class" key exists within the MyAttributes dictionary [1][2]. Conversely, if you write <input class="my-class" @attributes="MyAttributes" />, the "class" value inside the dictionary will win [2]. This design allows component authors to provide default attributes while still giving consumers the flexibility to override them by correctly positioning their own attributes relative to the @attributes directive [1][2].
Citations:
- 1: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/splat-attributes-and-arbitrary-parameters?view=aspnetcore-9.0
- 2: https://www.meziantou.net/capturing-unmatched-attributes-and-attribute-splatting-in-blazor.htm
- 3: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/splat-attributes-and-arbitrary-parameters?view=aspnetcore-10.0
- 4: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/splat-attributes-and-arbitrary-parameters?view=aspnetcore-8.0
- 5: Blazor right to left attributes? dotnet/AspNetCore.Docs#35667
- 6: order of processing @attributes dotnet/AspNetCore.Docs#16518
Do not override consumer-supplied aria-describedby after applying HTML attributes.
Blazor right-to-left attribute precedence means the explicit aria-describedby here wins over any consumer-supplied value in HtmlAttributes, including when it evaluates to null and removes the attribute. Build the final group/item aria-describedby in code behind, only providing a generated ID when no caller-supplied value exists.
📍 Affects 2 files
src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor#L6-L21(this comment)src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/_BitChoiceGroupItem.razor#L23-L47
🤖 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`
around lines 6 - 21, The explicit aria-describedby attributes in
BitChoiceGroup.razor and _BitChoiceGroupItem.razor override consumer values from
HtmlAttributes; update the code-behind for both the group and item to resolve
the final aria-describedby value, using the caller-supplied value when present
and generating the internal ID only when absent, then bind the markup to that
resolved value.
closes #12740
Summary by CodeRabbit
--bit-chg-dot-size;--bit-chg-dot-positionremoved).