Skip to content

Add AccordionList component (#8850)#12417

Open
msynk wants to merge 5 commits into
bitfoundation:developfrom
msynk:8850-blazorui-extras-accordionlist
Open

Add AccordionList component (#8850)#12417
msynk wants to merge 5 commits into
bitfoundation:developfrom
msynk:8850-blazorui-extras-accordionlist

Conversation

@msynk
Copy link
Copy Markdown
Member

@msynk msynk commented May 31, 2026

closes #8850

Summary by CodeRabbit

  • New Features

    • Added BitAccordionList with single/multiple expand modes, two-way binding, templating, per-item options, custom icons, styling, ExpandAll/CollapseAll, and configurable name-selector/class-style support
    • Added BitAccordionListOption and item/config models for flexible child-option and item-based workflows
  • Documentation / Demos

    • New comprehensive demo pages and examples (templates, events, binding, RTL, icon/styling samples, code snippets)
  • Styles

    • New accordion list layout and spacing styles
  • Tests

    • Unit tests for rendering, expansion behavior, events, binding, and option scenarios

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

Walkthrough

Adds BitAccordionList plus supporting types and BitAccordionListOption; implements deterministic key assignment, single/multiple expansion state with controlled/uncontrolled APIs, templates, icon/style resolution, SCSS, demos (item/custom/option), navigation, and a comprehensive BUnit test suite.

Changes

BitAccordionList Component Implementation

Layer / File(s) Summary
Data contracts and configuration types
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs, src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs, src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs, src/BlazorUI/Demo/Client/.../AccordionList/Section.cs
Defines BitAccordionListClassStyles, BitAccordionListItem, BitAccordionListNameSelectors<TItem>, and demo Section model used by component and demos.
Option component for cascading child registration
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs
BitAccordionListOption registers/unregisters with parent via cascading parameter and exposes per-option params (title, description, body/child content, icons, key, state, OnClick).
Main component logic and rendering
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor, src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs
BitAccordionList<TItem> implements rendering, key assignment, registration, expansion state (single/multiple), default/controlled precedence, templates (Header/Body), icon/style resolution, event callbacks (OnExpand, OnCollapse, OnToggle, OnItemClick), ExpandAll/CollapseAll, dynamic option registration, and NameSelectors support.
Component styling and import registration
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss, src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss, src/BlazorUI/Demo/.../AccordionList/BitAccordionListDemo.razor.scss
Adds .bit-acl stylesheet (flex column, full width, gap), imports shared functions, updates import order, and demo-specific SCSS.
Demo page setup and navigation
src/BlazorUI/Demo/.../AccordionList/BitAccordionListDemo.razor, .razor.cs, .razor.scss, src/BlazorUI/Demo/.../Shared/MainLayout.razor.NavItems.cs
Adds main demo page route /components/accordionlist, demo metadata, styling, and navigation entry under Extras.
Demo: BitAccordionListItem-based examples
src/BlazorUI/Demo/.../AccordionList/_BitAccordionListItemDemo.*
Item-based demos and sample code strings demonstrating basic/multiple/defaults/events/binding/templates/styling/RTL scenarios.
Demo: NameSelectors with custom Section type
src/BlazorUI/Demo/.../AccordionList/_BitAccordionListCustomDemo.*, Section.cs
Custom-type demos demonstrating mapping via BitAccordionListNameSelectors<Section> across many examples and sample strings.
Demo: BitAccordionListOption-based examples
src/BlazorUI/Demo/.../AccordionList/_BitAccordionListOptionDemo.*
Child-option demos showing BitAccordionListOption usage, events, binding, templates, styling, and RTL sample strings.
Comprehensive unit tests
src/BlazorUI/Tests/.../AccordionList/BitAccordionListTests.cs
BUnit tests covering rendering, expand/collapse behavior for single and multiple modes, default/controlled keys, events, two-way binding, ExpandAll/CollapseAll, option children, and NameSelectors mapping.

Sequence Diagram

sequenceDiagram
  participant User
  participant BitAccordionList
  participant Items as Items/Options
  participant State as ExpansionState

  User->>BitAccordionList: Initialize with Items/Options or ChildContent and parameters
  BitAccordionList->>Items: AssignItemKeys / RegisterOption
  BitAccordionList->>State: InitializeExpandedKeys (controlled/default/item)
  BitAccordionList->>User: Render BitAccordion per item

  User->>BitAccordionList: Click header or call ExpandAll/CollapseAll
  BitAccordionList->>State: Toggle / ExpandAll / CollapseAll
  BitAccordionList->>Items: Sync IsExpanded per item
  BitAccordionList->>User: Invoke OnExpand/OnCollapse/OnToggle callbacks
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I hop through code and weave a list,
Each panel folds with a gentle twist,
Options registered, keys assigned,
Templates, icons, states aligned,
A tiny rabbit’s accordion, neatly designed. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.84% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main change: adding a new AccordionList component. It is concise, directly related to the changeset, and provides meaningful information.
Linked Issues check ✅ Passed The PR successfully implements the AccordionList component requested in issue #8850, with complete feature set including rendering, state management, customization options, and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the AccordionList component and its supporting infrastructure. Navigation menu update is appropriate for feature discovery.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs (1)

113-135: ⚡ Quick win

Add explicit coverage for OnItemClick callback.

The suite validates OnExpand/OnCollapse/OnToggle, but there’s no direct assertion for OnItemClick. Since click-handling is a first-class behavior, add one test to verify it fires with the expected item key.

Proposed test addition
+    [TestMethod]
+    public void BitAccordionListShouldRaiseOnItemClick()
+    {
+        string? clicked = null;
+
+        var component = RenderComponent<BitAccordionList<BitAccordionListItem>>(parameters =>
+        {
+            parameters.Add(p => p.Items, GetItems());
+            parameters.Add(p => p.OnItemClick, (BitAccordionListItem i) => clicked = i.Key);
+        });
+
+        component.FindAll(".bit-acd-hdr")[1].Click();
+
+        Assert.AreEqual("b", clicked);
+    }
🤖 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/Extras/AccordionList/BitAccordionListTests.cs`
around lines 113 - 135, Extend the
BitAccordionListShouldRaiseExpandCollapseAndToggleEvents test to also verify the
OnItemClick callback: add a local variable (e.g., string? clicked = null), pass
parameters.Add(p => p.OnItemClick, (BitAccordionListItem i) => clicked = i.Key)
when rendering the BitAccordionList<BitAccordionListItem>, perform the same
.bit-acd-hdr click(s) on the rendered component, and assert that clicked equals
the expected item key ("a") after the click; keep the existing
OnExpand/OnCollapse/OnToggle assertions intact.
🤖 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.Extras/Components/AccordionList/BitAccordionList.razor.cs`:
- Around line 238-248: UnregisterOption currently removes the option from _items
and _expandedKeys but leaves _internalExpandedKey/_internalExpandedKeys and the
two-way bound properties (ExpandedKey/ExpandedKeys) stale; make UnregisterOption
update those bound/internal states by invoking the existing async
UpdateBoundKeys method (convert UnregisterOption to async Task if needed), await
UpdateBoundKeys so the internal representations and bound values are refreshed
consistently when a removed option was expanded, and call StateHasChanged after
the awaited update; reference the UnregisterOption method, _expandedKeys,
_internalExpandedKey/_internalExpandedKeys, ExpandedKey/ExpandedKeys, and
UpdateBoundKeys when making the change.
- Around line 186-189: The auto-generated key assignment using _items.Count can
collide with existing explicit keys or after removals; change the registration
logic that sets option.Key (in BitAccordionList option registration code) to use
a monotonic seed (e.g., add private int _optionKeySeed) and assign option.Key =
(_optionKeySeed++).ToString(); additionally, guard against any unlikely
duplicate by checking existing keys in _items (or _expandedKeys) and
incrementing the seed until a unique key is produced; optionally use a GUID
string if numeric keys would be confusing to consumers.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor`:
- Around line 110-123: The demo text claims to show Style, Class, Styles, and
Classes but only demonstrates Style and Styles in the BitAccordionList examples;
update the DemoExample (Id="example10", Title="Style & Class") to either change
the title/description to remove "Class/Classes" or add Class and Classes usage
to the BitAccordionList instances (refer to BitAccordionList, DemoExample,
example10RazorCode/example10CsharpCode and basicItems) by setting a Class (or
Classes) value on one example and/or adding a second example that uses Classes
to demonstrate per-part class overrides so the sample matches the description.

---

Nitpick comments:
In
`@src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs`:
- Around line 113-135: Extend the
BitAccordionListShouldRaiseExpandCollapseAndToggleEvents test to also verify the
OnItemClick callback: add a local variable (e.g., string? clicked = null), pass
parameters.Add(p => p.OnItemClick, (BitAccordionListItem i) => clicked = i.Key)
when rendering the BitAccordionList<BitAccordionListItem>, perform the same
.bit-acd-hdr click(s) on the rendered component, and assert that clicked equals
the expected item key ("a") after the click; keep the existing
OnExpand/OnCollapse/OnToggle assertions intact.
🪄 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: a4b934e5-21d6-42c1-ad8d-415aeada0451

📥 Commits

Reviewing files that changed from the base of the PR and between 046d116 and 943d841.

📒 Files selected for processing (23)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/Section.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs

@msynk
Copy link
Copy Markdown
Member Author

msynk commented Jun 1, 2026

@coderabbitai re-review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

@msynk Sure, I'll re-review the PR now!

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new BitAccordionList<TItem> component to Bit.BlazorUI.Extras, providing a list-oriented accordion API (single- and multi-expand) with support for item models, name selectors, and child option components, plus demo documentation and bUnit tests.

Changes:

  • Introduces BitAccordionList<TItem> along with supporting types (BitAccordionListItem, BitAccordionListOption, BitAccordionListNameSelectors, BitAccordionListClassStyles) and component styling.
  • Adds a full demo page and examples (Item / Custom / Option) and registers the page in the demo navigation.
  • Adds initial bUnit test coverage for rendering, expansion behavior, defaults, events, binding (single), and option/name-selector scenarios.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs Adds bUnit tests for AccordionList behaviors and APIs.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs Adds AccordionList to the Demo “Extras” navigation.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/Section.cs Demo model used for the “Custom generic” examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss Demo page styles for AccordionList examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.cs Demo page metadata (parameters, subclasses, members).
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor Adds the AccordionList demo page and example pivots.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.samples.cs Adds sample code strings for Option-based usage.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.cs Adds code-behind state for Option-based examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor Adds interactive Option-based examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.samples.cs Adds sample code strings for Item-based usage.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.cs Adds code-behind data for Item-based examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor Adds interactive Item-based examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs Adds sample code strings for custom-type + NameSelectors usage.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.cs Adds code-behind data for custom-type examples.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor Adds interactive custom-type + selectors examples.
src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss Registers the new component SCSS in the extras bundle.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs Adds option child component type for the list API.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs Adds NameSelectors mapping for custom generic item types.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs Adds the default item model used by Items API.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs Adds class/style mapping structure for AccordionList parts.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss Adds base styles for the AccordionList root.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs Implements AccordionList logic, binding, events, and rendering helpers.
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor Renders a list of BitAccordion instances and supports option child content.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs (1)

333-342: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Implicit index keys can collide with explicit keys.

AssignItemKeys assigns the loop index as the key for keyless items, but does not check it against keys already set explicitly on other items. e.g. item[0] has Key="1" explicit and item[1] is keyless → it gets "1", producing a duplicate. Since _expandedKeys, @key, and toggling rely on key uniqueness, this mismatches the collision guard already applied in RegisterOption (Line 192). Consider skipping/incrementing past keys that are already in use.

🤖 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.Extras/Components/AccordionList/BitAccordionList.razor.cs`
around lines 333 - 342, AssignItemKeys currently assigns i.ToString() to keyless
items without checking for collisions with explicit keys; update AssignItemKeys
to generate a candidate key (e.g., based on the loop index) and loop/increment
until the candidate is not already used by any existing item keys or in
_expandedKeys (or whatever set RegisterOption enforces), then call
SetItemKey(item, candidate). Use GetItemKey and SetItemKey to inspect and assign
keys and reference the same uniqueness check RegisterOption relies on to avoid
duplicates across _items and _expandedKeys.
🧹 Nitpick comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs (1)

94-101: 💤 Low value

Async UnregisterOption is invoked fire-and-forget during disposal.

Dispose(bool) discards the Task from Parent.UnregisterOption(this), so the awaited UpdateBoundKeys (which invokes ExpandedKey/ExpandedKeys callbacks) runs unobserved and any exception is swallowed. This is generally tolerable for IDisposable, but worth confirming the bound-key refresh isn't relied upon to complete synchronously when an expanded option is removed.

🤖 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.Extras/Components/AccordionList/BitAccordionListOption.cs`
around lines 94 - 101, Dispose(bool) currently fire-and-forgets the async
Parent.UnregisterOption(this), causing UpdateBoundKeys (and
ExpandedKey/ExpandedKeys callbacks) to run unobserved; change disposal to
observe/await the task: either implement IAsyncDisposable and make DisposeAsync
call await Parent.UnregisterOption(this), or if staying synchronous,
synchronously wait and observe exceptions by calling
Parent.UnregisterOption(this).GetAwaiter().GetResult() (and log/handle any
exception) inside Dispose(bool); reference Dispose(bool),
Parent.UnregisterOption(this), UpdateBoundKeys, ExpandedKey/ExpandedKeys when
making the change.
🤖 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.Extras/Components/AccordionList/BitAccordionList.razor.cs`:
- Around line 301-310: The change detection block in BitAccordionList.razor.cs
currently skips when Items becomes empty due to the Items.Any() guard, leaving
_items stale; update the condition so empty Items are processed too (remove the
Items.Any() check) and rely on the sequence/reference comparison between Items
and _oldItems; when the condition (ChildContent is null && Options is null &&
Items is not null && (_oldItems is null || !Items.SequenceEqual(_oldItems))) is
true, set _oldItems and _items from Items and then call AssignItemKeys() and
InitializeExpandedKeys() so the UI clears correctly when Items transitions to an
empty collection.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss`:
- Line 1: The SCSS import in BitAccordionList.scss uses a file extension which
violates the scss/load-partial-extension rule; update the `@import` in
BitAccordionList.scss that references
"../../../Bit.BlazorUI/Styles/functions.scss" to omit the ".scss" extension
(import "../../../Bit.BlazorUI/Styles/functions") so Stylelint passes and
linting is unblocked.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss`:
- Around line 1-2: The two `@import` statements referencing BitAccordionList.scss
and BitAppShell.scss violate the scss/load-partial-extension rule; remove the
“.scss” extensions in those import lines so they use extension-less imports
(e.g., change the imports that reference BitAccordionList.scss and
BitAppShell.scss to import the same module names without the .scss extension).

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor`:
- Around line 113-126: The description currently claims the demo shows Style,
Class, Styles, and Classes but the examples only use Style and Styles; either
update the sentence to only mention Style and Styles or add missing examples
that demonstrate Class and Classes; if adding examples, create a
BitAccordionList example (using the same Items="basicItems" TItem="Section"
NameSelectors="nameSelectors") that sets Class="your-css-class" to show the
single-class parameter and another example using Classes="@(new() { ItemTitle =
\"...\", ItemHeader = \"...\" })" to demonstrate the per-part Classes parameter
so the description matches the actual samples.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor`:
- Around line 247-277: The section header claims it demonstrates Style, Class,
Styles, and Classes but the examples only show Style and Styles; either change
the text to mention only Style and Styles or add usage of Class and Classes to
the BitAccordionList/BitAccordionListOption examples. To fix, update the
descriptive div ("Customize the appearance...") to remove "Class, and Classes"
if you prefer not to add examples, or add explicit Class attributes (e.g.,
Class="..." on BitAccordionList or BitAccordionListOption) and a Classes
parameter (e.g., Classes="new() { Item = \"...\", ItemTitle = \"...\" }") to one
of the BitAccordionList examples so the demo includes all four parameters (refer
to BitAccordionList, BitAccordionListOption, and their
Style/Class/Styles/Classes parameters).

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs`:
- Around line 333-342: AssignItemKeys currently assigns i.ToString() to keyless
items without checking for collisions with explicit keys; update AssignItemKeys
to generate a candidate key (e.g., based on the loop index) and loop/increment
until the candidate is not already used by any existing item keys or in
_expandedKeys (or whatever set RegisterOption enforces), then call
SetItemKey(item, candidate). Use GetItemKey and SetItemKey to inspect and assign
keys and reference the same uniqueness check RegisterOption relies on to avoid
duplicates across _items and _expandedKeys.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs`:
- Around line 94-101: Dispose(bool) currently fire-and-forgets the async
Parent.UnregisterOption(this), causing UpdateBoundKeys (and
ExpandedKey/ExpandedKeys callbacks) to run unobserved; change disposal to
observe/await the task: either implement IAsyncDisposable and make DisposeAsync
call await Parent.UnregisterOption(this), or if staying synchronous,
synchronously wait and observe exceptions by calling
Parent.UnregisterOption(this).GetAwaiter().GetResult() (and log/handle any
exception) inside Dispose(bool); reference Dispose(bool),
Parent.UnregisterOption(this), UpdateBoundKeys, ExpandedKey/ExpandedKeys when
making the change.
🪄 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: 2561e7cb-5099-4e93-b8d5-edf9220b77a2

📥 Commits

Reviewing files that changed from the base of the PR and between 046d116 and 2cc0d74.

📒 Files selected for processing (23)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/Section.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
@msynk
Copy link
Copy Markdown
Member Author

msynk commented Jun 1, 2026

@coderabbitai re-review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

@msynk Sure, I'll re-review the PR now!

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs`:
- Around line 175-254: The Razor sample string example4RazorCode references a
non-existent basicItems while the C# sample only defines eventsItems; update
example4RazorCode to bind the first BitAccordionList to eventsItems (replace
Items="basicItems" with Items="eventsItems") or alternatively add a basicItems
definition mirroring eventsItems so both lists compile; locate the string
constants example4RazorCode and example4CsharpCode and make the change so the
sample is internally consistent.
🪄 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: 9acce9ca-ee83-4ef3-afcd-74977e331dbf

📥 Commits

Reviewing files that changed from the base of the PR and between 046d116 and c52e885.

📒 Files selected for processing (23)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/Section.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs

@msynk
Copy link
Copy Markdown
Member Author

msynk commented Jun 1, 2026

@coderabbitai re-review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

@msynk Sure, I'll re-review the PR now!

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs (1)

934-938: ⚡ Quick win

Fire-and-forget on the option's OnClick swallows faults and ordering.

HandleOnItemClick awaits OnItemClick but InvokeItemClick discards the option callback's task (_ = listOption.OnClick.InvokeAsync(...)). Exceptions are lost and the callback may interleave with the subsequent ToggleItem. Consider making InvokeItemClick async and awaiting it from HandleOnItemClick.

♻️ Proposed change
-    private void InvokeItemClick(TItem item)
+    private async Task InvokeItemClick(TItem item)
     {
         if (item is BitAccordionListItem listItem)
         {
             listItem.OnClick?.Invoke(listItem);
             return;
         }

         if (item is BitAccordionListOption listOption)
         {
-            _ = listOption.OnClick.InvokeAsync(listOption);
+            await listOption.OnClick.InvokeAsync(listOption);
             return;
         }

Then update the call site:

-        InvokeItemClick(item);
+        await InvokeItemClick(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.Extras/Components/AccordionList/BitAccordionList.razor.cs`
around lines 934 - 938, The current fire-and-forget call in the option branch
swallows exceptions and allows ordering issues; change the method that contains
this snippet (e.g., InvokeItemClick) to be async and return a Task, replace the
discard call with an awaited call to listOption.OnClick.InvokeAsync(listOption),
and then update the caller HandleOnItemClick to await InvokeItemClick before
calling ToggleItem so the option callback's exceptions and ordering are
preserved.
🤖 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/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss`:
- Line 1: Stylelint flags the ::deep pseudo-element as unknown; to fix, add an
inline stylelint suppression around the rule in BitAccordionListDemo.razor.scss:
insert /* stylelint-disable selector-pseudo-element-no-unknown */ immediately
before the ::deep usage and /* stylelint-enable
selector-pseudo-element-no-unknown */ right after the related block so the
selector is allowed without changing global config; locate the ::deep selector
in the file to apply these comments.

---

Nitpick comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs`:
- Around line 934-938: The current fire-and-forget call in the option branch
swallows exceptions and allows ordering issues; change the method that contains
this snippet (e.g., InvokeItemClick) to be async and return a Task, replace the
discard call with an awaited call to listOption.OnClick.InvokeAsync(listOption),
and then update the caller HandleOnItemClick to await InvokeItemClick before
calling ToggleItem so the option callback's exceptions and ordering are
preserved.
🪄 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: a60b0f71-3c65-4575-8b77-671a274b257b

📥 Commits

Reviewing files that changed from the base of the PR and between 046d116 and 30c2235.

📒 Files selected for processing (23)
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionList.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListClassStyles.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListItem.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListNameSelectors.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/AccordionList/BitAccordionListOption.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/BitAccordionListDemo.razor.scss
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/Section.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListCustomDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListItemDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AccordionList/_BitAccordionListOptionDemo.razor.samples.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/AccordionList/BitAccordionListTests.cs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The BlazorUI needs a new AccordionList component

2 participants