@loke/ui
Version:
2 lines (1 loc) • 16.9 kB
JavaScript
var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache;var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var exports_tooltip={};__export(exports_tooltip,{createTooltipScope:()=>createTooltipScope,Trigger:()=>Trigger,TooltipTrigger:()=>TooltipTrigger,TooltipProvider:()=>TooltipProvider,TooltipPortal:()=>TooltipPortal,TooltipContent:()=>TooltipContent,TooltipArrow:()=>TooltipArrow,Tooltip:()=>Tooltip,Root:()=>Root3,Provider:()=>Provider,Portal:()=>Portal,Content:()=>Content2,Arrow:()=>Arrow2});module.exports=__toCommonJS(exports_tooltip);var import_compose_events=require("@loke/ui/compose-events"),import_compose_refs=require("@loke/ui/compose-refs"),import_context=require("@loke/ui/context"),import_dismissable_layer=require("@loke/ui/dismissable-layer"),PopperPrimitive=__toESM(require("@loke/ui/popper")),import_popper=require("@loke/ui/popper"),import_portal=require("@loke/ui/portal"),import_presence=require("@loke/ui/presence"),import_primitive=require("@loke/ui/primitive"),import_slot=require("@loke/ui/slot"),import_use_controllable_state=require("@loke/ui/use-controllable-state"),import_use_id=require("@loke/ui/use-id"),VisuallyHiddenPrimitive=__toESM(require("@loke/ui/visually-hidden")),import_react=require("react"),jsx_runtime=require("react/jsx-runtime"),[createTooltipContext,createTooltipScope]=import_context.createContextScope("Tooltip",[import_popper.createPopperScope]),usePopperScope=import_popper.createPopperScope(),PROVIDER_NAME="TooltipProvider",DEFAULT_DELAY_DURATION=700,TOOLTIP_OPEN="tooltip.open",[TooltipProviderContextProvider,useTooltipProviderContext]=createTooltipContext(PROVIDER_NAME),TooltipProvider=(props)=>{let{__scopeTooltip,delayDuration=DEFAULT_DELAY_DURATION,skipDelayDuration=300,disableHoverableContent=!1,children}=props,isOpenDelayedRef=import_react.useRef(!0),isPointerInTransitRef=import_react.useRef(!1),skipDelayTimerRef=import_react.useRef(0);return import_react.useEffect(()=>{let skipDelayTimer=skipDelayTimerRef.current;return()=>window.clearTimeout(skipDelayTimer)},[]),jsx_runtime.jsx(TooltipProviderContextProvider,{delayDuration,disableHoverableContent,isOpenDelayedRef,isPointerInTransitRef,onClose:import_react.useCallback(()=>{window.clearTimeout(skipDelayTimerRef.current),skipDelayTimerRef.current=window.setTimeout(()=>isOpenDelayedRef.current=!0,skipDelayDuration)},[skipDelayDuration]),onOpen:import_react.useCallback(()=>{window.clearTimeout(skipDelayTimerRef.current),isOpenDelayedRef.current=!1},[]),onPointerInTransitChange:import_react.useCallback((inTransit)=>{isPointerInTransitRef.current=inTransit},[]),scope:__scopeTooltip,children})};TooltipProvider.displayName=PROVIDER_NAME;var TOOLTIP_NAME="Tooltip",[TooltipContextProvider,useTooltipContext]=createTooltipContext(TOOLTIP_NAME),Tooltip=(props)=>{let{__scopeTooltip,children,open:openProp,defaultOpen,onOpenChange,disableHoverableContent:disableHoverableContentProp,delayDuration:delayDurationProp}=props,providerContext=useTooltipProviderContext(TOOLTIP_NAME,props.__scopeTooltip),popperScope=usePopperScope(__scopeTooltip),[trigger,setTrigger]=import_react.useState(null),contentId=import_use_id.useId(),openTimerRef=import_react.useRef(0),disableHoverableContent=disableHoverableContentProp??providerContext.disableHoverableContent,delayDuration=delayDurationProp??providerContext.delayDuration,wasOpenDelayedRef=import_react.useRef(!1),[open,setOpen]=import_use_controllable_state.useControllableState({caller:TOOLTIP_NAME,defaultProp:defaultOpen??!1,onChange:(o)=>{if(o)providerContext.onOpen(),document.dispatchEvent(new CustomEvent(TOOLTIP_OPEN));else providerContext.onClose();onOpenChange?.(o)},prop:openProp}),stateAttribute=import_react.useMemo(()=>{if(!open)return"closed";return wasOpenDelayedRef.current?"delayed-open":"instant-open"},[open]),handleOpen=import_react.useCallback(()=>{window.clearTimeout(openTimerRef.current),openTimerRef.current=0,wasOpenDelayedRef.current=!1,setOpen(!0)},[setOpen]),handleClose=import_react.useCallback(()=>{window.clearTimeout(openTimerRef.current),openTimerRef.current=0,setOpen(!1)},[setOpen]),handleDelayedOpen=import_react.useCallback(()=>{window.clearTimeout(openTimerRef.current),openTimerRef.current=window.setTimeout(()=>{wasOpenDelayedRef.current=!0,setOpen(!0),openTimerRef.current=0},delayDuration)},[delayDuration,setOpen]);return import_react.useEffect(()=>{return()=>{if(openTimerRef.current)window.clearTimeout(openTimerRef.current),openTimerRef.current=0}},[]),jsx_runtime.jsx(PopperPrimitive.Root,{...popperScope,children:jsx_runtime.jsx(TooltipContextProvider,{contentId,disableHoverableContent,onClose:handleClose,onOpen:handleOpen,onTriggerChange:setTrigger,onTriggerEnter:import_react.useCallback(()=>{if(providerContext.isOpenDelayedRef.current)handleDelayedOpen();else handleOpen()},[providerContext.isOpenDelayedRef,handleDelayedOpen,handleOpen]),onTriggerLeave:import_react.useCallback(()=>{if(disableHoverableContent)handleClose();else window.clearTimeout(openTimerRef.current),openTimerRef.current=0},[handleClose,disableHoverableContent]),open,scope:__scopeTooltip,stateAttribute,trigger,children})})};Tooltip.displayName=TOOLTIP_NAME;var TRIGGER_NAME="TooltipTrigger",TooltipTrigger=import_react.forwardRef((props,forwardedRef)=>{let{__scopeTooltip,...triggerProps}=props,context=useTooltipContext(TRIGGER_NAME,__scopeTooltip),providerContext=useTooltipProviderContext(TRIGGER_NAME,__scopeTooltip),popperScope=usePopperScope(__scopeTooltip),ref=import_react.useRef(null),composedRefs=import_compose_refs.useComposedRefs(forwardedRef,ref,context.onTriggerChange),isPointerDownRef=import_react.useRef(!1),hasPointerMoveOpenedRef=import_react.useRef(!1),handlePointerUp=import_react.useCallback(()=>isPointerDownRef.current=!1,[]);return import_react.useEffect(()=>{return()=>document.removeEventListener("pointerup",handlePointerUp)},[handlePointerUp]),jsx_runtime.jsx(PopperPrimitive.Anchor,{asChild:!0,...popperScope,children:jsx_runtime.jsx(import_primitive.Primitive.button,{"aria-describedby":context.open?context.contentId:void 0,"data-state":context.stateAttribute,...triggerProps,onBlur:import_compose_events.composeEventHandlers(props.onBlur,context.onClose),onClick:import_compose_events.composeEventHandlers(props.onClick,context.onClose),onFocus:import_compose_events.composeEventHandlers(props.onFocus,()=>{if(!isPointerDownRef.current)context.onOpen()}),onPointerDown:import_compose_events.composeEventHandlers(props.onPointerDown,()=>{if(context.open)context.onClose();isPointerDownRef.current=!0,document.addEventListener("pointerup",handlePointerUp,{once:!0})}),onPointerLeave:import_compose_events.composeEventHandlers(props.onPointerLeave,()=>{context.onTriggerLeave(),hasPointerMoveOpenedRef.current=!1}),onPointerMove:import_compose_events.composeEventHandlers(props.onPointerMove,(event)=>{if(event.pointerType==="touch")return;if(!(hasPointerMoveOpenedRef.current||providerContext.isPointerInTransitRef.current))context.onTriggerEnter(),hasPointerMoveOpenedRef.current=!0}),ref:composedRefs})})});TooltipTrigger.displayName=TRIGGER_NAME;var PORTAL_NAME="TooltipPortal",[PortalProvider,usePortalContext]=createTooltipContext(PORTAL_NAME,{forceMount:void 0}),TooltipPortal=(props)=>{let{__scopeTooltip,forceMount,children,container}=props,context=useTooltipContext(PORTAL_NAME,__scopeTooltip);return jsx_runtime.jsx(PortalProvider,{forceMount,scope:__scopeTooltip,children:jsx_runtime.jsx(import_presence.Presence,{present:forceMount||context.open,children:jsx_runtime.jsx(import_portal.Portal,{asChild:!0,container,children})})})};TooltipPortal.displayName=PORTAL_NAME;var CONTENT_NAME="TooltipContent",TooltipContent=import_react.forwardRef((props,forwardedRef)=>{let portalContext=usePortalContext(CONTENT_NAME,props.__scopeTooltip),{forceMount=portalContext.forceMount,side="top",...contentProps}=props,context=useTooltipContext(CONTENT_NAME,props.__scopeTooltip);return jsx_runtime.jsx(import_presence.Presence,{present:forceMount||context.open,children:context.disableHoverableContent?jsx_runtime.jsx(TooltipContentImpl,{side,...contentProps,ref:forwardedRef}):jsx_runtime.jsx(TooltipContentHoverable,{side,...contentProps,ref:forwardedRef})})}),TooltipContentHoverable=import_react.forwardRef((props,forwardedRef)=>{let context=useTooltipContext(CONTENT_NAME,props.__scopeTooltip),providerContext=useTooltipProviderContext(CONTENT_NAME,props.__scopeTooltip),ref=import_react.useRef(null),composedRefs=import_compose_refs.useComposedRefs(forwardedRef,ref),[pointerGraceArea,setPointerGraceArea]=import_react.useState(null),{trigger,onClose}=context,content=ref.current,{onPointerInTransitChange}=providerContext,handleRemoveGraceArea=import_react.useCallback(()=>{setPointerGraceArea(null),onPointerInTransitChange(!1)},[onPointerInTransitChange]),handleCreateGraceArea=import_react.useCallback((event,hoverTarget)=>{let currentTarget=event.currentTarget,exitPoint={x:event.clientX,y:event.clientY},exitSide=getExitSideFromRect(exitPoint,currentTarget.getBoundingClientRect()),paddedExitPoints=getPaddedExitPoints(exitPoint,exitSide),hoverTargetPoints=getPointsFromRect(hoverTarget.getBoundingClientRect()),graceArea=getHull([...paddedExitPoints,...hoverTargetPoints]);setPointerGraceArea(graceArea),onPointerInTransitChange(!0)},[onPointerInTransitChange]);return import_react.useEffect(()=>{return()=>handleRemoveGraceArea()},[handleRemoveGraceArea]),import_react.useEffect(()=>{if(trigger&&content){let handleTriggerLeave=(event)=>handleCreateGraceArea(event,content),handleContentLeave=(event)=>handleCreateGraceArea(event,trigger);return trigger.addEventListener("pointerleave",handleTriggerLeave),content.addEventListener("pointerleave",handleContentLeave),()=>{trigger.removeEventListener("pointerleave",handleTriggerLeave),content.removeEventListener("pointerleave",handleContentLeave)}}},[trigger,content,handleCreateGraceArea,handleRemoveGraceArea]),import_react.useEffect(()=>{if(pointerGraceArea){let handleTrackPointerGrace=(event)=>{let target=event.target,pointerPosition={x:event.clientX,y:event.clientY},hasEnteredTarget=trigger?.contains(target)||content?.contains(target),isPointerOutsideGraceArea=!isPointInPolygon(pointerPosition,pointerGraceArea);if(hasEnteredTarget)handleRemoveGraceArea();else if(isPointerOutsideGraceArea)handleRemoveGraceArea(),onClose()};return document.addEventListener("pointermove",handleTrackPointerGrace),()=>document.removeEventListener("pointermove",handleTrackPointerGrace)}},[trigger,content,pointerGraceArea,onClose,handleRemoveGraceArea]),jsx_runtime.jsx(TooltipContentImpl,{...props,ref:composedRefs})}),[VisuallyHiddenContentContextProvider,useVisuallyHiddenContentContext]=createTooltipContext(TOOLTIP_NAME,{isInside:!1}),Slottable=import_slot.createSlottable("TooltipContent"),TooltipContentImpl=import_react.forwardRef((props,forwardedRef)=>{let{__scopeTooltip,children,"aria-label":ariaLabel,onEscapeKeyDown,onPointerDownOutside,...contentProps}=props,context=useTooltipContext(CONTENT_NAME,__scopeTooltip),popperScope=usePopperScope(__scopeTooltip),{onClose}=context;return import_react.useEffect(()=>{return document.addEventListener(TOOLTIP_OPEN,onClose),()=>document.removeEventListener(TOOLTIP_OPEN,onClose)},[onClose]),import_react.useEffect(()=>{if(context.trigger){let handleScroll=(event)=>{if(event.target?.contains(context.trigger))onClose()};return window.addEventListener("scroll",handleScroll,{capture:!0}),()=>window.removeEventListener("scroll",handleScroll,{capture:!0})}},[context.trigger,onClose]),jsx_runtime.jsx(import_dismissable_layer.DismissableLayer,{asChild:!0,disableOutsidePointerEvents:!1,onDismiss:onClose,onEscapeKeyDown,onFocusOutside:(event)=>event.preventDefault(),onPointerDownOutside,children:jsx_runtime.jsxs(PopperPrimitive.Content,{"data-state":context.stateAttribute,...popperScope,...contentProps,ref:forwardedRef,style:{...contentProps.style,...{"--loke-tooltip-content-available-height":"var(--loke-popper-available-height)","--loke-tooltip-content-available-width":"var(--loke-popper-available-width)","--loke-tooltip-content-transform-origin":"var(--loke-popper-transform-origin)","--loke-tooltip-trigger-height":"var(--loke-popper-anchor-height)","--loke-tooltip-trigger-width":"var(--loke-popper-anchor-width)"}},children:[jsx_runtime.jsx(Slottable,{children}),jsx_runtime.jsx(VisuallyHiddenContentContextProvider,{isInside:!0,scope:__scopeTooltip,children:jsx_runtime.jsx(VisuallyHiddenPrimitive.Root,{id:context.contentId,role:"tooltip",children:ariaLabel||children})})]})})});TooltipContent.displayName=CONTENT_NAME;var ARROW_NAME="TooltipArrow",TooltipArrow=import_react.forwardRef((props,forwardedRef)=>{let{__scopeTooltip,...arrowProps}=props,popperScope=usePopperScope(__scopeTooltip);return useVisuallyHiddenContentContext(ARROW_NAME,__scopeTooltip).isInside?null:jsx_runtime.jsx(PopperPrimitive.Arrow,{...popperScope,...arrowProps,ref:forwardedRef})});TooltipArrow.displayName=ARROW_NAME;function getExitSideFromRect(point,rect){let top=Math.abs(rect.top-point.y),bottom=Math.abs(rect.bottom-point.y),right=Math.abs(rect.right-point.x),left=Math.abs(rect.left-point.x);switch(Math.min(top,bottom,right,left)){case left:return"left";case right:return"right";case top:return"top";case bottom:return"bottom";default:throw Error("unreachable")}}function getPaddedExitPoints(exitPoint,exitSide,padding=5){let paddedExitPoints=[];switch(exitSide){case"top":paddedExitPoints.push({x:exitPoint.x-padding,y:exitPoint.y+padding},{x:exitPoint.x+padding,y:exitPoint.y+padding});break;case"bottom":paddedExitPoints.push({x:exitPoint.x-padding,y:exitPoint.y-padding},{x:exitPoint.x+padding,y:exitPoint.y-padding});break;case"left":paddedExitPoints.push({x:exitPoint.x+padding,y:exitPoint.y-padding},{x:exitPoint.x+padding,y:exitPoint.y+padding});break;case"right":paddedExitPoints.push({x:exitPoint.x-padding,y:exitPoint.y-padding},{x:exitPoint.x-padding,y:exitPoint.y+padding});break}return paddedExitPoints}function getPointsFromRect(rect){let{top,right,bottom,left}=rect;return[{x:left,y:top},{x:right,y:top},{x:right,y:bottom},{x:left,y:bottom}]}function isPointInPolygon(point,polygon){let{x,y}=point,inside=!1;for(let i=0,j=polygon.length-1;i<polygon.length;j=i++){let ii=polygon[i],jj=polygon[j];if(ii==null||jj==null)continue;let{x:xi,y:yi}=ii,xj=jj.x,yj=jj.y;if(yi>y!==yj>y&&x<(xj-xi)*(y-yi)/(yj-yi)+xi)inside=!inside}return inside}function getHull(points){let newPoints=points.slice();return newPoints.sort((a,b)=>{if(a.x<b.x)return-1;if(a.x>b.x)return 1;if(a.y<b.y)return-1;if(a.y>b.y)return 1;return 0}),getHullPresorted(newPoints)}function getHullPresorted(points){if(points.length<=1)return points.slice();let upperHull=[];for(let p of points){while(upperHull.length>=2){let q=upperHull.at(-1),r=upperHull.at(-2);if(q==null||r==null)break;if((q.x-r.x)*(p.y-r.y)>=(q.y-r.y)*(p.x-r.x))upperHull.pop();else break}upperHull.push(p)}upperHull.pop();let lowerHull=[];for(let p of points.toReversed()){while(lowerHull.length>=2){let q=lowerHull.at(-1),r=lowerHull.at(-2);if(q==null||r==null)break;if((q.x-r.x)*(p.y-r.y)>=(q.y-r.y)*(p.x-r.x))lowerHull.pop();else break}lowerHull.push(p)}if(lowerHull.pop(),upperHull.length===1&&lowerHull.length===1&&upperHull[0]?.x===lowerHull[0]?.x&&upperHull[0]?.y===lowerHull[0]?.y)return upperHull;return upperHull.concat(lowerHull)}var Provider=TooltipProvider,Root3=Tooltip,Trigger=TooltipTrigger,Portal=TooltipPortal,Content2=TooltipContent,Arrow2=TooltipArrow;