react-essentials-functions 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +514 -3
- package/build/components/ConditionnalWrapper.d.ts +20 -3
- package/build/components/ConditionnalWrapper.js +19 -7
- package/build/hooks/index.d.ts +6 -0
- package/build/hooks/index.js +6 -0
- package/build/hooks/useClickOutside.d.ts +23 -0
- package/build/hooks/useClickOutside.js +42 -0
- package/build/hooks/useDebounce.d.ts +21 -0
- package/build/hooks/useDebounce.js +36 -0
- package/build/hooks/useDimensions.d.ts +22 -2
- package/build/hooks/useDimensions.js +53 -17
- package/build/hooks/useLocalStorage.d.ts +22 -0
- package/build/hooks/useLocalStorage.js +61 -0
- package/build/hooks/useMediaQuery.d.ts +17 -0
- package/build/hooks/useMediaQuery.js +43 -0
- package/build/hooks/usePrevious.d.ts +20 -0
- package/build/hooks/usePrevious.js +30 -0
- package/build/hooks/useSafeFetch.d.ts +26 -1
- package/build/hooks/useSafeFetch.js +43 -5
- package/build/hooks/useSafeState.d.ts +3 -1
- package/build/hooks/useSafeState.js +1 -2
- package/build/hooks/useScript.d.ts +36 -1
- package/build/hooks/useScript.js +55 -3
- package/build/hooks/useTheme.d.ts +24 -2
- package/build/hooks/useTheme.js +71 -9
- package/build/hooks/useToggle.d.ts +22 -0
- package/build/hooks/useToggle.js +38 -0
- package/build/hooks/useWindowDimensions.d.ts +22 -3
- package/build/hooks/useWindowDimensions.js +35 -16
- package/package.json +39 -59
package/build/hooks/useTheme.js
CHANGED
|
@@ -2,20 +2,82 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useTheme = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
+
const STORAGE_KEY = 'theme';
|
|
6
|
+
function getSystemTheme() {
|
|
7
|
+
if (typeof window === 'undefined') {
|
|
8
|
+
return 'light';
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
12
|
+
? 'dark'
|
|
13
|
+
: 'light';
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return 'light';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function getStoredTheme() {
|
|
20
|
+
try {
|
|
21
|
+
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
22
|
+
if (stored === 'light' || stored === 'dark') {
|
|
23
|
+
return stored;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Hook to manage theme (light/dark) with localStorage persistence.
|
|
33
|
+
* Automatically detects system color scheme preference.
|
|
34
|
+
*
|
|
35
|
+
* @returns A tuple containing:
|
|
36
|
+
* - current theme mode ('light' | 'dark')
|
|
37
|
+
* - function to toggle between themes
|
|
38
|
+
* - boolean indicating if the component is mounted (useful for SSR)
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* const [theme, toggleTheme, mounted] = useTheme();
|
|
43
|
+
*
|
|
44
|
+
* if (!mounted) return null; // Avoid hydration mismatch
|
|
45
|
+
*
|
|
46
|
+
* return (
|
|
47
|
+
* <button onClick={toggleTheme}>
|
|
48
|
+
* Switch to {theme === 'light' ? 'dark' : 'light'} mode
|
|
49
|
+
* </button>
|
|
50
|
+
* );
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
5
53
|
const useTheme = () => {
|
|
6
54
|
const [theme, setTheme] = (0, react_1.useState)('light');
|
|
7
55
|
const [mountedComponent, setMountedComponent] = (0, react_1.useState)(false);
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
56
|
+
const themeToggler = (0, react_1.useCallback)(() => {
|
|
57
|
+
setTheme((prevTheme) => {
|
|
58
|
+
const newTheme = prevTheme === 'light' ? 'dark' : 'light';
|
|
59
|
+
try {
|
|
60
|
+
window.localStorage.setItem(STORAGE_KEY, newTheme);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// localStorage may not be available
|
|
64
|
+
}
|
|
65
|
+
return newTheme;
|
|
66
|
+
});
|
|
67
|
+
}, []);
|
|
15
68
|
(0, react_1.useEffect)(() => {
|
|
16
|
-
const localTheme = window.localStorage.getItem('theme');
|
|
17
|
-
localTheme ? setTheme(localTheme) : setMode('light');
|
|
18
69
|
setMountedComponent(true);
|
|
70
|
+
const stored = getStoredTheme();
|
|
71
|
+
const initial = stored ?? getSystemTheme();
|
|
72
|
+
setTheme(initial);
|
|
73
|
+
if (!stored) {
|
|
74
|
+
try {
|
|
75
|
+
window.localStorage.setItem(STORAGE_KEY, initial);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// localStorage may not be available
|
|
79
|
+
}
|
|
80
|
+
}
|
|
19
81
|
}, []);
|
|
20
82
|
return [theme, themeToggler, mountedComponent];
|
|
21
83
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for managing a boolean toggle state.
|
|
3
|
+
* Provides a simple API for toggling, setting true, or setting false.
|
|
4
|
+
*
|
|
5
|
+
* @param initialValue - The initial boolean value (default: false)
|
|
6
|
+
* @returns A tuple of [value, toggle, setTrue, setFalse]
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* const [isOpen, toggleOpen, open, close] = useToggle(false);
|
|
11
|
+
*
|
|
12
|
+
* return (
|
|
13
|
+
* <div>
|
|
14
|
+
* <button onClick={toggleOpen}>Toggle</button>
|
|
15
|
+
* <button onClick={open}>Open</button>
|
|
16
|
+
* <button onClick={close}>Close</button>
|
|
17
|
+
* {isOpen && <Modal />}
|
|
18
|
+
* </div>
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useToggle(initialValue?: boolean): [boolean, () => void, () => void, () => void];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useToggle = useToggle;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
/**
|
|
6
|
+
* Hook for managing a boolean toggle state.
|
|
7
|
+
* Provides a simple API for toggling, setting true, or setting false.
|
|
8
|
+
*
|
|
9
|
+
* @param initialValue - The initial boolean value (default: false)
|
|
10
|
+
* @returns A tuple of [value, toggle, setTrue, setFalse]
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const [isOpen, toggleOpen, open, close] = useToggle(false);
|
|
15
|
+
*
|
|
16
|
+
* return (
|
|
17
|
+
* <div>
|
|
18
|
+
* <button onClick={toggleOpen}>Toggle</button>
|
|
19
|
+
* <button onClick={open}>Open</button>
|
|
20
|
+
* <button onClick={close}>Close</button>
|
|
21
|
+
* {isOpen && <Modal />}
|
|
22
|
+
* </div>
|
|
23
|
+
* );
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function useToggle(initialValue = false) {
|
|
27
|
+
const [value, setValue] = (0, react_1.useState)(initialValue);
|
|
28
|
+
const toggle = (0, react_1.useCallback)(() => {
|
|
29
|
+
setValue((prev) => !prev);
|
|
30
|
+
}, []);
|
|
31
|
+
const setTrue = (0, react_1.useCallback)(() => {
|
|
32
|
+
setValue(true);
|
|
33
|
+
}, []);
|
|
34
|
+
const setFalse = (0, react_1.useCallback)(() => {
|
|
35
|
+
setValue(false);
|
|
36
|
+
}, []);
|
|
37
|
+
return [value, toggle, setTrue, setFalse];
|
|
38
|
+
}
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
export
|
|
2
|
-
width: number
|
|
3
|
-
height: number
|
|
1
|
+
export type WindowDimensions = {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
4
|
};
|
|
5
|
+
/**
|
|
6
|
+
* Hook to get the current window dimensions.
|
|
7
|
+
* Automatically updates on resize with debounce for performance.
|
|
8
|
+
*
|
|
9
|
+
* @returns Object containing width and height of the window
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const { width, height } = useWindowDimensions();
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <div>
|
|
17
|
+
* Window size: {width} x {height}
|
|
18
|
+
* </div>
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useWindowDimensions(): WindowDimensions;
|
|
23
|
+
export default useWindowDimensions;
|
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useWindowDimensions = useWindowDimensions;
|
|
3
4
|
const react_1 = require("react");
|
|
5
|
+
/**
|
|
6
|
+
* Hook to get the current window dimensions.
|
|
7
|
+
* Automatically updates on resize with debounce for performance.
|
|
8
|
+
*
|
|
9
|
+
* @returns Object containing width and height of the window
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const { width, height } = useWindowDimensions();
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <div>
|
|
17
|
+
* Window size: {width} x {height}
|
|
18
|
+
* </div>
|
|
19
|
+
* );
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
4
22
|
function useWindowDimensions() {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
23
|
+
const getWindowDimensions = (0, react_1.useCallback)(() => {
|
|
24
|
+
if (typeof window === 'undefined') {
|
|
25
|
+
return { width: 0, height: 0 };
|
|
26
|
+
}
|
|
9
27
|
return {
|
|
10
|
-
width,
|
|
11
|
-
height,
|
|
28
|
+
width: window.innerWidth,
|
|
29
|
+
height: window.innerHeight,
|
|
12
30
|
};
|
|
13
|
-
}
|
|
14
|
-
const [windowDimensions, setWindowDimensions] = (0, react_1.useState)(getWindowDimensions
|
|
31
|
+
}, []);
|
|
32
|
+
const [windowDimensions, setWindowDimensions] = (0, react_1.useState)(getWindowDimensions);
|
|
15
33
|
(0, react_1.useEffect)(() => {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
function handleResize() {
|
|
19
|
-
setWindowDimensions(getWindowDimensions());
|
|
20
|
-
}
|
|
21
|
-
window.addEventListener('resize', handleResize);
|
|
22
|
-
return () => window.removeEventListener('resize', handleResize);
|
|
34
|
+
if (typeof window === 'undefined') {
|
|
35
|
+
return;
|
|
23
36
|
}
|
|
24
|
-
|
|
37
|
+
const handleResize = () => {
|
|
38
|
+
setWindowDimensions(getWindowDimensions());
|
|
39
|
+
};
|
|
40
|
+
window.addEventListener('resize', handleResize);
|
|
41
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
42
|
+
}, [getWindowDimensions]);
|
|
25
43
|
return windowDimensions;
|
|
26
44
|
}
|
|
45
|
+
// Keep default export for backwards compatibility
|
|
27
46
|
exports.default = useWindowDimensions;
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-essentials-functions",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"author": "maxgfr",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"description": "A collection of zero-
|
|
6
|
+
"description": "A collection of zero-dependency useful hooks and components for React",
|
|
7
7
|
"main": "./build/index.js",
|
|
8
|
+
"types": "./build/index.d.ts",
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
10
11
|
"url": "https://github.com/maxgfr/react-essentials-functions.git"
|
|
@@ -24,73 +25,52 @@
|
|
|
24
25
|
"zero-dependencies"
|
|
25
26
|
],
|
|
26
27
|
"scripts": {
|
|
27
|
-
"
|
|
28
|
-
"develop": "node -r @swc-node/register ./src/index.ts",
|
|
29
|
-
"test": "jest --passWithNoTests",
|
|
28
|
+
"test": "jest",
|
|
30
29
|
"test:watch": "jest --watch",
|
|
30
|
+
"test:coverage": "jest --coverage",
|
|
31
31
|
"clean": "rimraf build",
|
|
32
32
|
"build": "tsc -p tsconfig.build.json",
|
|
33
33
|
"build:watch": "tsc -w -p tsconfig.build.json",
|
|
34
|
-
"
|
|
35
|
-
"build:swc:watch": "swc ./src -d build -w",
|
|
34
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
36
35
|
"lint": "eslint ./src --ext .ts,.tsx",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"storybook:deploy": "npm run storybook:build && gh-pages -d storybook-static",
|
|
41
|
-
"storybook:deploy:action": "npm run storybook:build && gh-pages -d storybook-static -u \"github-actions-bot <support+actions@github.com>\"",
|
|
36
|
+
"format": "prettier --write './src/**/*.{ts,js,json,tsx,jsx}'",
|
|
37
|
+
"format:check": "prettier --check './src/**/*.{ts,js,json,tsx,jsx}'",
|
|
38
|
+
"ci": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run test:coverage",
|
|
42
39
|
"release": "semantic-release"
|
|
43
40
|
},
|
|
44
41
|
"peerDependencies": {
|
|
45
|
-
"react": "
|
|
46
|
-
"react-dom": "
|
|
42
|
+
"react": ">=17.0.0",
|
|
43
|
+
"react-dom": ">=17.0.0"
|
|
47
44
|
},
|
|
48
45
|
"devDependencies": {
|
|
49
|
-
"@
|
|
50
|
-
"@semantic-release/changelog": "^6.0.2",
|
|
51
|
-
"@semantic-release/commit-analyzer": "^9.0.2",
|
|
46
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
52
47
|
"@semantic-release/git": "^10.0.1",
|
|
53
|
-
"@semantic-release/github": "^
|
|
54
|
-
"@semantic-release/npm": "^
|
|
55
|
-
"@semantic-release/release-notes-generator": "^
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"@
|
|
60
|
-
"@
|
|
61
|
-
"@
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"eslint-config-prettier": "8.5.0",
|
|
81
|
-
"eslint-plugin-jest": "27.1.5",
|
|
82
|
-
"eslint-plugin-jsx-a11y": "^6.6.1",
|
|
83
|
-
"eslint-plugin-react": "^7.31.10",
|
|
84
|
-
"eslint-plugin-storybook": "^0.6.7",
|
|
85
|
-
"gh-pages": "^4.0.0",
|
|
86
|
-
"jest": "29.3.1",
|
|
87
|
-
"jest-environment-jsdom": "^29.3.0",
|
|
88
|
-
"nodemon": "2.0.20",
|
|
89
|
-
"prettier": "2.7.1",
|
|
90
|
-
"react": "^18.2.0",
|
|
91
|
-
"react-dom": "^18.2.0",
|
|
92
|
-
"rimraf": "3.0.2",
|
|
93
|
-
"semantic-release": "^19.0.5",
|
|
94
|
-
"typescript": "^4.8.4"
|
|
48
|
+
"@semantic-release/github": "^12.0.5",
|
|
49
|
+
"@semantic-release/npm": "^13.1.4",
|
|
50
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
51
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
52
|
+
"@testing-library/react": "^16.3.2",
|
|
53
|
+
"@testing-library/user-event": "^14.6.1",
|
|
54
|
+
"@types/jest": "^29.5.14",
|
|
55
|
+
"@types/node": "^22.19.9",
|
|
56
|
+
"@types/react": "^18.3.28",
|
|
57
|
+
"@types/react-dom": "^18.3.7",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
59
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
60
|
+
"eslint": "^8.57.1",
|
|
61
|
+
"eslint-config-prettier": "^10.1.8",
|
|
62
|
+
"eslint-plugin-jest": "^28.14.0",
|
|
63
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
64
|
+
"eslint-plugin-react": "^7.37.5",
|
|
65
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
68
|
+
"prettier": "^3.8.1",
|
|
69
|
+
"react": "^18.3.1",
|
|
70
|
+
"react-dom": "^18.3.1",
|
|
71
|
+
"rimraf": "^6.1.2",
|
|
72
|
+
"semantic-release": "^25.0.3",
|
|
73
|
+
"ts-jest": "^29.4.6",
|
|
74
|
+
"typescript": "^5.9.3"
|
|
95
75
|
}
|
|
96
76
|
}
|