Skip to content

feat: add smooth animation to Accordion component#1661

Closed
vadim-cebanu wants to merge 1 commit intothemesberg:mainfrom
vadim-cebanu:feat/accordion-animation
Closed

feat: add smooth animation to Accordion component#1661
vadim-cebanu wants to merge 1 commit intothemesberg:mainfrom
vadim-cebanu:feat/accordion-animation

Conversation

@vadim-cebanu
Copy link

@vadim-cebanu vadim-cebanu commented Mar 14, 2026

Adds a smooth slide-down animation to the Accordion component when opening/closing panels.

Currently the Accordion expands and collapses instantly which can be jarring for users.
This fix adds a CSS transition using max-height to create a smooth animation effect.

Fixes #909

Summary by CodeRabbit

  • New Features
    • Accordion items now animate smoothly when opening and closing, providing a more polished interaction experience.

@vercel
Copy link

vercel bot commented Mar 14, 2026

@vadim-cebanu is attempting to deploy a commit to the Bergside Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link

changeset-bot bot commented Mar 14, 2026

⚠️ No Changeset found

Latest commit: db9b372

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

The AccordionContent component now animates expansion and collapse using CSS transitions. The hidden attribute is replaced with inline styles: maxHeight transitions from 0px (closed) to 1000px (open) over 0.3 seconds, with overflow hidden to manage content clipping smoothly.

Changes

Cohort / File(s) Summary
Accordion Animation Enhancement
packages/ui/src/components/Accordion/AccordionContent.tsx
Replaces boolean hidden attribute with CSS-based height animation. Closed state sets maxHeight to 0 with overflow hidden; open state animates maxHeight to 1000px with 0.3s transition timing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 A tiny tweak, a hop of grace,
MaxHeight dancing into place,
No more snap—just glide and sway,
Accordions bloom in CSS's way!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding smooth animation to the Accordion component, which is the primary objective of this pull request.
Linked Issues check ✅ Passed The pull request implements the animation support requested in issue #909 by adding a CSS transition with max-height for smooth open/close animation of Accordion panels.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the animation feature for the Accordion component as requested in issue #909, with no extraneous modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can disable the changed files summary in the walkthrough.

Disable the reviews.changed_files_summary setting to disable the changed files summary in the walkthrough.

Copy link
Contributor

@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: 2

🧹 Nitpick comments (1)
packages/ui/src/components/Accordion/AccordionContent.tsx (1)

35-40: Merge consumer styles instead of allowing full overwrite.

Because ...restProps is spread after style, a passed style prop can wipe out animation styles. Merge incoming style explicitly.

