feat: add updatePositionDeps prop to popover component (#2390)

This commit is contained in:
u3u 2024-03-04 04:44:30 +08:00 committed by GitHub
parent 9b27da544e
commit a235e324b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 28 additions and 2 deletions

View File

@ -0,0 +1,5 @@
---
"@nextui-org/popover": minor
---
Add `updatePositionDeps` prop to popover component

View File

@ -159,6 +159,7 @@ You can customize the `Popover` component by passing custom Tailwind CSS classes
| 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. | |
| portalContainer | `HTMLElement` | The container element in which the overlay portal will be placed. | `document.body` |
| updatePositionDeps | `any[]` | The dependencies to force the popover position update. | `[]` |
| triggerRef | `RefObject<HTMLElement>` | The ref for the element which the popover positions itself with respect to. | - |
| scrollRef | `RefObject<HTMLElement>` | A ref for the scrollable region within the popover. | `overlayRef` |
| disableAnimation | `boolean` | Whether the popover is animated. | `false` |
@ -178,8 +179,8 @@ You can customize the `Popover` component by passing custom Tailwind CSS classes
### PopoverTrigger Props
| Attribute | Type | Description | Default |
| ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Attribute | Type | Description | Default |
| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| children\* | `ReactNode` | The popover trigger component, ensure the children passed is focusable. Users can tab to it using their keyboard, and it can take a ref. It is critical for accessibility. | - |
<Spacer y={2} />

View File

@ -47,6 +47,7 @@
"@nextui-org/button": "workspace:*",
"@nextui-org/shared-utils": "workspace:*",
"@nextui-org/react-utils": "workspace:*",
"@nextui-org/use-safe-layout-effect": "workspace:*",
"@react-aria/dialog": "^3.5.7",
"@react-aria/interactions": "^3.19.1",
"@react-aria/overlays": "^3.18.1",

View File

@ -9,6 +9,7 @@ import {
import {OverlayPlacement, ariaHideOutside, toReactAriaPlacement} from "@nextui-org/aria-utils";
import {OverlayTriggerState} from "@react-stately/overlays";
import {mergeProps} from "@react-aria/utils";
import {useSafeLayoutEffect} from "@nextui-org/use-safe-layout-effect";
export interface Props {
/**
@ -26,6 +27,11 @@ export interface Props {
* @default popoverRef
*/
scrollRef?: RefObject<HTMLElement>;
/**
* List of dependencies to update the position of the popover.
* @default []
*/
updatePositionDeps?: any[];
}
export type ReactAriaPopoverProps = Props & Omit<AriaPopoverProps, "placement"> & AriaOverlayProps;
@ -54,6 +60,7 @@ export function useReactAriaPopover(
shouldCloseOnInteractOutside,
isNonModal: isNonModalProp,
isKeyboardDismissDisabled,
updatePositionDeps = [],
...otherProps
} = props;
@ -82,6 +89,7 @@ export function useReactAriaPopover(
overlayProps: positionProps,
arrowProps,
placement,
updatePosition,
} = useOverlayPosition({
...otherProps,
shouldFlip,
@ -97,6 +105,12 @@ export function useReactAriaPopover(
onClose: () => {},
});
useSafeLayoutEffect(() => {
if (!updatePositionDeps.length) return;
// force update position when deps change
updatePosition();
}, updatePositionDeps);
useEffect(() => {
if (state.isOpen && !isNonModal && popoverRef.current) {
return ariaHideOutside([popoverRef.current]);

View File

@ -94,6 +94,7 @@ export function usePopover(originalProps: UsePopoverProps) {
isDismissable = true,
shouldCloseOnBlur,
portalContainer,
updatePositionDeps,
placement: placementProp = "top",
triggerType = "dialog",
showArrow = false,
@ -151,6 +152,7 @@ export function usePopover(originalProps: UsePopoverProps) {
crossOffset,
shouldFlip,
containerPadding,
updatePositionDeps,
isKeyboardDismissDisabled,
shouldCloseOnInteractOutside,
},

3
pnpm-lock.yaml generated
View File

@ -1777,6 +1777,9 @@ importers:
'@nextui-org/use-aria-button':
specifier: workspace:*
version: link:../../hooks/use-aria-button
'@nextui-org/use-safe-layout-effect':
specifier: workspace:*
version: link:../../hooks/use-safe-layout-effect
'@react-aria/dialog':
specifier: ^3.5.7
version: 3.5.7(react-dom@18.2.0)(react@18.2.0)