@ttoss/react-hooks 2.0.8 → 2.0.10
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 +44 -34
- package/dist/esm/index.js +111 -16
- package/dist/index.d.ts +17 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,35 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## 📚 About
|
|
4
4
|
|
|
5
|
-
**@ttoss/react-hooks** is
|
|
5
|
+
**@ttoss/react-hooks** is a collection of custom React hooks that can be used to simplify the development of React applications.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```shell
|
|
12
|
-
$ yarn add @ttoss/react-hooks
|
|
13
|
-
# or
|
|
14
|
-
$ npm install @ttoss/react-hooks
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @ttoss/react-hooks
|
|
15
11
|
```
|
|
16
12
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
### useScript
|
|
20
|
-
|
|
21
|
-
The `useScript` hook is used to load external scripts into your React component.
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
import React from 'react';
|
|
25
|
-
import { useScript } from '@ttoss/react-hooks';
|
|
26
|
-
|
|
27
|
-
export const ComponentWithScript = () => {
|
|
28
|
-
const url = 'https://your-domain.com/bundle-api.js';
|
|
29
|
-
const { status } = useScript(url);
|
|
30
|
-
|
|
31
|
-
return <div>{status === 'ready' ? 'Script loaded' : 'Loading'}</div>;
|
|
32
|
-
};
|
|
33
|
-
```
|
|
13
|
+
## API
|
|
34
14
|
|
|
35
15
|
### useDebounce
|
|
36
16
|
|
|
@@ -55,20 +35,50 @@ export const DebouncedInputComponent = () => {
|
|
|
55
35
|
};
|
|
56
36
|
```
|
|
57
37
|
|
|
58
|
-
|
|
38
|
+
### useLocalStorage
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
The `useLocalStorage` hook is used to store and retrieve values from the local storage.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import * as React from 'react';
|
|
44
|
+
import { useLocalStorage } from '@ttoss/react-hooks';
|
|
61
45
|
|
|
62
|
-
|
|
63
|
-
|
|
46
|
+
export const LocalStorageComponent = () => {
|
|
47
|
+
const [value, setValue] = useLocalStorage('key', 'default value');
|
|
64
48
|
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
return (
|
|
50
|
+
<div>
|
|
51
|
+
<input
|
|
52
|
+
type="text"
|
|
53
|
+
value={value}
|
|
54
|
+
onChange={(e) => setValue(e.target.value)}
|
|
55
|
+
placeholder="Type to save..."
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
67
59
|
};
|
|
68
60
|
```
|
|
69
61
|
|
|
70
|
-
|
|
62
|
+
It uses the `localStorage` storage by default, but you can also use the `sessionStorage` storage by passing the `Storage` option.
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
const [value, setValue] = useLocalStorage('key', 'default value', {
|
|
66
|
+
storage: window.sessionStorage,
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### useScript
|
|
71
|
+
|
|
72
|
+
The `useScript` hook is used to load external scripts into your React component.
|
|
71
73
|
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
+
```tsx
|
|
75
|
+
import React from 'react';
|
|
76
|
+
import { useScript } from '@ttoss/react-hooks';
|
|
77
|
+
|
|
78
|
+
export const ComponentWithScript = () => {
|
|
79
|
+
const url = 'https://your-domain.com/bundle-api.js';
|
|
80
|
+
const { status } = useScript(url);
|
|
81
|
+
|
|
82
|
+
return <div>{status === 'ready' ? 'Script loaded' : 'Loading'}</div>;
|
|
83
|
+
};
|
|
74
84
|
```
|
package/dist/esm/index.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
2
|
|
|
3
|
-
// src/
|
|
3
|
+
// src/useDebounce.ts
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
var
|
|
6
|
-
const [
|
|
5
|
+
var useDebounce = (value, delay) => {
|
|
6
|
+
const [debouncedValue, setDebouncedValue] = React.useState(value);
|
|
7
7
|
React.useEffect(() => {
|
|
8
|
+
const timer = setTimeout(() => {
|
|
9
|
+
return setDebouncedValue(value);
|
|
10
|
+
}, delay || 500);
|
|
11
|
+
return () => {
|
|
12
|
+
clearTimeout(timer);
|
|
13
|
+
};
|
|
14
|
+
}, [value, delay]);
|
|
15
|
+
return debouncedValue;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/useScript.ts
|
|
19
|
+
import * as React2 from "react";
|
|
20
|
+
var useScript = src => {
|
|
21
|
+
const [status, setStatus] = React2.useState(src ? "loading" : "idle");
|
|
22
|
+
React2.useEffect(() => {
|
|
8
23
|
if (!src) {
|
|
9
24
|
setStatus("idle");
|
|
10
25
|
return;
|
|
@@ -47,18 +62,98 @@ var useScript = src => {
|
|
|
47
62
|
};
|
|
48
63
|
};
|
|
49
64
|
|
|
50
|
-
// src/
|
|
51
|
-
import * as
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
// src/useStorage.ts
|
|
66
|
+
import * as React3 from "react";
|
|
67
|
+
function useStorage(key, defaultValue, options) {
|
|
68
|
+
const opts = React3.useMemo(() => {
|
|
69
|
+
return {
|
|
70
|
+
serializer: JSON.stringify,
|
|
71
|
+
parser: JSON.parse,
|
|
72
|
+
// eslint-disable-next-line no-console
|
|
73
|
+
logger: console.log,
|
|
74
|
+
syncData: true,
|
|
75
|
+
...options
|
|
76
|
+
};
|
|
77
|
+
}, [options]);
|
|
78
|
+
const {
|
|
79
|
+
serializer,
|
|
80
|
+
parser,
|
|
81
|
+
logger,
|
|
82
|
+
syncData,
|
|
83
|
+
storage
|
|
84
|
+
} = opts;
|
|
85
|
+
const effectiveStorage = storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
|
|
86
|
+
const rawValueRef = React3.useRef(null);
|
|
87
|
+
const [value, setValue] = React3.useState(() => {
|
|
88
|
+
if (typeof window === "undefined" || !effectiveStorage) {
|
|
89
|
+
return defaultValue;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
rawValueRef.current = effectiveStorage.getItem(key);
|
|
93
|
+
const res = rawValueRef.current ? parser(rawValueRef.current) : defaultValue;
|
|
94
|
+
return res;
|
|
95
|
+
} catch (e) {
|
|
96
|
+
logger(e);
|
|
97
|
+
return defaultValue;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
React3.useEffect(() => {
|
|
101
|
+
if (typeof window === "undefined" || !effectiveStorage) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const updateLocalStorage = () => {
|
|
105
|
+
if (value !== void 0) {
|
|
106
|
+
const newValue = serializer(value);
|
|
107
|
+
const oldValue = rawValueRef.current;
|
|
108
|
+
rawValueRef.current = newValue;
|
|
109
|
+
effectiveStorage.setItem(key, newValue);
|
|
110
|
+
window.dispatchEvent(new StorageEvent("storage", {
|
|
111
|
+
storageArea: effectiveStorage,
|
|
112
|
+
url: window.location.href,
|
|
113
|
+
key,
|
|
114
|
+
newValue,
|
|
115
|
+
oldValue
|
|
116
|
+
}));
|
|
117
|
+
} else {
|
|
118
|
+
effectiveStorage.removeItem(key);
|
|
119
|
+
window.dispatchEvent(new StorageEvent("storage", {
|
|
120
|
+
storageArea: effectiveStorage,
|
|
121
|
+
url: window.location.href,
|
|
122
|
+
key
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
updateLocalStorage();
|
|
128
|
+
} catch (e) {
|
|
129
|
+
logger(e);
|
|
130
|
+
}
|
|
131
|
+
}, [key, logger, serializer, effectiveStorage, value]);
|
|
132
|
+
React3.useEffect(() => {
|
|
133
|
+
if (!syncData) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const handleStorageChange = e => {
|
|
137
|
+
if (e.key !== key || e.storageArea !== effectiveStorage) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
if (e.newValue !== rawValueRef.current) {
|
|
142
|
+
rawValueRef.current = e.newValue;
|
|
143
|
+
setValue(e.newValue ? parser(e.newValue) : void 0);
|
|
144
|
+
}
|
|
145
|
+
} catch (e2) {
|
|
146
|
+
logger(e2);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
if (typeof window === "undefined") {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
window.addEventListener("storage", handleStorageChange);
|
|
58
153
|
return () => {
|
|
59
|
-
|
|
154
|
+
return window.removeEventListener("storage", handleStorageChange);
|
|
60
155
|
};
|
|
61
|
-
}, [
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
export { useDebounce, useScript };
|
|
156
|
+
}, [key, logger, parser, effectiveStorage, syncData]);
|
|
157
|
+
return [value, setValue];
|
|
158
|
+
}
|
|
159
|
+
export { useDebounce, useScript, useStorage };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
declare const useDebounce: <T>(value: T, delay?: number) => T;
|
|
4
|
+
|
|
1
5
|
type ScriptStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
2
6
|
/**
|
|
3
7
|
* https://usehooks.com/useScript/
|
|
@@ -9,6 +13,17 @@ declare const useScript: (src: string) => {
|
|
|
9
13
|
status: ScriptStatus;
|
|
10
14
|
};
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
type Serializer<T> = (object: T | undefined) => string;
|
|
17
|
+
type Parser<T> = (val: string) => T | undefined;
|
|
18
|
+
type Setter<T> = React.Dispatch<React.SetStateAction<T | undefined>>;
|
|
19
|
+
type Options<T> = Partial<{
|
|
20
|
+
serializer: Serializer<T>;
|
|
21
|
+
parser: Parser<T>;
|
|
22
|
+
logger: (error: any) => void;
|
|
23
|
+
syncData: boolean;
|
|
24
|
+
storage?: Storage;
|
|
25
|
+
}>;
|
|
26
|
+
declare function useStorage<T>(key: string, defaultValue: T, options?: Options<T>): [T, Setter<T>];
|
|
27
|
+
declare function useStorage<T>(key: string, defaultValue?: undefined, options?: Options<T>): [T | undefined, Setter<T>];
|
|
13
28
|
|
|
14
|
-
export { type ScriptStatus, useDebounce, useScript };
|
|
29
|
+
export { type ScriptStatus, useDebounce, useScript, useStorage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/react-hooks",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"description": "React hooks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ttoss",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"jest": "^29.7.0",
|
|
31
31
|
"react": "^19.0.0",
|
|
32
32
|
"tsup": "^8.3.5",
|
|
33
|
-
"@ttoss/
|
|
34
|
-
"@ttoss/
|
|
33
|
+
"@ttoss/config": "^1.35.2",
|
|
34
|
+
"@ttoss/test-utils": "^2.1.22"
|
|
35
35
|
},
|
|
36
36
|
"keywords": [
|
|
37
37
|
"React",
|