UNPKG

selection-popover

Version:

Easy-to-use, composable react selection popover.

2 lines 8.31 kB
import*as e from"react";import{createContext as M}from"@radix-ui/react-context";import{useComposedRefs as L}from"@radix-ui/react-compose-refs";import{Presence as j}from"@radix-ui/react-presence";import{useControllableState as Pe}from"@radix-ui/react-use-controllable-state";import{Primitive as q}from"@radix-ui/react-primitive";import{useSize as Re}from"@radix-ui/react-use-size";import{Portal as he}from"@radix-ui/react-portal";import{DismissableLayer as we}from"@radix-ui/react-dismissable-layer";import{useLayoutEffect as Z}from"@radix-ui/react-use-layout-effect";import*as z from"@radix-ui/react-arrow";import{useFloating as ye,autoUpdate as Ce,offset as ve,shift as be,limitShift as Ee,flip as Oe,hide as Te,arrow as xe,inline as Ae}from"@floating-ui/react-dom";var[De,b]=M("Selection"),tt=t=>{let{children:r,open:n,defaultOpen:o,onOpenChange:s,whileSelect:u=!1,disabled:i=!1,openDelay:l,closeDelay:a}=t,f=e.useRef(0),m=e.useRef(0),[g,R]=e.useState(null),[d,c]=e.useState({getBoundingClientRect:()=>DOMRect.fromRect(),getClientRects:()=>new DOMRectList}),[p=!1,S]=Pe({prop:n,defaultProp:o,onChange:s}),P=e.useCallback(w=>{clearTimeout(m.current),f.current=window.setTimeout(w,l)},[l]),h=e.useCallback(()=>{clearTimeout(f.current),m.current=window.setTimeout(()=>S(!1),a)},[a,S]);return e.createElement(De,{open:p,onOpenChange:S,onOpen:P,onClose:h,whileSelect:u,virtualRef:d,onVirtualRefChange:c,content:g,onContentChange:R,disabled:i},r)},T="SelectionTrigger",Ie=e.forwardRef((t,r)=>{let n=b(T),o=e.useRef(null),s=L(r,o);return n.whileSelect?e.createElement(Me,{...t,ref:r}):e.createElement(J,{...t,ref:s,onPointerUp:u=>{var i;(i=t.onPointerUp)==null||i.call(t,u),u.pointerType==="mouse"&&n.onOpen(()=>{let l=document.getSelection();if(!l)return;let a=o.current;if(!(a==null?void 0:a.contains(l.anchorNode))||l.toString().trim()===""||l.isCollapsed)return;let m=l.getRangeAt(0);n.onOpenChange(!0),n.onVirtualRefChange({getBoundingClientRect:()=>m.getBoundingClientRect(),getClientRects:()=>m.getClientRects()})})}})});Ie.displayName=T;var I,Me=e.forwardRef((t,r)=>{let n=b(T),[o,s]=e.useState(!1),u=e.useRef(null),i=e.useRef(""),l=e.useRef(!1),a=L(r,u),f=e.useCallback(()=>{s(!1)},[]),{onOpen:m,onOpenChange:g,onVirtualRefChange:R}=n;return e.useEffect(()=>{if(!n.disabled){let d=()=>{if(i.current!=="mouse")return;let c=document.getSelection();if(!c)return;let p=u.current;if(!(p==null?void 0:p.contains(c.anchorNode))){l.current=!1;return}if(c.isCollapsed){l.current=!1;return}if(c.toString().trim()!==""){let h=c==null?void 0:c.getRangeAt(0);l.current||m(()=>g(!0)),l.current=!0,R({getBoundingClientRect:()=>h.getBoundingClientRect(),getClientRects:()=>h.getClientRects()})}};return document.addEventListener("selectionchange",d),()=>document.removeEventListener("selectionchange",d)}},[n.disabled,g,m,R]),e.useEffect(()=>{if(o){let d=document.body;return I=d.style.userSelect||d.style.webkitUserSelect,d.style.userSelect="none",d.style.webkitUserSelect="none",()=>{d.style.userSelect=I,d.style.webkitUserSelect=I}}},[o]),e.useEffect(()=>()=>document.removeEventListener("pointerup",f),[f]),e.createElement(J,{...t,ref:a,onPointerDown:d=>{var c;(c=t.onPointerDown)==null||c.call(t,d),i.current=d.pointerType,s(!0),document.addEventListener("pointerup",f,{once:!0})},style:{userSelect:o?"text":void 0,WebkitUserSelect:o?"text":void 0,...t.style}})}),J=e.forwardRef((t,r)=>{let n=b(T),[o,s]=e.useState(!1),u=e.useCallback(()=>{s(!1)},[]);return e.useEffect(()=>{if(n.content&&o){let i=n.content,l=i.style.pointerEvents;return i.style.pointerEvents="none",()=>{i.style.pointerEvents=l}}},[n.content,o]),e.useEffect(()=>()=>document.removeEventListener("pointerup",u),[u]),e.createElement(q.div,{...t,ref:r,onPointerDown:i=>{var l;(l=t.onPointerDown)==null||l.call(t,i),s(!0),document.addEventListener("pointerup",u,{once:!0})}})}),N="SelectionPortal",[Le,Ne]=M(N,{forceMount:void 0}),He=t=>{let{forceMount:r,container:n,children:o}=t,s=b(N);return e.createElement(Le,{forceMount:r},e.createElement(j,{present:r||s.open},e.createElement(he,{asChild:!0,container:n},o)))};He.displayName=N;var E="SelectionContent",We=e.forwardRef((t,r)=>{let n=Ne(E),{forceMount:o=n.forceMount,...s}=t,u=b(E);return e.createElement(j,{present:o||u.open},e.createElement(ke,{...s,ref:r}))}),[Be,Ve]=M(E),ke=e.forwardRef((t,r)=>{var $,U,_,Y,F,X,G,K;let{side:n="top",sideOffset:o=0,align:s="center",alignOffset:u=0,arrowPadding:i=0,sticky:l="partial",collisionBoundary:a=[],collisionPadding:f=0,hideWhenDetached:m=!1,avoidCollisions:g=!0,onEscapeKeyDown:R,onPointerDownOutside:d,onFocusOutside:c,onInteractOutside:p,...S}=t,P=b(E),{onClose:h,onContentChange:w}=P,[y,te]=e.useState(null),ne=L(r,Se=>te(Se)),[x,oe]=e.useState(null),C=Re(x),re=($=C==null?void 0:C.width)!=null?$:0,H=(U=C==null?void 0:C.height)!=null?U:0,ie=n+(s!=="center"?"-"+s:""),le=typeof f=="number"?f:{top:0,right:0,bottom:0,left:0,...f},W=Array.isArray(a)?a:[a],se=W.length>0,B={padding:le,boundary:W.filter(_e),altBoundary:se},{x:A,y:D,strategy:ae,placement:ce,refs:O,middlewareData:v,isPositioned:V}=ye({strategy:"fixed",placement:ie,whileElementsMounted:Ce,middleware:[Ae(),Ye(),ve({mainAxis:o+H,alignmentAxis:u}),g?Oe(B):void 0,g?be({mainAxis:!0,crossAxis:!1,limiter:l==="partial"?Ee():void 0,...B}):void 0,x?xe({element:x,padding:i}):void 0,Fe({arrowWidth:re,arrowHeight:H}),m?Te({strategy:"referenceHidden"}):void 0]});Z(()=>{O.setReference(P.virtualRef),w(O.floating.current)},[P.virtualRef,w,O]);let[k,de]=ee(ce),ue=(_=v.arrow)==null?void 0:_.x,fe=(Y=v.arrow)==null?void 0:Y.y,pe=((F=v.arrow)==null?void 0:F.centerOffset)!==0,[me,ge]=e.useState();return Z(()=>{y&&ge(window.getComputedStyle(y).zIndex)},[y]),e.createElement("div",{ref:O.setFloating,style:{position:ae,top:0,left:0,transform:V?`translate3d(${Math.round(A!=null?A:0)}px, ${Math.round(D!=null?D:0)}px, 0)`:"translate3d(0, -200%, 0)",minWidth:"max-content",zIndex:me}},e.createElement(Be,{placedSide:k,onArrowChange:oe,arrowX:ue,arrowY:fe,shouldHideArrow:pe},e.createElement(we,{asChild:!0,onEscapeKeyDown:R,onPointerDownOutside:d,onFocusOutside:c,onInteractOutside:p,onDismiss:h},e.createElement(q.div,{"data-side":k,"data-align":de,"data-state":P.open?"open":"closed",...S,ref:ne,style:{userSelect:"none",...S.style,animation:V?void 0:"none",opacity:(X=v.hide)!=null&&X.referenceHidden?0:void 0,["--selection-popover-content-transform-origin"]:[(G=v.transformOrigin)==null?void 0:G.x,(K=v.transformOrigin)==null?void 0:K.y].join(" ")}}))))});We.displayName=E;var Q="SelectionArrow",$e={top:"bottom",right:"left",bottom:"top",left:"right"},Ue=e.forwardRef((t,r)=>{let n=Ve(Q),o=$e[n.placedSide];return e.createElement("span",{ref:n.onArrowChange,style:{position:"absolute",left:n.arrowX,top:n.arrowY,[o]:0,transformOrigin:{top:"",right:"0 0",bottom:"center 0",left:"100% 0"}[n.placedSide],transform:{top:"translateY(100%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)"}[n.placedSide],visibility:n.shouldHideArrow?"hidden":void 0}},e.createElement(z.Root,{...t,ref:r,style:{...t.style,display:"block"}}))});Ue.displayName=Q;function _e(t){return t!==null}function ee(t){let[r,n="center"]=t.split("-");return[r,n]}var Ye=()=>({name:"anchorCssProperties",async fn(t){let{rects:r,elements:n,platform:o}=t,{width:s,height:u}=r.reference,{width:i,height:l}=r.floating;n.floating.style.setProperty("--selection-popover-select-width",`${s}px`),n.floating.style.setProperty("--selection-popover-select-height",`${u}px`);let a=await o.getDimensions(n.floating);return i!==a.width||l!==a.height?{reset:{rects:!0}}:{}}}),Fe=t=>({name:"transformOrigin",options:t,fn(r){var S,P,h,w,y;let{placement:n,rects:o,middlewareData:s}=r,i=((S=s.arrow)==null?void 0:S.centerOffset)!==0,l=i?0:t.arrowWidth,a=i?0:t.arrowHeight,[f,m]=ee(n),g={start:"0%",center:"50%",end:"100%"}[m],R=((h=(P=s.arrow)==null?void 0:P.x)!=null?h:0)+l/2,d=((y=(w=s.arrow)==null?void 0:w.y)!=null?y:0)+a/2,c="",p="";return f==="bottom"?(c=i?g:`${R}px`,p=`${-a}px`):f==="top"?(c=i?g:`${R}px`,p=`${o.floating.height+a}px`):f==="right"?(c=`${-a}px`,p=i?g:`${d}px`):f==="left"&&(c=`${o.floating.width+a}px`,p=i?g:`${d}px`),{data:{x:c,y:p}}}});export{Ue as Arrow,We as Content,He as Portal,tt as Root,Ie as Trigger}; //# sourceMappingURL=index.mjs.map