Proposed fix
-  const { className, ...restProps } = resolveProps(props, provider.props?.accordionContent);
+  const { className, style, ...restProps } = resolveProps(props, provider.props?.accordionContent);
@@
       style={{
+        ...style,
         overflow: "hidden",
         maxHeight: isOpen ? "1000px" : "0",
         transition: "max-height 0.3s ease-in-out",
       }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/components/Accordion/AccordionContent.tsx` around lines 35 -
40, The component currently spreads {...restProps} after setting style which
allows a consumer-provided style to fully overwrite the animation/overflow
styles; change AccordionContent.tsx to extract style from restProps (e.g. const
{ style: consumerStyle, ...otherProps } = restProps), build a mergedStyle object
that sets overflow, maxHeight (based on isOpen), and transition and then spreads
consumerStyle last into that object (so consumer can override specific keys if
desired), and finally render with style={mergedStyle} and {...otherProps}
instead of {...restProps}.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/ui/src/components/Accordion/AccordionContent.tsx`:
- Around line 37-38: The hard-coded maxHeight ("1000px") in AccordionContent
causes clipping; change AccordionContent to measure the panel element's
scrollHeight via a ref (e.g., contentRef) and set its style.maxHeight to isOpen
? `${contentRef.current.scrollHeight}px` : "0" to animate to the actual content
height, and optionally clear maxHeight to "none" after the transition ends to
allow dynamic content resizing; update any useEffect or event handlers in
AccordionContent that currently toggle maxHeight to use this measured value and
listen for transitionend to reset if needed.
- Around line 35-40: AccordionContent currently animates collapse using
maxHeight but doesn't set the hidden semantics, leaving collapsed content
reachable by assistive tech; modify the AccordionContent component to manage a
hidden boolean (or use the DOM hidden attribute) alongside isOpen: when opening,
remove hidden before starting the maxHeight transition; when closing, start the
transition then set hidden=true in an onTransitionEnd handler (use a ref to the
container and listen for its transitionend) so the element is removed from
accessibility tree after the animation completes; update any places using
isOpen/restProps and ensure the element includes aria-hidden or the hidden
attribute consistently.

---

Nitpick comments:
In `@packages/ui/src/components/Accordion/AccordionContent.tsx`:
- Around line 35-40: The component currently spreads {...restProps} after
setting style which allows a consumer-provided style to fully overwrite the
animation/overflow styles; change AccordionContent.tsx to extract style from
restProps (e.g. const { style: consumerStyle, ...otherProps } = restProps),
build a mergedStyle object that sets overflow, maxHeight (based on isOpen), and
transition and then spreads consumerStyle last into that object (so consumer can
override specific keys if desired), and finally render with style={mergedStyle}
and {...otherProps} instead of {...restProps}.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 70534b6c-2e89-4c78-b3e8-2d29ad7c61e0

📥 Commits

Reviewing files that changed from the base of the PR and between 0f526aa and db9b372.

📒 Files selected for processing (1)
  • packages/ui/src/components/Accordion/AccordionContent.tsx

Comment on lines +35 to 40
style={{
overflow: "hidden",
maxHeight: isOpen ? "1000px" : "0",
transition: "max-height 0.3s ease-in-out",
}}
{...restProps}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Preserve hidden semantics for collapsed panels.

Replacing hidden with only max-height animation can leave collapsed content reachable by assistive tech/focus until/unless explicitly hidden. Please keep animation and restore hidden semantics after collapse completes.

Proposed fix
-import type { ComponentProps } from "react";
+import { useEffect, useState, type ComponentProps } from "react";
@@
 export function AccordionContent(props: AccordionContentProps) {
   const { isOpen } = useAccordionContext();
+  const [isHidden, setIsHidden] = useState(!isOpen);
+
+  useEffect(() => {
+    if (isOpen) setIsHidden(false);
+  }, [isOpen]);
@@
     <div
       className={twMerge(theme.base, className)}
       data-testid="flowbite-accordion-content"
+      hidden={isHidden}
+      aria-hidden={!isOpen}
+      onTransitionEnd={() => {
+        if (!isOpen) setIsHidden(true);
+      }}
       style={{
         overflow: "hidden",
         maxHeight: isOpen ? "1000px" : "0",
         transition: "max-height 0.3s ease-in-out",
       }}
       {...restProps}
     />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/components/Accordion/AccordionContent.tsx` around lines 35 -
40, AccordionContent currently animates collapse using maxHeight but doesn't set
the hidden semantics, leaving collapsed content reachable by assistive tech;
modify the AccordionContent component to manage a hidden boolean (or use the DOM
hidden attribute) alongside isOpen: when opening, remove hidden before starting
the maxHeight transition; when closing, start the transition then set
hidden=true in an onTransitionEnd handler (use a ref to the container and listen
for its transitionend) so the element is removed from accessibility tree after
the animation completes; update any places using isOpen/restProps and ensure the
element includes aria-hidden or the hidden attribute consistently.

Comment on lines +37 to +38
maxHeight: isOpen ? "1000px" : "0",
transition: "max-height 0.3s ease-in-out",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid hard-coded maxHeight: 1000px; it can truncate content.

If panel content exceeds 1000px, the open state is clipped. Measure and animate to scrollHeight instead of a fixed cap.

Proposed fix
-import type { ComponentProps } from "react";
+import { useLayoutEffect, useRef, useState, type ComponentProps } from "react";
@@
 export function AccordionContent(props: AccordionContentProps) {
   const { isOpen } = useAccordionContext();
+  const contentRef = useRef<HTMLDivElement>(null);
+  const [maxHeight, setMaxHeight] = useState("0px");
+
+  useLayoutEffect(() => {
+    const el = contentRef.current;
+    if (!el) return;
+    setMaxHeight(isOpen ? `${el.scrollHeight}px` : "0px");
+  }, [isOpen, props.children]);
@@
     <div
+      ref={contentRef}
       className={twMerge(theme.base, className)}
       data-testid="flowbite-accordion-content"
       style={{
         overflow: "hidden",
-        maxHeight: isOpen ? "1000px" : "0",
+        maxHeight,
         transition: "max-height 0.3s ease-in-out",
       }}
       {...restProps}
     />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/components/Accordion/AccordionContent.tsx` around lines 37 -
38, The hard-coded maxHeight ("1000px") in AccordionContent causes clipping;
change AccordionContent to measure the panel element's scrollHeight via a ref
(e.g., contentRef) and set its style.maxHeight to isOpen ?
`${contentRef.current.scrollHeight}px` : "0" to animate to the actual content
height, and optionally clear maxHeight to "none" after the transition ends to
allow dynamic content resizing; update any useEffect or event handlers in
AccordionContent that currently toggle maxHeight to use this measured value and
listen for transitionend to reset if needed.

@vadim-cebanu vadim-cebanu closed this by deleting the head repository Mar 14, 2026
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.

Add animation to Accordion component

1 participant