UNPKG

@loke/ui

Version:
2 lines (1 loc) 7.38 kB
import{autoUpdate,flip,arrow as floatingUIarrow,hide,limitShift,offset,shift,size,useFloating}from"@floating-ui/react-dom";import{Arrow as ArrowPrimitive}from"@loke/ui/arrow";import{useComposedRefs}from"@loke/ui/compose-refs";import{createContextScope}from"@loke/ui/context";import{Primitive}from"@loke/ui/primitive";import{useCallbackRef}from"@loke/ui/use-callback-ref";import{useLayoutEffect}from"@loke/ui/use-layout-effect";import{useSize}from"@loke/ui/use-size";import{forwardRef,useEffect,useRef,useState}from"react";import{jsx}from"react/jsx-runtime";var SIDE_OPTIONS=["top","right","bottom","left"],ALIGN_OPTIONS=["start","center","end"],POPPER_NAME="Popper",[createPopperContext,createPopperScope]=createContextScope(POPPER_NAME),[PopperProvider,usePopperContext]=createPopperContext(POPPER_NAME),Popper=(props)=>{let{__scopePopper,children}=props,[anchor,setAnchor]=useState(null);return jsx(PopperProvider,{anchor,onAnchorChange:setAnchor,scope:__scopePopper,children})};Popper.displayName=POPPER_NAME;var ANCHOR_NAME="PopperAnchor",PopperAnchor=forwardRef((props,forwardedRef)=>{let{__scopePopper,virtualRef,...anchorProps}=props,context=usePopperContext(ANCHOR_NAME,__scopePopper),ref=useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),anchorRef=useRef(null);return useEffect(()=>{let previousAnchor=anchorRef.current;if(anchorRef.current=virtualRef?.current||ref.current,previousAnchor!==anchorRef.current)context.onAnchorChange(anchorRef.current)}),virtualRef?null:jsx(Primitive.div,{...anchorProps,ref:composedRefs})});PopperAnchor.displayName=ANCHOR_NAME;var CONTENT_NAME="PopperContent",[PopperContentProvider,useContentContext]=createPopperContext(CONTENT_NAME),PopperContent=forwardRef((props,forwardedRef)=>{let{__scopePopper,side="bottom",sideOffset=0,align="center",alignOffset=0,arrowPadding=0,avoidCollisions=!0,collisionBoundary=[],collisionPadding:collisionPaddingProp=0,sticky="partial",hideWhenDetached=!1,updatePositionStrategy="optimized",onPlaced,...contentProps}=props,context=usePopperContext(CONTENT_NAME,__scopePopper),[content,setContent]=useState(null),composedRefs=useComposedRefs(forwardedRef,(node)=>setContent(node)),[arrow,setArrow]=useState(null),arrowSize=useSize(arrow),arrowWidth=arrowSize?.width??0,arrowHeight=arrowSize?.height??0,desiredPlacement=side+(align!=="center"?`-${align}`:""),collisionPadding=typeof collisionPaddingProp==="number"?collisionPaddingProp:{bottom:0,left:0,right:0,top:0,...collisionPaddingProp},boundary=Array.isArray(collisionBoundary)?collisionBoundary:[collisionBoundary],detectOverflowOptions={altBoundary:boundary.length>0,boundary:boundary.filter(isNotNull),padding:collisionPadding},{refs,floatingStyles,placement,isPositioned,middlewareData}=useFloating({elements:{reference:context.anchor},middleware:[offset({alignmentAxis:alignOffset,mainAxis:sideOffset+arrowHeight}),avoidCollisions&&shift({crossAxis:!1,limiter:sticky==="partial"?limitShift():void 0,mainAxis:!0,...detectOverflowOptions}),avoidCollisions&&flip({...detectOverflowOptions}),size({...detectOverflowOptions,apply:({elements,rects,availableWidth,availableHeight})=>{let{width:anchorWidth,height:anchorHeight}=rects.reference,contentStyle=elements.floating.style;contentStyle.setProperty("--loke-popper-available-width",`${availableWidth}px`),contentStyle.setProperty("--loke-popper-available-height",`${availableHeight}px`),contentStyle.setProperty("--loke-popper-anchor-width",`${anchorWidth}px`),contentStyle.setProperty("--loke-popper-anchor-height",`${anchorHeight}px`)}}),arrow&&floatingUIarrow({element:arrow,padding:arrowPadding}),transformOrigin({arrowHeight,arrowWidth}),hideWhenDetached&&hide({strategy:"referenceHidden",...detectOverflowOptions})],placement:desiredPlacement,strategy:"fixed",whileElementsMounted:(...args)=>{return autoUpdate(...args,{animationFrame:updatePositionStrategy==="always"})}}),[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),handlePlaced=useCallbackRef(onPlaced);useLayoutEffect(()=>{if(isPositioned)handlePlaced?.()},[isPositioned,handlePlaced]);let arrowX=middlewareData.arrow?.x,arrowY=middlewareData.arrow?.y,cannotCenterArrow=middlewareData.arrow?.centerOffset!==0,[contentZIndex,setContentZIndex]=useState();return useLayoutEffect(()=>{if(content)setContentZIndex(window.getComputedStyle(content).zIndex)},[content]),jsx("div",{"data-loke-popper-content-wrapper":"",dir:props.dir,ref:refs.setFloating,style:{...floatingStyles,"--loke-popper-transform-origin":[middlewareData.transformOrigin?.x,middlewareData.transformOrigin?.y].join(" "),minWidth:"max-content",transform:isPositioned?floatingStyles.transform:"translate(0, -200%)",zIndex:contentZIndex,...middlewareData.hide?.referenceHidden&&{pointerEvents:"none",visibility:"hidden"}},children:jsx(PopperContentProvider,{arrowX,arrowY,onArrowChange:setArrow,placedSide,scope:__scopePopper,shouldHideArrow:cannotCenterArrow,children:jsx(Primitive.div,{"data-align":placedAlign,"data-side":placedSide,...contentProps,ref:composedRefs,style:{...contentProps.style,animation:isPositioned?void 0:"none"}})})})});PopperContent.displayName=CONTENT_NAME;var ARROW_NAME="PopperArrow",OPPOSITE_SIDE={bottom:"top",left:"right",right:"left",top:"bottom"},PopperArrow=forwardRef((props,forwardedRef)=>{let{__scopePopper,...arrowProps}=props,contentContext=useContentContext(ARROW_NAME,__scopePopper),baseSide=OPPOSITE_SIDE[contentContext.placedSide];return jsx("span",{ref:contentContext.onArrowChange,style:{left:contentContext.arrowX,position:"absolute",top:contentContext.arrowY,[baseSide]:0,transform:{bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",top:"translateY(100%)"}[contentContext.placedSide],transformOrigin:{bottom:"center 0",left:"100% 0",right:"0 0",top:""}[contentContext.placedSide],visibility:contentContext.shouldHideArrow?"hidden":void 0},children:jsx(ArrowPrimitive,{...arrowProps,ref:forwardedRef,style:{...arrowProps.style,display:"block"}})})});PopperArrow.displayName=ARROW_NAME;function isNotNull(value){return value!==null}var transformOrigin=(options)=>({fn(data){let{placement,rects,middlewareData}=data,isArrowHidden=middlewareData.arrow?.centerOffset!==0,arrowWidth=isArrowHidden?0:options.arrowWidth,arrowHeight=isArrowHidden?0:options.arrowHeight,[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),noArrowAlign={center:"50%",end:"100%",start:"0%"}[placedAlign],arrowXCenter=(middlewareData.arrow?.x??0)+arrowWidth/2,arrowYCenter=(middlewareData.arrow?.y??0)+arrowHeight/2,x="",y="";if(placedSide==="bottom")x=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y=`${-arrowHeight}px`;else if(placedSide==="top")x=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y=`${rects.floating.height+arrowHeight}px`;else if(placedSide==="right")x=`${-arrowHeight}px`,y=isArrowHidden?noArrowAlign:`${arrowYCenter}px`;else if(placedSide==="left")x=`${rects.floating.width+arrowHeight}px`,y=isArrowHidden?noArrowAlign:`${arrowYCenter}px`;return{data:{x,y}}},name:"transformOrigin",options});function getSideAndAlignFromPlacement(placement){let[side,align="center"]=placement.split("-");return[side,align]}var Root=Popper,Anchor=PopperAnchor,Content=PopperContent,Arrow=PopperArrow;export{createPopperScope,SIDE_OPTIONS,Root,PopperContent,PopperArrow,PopperAnchor,Popper,Content,Arrow,Anchor,ALIGN_OPTIONS};