import {isElement} from '@floating-ui/utils/dom'; import {act, render, screen} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import {useCallback, useLayoutEffect, useState} from 'react'; import {vi} from 'vitest'; import { useClick, useDismiss, useFloating, useFocus, useHover, useInteractions, } from '../../src'; describe('positionReference', () => { test('sets separate refs', () => { function App() { const {refs} = useFloating(); return ( <>
{String(refs.domReference.current?.getAttribute('data-testid'))}
{String(isElement(refs.reference.current))}
); } const {getByTestId, rerender} = render(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('false'); rerender(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('false'); }); test('handles unstable reference prop', () => { function App() { const {refs} = useFloating(); return ( <>
refs.setReference(node)} data-testid="reference" />
{String(refs.domReference.current?.getAttribute('data-testid'))}
{String(isElement(refs.reference.current))}
); } const {getByTestId, rerender} = render(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('false'); rerender(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('false'); }); test('handles real virtual element', () => { function App() { const {refs} = useFloating(); useLayoutEffect(() => { refs.setPositionReference({ getBoundingClientRect: () => ({ x: 218, y: 0, width: 0, height: 0, left: 0, right: 0, top: 0, bottom: 0, }), }); }, [refs]); return ( <>
refs.setReference(node)} data-testid="reference" />
{String(refs.domReference.current?.getAttribute('data-testid'))}
{refs.reference.current?.getBoundingClientRect().x}
); } const {getByTestId, rerender} = render(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('218'); rerender(); expect(getByTestId('reference-text').textContent).toBe('reference'); expect(getByTestId('position-reference-text').textContent).toBe('218'); }); }); test('#2129: interactions.getFloatingProps as a dep does not cause setState loop', () => { function App() { const {refs, context} = useFloating({ open: true, }); const interactions = useInteractions([ useHover(context), useClick(context), useFocus(context), useDismiss(context), ]); const Tooltip = useCallback(() => { return (
); }, [refs, interactions]); return ( <>
); } render(); expect(screen.queryByTestId('floating')).toBeInTheDocument(); }); test('domReference refers to externally synchronized `reference`', async () => { function App() { const [referenceEl, setReferenceEl] = useState(null); const [isOpen, setIsOpen] = useState(false); const {refs, context} = useFloating({ open: isOpen, onOpenChange: setIsOpen, elements: {reference: referenceEl}, }); const hover = useHover(context); const {getReferenceProps, getFloatingProps} = useInteractions([hover]); return ( <>