Skip to content

Commit 83cbad8

Browse files
authored
feat: introduce useToggle hook (#220)
1 parent a8ecd70 commit 83cbad8

File tree

7 files changed

+110
-0
lines changed

7 files changed

+110
-0
lines changed

package-lock.json

+37
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
"dependencies": {
115115
"@datepicker-react/hooks": "^2.3.1",
116116
"@styled-system/theme-get": "^5.1.2",
117+
"@testing-library/react-hooks": "^8.0.0",
117118
"@types/react-select": "^3.0.13",
118119
"@types/styled-system": "^5.1.9",
119120
"date-fns": "^2.11.1",

src/hooks/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { useToggle } from './useToggle';

src/hooks/tests/useToggle.spec.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { act, cleanup, renderHook } from '@testing-library/react-hooks';
2+
3+
import { useToggle } from '../useToggle';
4+
5+
describe('useToggle hook', () => {
6+
afterEach(cleanup);
7+
8+
it('should return boolean and a function inside the Array', () => {
9+
const { result } = renderHook(() => useToggle());
10+
const [value, toggle] = result.current;
11+
12+
expect(typeof value).toBe('boolean');
13+
expect(typeof toggle).toBe('function');
14+
});
15+
16+
it('should toggle the value', () => {
17+
const { result } = renderHook(() => useToggle());
18+
const [, toggle] = result.current;
19+
20+
expect(result.current[0]).toBe(false);
21+
22+
act(() => {
23+
toggle();
24+
});
25+
expect(result.current[0]).toBe(true);
26+
27+
act(() => {
28+
toggle();
29+
});
30+
expect(result.current[0]).toBe(false);
31+
});
32+
33+
it('should set the boolean passed as argument', () => {
34+
const { result } = renderHook(() => useToggle());
35+
const [, toggle] = result.current;
36+
37+
act(() => {
38+
toggle(true);
39+
});
40+
expect(result.current[0]).toBe(true);
41+
42+
act(() => {
43+
toggle(true);
44+
});
45+
expect(result.current[0]).toBe(true);
46+
47+
act(() => {
48+
toggle(false);
49+
});
50+
expect(result.current[0]).toBe(false);
51+
});
52+
});

src/hooks/useToggle.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useReducer } from 'react';
2+
3+
export type DispatchWithOptionalAction<Type> = (_arg?: Type | unknown) => void;
4+
5+
export type UseToggleType<Type> = [Type, DispatchWithOptionalAction<Type>];
6+
7+
function toggle(currentValue: boolean, newValue: boolean | undefined) {
8+
return typeof newValue === 'boolean' ? newValue : !currentValue;
9+
}
10+
11+
function useToggle(initialValue = false): UseToggleType<boolean> {
12+
return useReducer(toggle, initialValue);
13+
}
14+
15+
export { useToggle };

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import './polyfills';
33
export * from './components';
44
export * from './essentials';
55
export * from './icons';
6+
export * from './hooks';
67
export { get as themeGet } from './utils/themeGet';

src/utils/hooks/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { useControlledState } from './useControlledState';
2+
export { useGeneratedId } from './useGeneratedId';
3+
export { useIsEscKeyPressed } from './useIsEscKeyPressed';

0 commit comments

Comments
 (0)