fix(accordion): keepContentMounted with disableAnimation (#5172)

* fix(accordion): keepContentMounted with disableAnimation

* feat(accordion): add test cases

* fix(accordion): use waitFor
This commit is contained in:
աӄա 2025-04-19 23:24:17 +08:00 committed by GitHub
parent 500ed771e2
commit 531518f2ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 103 additions and 4 deletions

View File

@ -0,0 +1,5 @@
---
"@heroui/accordion": patch
---
fixed keepContentMounted with disableAnimation (#5157)

View File

@ -1,6 +1,6 @@
import "@testing-library/jest-dom"; import "@testing-library/jest-dom";
import * as React from "react"; import * as React from "react";
import {act, render} from "@testing-library/react"; import {act, render, waitFor} from "@testing-library/react";
import {focus, shouldIgnoreReactWarning, spy} from "@heroui/test-utils"; import {focus, shouldIgnoreReactWarning, spy} from "@heroui/test-utils";
import userEvent, {UserEvent} from "@testing-library/user-event"; import userEvent, {UserEvent} from "@testing-library/user-event";
import {Input} from "@heroui/input"; import {Input} from "@heroui/input";
@ -267,7 +267,7 @@ describe("Accordion", () => {
expect(button).toHaveAttribute("aria-expanded", "true"); expect(button).toHaveAttribute("aria-expanded", "true");
}); });
it("should support keepContentMounted", async () => { it("should support keepContentMounted={true}", async () => {
const wrapper = render( const wrapper = render(
<Accordion keepContentMounted> <Accordion keepContentMounted>
<AccordionItem key="1" data-testid="item-1" title="Accordion Item 1"> <AccordionItem key="1" data-testid="item-1" title="Accordion Item 1">
@ -289,8 +289,98 @@ describe("Accordion", () => {
const button2 = item2.querySelector("button") as HTMLElement; const button2 = item2.querySelector("button") as HTMLElement;
await user.click(button2); await user.click(button2);
await waitFor(() => {
expect(item1.querySelector("[role='region']")).toBeInTheDocument();
expect(item2.querySelector("[role='region']")).toBeInTheDocument();
});
});
it("should support keepContentMounted={false}", async () => {
const wrapper = render(
<Accordion keepContentMounted={false}>
<AccordionItem key="1" data-testid="item-1" title="Accordion Item 1">
Accordion Item 1 description
</AccordionItem>
<AccordionItem key="2" data-testid="item-2" title="Accordion Item 2">
Accordion Item 2 description
</AccordionItem>
</Accordion>,
);
const item1 = wrapper.getByTestId("item-1");
const button = item1.querySelector("button") as HTMLElement;
expect(item1.querySelector("[role='region']")).not.toBeInTheDocument();
await user.click(button);
const item2 = wrapper.getByTestId("item-2");
const button2 = item2.querySelector("button") as HTMLElement;
await user.click(button2);
await waitFor(() => {
expect(item1.querySelector("[role='region']")).not.toBeInTheDocument();
expect(item2.querySelector("[role='region']")).toBeInTheDocument();
});
});
it("should support keepContentMounted={true} & disableAnimation={true}", async () => {
const wrapper = render(
<Accordion disableAnimation keepContentMounted>
<AccordionItem key="1" data-testid="item-1" title="Accordion Item 1">
Accordion Item 1 description
</AccordionItem>
<AccordionItem key="2" data-testid="item-2" title="Accordion Item 2">
Accordion Item 2 description
</AccordionItem>
</Accordion>,
);
const item1 = wrapper.getByTestId("item-1");
const button = item1.querySelector("button") as HTMLElement;
expect(item1.querySelector("[role='region']")).toBeInTheDocument(); expect(item1.querySelector("[role='region']")).toBeInTheDocument();
expect(item2.querySelector("[role='region']")).toBeInTheDocument();
await user.click(button);
const item2 = wrapper.getByTestId("item-2");
const button2 = item2.querySelector("button") as HTMLElement;
await user.click(button2);
await waitFor(() => {
expect(item1.querySelector("[role='region']")).toBeInTheDocument();
expect(item2.querySelector("[role='region']")).toBeInTheDocument();
});
});
it("should support keepContentMounted={false} & disableAnimation={true}", async () => {
const wrapper = render(
<Accordion disableAnimation keepContentMounted={false}>
<AccordionItem key="1" data-testid="item-1" title="Accordion Item 1">
Accordion Item 1 description
</AccordionItem>
<AccordionItem key="2" data-testid="item-2" title="Accordion Item 2">
Accordion Item 2 description
</AccordionItem>
</Accordion>,
);
const item1 = wrapper.getByTestId("item-1");
const button = item1.querySelector("button") as HTMLElement;
expect(item1.querySelector("[role='region']")).not.toBeInTheDocument();
await user.click(button);
const item2 = wrapper.getByTestId("item-2");
const button2 = item2.querySelector("button") as HTMLElement;
await user.click(button2);
await waitFor(() => {
expect(item1.querySelector("[role='region']")).not.toBeInTheDocument();
expect(item2.querySelector("[role='region']")).toBeInTheDocument();
});
}); });
it("should handle arrow key navigation within Input inside AccordionItem", async () => { it("should handle arrow key navigation within Input inside AccordionItem", async () => {

View File

@ -54,7 +54,11 @@ const AccordionItem = forwardRef<"button", AccordionItemProps>((props, ref) => {
const content = useMemo(() => { const content = useMemo(() => {
if (disableAnimation) { if (disableAnimation) {
return <div {...getContentProps()}>{children}</div>; if (keepContentMounted) {
return <div {...getContentProps()}>{children}</div>;
}
return isOpen && <div {...getContentProps()}>{children}</div>;
} }
const transitionVariants: Variants = { const transitionVariants: Variants = {