UNPKG

@loke/ui

Version:
2 lines (1 loc) 8.45 kB
import{composeEventHandlers}from"@loke/ui/compose-events";import{useComposedRefs}from"@loke/ui/compose-refs";import{createContextScope}from"@loke/ui/context";import{DismissableLayer}from"@loke/ui/dismissable-layer";import{useFocusGuards}from"@loke/ui/focus-guards";import{FocusScope}from"@loke/ui/focus-scope";import*as PopperPrimitive from"@loke/ui/popper";import{createPopperScope}from"@loke/ui/popper";import{Portal as PortalPrimitive}from"@loke/ui/portal";import{Presence}from"@loke/ui/presence";import{Primitive}from"@loke/ui/primitive";import{createSlot}from"@loke/ui/slot";import{useControllableState}from"@loke/ui/use-controllable-state";import{useId}from"@loke/ui/use-id";import{hideOthers}from"aria-hidden";import{forwardRef,useCallback,useEffect,useRef,useState}from"react";import{RemoveScroll}from"react-remove-scroll";import{jsx}from"react/jsx-runtime";var POPOVER_NAME="Popover",[createPopoverContext,createPopoverScope]=createContextScope(POPOVER_NAME,[createPopperScope]),usePopperScope=createPopperScope(),[PopoverProvider,usePopoverContext]=createPopoverContext(POPOVER_NAME),Popover=(props)=>{let{__scopePopover,children,open:openProp,defaultOpen,onOpenChange,modal=!1}=props,popperScope=usePopperScope(__scopePopover),triggerRef=useRef(null),[hasCustomAnchor,setHasCustomAnchor]=useState(!1),[open,setOpen]=useControllableState({caller:POPOVER_NAME,defaultProp:defaultOpen??!1,onChange:onOpenChange,prop:openProp});return jsx(PopperPrimitive.Root,{...popperScope,children:jsx(PopoverProvider,{contentId:useId(),hasCustomAnchor,modal,onCustomAnchorAdd:useCallback(()=>setHasCustomAnchor(!0),[]),onCustomAnchorRemove:useCallback(()=>setHasCustomAnchor(!1),[]),onOpenChange:setOpen,onOpenToggle:useCallback(()=>setOpen((prevOpen)=>!prevOpen),[setOpen]),open,scope:__scopePopover,triggerRef,children})})};Popover.displayName=POPOVER_NAME;var ANCHOR_NAME="PopoverAnchor",PopoverAnchor=forwardRef((props,forwardedRef)=>{let{__scopePopover,...anchorProps}=props,context=usePopoverContext(ANCHOR_NAME,__scopePopover),popperScope=usePopperScope(__scopePopover),{onCustomAnchorAdd,onCustomAnchorRemove}=context;return useEffect(()=>{return onCustomAnchorAdd(),()=>onCustomAnchorRemove()},[onCustomAnchorAdd,onCustomAnchorRemove]),jsx(PopperPrimitive.Anchor,{...popperScope,...anchorProps,ref:forwardedRef})});PopoverAnchor.displayName=ANCHOR_NAME;var TRIGGER_NAME="PopoverTrigger",PopoverTrigger=forwardRef((props,forwardedRef)=>{let{__scopePopover,...triggerProps}=props,context=usePopoverContext(TRIGGER_NAME,__scopePopover),popperScope=usePopperScope(__scopePopover),composedTriggerRef=useComposedRefs(forwardedRef,context.triggerRef),trigger=jsx(Primitive.button,{"aria-controls":context.contentId,"aria-expanded":context.open,"aria-haspopup":"dialog","data-state":getState(context.open),type:"button",...triggerProps,onClick:composeEventHandlers(props.onClick,context.onOpenToggle),ref:composedTriggerRef});return context.hasCustomAnchor?trigger:jsx(PopperPrimitive.Anchor,{asChild:!0,...popperScope,children:trigger})});PopoverTrigger.displayName=TRIGGER_NAME;var PORTAL_NAME="PopoverPortal",[PortalProvider,usePortalContext]=createPopoverContext(PORTAL_NAME,{forceMount:void 0}),PopoverPortal=(props)=>{let{__scopePopover,forceMount,children,container}=props,context=usePopoverContext(PORTAL_NAME,__scopePopover);return jsx(PortalProvider,{forceMount,scope:__scopePopover,children:jsx(Presence,{present:forceMount||context.open,children:jsx(PortalPrimitive,{asChild:!0,container,children})})})};PopoverPortal.displayName=PORTAL_NAME;var CONTENT_NAME="PopoverContent",PopoverContent=forwardRef((props,forwardedRef)=>{let portalContext=usePortalContext(CONTENT_NAME,props.__scopePopover),{forceMount=portalContext.forceMount,...contentProps}=props,context=usePopoverContext(CONTENT_NAME,props.__scopePopover);return jsx(Presence,{present:forceMount||context.open,children:context.modal?jsx(PopoverContentModal,{...contentProps,ref:forwardedRef}):jsx(PopoverContentNonModal,{...contentProps,ref:forwardedRef})})});PopoverContent.displayName=CONTENT_NAME;var Slot=createSlot("PopoverContent.RemoveScroll"),PopoverContentModal=forwardRef((props,forwardedRef)=>{let context=usePopoverContext(CONTENT_NAME,props.__scopePopover),contentRef=useRef(null),composedRefs=useComposedRefs(forwardedRef,contentRef),isRightClickOutsideRef=useRef(!1);return useEffect(()=>{let content=contentRef.current;if(content)return hideOthers(content)},[]),jsx(RemoveScroll,{allowPinchZoom:!0,as:Slot,children:jsx(PopoverContentImpl,{...props,disableOutsidePointerEvents:!0,onCloseAutoFocus:composeEventHandlers(props.onCloseAutoFocus,(event)=>{if(event.preventDefault(),!isRightClickOutsideRef.current)context.triggerRef.current?.focus()}),onFocusOutside:composeEventHandlers(props.onFocusOutside,(event)=>event.preventDefault(),{checkForDefaultPrevented:!1}),onPointerDownOutside:composeEventHandlers(props.onPointerDownOutside,(event)=>{let originalEvent=event.detail.originalEvent,ctrlLeftClick=originalEvent.button===0&&originalEvent.ctrlKey===!0,isRightClick=originalEvent.button===2||ctrlLeftClick;isRightClickOutsideRef.current=isRightClick},{checkForDefaultPrevented:!1}),ref:composedRefs,trapFocus:context.open})})}),PopoverContentNonModal=forwardRef((props,forwardedRef)=>{let context=usePopoverContext(CONTENT_NAME,props.__scopePopover),hasInteractedOutsideRef=useRef(!1),hasPointerDownOutsideRef=useRef(!1);return jsx(PopoverContentImpl,{...props,disableOutsidePointerEvents:!1,onCloseAutoFocus:(event)=>{if(props.onCloseAutoFocus?.(event),!event.defaultPrevented){if(!hasInteractedOutsideRef.current)context.triggerRef.current?.focus();event.preventDefault()}hasInteractedOutsideRef.current=!1,hasPointerDownOutsideRef.current=!1},onInteractOutside:(event)=>{if(props.onInteractOutside?.(event),!event.defaultPrevented){if(hasInteractedOutsideRef.current=!0,event.detail.originalEvent.type==="pointerdown")hasPointerDownOutsideRef.current=!0}let target=event.target;if(context.triggerRef.current?.contains(target))event.preventDefault();if(event.detail.originalEvent.type==="focusin"&&hasPointerDownOutsideRef.current)event.preventDefault()},ref:forwardedRef,trapFocus:!1})}),PopoverContentImpl=forwardRef((props,forwardedRef)=>{let{__scopePopover,trapFocus,onOpenAutoFocus,onCloseAutoFocus,disableOutsidePointerEvents,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,...contentProps}=props,context=usePopoverContext(CONTENT_NAME,__scopePopover),popperScope=usePopperScope(__scopePopover);return useFocusGuards(),jsx(FocusScope,{asChild:!0,loop:!0,onMountAutoFocus:onOpenAutoFocus,onUnmountAutoFocus:onCloseAutoFocus,trapped:trapFocus,children:jsx(DismissableLayer,{asChild:!0,disableOutsidePointerEvents,onDismiss:()=>context.onOpenChange(!1),onEscapeKeyDown,onFocusOutside,onInteractOutside,onPointerDownOutside,children:jsx(PopperPrimitive.Content,{"data-state":getState(context.open),id:context.contentId,role:"dialog",...popperScope,...contentProps,ref:forwardedRef,style:{...contentProps.style,...{"--loke-popover-content-available-height":"var(--loke-popper-available-height)","--loke-popover-content-available-width":"var(--loke-popper-available-width)","--loke-popover-content-transform-origin":"var(--loke-popper-transform-origin)","--loke-popover-trigger-height":"var(--loke-popper-anchor-height)","--loke-popover-trigger-width":"var(--loke-popper-anchor-width)"}}})})})}),CLOSE_NAME="PopoverClose",PopoverClose=forwardRef((props,forwardedRef)=>{let{__scopePopover,...closeProps}=props,context=usePopoverContext(CLOSE_NAME,__scopePopover);return jsx(Primitive.button,{type:"button",...closeProps,onClick:composeEventHandlers(props.onClick,()=>context.onOpenChange(!1)),ref:forwardedRef})});PopoverClose.displayName=CLOSE_NAME;var ARROW_NAME="PopoverArrow",PopoverArrow=forwardRef((props,forwardedRef)=>{let{__scopePopover,...arrowProps}=props,popperScope=usePopperScope(__scopePopover);return jsx(PopperPrimitive.Arrow,{...popperScope,...arrowProps,ref:forwardedRef})});PopoverArrow.displayName=ARROW_NAME;function getState(open){return open?"open":"closed"}var Root2=Popover,Anchor2=PopoverAnchor,Trigger=PopoverTrigger,Portal=PopoverPortal,Content2=PopoverContent,Close=PopoverClose,Arrow2=PopoverArrow;export{createPopoverScope,Trigger,Root2 as Root,Portal,PopoverTrigger,PopoverPortal,PopoverContent,PopoverClose,PopoverArrow,PopoverAnchor,Popover,Content2 as Content,Close,Arrow2 as Arrow,Anchor2 as Anchor};