Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/slow-paws-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nextui-org/popover": minor
---

added `shouldCloseOnScroll` to control the popover closing on scroll (#3594)
3 changes: 2 additions & 1 deletion apps/docs/content/docs/components/popover.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ You can customize the `Popover` component by passing custom Tailwind CSS classes
| showArrow | `boolean` | Whether the popover should have an arrow. | `false` |
| shouldFlip | `boolean` | Whether the popover should change its placement and flip when it's about to overflow its boundary area. | `true` |
| triggerScaleOnOpen | `boolean` | Whether the trigger should scale down when the popover is open. | `true` |
| shouldBlockScroll | `boolean` | Whether to block scrolling outside the popover. | `false` |
| shouldBlockScroll | `boolean` | Whether the popover should block the scroll outside the popover. | `true` |
| shouldCloseOnScroll | `boolean` | Wheather the popover should close on scroll | `false` |
| isKeyboardDismissDisabled | `boolean` | Whether pressing the escape key to close the popover should be disabled. | `false` |
| shouldCloseOnBlur | `boolean` | Whether the popover should close when focus is lost or moves outside it. | `false` |
| motionProps | [MotionProps](#motion-props) | The props to modify the framer motion animation. Use the `variants` API to create your own animation. | |
Expand Down
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 @@ -348,3 +348,36 @@ describe("Popover", () => {
expect(popover).toHaveAttribute("aria-expanded", "false");
});
});

it("should close popover on scroll when shouldCloseOnScroll is false", async () => {
const wrapper = render(
<Popover shouldCloseOnScroll={false}>
<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 still open
expect(popover).toHaveAttribute("aria-expanded", "true");
});
8 changes: 7 additions & 1 deletion packages/components/popover/src/use-aria-popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export interface Props {
* @default []
*/
updatePositionDeps?: any[];
/**
* Whether the popover should close on scroll.
* @default true
*/
shouldCloseOnScroll?: boolean;
}

export type ReactAriaPopoverProps = Props & Omit<AriaPopoverProps, "placement"> & AriaOverlayProps;
Expand All @@ -60,6 +65,7 @@ export function useReactAriaPopover(
boundaryElement,
isDismissable = true,
shouldCloseOnBlur = true,
shouldCloseOnScroll = true,
placement: placementProp = "top",
containerPadding,
shouldCloseOnInteractOutside,
Expand Down Expand Up @@ -102,7 +108,7 @@ export function useReactAriaPopover(
containerPadding,
placement: toReactAriaPlacement(placementProp),
offset: showArrow ? offset + 3 : offset,
onClose: isNonModal ? state.close : () => {},
onClose: isNonModal && shouldCloseOnScroll ? state.close : () => {},
});

useSafeLayoutEffect(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/components/popover/src/use-popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export function usePopover(originalProps: UsePopoverProps) {
boundaryElement,
isKeyboardDismissDisabled,
shouldCloseOnInteractOutside,
shouldCloseOnScroll,
motionProps,
className,
classNames,
Expand Down Expand Up @@ -169,6 +170,7 @@ export function usePopover(originalProps: UsePopoverProps) {
containerPadding,
updatePositionDeps,
isKeyboardDismissDisabled,
shouldCloseOnScroll,
shouldCloseOnInteractOutside,
},
state,
Expand Down
5 changes: 5 additions & 0 deletions packages/components/popover/stories/popover.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ export default {
type: "boolean",
},
},
shouldCloseOnScroll: {
control: {
type: "boolean",
},
},
disableAnimation: {
control: {
type: "boolean",
Expand Down