Files
react/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
2025-12-28 20:50:08 +00:00

221 lines
5.7 KiB
JavaScript

import { arrow as arrow$1, computePosition } from '@floating-ui/dom';
export { autoPlacement, autoUpdate, computePosition, detectOverflow, flip, getOverflowAncestors, hide, inline, limitShift, offset, platform, shift, size } from '@floating-ui/dom';
import * as React from 'react';
import { useLayoutEffect, useEffect } from 'react';
import * as ReactDOM from 'react-dom';
/**
* A data provider that provides data to position an inner element of the
* floating element (usually a triangle or caret) so that it is 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 => {
const {
element,
padding
} = options;
function isRef(value) {
return Object.prototype.hasOwnProperty.call(value, 'current');
}
return {
name: 'arrow',
options,
fn(args) {
if (isRef(element)) {
if (element.current != null) {
return arrow$1({
element: element.current,
padding
}).fn(args);
}
return {};
} else if (element) {
return arrow$1({
element,
padding
}).fn(args);
}
return {};
}
};
};
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, i, 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 (!Object.prototype.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 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/react
*/
function useFloating(options) {
if (options === void 0) {
options = {};
}
const {
placement = 'bottom',
strategy = 'absolute',
middleware = [],
platform,
whileElementsMounted,
open
} = options;
const [data, setData] = React.useState({
x: null,
y: null,
strategy,
placement,
middlewareData: {},
isPositioned: false
});
const [latestMiddleware, setLatestMiddleware] = React.useState(middleware);
if (!deepEqual(latestMiddleware, middleware)) {
setLatestMiddleware(middleware);
}
const referenceRef = React.useRef(null);
const floatingRef = React.useRef(null);
const dataRef = React.useRef(data);
const whileElementsMountedRef = useLatestRef(whileElementsMounted);
const platformRef = useLatestRef(platform);
const [reference, _setReference] = React.useState(null);
const [floating, _setFloating] = React.useState(null);
const setReference = React.useCallback(node => {
if (referenceRef.current !== node) {
referenceRef.current = node;
_setReference(node);
}
}, []);
const setFloating = React.useCallback(node => {
if (floatingRef.current !== node) {
floatingRef.current = node;
_setFloating(node);
}
}, []);
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,
isPositioned: true
};
if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
dataRef.current = fullData;
ReactDOM.flushSync(() => {
setData(fullData);
});
}
});
}, [latestMiddleware, placement, strategy, platformRef]);
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 (reference && floating) {
if (whileElementsMountedRef.current) {
return whileElementsMountedRef.current(reference, floating, update);
} else {
update();
}
}
}, [reference, floating, update, whileElementsMountedRef]);
const refs = React.useMemo(() => ({
reference: referenceRef,
floating: floatingRef,
setReference,
setFloating
}), [setReference, setFloating]);
const elements = React.useMemo(() => ({
reference,
floating
}), [reference, floating]);
return React.useMemo(() => ({
...data,
update,
refs,
elements,
reference: setReference,
floating: setFloating
}), [data, update, refs, elements, setReference, setFloating]);
}
export { arrow, useFloating };