Spaces:
Running
Running
| "use client"; | |
| // src/popper.tsx | |
| import * as React from "react"; | |
| import { | |
| useFloating, | |
| autoUpdate, | |
| offset, | |
| shift, | |
| limitShift, | |
| hide, | |
| arrow as floatingUIarrow, | |
| flip, | |
| size | |
| } from "@floating-ui/react-dom"; | |
| import * as ArrowPrimitive from "@radix-ui/react-arrow"; | |
| import { useComposedRefs } from "@radix-ui/react-compose-refs"; | |
| import { createContextScope } from "@radix-ui/react-context"; | |
| import { Primitive } from "@radix-ui/react-primitive"; | |
| import { useCallbackRef } from "@radix-ui/react-use-callback-ref"; | |
| import { useLayoutEffect } from "@radix-ui/react-use-layout-effect"; | |
| import { useSize } from "@radix-ui/react-use-size"; | |
| import { jsx } from "react/jsx-runtime"; | |
| var SIDE_OPTIONS = ["top", "right", "bottom", "left"]; | |
| var ALIGN_OPTIONS = ["start", "center", "end"]; | |
| var POPPER_NAME = "Popper"; | |
| var [createPopperContext, createPopperScope] = createContextScope(POPPER_NAME); | |
| var [PopperProvider, usePopperContext] = createPopperContext(POPPER_NAME); | |
| var Popper = (props) => { | |
| const { __scopePopper, children } = props; | |
| const [anchor, setAnchor] = React.useState(null); | |
| return /* @__PURE__ */ jsx(PopperProvider, { scope: __scopePopper, anchor, onAnchorChange: setAnchor, children }); | |
| }; | |
| Popper.displayName = POPPER_NAME; | |
| var ANCHOR_NAME = "PopperAnchor"; | |
| var PopperAnchor = React.forwardRef( | |
| (props, forwardedRef) => { | |
| const { __scopePopper, virtualRef, ...anchorProps } = props; | |
| const context = usePopperContext(ANCHOR_NAME, __scopePopper); | |
| const ref = React.useRef(null); | |
| const composedRefs = useComposedRefs(forwardedRef, ref); | |
| React.useEffect(() => { | |
| context.onAnchorChange(virtualRef?.current || ref.current); | |
| }); | |
| return virtualRef ? null : /* @__PURE__ */ jsx(Primitive.div, { ...anchorProps, ref: composedRefs }); | |
| } | |
| ); | |
| PopperAnchor.displayName = ANCHOR_NAME; | |
| var CONTENT_NAME = "PopperContent"; | |
| var [PopperContentProvider, useContentContext] = createPopperContext(CONTENT_NAME); | |
| var PopperContent = React.forwardRef( | |
| (props, forwardedRef) => { | |
| const { | |
| __scopePopper, | |
| side = "bottom", | |
| sideOffset = 0, | |
| align = "center", | |
| alignOffset = 0, | |
| arrowPadding = 0, | |
| avoidCollisions = true, | |
| collisionBoundary = [], | |
| collisionPadding: collisionPaddingProp = 0, | |
| sticky = "partial", | |
| hideWhenDetached = false, | |
| updatePositionStrategy = "optimized", | |
| onPlaced, | |
| ...contentProps | |
| } = props; | |
| const context = usePopperContext(CONTENT_NAME, __scopePopper); | |
| const [content, setContent] = React.useState(null); | |
| const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node)); | |
| const [arrow, setArrow] = React.useState(null); | |
| const arrowSize = useSize(arrow); | |
| const arrowWidth = arrowSize?.width ?? 0; | |
| const arrowHeight = arrowSize?.height ?? 0; | |
| const desiredPlacement = side + (align !== "center" ? "-" + align : ""); | |
| const collisionPadding = typeof collisionPaddingProp === "number" ? collisionPaddingProp : { top: 0, right: 0, bottom: 0, left: 0, ...collisionPaddingProp }; | |
| const boundary = Array.isArray(collisionBoundary) ? collisionBoundary : [collisionBoundary]; | |
| const hasExplicitBoundaries = boundary.length > 0; | |
| const detectOverflowOptions = { | |
| padding: collisionPadding, | |
| boundary: boundary.filter(isNotNull), | |
| // with `strategy: 'fixed'`, this is the only way to get it to respect boundaries | |
| altBoundary: hasExplicitBoundaries | |
| }; | |
| const { refs, floatingStyles, placement, isPositioned, middlewareData } = useFloating({ | |
| // default to `fixed` strategy so users don't have to pick and we also avoid focus scroll issues | |
| strategy: "fixed", | |
| placement: desiredPlacement, | |
| whileElementsMounted: (...args) => { | |
| const cleanup = autoUpdate(...args, { | |
| animationFrame: updatePositionStrategy === "always" | |
| }); | |
| return cleanup; | |
| }, | |
| elements: { | |
| reference: context.anchor | |
| }, | |
| middleware: [ | |
| offset({ mainAxis: sideOffset + arrowHeight, alignmentAxis: alignOffset }), | |
| avoidCollisions && shift({ | |
| mainAxis: true, | |
| crossAxis: false, | |
| limiter: sticky === "partial" ? limitShift() : void 0, | |
| ...detectOverflowOptions | |
| }), | |
| avoidCollisions && flip({ ...detectOverflowOptions }), | |
| size({ | |
| ...detectOverflowOptions, | |
| apply: ({ elements, rects, availableWidth, availableHeight }) => { | |
| const { width: anchorWidth, height: anchorHeight } = rects.reference; | |
| const contentStyle = elements.floating.style; | |
| contentStyle.setProperty("--radix-popper-available-width", `${availableWidth}px`); | |
| contentStyle.setProperty("--radix-popper-available-height", `${availableHeight}px`); | |
| contentStyle.setProperty("--radix-popper-anchor-width", `${anchorWidth}px`); | |
| contentStyle.setProperty("--radix-popper-anchor-height", `${anchorHeight}px`); | |
| } | |
| }), | |
| arrow && floatingUIarrow({ element: arrow, padding: arrowPadding }), | |
| transformOrigin({ arrowWidth, arrowHeight }), | |
| hideWhenDetached && hide({ strategy: "referenceHidden", ...detectOverflowOptions }) | |
| ] | |
| }); | |
| const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement); | |
| const handlePlaced = useCallbackRef(onPlaced); | |
| useLayoutEffect(() => { | |
| if (isPositioned) { | |
| handlePlaced?.(); | |
| } | |
| }, [isPositioned, handlePlaced]); | |
| const arrowX = middlewareData.arrow?.x; | |
| const arrowY = middlewareData.arrow?.y; | |
| const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0; | |
| const [contentZIndex, setContentZIndex] = React.useState(); | |
| useLayoutEffect(() => { | |
| if (content) setContentZIndex(window.getComputedStyle(content).zIndex); | |
| }, [content]); | |
| return /* @__PURE__ */ jsx( | |
| "div", | |
| { | |
| ref: refs.setFloating, | |
| "data-radix-popper-content-wrapper": "", | |
| style: { | |
| ...floatingStyles, | |
| transform: isPositioned ? floatingStyles.transform : "translate(0, -200%)", | |
| // keep off the page when measuring | |
| minWidth: "max-content", | |
| zIndex: contentZIndex, | |
| ["--radix-popper-transform-origin"]: [ | |
| middlewareData.transformOrigin?.x, | |
| middlewareData.transformOrigin?.y | |
| ].join(" "), | |
| // hide the content if using the hide middleware and should be hidden | |
| // set visibility to hidden and disable pointer events so the UI behaves | |
| // as if the PopperContent isn't there at all | |
| ...middlewareData.hide?.referenceHidden && { | |
| visibility: "hidden", | |
| pointerEvents: "none" | |
| } | |
| }, | |
| dir: props.dir, | |
| children: /* @__PURE__ */ jsx( | |
| PopperContentProvider, | |
| { | |
| scope: __scopePopper, | |
| placedSide, | |
| onArrowChange: setArrow, | |
| arrowX, | |
| arrowY, | |
| shouldHideArrow: cannotCenterArrow, | |
| children: /* @__PURE__ */ jsx( | |
| Primitive.div, | |
| { | |
| "data-side": placedSide, | |
| "data-align": placedAlign, | |
| ...contentProps, | |
| ref: composedRefs, | |
| style: { | |
| ...contentProps.style, | |
| // if the PopperContent hasn't been placed yet (not all measurements done) | |
| // we prevent animations so that users's animation don't kick in too early referring wrong sides | |
| animation: !isPositioned ? "none" : void 0 | |
| } | |
| } | |
| ) | |
| } | |
| ) | |
| } | |
| ); | |
| } | |
| ); | |
| PopperContent.displayName = CONTENT_NAME; | |
| var ARROW_NAME = "PopperArrow"; | |
| var OPPOSITE_SIDE = { | |
| top: "bottom", | |
| right: "left", | |
| bottom: "top", | |
| left: "right" | |
| }; | |
| var PopperArrow = React.forwardRef(function PopperArrow2(props, forwardedRef) { | |
| const { __scopePopper, ...arrowProps } = props; | |
| const contentContext = useContentContext(ARROW_NAME, __scopePopper); | |
| const baseSide = OPPOSITE_SIDE[contentContext.placedSide]; | |
| return ( | |
| // we have to use an extra wrapper because `ResizeObserver` (used by `useSize`) | |
| // doesn't report size as we'd expect on SVG elements. | |
| // it reports their bounding box which is effectively the largest path inside the SVG. | |
| /* @__PURE__ */ jsx( | |
| "span", | |
| { | |
| ref: contentContext.onArrowChange, | |
| style: { | |
| position: "absolute", | |
| left: contentContext.arrowX, | |
| top: contentContext.arrowY, | |
| [baseSide]: 0, | |
| transformOrigin: { | |
| top: "", | |
| right: "0 0", | |
| bottom: "center 0", | |
| left: "100% 0" | |
| }[contentContext.placedSide], | |
| transform: { | |
| top: "translateY(100%)", | |
| right: "translateY(50%) rotate(90deg) translateX(-50%)", | |
| bottom: `rotate(180deg)`, | |
| left: "translateY(50%) rotate(-90deg) translateX(50%)" | |
| }[contentContext.placedSide], | |
| visibility: contentContext.shouldHideArrow ? "hidden" : void 0 | |
| }, | |
| children: /* @__PURE__ */ jsx( | |
| ArrowPrimitive.Root, | |
| { | |
| ...arrowProps, | |
| ref: forwardedRef, | |
| style: { | |
| ...arrowProps.style, | |
| // ensures the element can be measured correctly (mostly for if SVG) | |
| display: "block" | |
| } | |
| } | |
| ) | |
| } | |
| ) | |
| ); | |
| }); | |
| PopperArrow.displayName = ARROW_NAME; | |
| function isNotNull(value) { | |
| return value !== null; | |
| } | |
| var transformOrigin = (options) => ({ | |
| name: "transformOrigin", | |
| options, | |
| fn(data) { | |
| const { placement, rects, middlewareData } = data; | |
| const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0; | |
| const isArrowHidden = cannotCenterArrow; | |
| const arrowWidth = isArrowHidden ? 0 : options.arrowWidth; | |
| const arrowHeight = isArrowHidden ? 0 : options.arrowHeight; | |
| const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement); | |
| const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[placedAlign]; | |
| const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2; | |
| const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2; | |
| let x = ""; | |
| let 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 } }; | |
| } | |
| }); | |
| function getSideAndAlignFromPlacement(placement) { | |
| const [side, align = "center"] = placement.split("-"); | |
| return [side, align]; | |
| } | |
| var Root2 = Popper; | |
| var Anchor = PopperAnchor; | |
| var Content = PopperContent; | |
| var Arrow = PopperArrow; | |
| export { | |
| ALIGN_OPTIONS, | |
| Anchor, | |
| Arrow, | |
| Content, | |
| Popper, | |
| PopperAnchor, | |
| PopperArrow, | |
| PopperContent, | |
| Root2 as Root, | |
| SIDE_OPTIONS, | |
| createPopperScope | |
| }; | |
| //# sourceMappingURL=index.mjs.map | |