fix(popover): arrow glitch in popover content (#5504)

* fix(popover): make PopoverContent children prop optional to fix TS error

* chore(changeset): created changeset

* fix(popover): do not show content when children is null / undefined

* fix(popover): add test case

* chore(changeset): update changeset message

---------

Co-authored-by: i_nicck <i_nicck@i-niccks-MacBook-Air.local>
Co-authored-by: WK Wong <wingkwong.code@gmail.com>
This commit is contained in:
Shagun Sharma 2025-07-28 22:22:45 +05:30 committed by GitHub
parent 8dc4bab4ec
commit 5eb686843b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 7 deletions

View File

@ -0,0 +1,5 @@
---
"@heroui/popover": patch
---
fix(popover): arrow glitch in popover content (#4142)

View File

@ -369,3 +369,40 @@ it("should close popover on scroll when shouldCloseOnScroll is false", async ()
// assert that the popover is still open
expect(popover).toHaveAttribute("aria-expanded", "true");
});
it("should display popover content only after content is ready", async () => {
jest.useFakeTimers();
const TestComponent = () => {
const [content, setContent] = React.useState("");
React.useEffect(() => {
const timer = setTimeout(() => {
setContent("test content");
}, 1000);
return () => clearTimeout(timer);
}, []);
return (
<Popover defaultOpen>
<PopoverTrigger>
<Button data-testid="trigger">Open popover</Button>
</PopoverTrigger>
<PopoverContent data-testid="content-test">{content}</PopoverContent>
</Popover>
);
};
const wrapper = render(<TestComponent />);
expect(wrapper.queryByTestId("content-test")).not.toBeInTheDocument();
act(() => {
jest.advanceTimersByTime(1000);
});
expect(wrapper.getByTestId("content-test")).toBeInTheDocument();
jest.useRealTimers();
});

View File

@ -15,7 +15,7 @@ import {usePopoverContext} from "./popover-context";
export interface PopoverContentProps
extends AriaDialogProps,
Omit<HTMLHeroUIProps, "children" | "role"> {
children: ReactNode | ((titleProps: DOMAttributes<HTMLElement>) => ReactNode);
children?: ReactNode | ((titleProps: DOMAttributes<HTMLElement>) => ReactNode);
}
const domAnimation = () => import("@heroui/dom-animation").then((res) => res.default);
@ -47,14 +47,16 @@ const PopoverContent = (props: PopoverContentProps) => {
const Component = as || OverlayComponent || "div";
const content = (
const content = children && (
<>
{!isNonModal && <DismissButton onDismiss={onClose} />}
<Component {...dialogProps}>
<div {...getContentProps({className})}>
{typeof children === "function" ? children(titleProps) : children}
</div>
</Component>
{
<Component {...dialogProps}>
<div {...getContentProps({className})}>
{typeof children === "function" ? children(titleProps) : children}
</div>
</Component>
}
<DismissButton onDismiss={onClose} />
</>
);