diff --git a/apps/web/src/components/ui/closing-positioner.tsx b/apps/web/src/components/ui/closing-positioner.tsx new file mode 100644 index 0000000000000..2adb81bec36b7 --- /dev/null +++ b/apps/web/src/components/ui/closing-positioner.tsx @@ -0,0 +1,18 @@ +import { useState, type ComponentProps, type CSSProperties } from "react"; + +const PLACEMENT_KEYS = ["position", "top", "right", "bottom", "left", "transform"] as const; + +type Placement = Pick; + +function ClosingPositioner({ open, style, ...props }: ComponentProps<"div"> & { open: boolean }) { + const [openPlacement, setOpenPlacement] = useState({}); + if (open && style && PLACEMENT_KEYS.some((key) => style[key] !== openPlacement[key])) { + const { position, top, right, bottom, left, transform } = style; + setOpenPlacement({ position, top, right, bottom, left, transform }); + } + return
; +} + +export function renderClosingPositioner(props: ComponentProps<"div">, state: { open: boolean }) { + return ; +} diff --git a/apps/web/src/components/ui/menu.tsx b/apps/web/src/components/ui/menu.tsx index 95c459b8f8e8f..47ae92c241e15 100644 --- a/apps/web/src/components/ui/menu.tsx +++ b/apps/web/src/components/ui/menu.tsx @@ -4,6 +4,7 @@ import type * as React from "react"; import { cn } from "~/lib/utils"; import { buttonVariants } from "./button"; +import { renderClosingPositioner } from "./closing-positioner"; import { Input, type InputProps } from "./input"; import { Spinner } from "./spinner"; @@ -45,6 +46,7 @@ function MenuPopup({ anchor={anchor} className="z-[130]" data-slot="menu-positioner" + render={renderClosingPositioner} side={side} sideOffset={sideOffset} > diff --git a/apps/web/src/components/ui/popover.tsx b/apps/web/src/components/ui/popover.tsx index 18b84000d8f7a..2261b1a8f54c3 100644 --- a/apps/web/src/components/ui/popover.tsx +++ b/apps/web/src/components/ui/popover.tsx @@ -2,6 +2,8 @@ import { Popover as PopoverPrimitive } from "@base-ui/react/popover"; import { cn } from "~/lib/utils"; +import { renderClosingPositioner } from "./closing-positioner"; + const PopoverCreateHandle = PopoverPrimitive.createHandle; const Popover = PopoverPrimitive.Root; @@ -82,6 +84,7 @@ function PopoverPopup({ : "z-[130]", )} data-slot="popover-positioner" + render={renderClosingPositioner} side={side} sideOffset={sideOffset} >