react-hook-toolkit 3.0.2 → 3.0.3
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/dist/chunk1213/chunk158261.js +22 -22
- package/dist/chunk1415/chunk143.js +21 -25
- package/dist/chunk1516/chunk0021.js +263 -347
- package/dist/chunk1516/chunk0022.js +159 -277
- package/dist/chunk1516/chunk3312.d.ts +63 -0
- package/dist/chunk1516/chunk3312.js +462 -0
- package/dist/chunk1516/chunk726433.js +172 -206
- package/dist/chunk1516/chunk940514.js +284 -415
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/utils.js +42 -68
- package/package.json +1 -1
|
@@ -1,70 +1,14 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
49
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
50
|
-
if (ar || !(i in from)) {
|
|
51
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
52
|
-
ar[i] = from[i];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
|
-
};
|
|
57
1
|
import { useState, useEffect, useCallback, useRef, useContext, createContext, useMemo } from 'react';
|
|
58
2
|
import { isReady } from './chunk940514';
|
|
59
3
|
export function useGeoLocation() {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
useEffect(
|
|
63
|
-
|
|
4
|
+
const [position, setPosition] = useState(null);
|
|
5
|
+
const [error, setError] = useState(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const success = (pos) => {
|
|
64
8
|
setPosition(pos);
|
|
65
9
|
};
|
|
66
|
-
|
|
67
|
-
setError(new Error(
|
|
10
|
+
const failure = (err) => {
|
|
11
|
+
setError(new Error(`Geolocation error: ${err.message}`));
|
|
68
12
|
};
|
|
69
13
|
if (navigator.geolocation) {
|
|
70
14
|
navigator.geolocation.getCurrentPosition(success, failure);
|
|
@@ -73,117 +17,117 @@ export function useGeoLocation() {
|
|
|
73
17
|
setError(new Error('Geolocation not supported'));
|
|
74
18
|
}
|
|
75
19
|
}, []);
|
|
76
|
-
return { position
|
|
20
|
+
return { position, error };
|
|
77
21
|
}
|
|
78
22
|
export function useTimer(initialTime) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
useEffect(
|
|
23
|
+
const [time, setTime] = useState(initialTime);
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
useEffect(() => {
|
|
82
26
|
try {
|
|
83
|
-
|
|
84
|
-
setTime(
|
|
27
|
+
const intervalId = setInterval(() => {
|
|
28
|
+
setTime((prevTime) => prevTime - 1);
|
|
85
29
|
}, 1000);
|
|
86
|
-
return
|
|
30
|
+
return () => clearInterval(intervalId);
|
|
87
31
|
}
|
|
88
32
|
catch (err) {
|
|
89
33
|
setError(err instanceof Error ? err : new Error('Failed to start timer'));
|
|
90
34
|
}
|
|
91
35
|
}, []);
|
|
92
|
-
return { time
|
|
36
|
+
return { time, error };
|
|
93
37
|
}
|
|
94
38
|
export function useIsMounted() {
|
|
95
|
-
|
|
96
|
-
useEffect(
|
|
39
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
40
|
+
useEffect(() => {
|
|
97
41
|
setIsMounted(true);
|
|
98
|
-
return
|
|
42
|
+
return () => setIsMounted(false);
|
|
99
43
|
}, []);
|
|
100
44
|
return isMounted;
|
|
101
45
|
}
|
|
102
46
|
export function useCss(css) {
|
|
103
|
-
|
|
104
|
-
useEffect(
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
useEffect(() => {
|
|
105
49
|
try {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
document.head.appendChild(
|
|
109
|
-
return
|
|
110
|
-
document.head.removeChild(
|
|
50
|
+
const style = document.createElement('style');
|
|
51
|
+
style.textContent = css;
|
|
52
|
+
document.head.appendChild(style);
|
|
53
|
+
return () => {
|
|
54
|
+
document.head.removeChild(style);
|
|
111
55
|
};
|
|
112
56
|
}
|
|
113
57
|
catch (err) {
|
|
114
58
|
setError(err instanceof Error ? err : new Error('Failed to apply CSS'));
|
|
115
59
|
}
|
|
116
60
|
}, [css]);
|
|
117
|
-
return { error
|
|
61
|
+
return { error };
|
|
118
62
|
}
|
|
119
63
|
export function useSpeak(text) {
|
|
120
|
-
|
|
121
|
-
|
|
64
|
+
const [error, setError] = useState(null);
|
|
65
|
+
const speak = () => {
|
|
122
66
|
try {
|
|
123
|
-
|
|
67
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
124
68
|
speechSynthesis.speak(utterance);
|
|
125
69
|
}
|
|
126
70
|
catch (err) {
|
|
127
71
|
setError(err instanceof Error ? err : new Error('Failed to speak'));
|
|
128
72
|
}
|
|
129
73
|
};
|
|
130
|
-
return { speak
|
|
74
|
+
return { speak, error };
|
|
131
75
|
}
|
|
132
76
|
export function useCountUp(target, duration) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
useEffect(
|
|
77
|
+
const [count, setCount] = useState(0);
|
|
78
|
+
const [error, setError] = useState(null);
|
|
79
|
+
useEffect(() => {
|
|
136
80
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
81
|
+
let startTime = Date.now();
|
|
82
|
+
const intervalId = setInterval(() => {
|
|
83
|
+
const elapsed = Date.now() - startTime;
|
|
140
84
|
setCount(Math.min(target, (elapsed / duration) * target));
|
|
141
85
|
if (count >= target)
|
|
142
|
-
clearInterval(
|
|
86
|
+
clearInterval(intervalId);
|
|
143
87
|
}, 1000);
|
|
144
|
-
return
|
|
88
|
+
return () => clearInterval(intervalId);
|
|
145
89
|
}
|
|
146
90
|
catch (err) {
|
|
147
91
|
setError(err instanceof Error ? err : new Error('Failed to count up'));
|
|
148
92
|
}
|
|
149
93
|
}, [target, duration]);
|
|
150
|
-
return { count
|
|
94
|
+
return { count, error };
|
|
151
95
|
}
|
|
152
96
|
export function useCountDown(start) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
useEffect(
|
|
97
|
+
const [count, setCount] = useState(start);
|
|
98
|
+
const [error, setError] = useState(null);
|
|
99
|
+
useEffect(() => {
|
|
156
100
|
try {
|
|
157
101
|
if (count <= 0)
|
|
158
102
|
return;
|
|
159
|
-
|
|
160
|
-
setCount(
|
|
103
|
+
const intervalId = setInterval(() => {
|
|
104
|
+
setCount((prevCount) => Math.max(0, prevCount - 1));
|
|
161
105
|
}, 1000);
|
|
162
|
-
return
|
|
106
|
+
return () => clearInterval(intervalId);
|
|
163
107
|
}
|
|
164
108
|
catch (err) {
|
|
165
109
|
setError(err instanceof Error ? err : new Error('Failed to start countdown'));
|
|
166
110
|
}
|
|
167
111
|
}, [count]);
|
|
168
|
-
return { count
|
|
112
|
+
return { count, error };
|
|
169
113
|
}
|
|
170
|
-
export
|
|
171
|
-
|
|
114
|
+
export const useBattery = () => {
|
|
115
|
+
const [batteryState, setBatteryState] = useState({
|
|
172
116
|
supported: true,
|
|
173
117
|
loading: true,
|
|
174
118
|
level: null,
|
|
175
119
|
charging: null,
|
|
176
120
|
chargingTime: null,
|
|
177
121
|
dischargingTime: null,
|
|
178
|
-
})
|
|
179
|
-
useEffect(
|
|
122
|
+
});
|
|
123
|
+
useEffect(() => {
|
|
180
124
|
if (!isReady()) {
|
|
181
|
-
setBatteryState(
|
|
125
|
+
setBatteryState((prevState) => (Object.assign(Object.assign({}, prevState), { supported: false, loading: false })));
|
|
182
126
|
return;
|
|
183
127
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
128
|
+
const _navigator = navigator;
|
|
129
|
+
let battery = null;
|
|
130
|
+
const handleBatteryChange = () => {
|
|
187
131
|
if (battery) {
|
|
188
132
|
setBatteryState({
|
|
189
133
|
supported: true,
|
|
@@ -195,7 +139,7 @@ export var useBattery = function () {
|
|
|
195
139
|
});
|
|
196
140
|
}
|
|
197
141
|
};
|
|
198
|
-
_navigator.getBattery().then(
|
|
142
|
+
_navigator.getBattery().then((_battery) => {
|
|
199
143
|
battery = _battery;
|
|
200
144
|
handleBatteryChange();
|
|
201
145
|
_battery.addEventListener('levelchange', handleBatteryChange);
|
|
@@ -203,7 +147,7 @@ export var useBattery = function () {
|
|
|
203
147
|
_battery.addEventListener('chargingtimechange', handleBatteryChange);
|
|
204
148
|
_battery.addEventListener('dischargingtimechange', handleBatteryChange);
|
|
205
149
|
});
|
|
206
|
-
return
|
|
150
|
+
return () => {
|
|
207
151
|
if (battery) {
|
|
208
152
|
battery.removeEventListener('levelchange', handleBatteryChange);
|
|
209
153
|
battery.removeEventListener('chargingchange', handleBatteryChange);
|
|
@@ -214,76 +158,76 @@ export var useBattery = function () {
|
|
|
214
158
|
}, []);
|
|
215
159
|
return batteryState;
|
|
216
160
|
};
|
|
217
|
-
export
|
|
218
|
-
|
|
219
|
-
useEffect(
|
|
161
|
+
export const useEventListener = (eventName, handler, elementRef, options) => {
|
|
162
|
+
const savedHandler = useRef();
|
|
163
|
+
useEffect(() => {
|
|
220
164
|
savedHandler.current = handler;
|
|
221
165
|
}, [handler]);
|
|
222
|
-
useEffect(
|
|
223
|
-
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
const element = (elementRef && elementRef.current) || window;
|
|
224
168
|
if (!isReady() || !element)
|
|
225
169
|
return;
|
|
226
|
-
|
|
170
|
+
const eventListener = (event) => {
|
|
227
171
|
if (savedHandler.current) {
|
|
228
172
|
savedHandler.current(event);
|
|
229
173
|
}
|
|
230
174
|
};
|
|
231
175
|
element.addEventListener(eventName, eventListener, options);
|
|
232
|
-
return
|
|
176
|
+
return () => {
|
|
233
177
|
element.removeEventListener(eventName, eventListener, options);
|
|
234
178
|
};
|
|
235
179
|
}, [eventName, elementRef, options]);
|
|
236
180
|
};
|
|
237
|
-
export
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
181
|
+
export const useHistory = () => {
|
|
182
|
+
const [history, setHistory] = useState(window.history);
|
|
183
|
+
const [state, setState] = useState(null);
|
|
184
|
+
const push = useCallback((path, state) => {
|
|
241
185
|
if (isReady()) {
|
|
242
186
|
window.history.pushState(state, "", path);
|
|
243
187
|
setState(state || null);
|
|
244
188
|
}
|
|
245
189
|
}, []);
|
|
246
|
-
|
|
190
|
+
const replace = useCallback((path, state) => {
|
|
247
191
|
if (isReady()) {
|
|
248
192
|
window.history.replaceState(state, "", path);
|
|
249
193
|
setState(state || null);
|
|
250
194
|
}
|
|
251
195
|
}, []);
|
|
252
|
-
|
|
196
|
+
const goBack = useCallback(() => {
|
|
253
197
|
if (isReady()) {
|
|
254
198
|
window.history.back();
|
|
255
199
|
}
|
|
256
200
|
}, []);
|
|
257
|
-
|
|
201
|
+
const goForward = useCallback(() => {
|
|
258
202
|
if (isReady()) {
|
|
259
203
|
window.history.forward();
|
|
260
204
|
}
|
|
261
205
|
}, []);
|
|
262
|
-
useEffect(
|
|
263
|
-
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
const handlePopState = (event) => {
|
|
264
208
|
setState(event.state || null);
|
|
265
209
|
};
|
|
266
210
|
if (isReady()) {
|
|
267
211
|
window.addEventListener("popstate", handlePopState);
|
|
268
|
-
return
|
|
212
|
+
return () => {
|
|
269
213
|
window.removeEventListener("popstate", handlePopState);
|
|
270
214
|
};
|
|
271
215
|
}
|
|
272
216
|
}, []);
|
|
273
217
|
return {
|
|
274
|
-
history
|
|
275
|
-
state
|
|
276
|
-
push
|
|
277
|
-
replace
|
|
278
|
-
goBack
|
|
279
|
-
goForward
|
|
218
|
+
history,
|
|
219
|
+
state,
|
|
220
|
+
push,
|
|
221
|
+
replace,
|
|
222
|
+
goBack,
|
|
223
|
+
goForward,
|
|
280
224
|
};
|
|
281
225
|
};
|
|
282
|
-
export
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
useEffect(
|
|
226
|
+
export const usePreferredLanguage = () => {
|
|
227
|
+
const [language, setLanguage] = useState(isReady() ? navigator.language : "");
|
|
228
|
+
const [languages, setLanguages] = useState(isReady() ? Array.from(navigator.languages) : []);
|
|
229
|
+
const [isSupported, setIsSupported] = useState(isReady() && !!navigator.language);
|
|
230
|
+
useEffect(() => {
|
|
287
231
|
if (isReady()) {
|
|
288
232
|
if (navigator.language) {
|
|
289
233
|
setLanguage(navigator.language);
|
|
@@ -302,57 +246,57 @@ export var usePreferredLanguage = function () {
|
|
|
302
246
|
}
|
|
303
247
|
}, []);
|
|
304
248
|
return {
|
|
305
|
-
language
|
|
306
|
-
languages
|
|
307
|
-
isSupported
|
|
249
|
+
language,
|
|
250
|
+
languages,
|
|
251
|
+
isSupported,
|
|
308
252
|
};
|
|
309
253
|
};
|
|
310
|
-
export
|
|
311
|
-
|
|
254
|
+
export const useSessionStorage = (key, initialValue) => {
|
|
255
|
+
const [storedValue, setStoredValue] = useState(() => {
|
|
312
256
|
if (!isReady()) {
|
|
313
257
|
return initialValue;
|
|
314
258
|
}
|
|
315
259
|
try {
|
|
316
|
-
|
|
260
|
+
const item = window.sessionStorage.getItem(key);
|
|
317
261
|
return item ? JSON.parse(item) : initialValue;
|
|
318
262
|
}
|
|
319
263
|
catch (error) {
|
|
320
|
-
console.warn(
|
|
264
|
+
console.warn(`Error reading sessionStorage key "${key}":`, error);
|
|
321
265
|
return initialValue;
|
|
322
266
|
}
|
|
323
|
-
})
|
|
324
|
-
|
|
267
|
+
});
|
|
268
|
+
const setValue = (value) => {
|
|
325
269
|
try {
|
|
326
|
-
|
|
270
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
327
271
|
setStoredValue(valueToStore);
|
|
328
272
|
if (isReady()) {
|
|
329
273
|
window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
|
|
330
274
|
}
|
|
331
275
|
}
|
|
332
276
|
catch (error) {
|
|
333
|
-
console.warn(
|
|
277
|
+
console.warn(`Error setting sessionStorage key "${key}":`, error);
|
|
334
278
|
}
|
|
335
279
|
};
|
|
336
280
|
return [storedValue, setValue];
|
|
337
281
|
};
|
|
338
|
-
export
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
useEffect(
|
|
282
|
+
export const useSound = (url) => {
|
|
283
|
+
const [audio, setAudio] = useState(null);
|
|
284
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
285
|
+
const [error, setError] = useState(null);
|
|
286
|
+
useEffect(() => {
|
|
343
287
|
if (!isReady() || !window.Audio) {
|
|
344
288
|
setError(new Error("Sound is not supported in this environment."));
|
|
345
289
|
return;
|
|
346
290
|
}
|
|
347
|
-
|
|
291
|
+
const audioElement = new Audio(url);
|
|
348
292
|
setAudio(audioElement);
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
293
|
+
const handlePlay = () => setIsPlaying(true);
|
|
294
|
+
const handlePause = () => setIsPlaying(false);
|
|
295
|
+
const handleError = (e) => setError(e);
|
|
352
296
|
audioElement.addEventListener("play", handlePlay);
|
|
353
297
|
audioElement.addEventListener("pause", handlePause);
|
|
354
298
|
audioElement.addEventListener("error", handleError);
|
|
355
|
-
return
|
|
299
|
+
return () => {
|
|
356
300
|
audioElement.removeEventListener("play", handlePlay);
|
|
357
301
|
audioElement.removeEventListener("pause", handlePause);
|
|
358
302
|
audioElement.removeEventListener("error", handleError);
|
|
@@ -360,78 +304,78 @@ export var useSound = function (url) {
|
|
|
360
304
|
audioElement.currentTime = 0;
|
|
361
305
|
};
|
|
362
306
|
}, [url]);
|
|
363
|
-
|
|
307
|
+
const play = useCallback(() => {
|
|
364
308
|
if (audio) {
|
|
365
|
-
audio.play().catch(
|
|
309
|
+
audio.play().catch((e) => setError(e));
|
|
366
310
|
}
|
|
367
311
|
}, [audio]);
|
|
368
|
-
|
|
312
|
+
const pause = useCallback(() => {
|
|
369
313
|
if (audio) {
|
|
370
314
|
audio.pause();
|
|
371
315
|
}
|
|
372
316
|
}, [audio]);
|
|
373
|
-
|
|
317
|
+
const stop = useCallback(() => {
|
|
374
318
|
if (audio) {
|
|
375
319
|
audio.pause();
|
|
376
320
|
audio.currentTime = 0;
|
|
377
321
|
}
|
|
378
322
|
}, [audio]);
|
|
379
|
-
|
|
323
|
+
const setVolume = useCallback((volume) => {
|
|
380
324
|
if (audio) {
|
|
381
325
|
audio.volume = volume;
|
|
382
326
|
}
|
|
383
327
|
}, [audio]);
|
|
384
328
|
return {
|
|
385
|
-
play
|
|
386
|
-
pause
|
|
387
|
-
stop
|
|
388
|
-
setVolume
|
|
389
|
-
isPlaying
|
|
390
|
-
error
|
|
329
|
+
play,
|
|
330
|
+
pause,
|
|
331
|
+
stop,
|
|
332
|
+
setVolume,
|
|
333
|
+
isPlaying,
|
|
334
|
+
error,
|
|
391
335
|
};
|
|
392
336
|
};
|
|
393
|
-
export
|
|
394
|
-
|
|
337
|
+
export const useTouch = (elementRef) => {
|
|
338
|
+
const [touchStart, setTouchStart] = useState({
|
|
395
339
|
x: null,
|
|
396
340
|
y: null,
|
|
397
|
-
})
|
|
398
|
-
|
|
341
|
+
});
|
|
342
|
+
const [touchMove, setTouchMove] = useState({
|
|
399
343
|
x: null,
|
|
400
344
|
y: null,
|
|
401
|
-
})
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
345
|
+
});
|
|
346
|
+
const [touchEnd, setTouchEnd] = useState({ x: null, y: null });
|
|
347
|
+
const handleTouchStart = useCallback((event) => {
|
|
348
|
+
const touch = event.touches[0];
|
|
405
349
|
setTouchStart({ x: touch.clientX, y: touch.clientY });
|
|
406
350
|
}, []);
|
|
407
|
-
|
|
408
|
-
|
|
351
|
+
const handleTouchMove = useCallback((event) => {
|
|
352
|
+
const touch = event.touches[0];
|
|
409
353
|
setTouchMove({ x: touch.clientX, y: touch.clientY });
|
|
410
354
|
}, []);
|
|
411
|
-
|
|
355
|
+
const handleTouchEnd = useCallback(() => {
|
|
412
356
|
setTouchEnd(touchMove);
|
|
413
357
|
setTouchMove({ x: null, y: null });
|
|
414
358
|
setTouchStart({ x: null, y: null });
|
|
415
359
|
}, [touchMove]);
|
|
416
|
-
useEffect(
|
|
360
|
+
useEffect(() => {
|
|
417
361
|
if (!isReady() || !elementRef.current) {
|
|
418
362
|
return;
|
|
419
363
|
}
|
|
420
|
-
|
|
364
|
+
const element = elementRef.current;
|
|
421
365
|
element.addEventListener("touchstart", handleTouchStart);
|
|
422
366
|
element.addEventListener("touchmove", handleTouchMove);
|
|
423
367
|
element.addEventListener("touchend", handleTouchEnd);
|
|
424
|
-
return
|
|
368
|
+
return () => {
|
|
425
369
|
element.removeEventListener("touchstart", handleTouchStart);
|
|
426
370
|
element.removeEventListener("touchmove", handleTouchMove);
|
|
427
371
|
element.removeEventListener("touchend", handleTouchEnd);
|
|
428
372
|
};
|
|
429
373
|
}, [elementRef, handleTouchStart, handleTouchMove, handleTouchEnd]);
|
|
430
|
-
return { touchStart
|
|
374
|
+
return { touchStart, touchMove, touchEnd };
|
|
431
375
|
};
|
|
432
|
-
export
|
|
433
|
-
|
|
434
|
-
useEffect(
|
|
376
|
+
export const useUpdateEffect = (effect, deps) => {
|
|
377
|
+
const isFirstMount = useRef(true);
|
|
378
|
+
useEffect(() => {
|
|
435
379
|
if (!isReady()) {
|
|
436
380
|
return;
|
|
437
381
|
}
|
|
@@ -442,258 +386,230 @@ export var useUpdateEffect = function (effect, deps) {
|
|
|
442
386
|
return effect();
|
|
443
387
|
}, deps);
|
|
444
388
|
};
|
|
445
|
-
export
|
|
446
|
-
|
|
389
|
+
export const usePersistedForm = (key, initialValue) => {
|
|
390
|
+
const [state, setState] = useState(() => {
|
|
447
391
|
try {
|
|
448
|
-
|
|
392
|
+
const stored = localStorage.getItem(key);
|
|
449
393
|
return stored ? JSON.parse(stored) : initialValue;
|
|
450
394
|
}
|
|
451
395
|
catch (_a) {
|
|
452
396
|
return initialValue;
|
|
453
397
|
}
|
|
454
|
-
})
|
|
455
|
-
useEffect(
|
|
398
|
+
});
|
|
399
|
+
useEffect(() => {
|
|
456
400
|
localStorage.setItem(key, JSON.stringify(state));
|
|
457
401
|
}, [key, state]);
|
|
458
402
|
return [state, setState];
|
|
459
403
|
};
|
|
460
|
-
export
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
404
|
+
export const useCrossFieldValidation = (validate) => {
|
|
405
|
+
const [errors, setErrors] = useState({});
|
|
406
|
+
const validateFields = (values) => {
|
|
407
|
+
const newErrors = validate(values);
|
|
464
408
|
setErrors(newErrors);
|
|
465
|
-
return Object.values(newErrors).every(
|
|
409
|
+
return Object.values(newErrors).every((e) => !e);
|
|
466
410
|
};
|
|
467
|
-
return { errors
|
|
411
|
+
return { errors, validateFields };
|
|
468
412
|
};
|
|
469
|
-
export
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
};
|
|
476
|
-
return { fields: fields, append: append, remove: remove, update: update };
|
|
413
|
+
export const useFieldArray = (initialValue) => {
|
|
414
|
+
const [fields, setFields] = useState(initialValue);
|
|
415
|
+
const append = (item) => setFields([...fields, item]);
|
|
416
|
+
const remove = (index) => setFields(fields.filter((_, i) => i !== index));
|
|
417
|
+
const update = (index, item) => setFields(fields.map((f, i) => (i === index ? item : f)));
|
|
418
|
+
return { fields, append, remove, update };
|
|
477
419
|
};
|
|
478
|
-
export
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
setSubmitError(err_1 instanceof Error ? err_1.message : 'Submission failed');
|
|
496
|
-
return [3 /*break*/, 4];
|
|
497
|
-
case 3:
|
|
498
|
-
setIsSubmitting(false);
|
|
499
|
-
return [7 /*endfinally*/];
|
|
500
|
-
case 4: return [2 /*return*/];
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
}); };
|
|
504
|
-
return { handleSubmit: handleSubmit, isSubmitting: isSubmitting, submitError: submitError };
|
|
420
|
+
export const useFormSubmit = (handler) => {
|
|
421
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
422
|
+
const [submitError, setSubmitError] = useState(null);
|
|
423
|
+
const handleSubmit = async (data) => {
|
|
424
|
+
try {
|
|
425
|
+
setIsSubmitting(true);
|
|
426
|
+
setSubmitError(null);
|
|
427
|
+
await handler(data);
|
|
428
|
+
}
|
|
429
|
+
catch (err) {
|
|
430
|
+
setSubmitError(err instanceof Error ? err.message : 'Submission failed');
|
|
431
|
+
}
|
|
432
|
+
finally {
|
|
433
|
+
setIsSubmitting(false);
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
return { handleSubmit, isSubmitting, submitError };
|
|
505
437
|
};
|
|
506
|
-
export
|
|
507
|
-
|
|
438
|
+
export const useSmartForm = (initialValues, storageKey) => {
|
|
439
|
+
const [values, setValues] = useState(() => {
|
|
508
440
|
if (!storageKey)
|
|
509
441
|
return initialValues;
|
|
510
442
|
try {
|
|
511
|
-
|
|
443
|
+
const saved = localStorage.getItem(storageKey);
|
|
512
444
|
return saved ? JSON.parse(saved) : initialValues;
|
|
513
445
|
}
|
|
514
446
|
catch (_a) {
|
|
515
447
|
return initialValues;
|
|
516
448
|
}
|
|
517
|
-
})
|
|
518
|
-
|
|
519
|
-
useEffect(
|
|
449
|
+
});
|
|
450
|
+
const [dirty, setDirty] = useState(false);
|
|
451
|
+
useEffect(() => {
|
|
520
452
|
if (storageKey && dirty) {
|
|
521
|
-
|
|
453
|
+
const timer = setTimeout(() => {
|
|
522
454
|
localStorage.setItem(storageKey, JSON.stringify(values));
|
|
523
455
|
}, 500);
|
|
524
|
-
return
|
|
456
|
+
return () => clearTimeout(timer);
|
|
525
457
|
}
|
|
526
458
|
}, [values, storageKey, dirty]);
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
setValues(
|
|
530
|
-
var _a;
|
|
531
|
-
return (__assign(__assign({}, prev), (_a = {}, _a[name] = type === 'checkbox' ? checked : value, _a)));
|
|
532
|
-
});
|
|
459
|
+
const handleChange = (e) => {
|
|
460
|
+
const { name, value, type, checked } = e.target;
|
|
461
|
+
setValues(prev => (Object.assign(Object.assign({}, prev), { [name]: type === 'checkbox' ? checked : value })));
|
|
533
462
|
setDirty(true);
|
|
534
463
|
};
|
|
535
|
-
return { values
|
|
464
|
+
return { values, handleChange, setValues, dirty };
|
|
536
465
|
};
|
|
537
|
-
export
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
setStates(
|
|
466
|
+
export const useUndo = (initialState) => {
|
|
467
|
+
const [states, setStates] = useState([initialState]);
|
|
468
|
+
const [index, setIndex] = useState(0);
|
|
469
|
+
const present = states[index];
|
|
470
|
+
const canUndo = index > 0;
|
|
471
|
+
const canRedo = index < states.length - 1;
|
|
472
|
+
const updateState = (newState) => {
|
|
473
|
+
const newStates = states.slice(0, index + 1);
|
|
474
|
+
setStates([...newStates, newState]);
|
|
546
475
|
setIndex(newStates.length);
|
|
547
476
|
};
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
return { state: present, setState: updateState, undo
|
|
477
|
+
const undo = () => canUndo && setIndex(i => i - 1);
|
|
478
|
+
const redo = () => canRedo && setIndex(i => i + 1);
|
|
479
|
+
return { state: present, setState: updateState, undo, redo, canUndo, canRedo };
|
|
551
480
|
};
|
|
552
|
-
export
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
481
|
+
export const useFormWizard = (steps, initialValues) => {
|
|
482
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
483
|
+
const [values, setValues] = useState(initialValues);
|
|
484
|
+
const [errors, setErrors] = useState({});
|
|
485
|
+
const next = () => {
|
|
557
486
|
var _a, _b;
|
|
558
|
-
|
|
487
|
+
const validation = ((_b = (_a = steps[currentStep]).validate) === null || _b === void 0 ? void 0 : _b.call(_a, values)) || {};
|
|
559
488
|
if (Object.keys(validation).length > 0) {
|
|
560
489
|
setErrors(validation);
|
|
561
490
|
return;
|
|
562
491
|
}
|
|
563
492
|
setErrors({});
|
|
564
|
-
setCurrentStep(
|
|
493
|
+
setCurrentStep(prev => Math.min(prev + 1, steps.length - 1));
|
|
565
494
|
};
|
|
566
|
-
|
|
567
|
-
setCurrentStep(
|
|
495
|
+
const prev = () => {
|
|
496
|
+
setCurrentStep(prev => Math.max(prev - 1, 0));
|
|
568
497
|
};
|
|
569
498
|
return {
|
|
570
|
-
currentStep
|
|
499
|
+
currentStep,
|
|
571
500
|
CurrentStep: steps[currentStep].component,
|
|
572
|
-
values
|
|
573
|
-
setValues
|
|
574
|
-
next
|
|
575
|
-
prev
|
|
576
|
-
errors
|
|
501
|
+
values,
|
|
502
|
+
setValues,
|
|
503
|
+
next,
|
|
504
|
+
prev,
|
|
505
|
+
errors,
|
|
577
506
|
isFirstStep: currentStep === 0,
|
|
578
507
|
isLastStep: currentStep === steps.length - 1,
|
|
579
508
|
};
|
|
580
509
|
};
|
|
581
|
-
export
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
510
|
+
export const createOptimizedContext = () => {
|
|
511
|
+
const Context = createContext(undefined);
|
|
512
|
+
const useOptimizedContext = (selector) => {
|
|
513
|
+
const value = useContext(Context);
|
|
585
514
|
if (value === undefined)
|
|
586
515
|
throw new Error('Missing provider');
|
|
587
|
-
return useMemo(
|
|
516
|
+
return useMemo(() => selector(value), [value, selector]);
|
|
588
517
|
};
|
|
589
518
|
return [Context.Provider, useOptimizedContext];
|
|
590
519
|
};
|
|
591
|
-
export
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
520
|
+
export const useWebSocket = (url, onMessage) => {
|
|
521
|
+
const [data, setData] = useState(null);
|
|
522
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
523
|
+
const [socket, setSocket] = useState(null);
|
|
524
|
+
const send = useCallback((message) => {
|
|
596
525
|
if ((socket === null || socket === void 0 ? void 0 : socket.readyState) === WebSocket.OPEN) {
|
|
597
526
|
socket.send(JSON.stringify(message));
|
|
598
527
|
}
|
|
599
528
|
}, [socket]);
|
|
600
|
-
useEffect(
|
|
601
|
-
|
|
529
|
+
useEffect(() => {
|
|
530
|
+
const ws = new WebSocket(url);
|
|
602
531
|
setSocket(ws);
|
|
603
|
-
ws.onopen =
|
|
604
|
-
ws.onclose =
|
|
605
|
-
ws.onmessage =
|
|
606
|
-
|
|
532
|
+
ws.onopen = () => setIsConnected(true);
|
|
533
|
+
ws.onclose = () => setIsConnected(false);
|
|
534
|
+
ws.onmessage = (event) => {
|
|
535
|
+
const newData = JSON.parse(event.data);
|
|
607
536
|
setData(newData);
|
|
608
537
|
onMessage === null || onMessage === void 0 ? void 0 : onMessage(newData);
|
|
609
538
|
};
|
|
610
|
-
return
|
|
539
|
+
return () => ws.close();
|
|
611
540
|
}, [url, onMessage]);
|
|
612
|
-
return { data
|
|
541
|
+
return { data, send, isConnected };
|
|
613
542
|
};
|
|
614
|
-
export
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
543
|
+
export const useDragReorder = (initialItems) => {
|
|
544
|
+
const [items, setItems] = useState(initialItems);
|
|
545
|
+
const dragItem = useRef(null);
|
|
546
|
+
const dragOverItem = useRef(null);
|
|
547
|
+
const handleDragStart = (index) => {
|
|
619
548
|
dragItem.current = index;
|
|
620
549
|
};
|
|
621
|
-
|
|
550
|
+
const handleDragEnter = (index) => {
|
|
622
551
|
dragOverItem.current = index;
|
|
623
552
|
};
|
|
624
|
-
|
|
553
|
+
const handleDrop = () => {
|
|
625
554
|
if (dragItem.current === null || dragOverItem.current === null)
|
|
626
555
|
return;
|
|
627
|
-
|
|
628
|
-
|
|
556
|
+
const newItems = [...items];
|
|
557
|
+
const draggedItem = newItems[dragItem.current];
|
|
629
558
|
newItems.splice(dragItem.current, 1);
|
|
630
559
|
newItems.splice(dragOverItem.current, 0, draggedItem);
|
|
631
560
|
setItems(newItems);
|
|
632
561
|
dragItem.current = null;
|
|
633
562
|
dragOverItem.current = null;
|
|
634
563
|
};
|
|
635
|
-
return { items
|
|
564
|
+
return { items, handleDragStart, handleDragEnter, handleDrop };
|
|
636
565
|
};
|
|
637
|
-
export
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
var lastElementRef = useCallback(function (node) {
|
|
566
|
+
export const useInfiniteScroll = (fetchData, initialData = []) => {
|
|
567
|
+
const [data, setData] = useState(initialData);
|
|
568
|
+
const [page, setPage] = useState(1);
|
|
569
|
+
const [loading, setLoading] = useState(false);
|
|
570
|
+
const [hasMore, setHasMore] = useState(true);
|
|
571
|
+
const observer = useRef();
|
|
572
|
+
const lastElementRef = useCallback((node) => {
|
|
645
573
|
if (loading)
|
|
646
574
|
return;
|
|
647
575
|
if (observer.current)
|
|
648
576
|
observer.current.disconnect();
|
|
649
|
-
observer.current = new IntersectionObserver(
|
|
577
|
+
observer.current = new IntersectionObserver(entries => {
|
|
650
578
|
if (entries[0].isIntersecting && hasMore) {
|
|
651
|
-
setPage(
|
|
579
|
+
setPage(prev => prev + 1);
|
|
652
580
|
}
|
|
653
581
|
});
|
|
654
582
|
if (node)
|
|
655
583
|
observer.current.observe(node);
|
|
656
584
|
}, [loading, hasMore]);
|
|
657
|
-
useEffect(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
newData_1 = _a.sent();
|
|
670
|
-
setData(function (prev) { return __spreadArray(__spreadArray([], prev, true), newData_1, true); });
|
|
671
|
-
setHasMore(newData_1.length > 0);
|
|
672
|
-
return [3 /*break*/, 4];
|
|
673
|
-
case 3:
|
|
674
|
-
setLoading(false);
|
|
675
|
-
return [7 /*endfinally*/];
|
|
676
|
-
case 4: return [2 /*return*/];
|
|
677
|
-
}
|
|
678
|
-
});
|
|
679
|
-
}); };
|
|
585
|
+
useEffect(() => {
|
|
586
|
+
const loadData = async () => {
|
|
587
|
+
setLoading(true);
|
|
588
|
+
try {
|
|
589
|
+
const newData = await fetchData(page);
|
|
590
|
+
setData(prev => [...prev, ...newData]);
|
|
591
|
+
setHasMore(newData.length > 0);
|
|
592
|
+
}
|
|
593
|
+
finally {
|
|
594
|
+
setLoading(false);
|
|
595
|
+
}
|
|
596
|
+
};
|
|
680
597
|
loadData();
|
|
681
598
|
}, [page, fetchData]);
|
|
682
|
-
return { data
|
|
599
|
+
return { data, loading, hasMore, lastElementRef };
|
|
683
600
|
};
|
|
684
|
-
export
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
useEffect(function () {
|
|
601
|
+
export const useEventListeners = (eventType, handler, element = window, options) => {
|
|
602
|
+
const savedHandler = useRef(handler);
|
|
603
|
+
useEffect(() => {
|
|
688
604
|
savedHandler.current = handler;
|
|
689
605
|
}, [handler]);
|
|
690
|
-
useEffect(
|
|
691
|
-
|
|
606
|
+
useEffect(() => {
|
|
607
|
+
const isSupported = element && element.addEventListener;
|
|
692
608
|
if (!isSupported)
|
|
693
609
|
return;
|
|
694
|
-
|
|
610
|
+
const listener = (event) => savedHandler.current(event);
|
|
695
611
|
element.addEventListener(eventType, listener, options);
|
|
696
|
-
return
|
|
612
|
+
return () => {
|
|
697
613
|
element.removeEventListener(eventType, listener, options);
|
|
698
614
|
};
|
|
699
615
|
}, [eventType, element, options]);
|