mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
fix(popover): correct initial animation direction to match fallback placement (#4460)
* fix(popover): correct initial animation direction to match fallback placement * fix: type error * chore: add changeset
This commit is contained in:
parent
4f0ef5818b
commit
fb46df2430
5
.changeset/witty-goats-trade.md
Normal file
5
.changeset/witty-goats-trade.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@nextui-org/popover": patch
|
||||
---
|
||||
|
||||
Fix initial animation direction to match fallback placement (#4290)
|
||||
@ -14,7 +14,7 @@ import {
|
||||
PropGetter,
|
||||
useProviderContext,
|
||||
} from "@nextui-org/system";
|
||||
import {getArrowPlacement, getShouldUseAxisPlacement} from "@nextui-org/aria-utils";
|
||||
import {getArrowPlacement} from "@nextui-org/aria-utils";
|
||||
import {popover} from "@nextui-org/theme";
|
||||
import {mergeProps, mergeRefs} from "@react-aria/utils";
|
||||
import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
|
||||
@ -81,6 +81,8 @@ export interface Props extends HTMLNextUIProps<"div"> {
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const DEFAULT_PLACEMENT = "top";
|
||||
|
||||
export type UsePopoverProps = Props &
|
||||
Omit<ReactAriaPopoverProps, "triggerRef" | "popoverRef"> &
|
||||
OverlayTriggerProps &
|
||||
@ -110,7 +112,7 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
portalContainer,
|
||||
updatePositionDeps,
|
||||
dialogProps: dialogPropsProp,
|
||||
placement: placementProp = "top",
|
||||
placement: placementProp = DEFAULT_PLACEMENT,
|
||||
triggerType = "dialog",
|
||||
showArrow = false,
|
||||
offset = 7,
|
||||
@ -150,11 +152,7 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
|
||||
const state = stateProp || innerState;
|
||||
|
||||
const {
|
||||
popoverProps,
|
||||
underlayProps,
|
||||
placement: ariaPlacement,
|
||||
} = useReactAriaPopover(
|
||||
const {popoverProps, underlayProps, placement} = useReactAriaPopover(
|
||||
{
|
||||
triggerRef,
|
||||
isNonModal,
|
||||
@ -208,7 +206,7 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
"data-focus": dataAttr(isFocused),
|
||||
"data-arrow": dataAttr(showArrow),
|
||||
"data-focus-visible": dataAttr(isFocusVisible),
|
||||
"data-placement": getArrowPlacement(ariaPlacement || "top", placementProp),
|
||||
"data-placement": getArrowPlacement(placement || DEFAULT_PLACEMENT, placementProp),
|
||||
...mergeProps(focusProps, dialogPropsProp, props),
|
||||
className: slots.base({class: clsx(baseStyles)}),
|
||||
style: {
|
||||
@ -222,18 +220,10 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
"data-slot": "content",
|
||||
"data-open": dataAttr(state.isOpen),
|
||||
"data-arrow": dataAttr(showArrow),
|
||||
"data-placement": getArrowPlacement(ariaPlacement || "top", placementProp),
|
||||
"data-placement": getArrowPlacement(placement || DEFAULT_PLACEMENT, placementProp),
|
||||
className: slots.content({class: clsx(classNames?.content, props.className)}),
|
||||
}),
|
||||
[slots, state.isOpen, showArrow, ariaPlacement, placementProp, classNames],
|
||||
);
|
||||
|
||||
const placement = useMemo(
|
||||
() =>
|
||||
getShouldUseAxisPlacement(ariaPlacement || "top", placementProp)
|
||||
? ariaPlacement || placementProp
|
||||
: placementProp,
|
||||
[ariaPlacement, placementProp],
|
||||
[slots, state.isOpen, showArrow, placement, placementProp, classNames],
|
||||
);
|
||||
|
||||
const onPress = useCallback(
|
||||
@ -317,7 +307,7 @@ export function usePopover(originalProps: UsePopoverProps) {
|
||||
classNames,
|
||||
showArrow,
|
||||
triggerRef,
|
||||
placement,
|
||||
placement: placement || DEFAULT_PLACEMENT,
|
||||
isNonModal,
|
||||
popoverRef: domRef,
|
||||
portalContainer,
|
||||
|
||||
@ -127,11 +127,11 @@ const content = (
|
||||
</PopoverContent>
|
||||
);
|
||||
|
||||
const Template = (args: PopoverProps) => {
|
||||
const Template = ({label = "Open Popover", ...args}: PopoverProps & {label: string}) => {
|
||||
return (
|
||||
<Popover {...args}>
|
||||
<PopoverTrigger>
|
||||
<Button>Open Popover</Button>
|
||||
<Button>{label}</Button>
|
||||
</PopoverTrigger>
|
||||
{content}
|
||||
</Popover>
|
||||
@ -581,6 +581,32 @@ export const CustomMotion = {
|
||||
},
|
||||
};
|
||||
|
||||
export const WithFallbackPlacements = {
|
||||
args: {
|
||||
...defaultProps,
|
||||
},
|
||||
render: (args) => (
|
||||
<div className="relative h-screen w-screen">
|
||||
<div className="absolute top-0 left-0 p-8 flex gap-4">
|
||||
<Template {...args} label="placement: top" placement="top" />
|
||||
<Template {...args} label="placement: bottom" placement="bottom" />
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 p-8 flex gap-4">
|
||||
<Template {...args} label="placement: bottom" placement="bottom" />
|
||||
<Template {...args} label="placement: top" placement="top" />
|
||||
</div>
|
||||
<div className="absolute left-0 top-1/2 -translate-y-1/2 p-8 flex flex-col gap-4">
|
||||
<Template {...args} label="placement: left" placement="left" />
|
||||
<Template {...args} label="placement: right" placement="right" />
|
||||
</div>
|
||||
<div className="absolute right-0 top-1/2 -translate-y-1/2 p-8 flex flex-col gap-4">
|
||||
<Template {...args} label="placement: right" placement="right" />
|
||||
<Template {...args} label="placement: left" placement="left" />
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const WithShouldBlockScroll = {
|
||||
render: (args) => {
|
||||
return (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user