Skip to content

Commit

Permalink
feat(popover): added control for closing popover on scroll (#3595)
Browse files Browse the repository at this point in the history
* fix(navbar): fixed the height when style h-full

* fix(navbar): fixed the height when style h-full

* docs(changeset): resolved extra file

* feat(popover): added control for closing popover on scroll

* update(changeset):  correction

* feat(popover): removed extra story

* refactor(test): corrected test for both true and false values of shouldCloseOnScroll

* refactor(docs): added shouldCloseOnScroll prop

* chore(changeset): change to minor

---------

Co-authored-by: աӄա <wingkwong.code@gmail.com>
  • Loading branch information
2 people authored and ryo-manba committed Nov 6, 2024
1 parent 3d8466c commit 01c1916
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
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 @@ -334,3 +334,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

0 comments on commit 01c1916

Please sign in to comment.