Skip to content

Commit

Permalink
fix(popover): close popover on scroll (#3414)
Browse files Browse the repository at this point in the history
* fix(popover): close popover on scroll

* feat(popover): add "should close popover on scroll" test

* feat(changeset): add changeset

* feat(select): add ScrollableContainerTemplate
  • Loading branch information
wingkwong authored Jul 6, 2024
1 parent a164c26 commit 444d320
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/sweet-flowers-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nextui-org/popover": patch
---

close popover on scroll (#3265)
33 changes: 33 additions & 0 deletions packages/components/popover/__tests__/popover.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,37 @@ describe("Popover", () => {
// assert that the popover is still open
expect(popover).toHaveAttribute("aria-expanded", "true");
});

it("should close popover on scroll", async () => {
const wrapper = render(
<Popover>
<PopoverTrigger>
<Button data-testid="popover">Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<Select data-testid="select" label="Select country">
<SelectItem key="argentina">Argentina</SelectItem>
<SelectItem key="venezuela">Venezuela</SelectItem>
<SelectItem key="brazil">Brazil</SelectItem>
</Select>
</PopoverContent>
</Popover>,
);

const popover = wrapper.getByTestId("popover");

// open popover
await act(async () => {
await userEvent.click(popover);
});

// assert that the popover is open
expect(popover).toHaveAttribute("aria-expanded", "true");

// scroll it
fireEvent.scroll(document.body);

// assert that the popover is closed
expect(popover).toHaveAttribute("aria-expanded", "false");
});
});
2 changes: 1 addition & 1 deletion packages/components/popover/src/use-aria-popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function useReactAriaPopover(
containerPadding,
placement: toReactAriaPlacement(placementProp),
offset: showArrow ? offset + 3 : offset,
onClose: () => {},
onClose: isNonModal ? state.close : () => {},
});

useSafeLayoutEffect(() => {
Expand Down
73 changes: 73 additions & 0 deletions packages/components/select/stories/select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,71 @@ const WithReactHookFormTemplate = (args: SelectProps) => {
);
};

const ScrollableContainerTemplate = (args: SelectProps) => {
const categories = [
{
target: "Animals",
items: [
{name: "Lion", emoji: "🦁"},
{name: "Tiger", emoji: "🐅"},
{name: "Elephant", emoji: "🐘"},
{name: "Kangaroo", emoji: "🦘"},
{name: "Panda", emoji: "🐼"},
{name: "Giraffe", emoji: "🦒"},
{name: "Zebra", emoji: "🦓"},
{name: "Cheetah", emoji: "🐆"},
],
},
{
target: "Birds",
items: [
{name: "Eagle", emoji: "🦅"},
{name: "Parrot", emoji: "🦜"},
{name: "Penguin", emoji: "🐧"},
{name: "Ostrich", emoji: "🦢"},
{name: "Peacock", emoji: "🦚"},
{name: "Swan", emoji: "🦢"},
{name: "Falcon", emoji: "🦅"},
{name: "Flamingo", emoji: "🦩"},
],
},
];
const DEFAULT_CATEGORY = "Animals";

return (
<>
<form className="h-full overflow-auto">
<div className="flex justify-between h-[1500px]">
<div className="flex items-center gap-2">
<div className="flex w-full flex-wrap gap-4 md:flex-nowrap">
<Select
aria-label="Favourite Animals"
className="w-52"
defaultSelectedKeys={[DEFAULT_CATEGORY]}
label="Category"
name="Category"
{...args}
>
{categories.map((category, idx, arr) => (
<SelectSection
key={category.target}
showDivider={idx !== arr.length - 1}
title={category.target}
>
{category.items.map((item) => (
<SelectItem key={item.name}>{`${item.emoji} ${item.name}`}</SelectItem>
))}
</SelectSection>
))}
</Select>
</div>
</div>
</div>
</form>
</>
);
};

export const Default = {
render: MirrorTemplate,

Expand Down Expand Up @@ -839,6 +904,14 @@ export const WithReactHookForm = {
},
};

export const WithScrollableContainer = {
render: ScrollableContainerTemplate,

args: {
...defaultProps,
},
};

export const Controlled = {
render: ControlledTemplate,

Expand Down

0 comments on commit 444d320

Please sign in to comment.