Spaces:
Running
Running
| import { computePosition, arrow as arrow$2, offset as offset$1, shift as shift$1, limitShift as limitShift$1, flip as flip$1, size as size$1, autoPlacement as autoPlacement$1, hide as hide$1, inline as inline$1 } from '@floating-ui/dom'; | |
| export { autoUpdate, computePosition, detectOverflow, getOverflowAncestors, platform } from '@floating-ui/dom'; | |
| import * as React from 'react'; | |
| import { useLayoutEffect, useEffect } from 'react'; | |
| import * as ReactDOM from 'react-dom'; | |
| var index = typeof document !== 'undefined' ? useLayoutEffect : useEffect; | |
| // Fork of `fast-deep-equal` that only does the comparisons we need and compares | |
| // functions | |
| function deepEqual(a, b) { | |
| if (a === b) { | |
| return true; | |
| } | |
| if (typeof a !== typeof b) { | |
| return false; | |
| } | |
| if (typeof a === 'function' && a.toString() === b.toString()) { | |
| return true; | |
| } | |
| let length; | |
| let i; | |
| let keys; | |
| if (a && b && typeof a === 'object') { | |
| if (Array.isArray(a)) { | |
| length = a.length; | |
| if (length !== b.length) return false; | |
| for (i = length; i-- !== 0;) { | |
| if (!deepEqual(a[i], b[i])) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| keys = Object.keys(a); | |
| length = keys.length; | |
| if (length !== Object.keys(b).length) { | |
| return false; | |
| } | |
| for (i = length; i-- !== 0;) { | |
| if (!{}.hasOwnProperty.call(b, keys[i])) { | |
| return false; | |
| } | |
| } | |
| for (i = length; i-- !== 0;) { | |
| const key = keys[i]; | |
| if (key === '_owner' && a.$$typeof) { | |
| continue; | |
| } | |
| if (!deepEqual(a[key], b[key])) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| return a !== a && b !== b; | |
| } | |
| function getDPR(element) { | |
| if (typeof window === 'undefined') { | |
| return 1; | |
| } | |
| const win = element.ownerDocument.defaultView || window; | |
| return win.devicePixelRatio || 1; | |
| } | |
| function roundByDPR(element, value) { | |
| const dpr = getDPR(element); | |
| return Math.round(value * dpr) / dpr; | |
| } | |
| function useLatestRef(value) { | |
| const ref = React.useRef(value); | |
| index(() => { | |
| ref.current = value; | |
| }); | |
| return ref; | |
| } | |
| /** | |
| * Provides data to position a floating element. | |
| * @see https://floating-ui.com/docs/useFloating | |
| */ | |
| function useFloating(options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| const { | |
| placement = 'bottom', | |
| strategy = 'absolute', | |
| middleware = [], | |
| platform, | |
| elements: { | |
| reference: externalReference, | |
| floating: externalFloating | |
| } = {}, | |
| transform = true, | |
| whileElementsMounted, | |
| open | |
| } = options; | |
| const [data, setData] = React.useState({ | |
| x: 0, | |
| y: 0, | |
| strategy, | |
| placement, | |
| middlewareData: {}, | |
| isPositioned: false | |
| }); | |
| const [latestMiddleware, setLatestMiddleware] = React.useState(middleware); | |
| if (!deepEqual(latestMiddleware, middleware)) { | |
| setLatestMiddleware(middleware); | |
| } | |
| const [_reference, _setReference] = React.useState(null); | |
| const [_floating, _setFloating] = React.useState(null); | |
| const setReference = React.useCallback(node => { | |
| if (node !== referenceRef.current) { | |
| referenceRef.current = node; | |
| _setReference(node); | |
| } | |
| }, []); | |
| const setFloating = React.useCallback(node => { | |
| if (node !== floatingRef.current) { | |
| floatingRef.current = node; | |
| _setFloating(node); | |
| } | |
| }, []); | |
| const referenceEl = externalReference || _reference; | |
| const floatingEl = externalFloating || _floating; | |
| const referenceRef = React.useRef(null); | |
| const floatingRef = React.useRef(null); | |
| const dataRef = React.useRef(data); | |
| const hasWhileElementsMounted = whileElementsMounted != null; | |
| const whileElementsMountedRef = useLatestRef(whileElementsMounted); | |
| const platformRef = useLatestRef(platform); | |
| const openRef = useLatestRef(open); | |
| const update = React.useCallback(() => { | |
| if (!referenceRef.current || !floatingRef.current) { | |
| return; | |
| } | |
| const config = { | |
| placement, | |
| strategy, | |
| middleware: latestMiddleware | |
| }; | |
| if (platformRef.current) { | |
| config.platform = platformRef.current; | |
| } | |
| computePosition(referenceRef.current, floatingRef.current, config).then(data => { | |
| const fullData = { | |
| ...data, | |
| // The floating element's position may be recomputed while it's closed | |
| // but still mounted (such as when transitioning out). To ensure | |
| // `isPositioned` will be `false` initially on the next open, avoid | |
| // setting it to `true` when `open === false` (must be specified). | |
| isPositioned: openRef.current !== false | |
| }; | |
| if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) { | |
| dataRef.current = fullData; | |
| ReactDOM.flushSync(() => { | |
| setData(fullData); | |
| }); | |
| } | |
| }); | |
| }, [latestMiddleware, placement, strategy, platformRef, openRef]); | |
| index(() => { | |
| if (open === false && dataRef.current.isPositioned) { | |
| dataRef.current.isPositioned = false; | |
| setData(data => ({ | |
| ...data, | |
| isPositioned: false | |
| })); | |
| } | |
| }, [open]); | |
| const isMountedRef = React.useRef(false); | |
| index(() => { | |
| isMountedRef.current = true; | |
| return () => { | |
| isMountedRef.current = false; | |
| }; | |
| }, []); | |
| index(() => { | |
| if (referenceEl) referenceRef.current = referenceEl; | |
| if (floatingEl) floatingRef.current = floatingEl; | |
| if (referenceEl && floatingEl) { | |
| if (whileElementsMountedRef.current) { | |
| return whileElementsMountedRef.current(referenceEl, floatingEl, update); | |
| } | |
| update(); | |
| } | |
| }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]); | |
| const refs = React.useMemo(() => ({ | |
| reference: referenceRef, | |
| floating: floatingRef, | |
| setReference, | |
| setFloating | |
| }), [setReference, setFloating]); | |
| const elements = React.useMemo(() => ({ | |
| reference: referenceEl, | |
| floating: floatingEl | |
| }), [referenceEl, floatingEl]); | |
| const floatingStyles = React.useMemo(() => { | |
| const initialStyles = { | |
| position: strategy, | |
| left: 0, | |
| top: 0 | |
| }; | |
| if (!elements.floating) { | |
| return initialStyles; | |
| } | |
| const x = roundByDPR(elements.floating, data.x); | |
| const y = roundByDPR(elements.floating, data.y); | |
| if (transform) { | |
| return { | |
| ...initialStyles, | |
| transform: "translate(" + x + "px, " + y + "px)", | |
| ...(getDPR(elements.floating) >= 1.5 && { | |
| willChange: 'transform' | |
| }) | |
| }; | |
| } | |
| return { | |
| position: strategy, | |
| left: x, | |
| top: y | |
| }; | |
| }, [strategy, transform, elements.floating, data.x, data.y]); | |
| return React.useMemo(() => ({ | |
| ...data, | |
| update, | |
| refs, | |
| elements, | |
| floatingStyles | |
| }), [data, update, refs, elements, floatingStyles]); | |
| } | |
| /** | |
| * Provides data to position an inner element of the floating element so that it | |
| * appears centered to the reference element. | |
| * This wraps the core `arrow` middleware to allow React refs as the element. | |
| * @see https://floating-ui.com/docs/arrow | |
| */ | |
| const arrow$1 = options => { | |
| function isRef(value) { | |
| return {}.hasOwnProperty.call(value, 'current'); | |
| } | |
| return { | |
| name: 'arrow', | |
| options, | |
| fn(state) { | |
| const { | |
| element, | |
| padding | |
| } = typeof options === 'function' ? options(state) : options; | |
| if (element && isRef(element)) { | |
| if (element.current != null) { | |
| return arrow$2({ | |
| element: element.current, | |
| padding | |
| }).fn(state); | |
| } | |
| return {}; | |
| } | |
| if (element) { | |
| return arrow$2({ | |
| element, | |
| padding | |
| }).fn(state); | |
| } | |
| return {}; | |
| } | |
| }; | |
| }; | |
| /** | |
| * Modifies the placement by translating the floating element along the | |
| * specified axes. | |
| * A number (shorthand for `mainAxis` or distance), or an axes configuration | |
| * object may be passed. | |
| * @see https://floating-ui.com/docs/offset | |
| */ | |
| const offset = (options, deps) => ({ | |
| ...offset$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Optimizes the visibility of the floating element by shifting it in order to | |
| * keep it in view when it will overflow the clipping boundary. | |
| * @see https://floating-ui.com/docs/shift | |
| */ | |
| const shift = (options, deps) => ({ | |
| ...shift$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Built-in `limiter` that will stop `shift()` at a certain point. | |
| */ | |
| const limitShift = (options, deps) => ({ | |
| ...limitShift$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Optimizes the visibility of the floating element by flipping the `placement` | |
| * in order to keep it in view when the preferred placement(s) will overflow the | |
| * clipping boundary. Alternative to `autoPlacement`. | |
| * @see https://floating-ui.com/docs/flip | |
| */ | |
| const flip = (options, deps) => ({ | |
| ...flip$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Provides data that allows you to change the size of the floating element — | |
| * for instance, prevent it from overflowing the clipping boundary or match the | |
| * width of the reference element. | |
| * @see https://floating-ui.com/docs/size | |
| */ | |
| const size = (options, deps) => ({ | |
| ...size$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Optimizes the visibility of the floating element by choosing the placement | |
| * that has the most space available automatically, without needing to specify a | |
| * preferred placement. Alternative to `flip`. | |
| * @see https://floating-ui.com/docs/autoPlacement | |
| */ | |
| const autoPlacement = (options, deps) => ({ | |
| ...autoPlacement$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Provides data to hide the floating element in applicable situations, such as | |
| * when it is not in the same clipping context as the reference element. | |
| * @see https://floating-ui.com/docs/hide | |
| */ | |
| const hide = (options, deps) => ({ | |
| ...hide$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Provides improved positioning for inline reference elements that can span | |
| * over multiple lines, such as hyperlinks or range selections. | |
| * @see https://floating-ui.com/docs/inline | |
| */ | |
| const inline = (options, deps) => ({ | |
| ...inline$1(options), | |
| options: [options, deps] | |
| }); | |
| /** | |
| * Provides data to position an inner element of the floating element so that it | |
| * appears centered to the reference element. | |
| * This wraps the core `arrow` middleware to allow React refs as the element. | |
| * @see https://floating-ui.com/docs/arrow | |
| */ | |
| const arrow = (options, deps) => ({ | |
| ...arrow$1(options), | |
| options: [options, deps] | |
| }); | |
| export { arrow, autoPlacement, flip, hide, inline, limitShift, offset, shift, size, useFloating }; | |