Skip to content

[CL-1115] accordion component#20508

Draft
BryanCunningham wants to merge 7 commits intomainfrom
uif/CL-1115/accordion-component
Draft

[CL-1115] accordion component#20508
BryanCunningham wants to merge 7 commits intomainfrom
uif/CL-1115/accordion-component

Conversation

@BryanCunningham
Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/CL-1115

📔 Objective

Create new accordion component

📸 Screenshots

Variant: default

Size: default

image

Size: sm

image

Variant: subtle

Size: default

image

Size: sm

image

@BryanCunningham BryanCunningham added the ai-review Request a Claude code review label May 5, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR introduces a new bit-accordion component along with a bit-accordion-group wrapper that supports an optional single-select mode. The implementation uses Angular signals (input, model, effect, computed), follows tw- Tailwind prefix conventions, exposes the components via the existing libs/components barrel, and adds a new --color-fg-inactive token for inactive states. Accessibility is well-handled (aria-expanded, aria-controls, aria-labelledby, role="region", focus-visible ring), and the test, story, and MDX coverage is solid.

Code Review Details

No additional findings beyond the existing review thread by @vleague2. The author has addressed or responded to all raised concerns (storybook arg formatting, slot=end projection, title vs heading naming, inline styles consolidation, untracked rationale). The single-select effect + untracked pattern is correct given Angular's signal-write-from-effect rule, and the nextId++ module-scoped id pattern matches the existing disclosure.component.ts precedent in this library.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 45.88235% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.11%. Comparing base (be70072) to head (d57d173).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
libs/components/src/accordion/accordion.stories.ts 0.00% 28 Missing ⚠️
...bs/components/src/accordion/accordion.component.ts 72.34% 2 Missing and 11 partials ⚠️
...ponents/src/accordion/accordion-group.component.ts 28.57% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #20508      +/-   ##
==========================================
- Coverage   47.11%   47.11%   -0.01%     
==========================================
  Files        3951     3955       +4     
  Lines      119722   119839     +117     
  Branches    18346    18364      +18     
==========================================
+ Hits        56407    56460      +53     
- Misses      59081    59133      +52     
- Partials     4234     4246      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread libs/components/src/accordion/accordion.component.spec.ts Outdated
Comment thread libs/components/src/accordion/accordion.component.ts Outdated
effect(() => {
const activeId = this.group?._activeAccordionId();
if (activeId != null && activeId !== this._baseId) {
untracked(() => this.open.set(false));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why the untracked wrapper here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We are closing this accordion imperatively if the parent group component is single select and is controlling which accordion is open. We had to use untracked here because you can't write to a model inside of an effect AFAIK

].join(" "),
);

private readonly triggerSizeClasses = computed((): string[] => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are other styles inline as ternaries; does this one need to be separate?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not necessarily. I can move it. Generally, I like the idea of all the styles being in the component vs the template. I guess I should just commit one way or the other :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For this one I think it is still used in the component side not the template. It's just split out into another function by itself

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to be inline

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm not sure why I did it that way.

<bit-icon-tile [icon]="startIcon()" [size]="iconTileSize()" variant="contrast"></bit-icon-tile>
}
<div class="tw-flex tw-flex-col tw-flex-1 tw-min-w-0 tw-gap-1 tw-items-start">
<span [class]="headingClassList()">{{ heading() }}</span>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are there any typography variants that we can use for heading and subtitle?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes and no. Because this switches text sizes and colors based on inactive state and the size variant passed in this felt easier to swap

Comment thread libs/components/src/accordion/accordion.stories.ts Outdated
Comment thread libs/components/src/accordion/accordion.stories.ts Outdated
Comment thread libs/components/src/accordion/accordion.stories.ts Outdated
Comment thread libs/components/src/accordion/accordion.component.html Outdated
Comment thread libs/components/src/accordion/accordion.component.ts Outdated
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

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

Labels

ai-review Request a Claude code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants