import {act, fireEvent, render, screen} from '@testing-library/react';
import {cloneElement, useState} from 'react';
import {vi} from 'vitest';
import {
FloatingDelayGroup,
useDelayGroup,
useDelayGroupContext,
useFloating,
useHover,
useInteractions,
} from '../../src';
vi.useFakeTimers();
interface Props {
label: string;
children: JSX.Element;
}
export const Tooltip = ({children, label}: Props) => {
const {delay} = useDelayGroupContext();
const [open, setOpen] = useState(false);
const {x, y, refs, strategy, context} = useFloating({
open,
onOpenChange: setOpen,
});
const {getReferenceProps} = useInteractions([
useHover(context, {delay}),
useDelayGroup(context, {id: label}),
]);
return (
<>
{cloneElement(
children,
getReferenceProps({
ref: refs.setReference,
...children.props,
}),
)}
{open && (
{label}
)}
>
);
};
function App() {
return (
);
}
test('groups delays correctly', async () => {
render();
fireEvent.mouseEnter(screen.getByTestId('reference-one'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-one')).not.toBeInTheDocument();
await act(async () => {
vi.advanceTimersByTime(999);
});
expect(screen.queryByTestId('floating-one')).toBeInTheDocument();
fireEvent.mouseEnter(screen.getByTestId('reference-two'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-one')).not.toBeInTheDocument();
expect(screen.queryByTestId('floating-two')).toBeInTheDocument();
fireEvent.mouseEnter(screen.getByTestId('reference-three'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-two')).not.toBeInTheDocument();
expect(screen.queryByTestId('floating-three')).toBeInTheDocument();
fireEvent.mouseLeave(screen.getByTestId('reference-three'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-three')).toBeInTheDocument();
await act(async () => {
vi.advanceTimersByTime(199);
});
expect(screen.queryByTestId('floating-three')).not.toBeInTheDocument();
});
test('timeoutMs', async () => {
function App() {
return (
);
}
render();
fireEvent.mouseEnter(screen.getByTestId('reference-one'));
await act(async () => {
vi.advanceTimersByTime(1000);
});
fireEvent.mouseLeave(screen.getByTestId('reference-one'));
expect(screen.queryByTestId('floating-one')).toBeInTheDocument();
await act(async () => {
vi.advanceTimersByTime(499);
});
expect(screen.queryByTestId('floating-one')).not.toBeInTheDocument();
fireEvent.mouseEnter(screen.getByTestId('reference-two'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-two')).toBeInTheDocument();
fireEvent.mouseEnter(screen.getByTestId('reference-three'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-two')).not.toBeInTheDocument();
expect(screen.queryByTestId('floating-three')).toBeInTheDocument();
fireEvent.mouseLeave(screen.getByTestId('reference-three'));
await act(async () => {
vi.advanceTimersByTime(1);
});
expect(screen.queryByTestId('floating-three')).toBeInTheDocument();
await act(async () => {
vi.advanceTimersByTime(99);
});
expect(screen.queryByTestId('floating-three')).not.toBeInTheDocument();
});