Skip to content

Commit c4e7061

Browse files
committed
main 🧊 add use hover test
1 parent 2ba3d0d commit c4e7061

File tree

4 files changed

+128
-86
lines changed

4 files changed

+128
-86
lines changed

‎packages/core/src/bundle/hooks/useHover/useHover.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { useRefState } from '../useRefState/useRefState';
2626
* @overload
2727
* @template Target The target element
2828
* @param {(event: Event) => void} [callback] The callback function to be invoked on mouse enter
29-
* @returns {UseHoverReturn<Target>} The state of the hover
29+
* @returns {{ ref: StateRef<Target> } & UseHoverReturn} The state of the hover
3030
*
3131
* @example
3232
* const [ref, hovering] = useHover(() => console.log('callback'));
@@ -35,7 +35,7 @@ import { useRefState } from '../useRefState/useRefState';
3535
* @template Target The target element
3636
* @param {(event: Event) => void} [options.onEntry] The callback function to be invoked on mouse enter
3737
* @param {(event: Event) => void} [options.onLeave] The callback function to be invoked on mouse leave
38-
* @returns {UseHoverReturn<Target>} The state of the hover
38+
* @returns {{ ref: StateRef<Target> } & UseHoverReturn} The state of the hover
3939
*
4040
* @example
4141
* const [ref, hovering] = useHover(options);
@@ -73,5 +73,8 @@ export const useHover = (...params) => {
7373
};
7474
}, [target, internalRef.state]);
7575
if (target) return hovering;
76-
return [internalRef, hovering];
76+
return {
77+
ref: internalRef,
78+
value: hovering
79+
};
7780
};
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { act, renderHook } from '@testing-library/react';
2+
3+
import { target } from '@/utils/helpers';
4+
5+
import type { StateRef } from '../useRefState/useRefState';
6+
import type { UseHoverReturn } from './useHover';
7+
8+
import { useHover } from './useHover';
9+
10+
const targets = [
11+
undefined,
12+
target('#target'),
13+
target(document.getElementById('target')!),
14+
target(() => document.getElementById('target')!),
15+
{ current: document.getElementById('target') }
16+
];
17+
const element = document.getElementById('target')! as HTMLDivElement;
18+
19+
targets.forEach((target) => {
20+
describe(`${target}`, () => {
21+
it('Should use hover', () => {
22+
const { result } = renderHook(() => {
23+
if (target)
24+
return useHover(target) as unknown as {
25+
ref: StateRef<HTMLDivElement>;
26+
} & UseHoverReturn;
27+
return useHover<HTMLDivElement>();
28+
});
29+
30+
if (!target) act(() => result.current.ref(element));
31+
32+
if (target) expect(result.current).toBe(false);
33+
if (!target) {
34+
expect(result.current.value).toBe(false);
35+
expect(result.current.ref).toBeTypeOf('function');
36+
}
37+
});
38+
39+
it('Should change value on hover events', () => {
40+
const { result } = renderHook(() => {
41+
if (target)
42+
return useHover(target) as unknown as {
43+
ref: StateRef<HTMLDivElement>;
44+
} & UseHoverReturn;
45+
return useHover<HTMLDivElement>();
46+
});
47+
48+
if (!target) act(() => result.current.ref(element));
49+
50+
if (target) expect(result.current).toBe(false);
51+
if (!target) expect(result.current.value).toBe(false);
52+
53+
act(() => element.dispatchEvent(new Event('mouseenter')));
54+
55+
if (target) expect(result.current).toBe(true);
56+
if (!target) expect(result.current.value).toBe(true);
57+
58+
act(() => element.dispatchEvent(new Event('mouseleave')));
59+
60+
if (target) expect(result.current).toBe(false);
61+
if (!target) expect(result.current.value).toBe(false);
62+
});
63+
64+
it('Should call callback on hover', () => {
65+
const callback = vi.fn();
66+
67+
const { result } = renderHook(() => {
68+
if (target)
69+
return useHover(target, callback) as unknown as {
70+
ref: StateRef<HTMLDivElement>;
71+
} & UseHoverReturn;
72+
return useHover<HTMLDivElement>(callback);
73+
});
74+
75+
if (!target) act(() => result.current.ref(element));
76+
77+
act(() => element.dispatchEvent(new Event('mouseenter')));
78+
79+
expect(callback).toHaveBeenCalledTimes(1);
80+
});
81+
82+
it('Should call onEntry and onLeave callbacks', () => {
83+
const onEntry = vi.fn();
84+
const onLeave = vi.fn();
85+
86+
const { result } = renderHook(() => {
87+
if (target)
88+
return useHover(target, { onEntry, onLeave }) as unknown as {
89+
ref: StateRef<HTMLDivElement>;
90+
} & UseHoverReturn;
91+
return useHover<HTMLDivElement>({ onEntry, onLeave });
92+
});
93+
94+
if (!target) act(() => result.current.ref(element));
95+
96+
act(() => element.dispatchEvent(new Event('mouseenter')));
97+
98+
expect(onEntry).toHaveBeenCalledTimes(1);
99+
expect(onLeave).not.toHaveBeenCalled();
100+
101+
act(() => element.dispatchEvent(new Event('mouseleave')));
102+
103+
expect(onEntry).toHaveBeenCalledTimes(1);
104+
expect(onLeave).toHaveBeenCalledTimes(1);
105+
});
106+
});
107+
});

