From 7aa0618ae30ba3de17bcace826d5a77ec5f2208a Mon Sep 17 00:00:00 2001 From: p-sw <shinwoo.park@psw.kr> Date: Sun, 30 Jun 2024 22:48:52 +0900 Subject: [PATCH] feat(Popover): add controlled in PopoverContext to disable outside click on controlled --- packages/react/components/Popover.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/react/components/Popover.tsx b/packages/react/components/Popover.tsx index 15a7531..518b0f3 100644 --- a/packages/react/components/Popover.tsx +++ b/packages/react/components/Popover.tsx @@ -2,6 +2,7 @@ import { type AsChild, Slot, type VariantProps, vcn } from "@pswui-lib"; import React, { useContext, useEffect, useRef } from "react"; interface IPopoverContext { + controlled: boolean; opened: boolean; } @@ -10,6 +11,7 @@ const PopoverContext = React.createContext< >([ { opened: false, + controlled: false, }, () => { if (process.env.NODE_ENV && process.env.NODE_ENV === "development") { @@ -28,12 +30,15 @@ interface PopoverProps extends AsChild { const Popover = ({ children, opened, asChild }: PopoverProps) => { const [state, setState] = React.useState<IPopoverContext>({ opened: opened ?? false, + controlled: opened !== undefined, }); useEffect(() => { - if (opened !== undefined) { - setState((p) => ({ ...p, opened: opened })); - } + setState((p) => ({ + ...p, + controlled: opened !== undefined, + opened: opened !== undefined ? opened : p.opened, + })); }, [opened]); const Comp = asChild ? Slot : "div"; @@ -209,11 +214,12 @@ const PopoverContent = React.forwardRef<HTMLDivElement, PopoverContentProps>( setState((prev) => ({ ...prev, opened: false })); } } - document.addEventListener("mousedown", handleOutsideClick); + !state.controlled && + document.addEventListener("mousedown", handleOutsideClick); return () => { document.removeEventListener("mousedown", handleOutsideClick); }; - }, [setState]); + }, [state.controlled, setState]); return ( <div