‎packages/core/src/hooks/useHover/useHover.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export interface UseHoverOptions {
1616
onLeave?: (event: Event) => void;
1717
}
1818

19+
export interface UseHoverReturn {
20+
value: boolean;
21+
}
22+
1923
export interface UseHover {
2024
(target: HookTarget, callback?: (event: Event) => void): boolean;
2125

@@ -24,9 +28,12 @@ export interface UseHover {
2428
<Target extends Element>(
2529
callback?: (event: Event) => void,
2630
target?: never
27-
): [StateRef<Target>, boolean];
31+
): { ref: StateRef<Target> } & UseHoverReturn;
2832

29-
<Target extends Element>(options?: UseHoverOptions, target?: never): [StateRef<Target>, boolean];
33+
<Target extends Element>(
34+
options?: UseHoverOptions,
35+
target?: never
36+
): { ref: StateRef<Target> } & UseHoverReturn;
3037
}
3138

3239
/**
@@ -54,7 +61,7 @@ export interface UseHover {
5461
* @overload
5562
* @template Target The target element
5663
* @param {(event: Event) => void} [callback] The callback function to be invoked on mouse enter
57-
* @returns {UseHoverReturn<Target>} The state of the hover
64+
* @returns {{ ref: StateRef<Target> } & UseHoverReturn} The state of the hover
5865
*
5966
* @example
6067
* const [ref, hovering] = useHover(() => console.log('callback'));
@@ -63,7 +70,7 @@ export interface UseHover {
6370
* @template Target The target element
6471
* @param {(event: Event) => void} [options.onEntry] The callback function to be invoked on mouse enter
6572
* @param {(event: Event) => void} [options.onLeave] The callback function to be invoked on mouse leave
66-
* @returns {UseHoverReturn<Target>} The state of the hover
73+
* @returns {{ ref: StateRef<Target> } & UseHoverReturn} The state of the hover
6774
*
6875
* @example
6976
* const [ref, hovering] = useHover(options);
@@ -112,5 +119,8 @@ export const useHover = ((...params: any[]) => {
112119
}, [target, internalRef.state]);
113120

114121
if (target) return hovering;
115-
return [internalRef, hovering] as const;
122+
return {
123+
ref: internalRef,
124+
value: hovering
125+
} as const;
116126
}) as UseHover;

‎src/hooks/useHover/useHover.test.ts

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)