@hairy/react-lib 1.1.1
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/LICENSE +23 -0
- package/dist/index.cjs +450 -0
- package/dist/index.d.ts +173 -0
- package/dist/index.mjs +389 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-PRESENT Hairyf<https://github.com/hairyf>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Case: () => Case,
|
|
34
|
+
Default: () => Default,
|
|
35
|
+
Else: () => Else,
|
|
36
|
+
If: () => If,
|
|
37
|
+
Injector: () => Injector,
|
|
38
|
+
Switch: () => Switch,
|
|
39
|
+
Then: () => Then,
|
|
40
|
+
Trans: () => Trans,
|
|
41
|
+
Unless: () => Unless,
|
|
42
|
+
cls: () => cls,
|
|
43
|
+
defineAsyncStorage: () => defineAsyncStorage,
|
|
44
|
+
defineStore: () => defineStore,
|
|
45
|
+
proxyWithPersistant: () => proxyWithPersistant,
|
|
46
|
+
storeToState: () => storeToState,
|
|
47
|
+
storeToStates: () => storeToStates,
|
|
48
|
+
useAsyncCallback: () => useAsyncCallback,
|
|
49
|
+
useAsyncState: () => useAsyncState,
|
|
50
|
+
useDebounce: () => useDebounce,
|
|
51
|
+
useEventBus: () => useEventBus,
|
|
52
|
+
useFetchRequestIntercept: () => useFetchRequestIntercept,
|
|
53
|
+
useFetchResponseIntercept: () => useFetchResponseIntercept,
|
|
54
|
+
useMounted: () => useMounted,
|
|
55
|
+
useStore: () => useStore,
|
|
56
|
+
useWatch: () => useWatch,
|
|
57
|
+
useWhenever: () => useWhenever
|
|
58
|
+
});
|
|
59
|
+
module.exports = __toCommonJS(src_exports);
|
|
60
|
+
|
|
61
|
+
// src/components/condition/Case.ts
|
|
62
|
+
function Case(props) {
|
|
63
|
+
return props.children;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/components/condition/Default.ts
|
|
67
|
+
function Default(props) {
|
|
68
|
+
return props.children;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/components/condition/Else.ts
|
|
72
|
+
function Else(props) {
|
|
73
|
+
return props.children;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/components/condition/If.ts
|
|
77
|
+
var import_react = require("react");
|
|
78
|
+
|
|
79
|
+
// src/components/condition/Then.ts
|
|
80
|
+
function Then(props) {
|
|
81
|
+
return props.children;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/components/condition/If.ts
|
|
85
|
+
function If(props) {
|
|
86
|
+
const children = props.then || props.children;
|
|
87
|
+
const elements = import_react.Children.toArray(children);
|
|
88
|
+
const thenChild = elements.find((c) => c.type === Then);
|
|
89
|
+
const elseChild = elements.find((c) => c.type === Else);
|
|
90
|
+
return thenChild || elseChild ? props.cond ? thenChild : elseChild : props.cond ? children : props.else;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/components/condition/Switch.ts
|
|
94
|
+
var import_react2 = require("react");
|
|
95
|
+
function Switch(props) {
|
|
96
|
+
var _a;
|
|
97
|
+
const isUseValue = props.value !== void 0;
|
|
98
|
+
let matchingCase;
|
|
99
|
+
let defaultCase;
|
|
100
|
+
import_react2.Children.forEach(props.children, (child) => {
|
|
101
|
+
if (!(0, import_react2.isValidElement)(child) || matchingCase)
|
|
102
|
+
return;
|
|
103
|
+
if (child.type === Case) {
|
|
104
|
+
const cond = child.props.cond;
|
|
105
|
+
if (isUseValue ? props.value === cond : cond) {
|
|
106
|
+
matchingCase = child;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (!defaultCase && child.type === Default)
|
|
111
|
+
defaultCase = child;
|
|
112
|
+
});
|
|
113
|
+
return (_a = matchingCase != null ? matchingCase : defaultCase) != null ? _a : null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/components/condition/Unless.ts
|
|
117
|
+
var import_react3 = require("react");
|
|
118
|
+
function Unless(props) {
|
|
119
|
+
const children = props.then || props.children;
|
|
120
|
+
const elements = import_react3.Children.toArray(children);
|
|
121
|
+
const thenChild = elements.find((c) => c.type === Then);
|
|
122
|
+
const elseChild = elements.find((c) => c.type === Else);
|
|
123
|
+
return thenChild || elseChild ? !props.cond ? elseChild : thenChild : !props.cond ? props.children : props.else;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/components/utils/Injector.ts
|
|
127
|
+
var import_react4 = require("react");
|
|
128
|
+
function Injector(props) {
|
|
129
|
+
const installs = (0, import_react4.useMemo)(
|
|
130
|
+
() => props.install.map(repack).reverse(),
|
|
131
|
+
[props.install]
|
|
132
|
+
);
|
|
133
|
+
return installs.reduce(
|
|
134
|
+
(child, { component: Component, props: props2 }) => (0, import_react4.createElement)(Component, props2, child),
|
|
135
|
+
props.children
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
function repack(c) {
|
|
139
|
+
return c.component ? c : { component: c };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/components/utils/Trans.ts
|
|
143
|
+
var import_react_i18next = require("react-i18next");
|
|
144
|
+
var import_react5 = require("react");
|
|
145
|
+
var import_html_parse_stringify = __toESM(require("html-parse-stringify"));
|
|
146
|
+
function Trans({ i18nKey, ...additionalProps }) {
|
|
147
|
+
const translation = (0, import_react_i18next.useTranslation)().t(i18nKey, additionalProps);
|
|
148
|
+
return renderNodes(import_html_parse_stringify.default.parse(translation), additionalProps);
|
|
149
|
+
}
|
|
150
|
+
var index = 0;
|
|
151
|
+
function renderNodes(tokens, values) {
|
|
152
|
+
return tokens.map((token) => {
|
|
153
|
+
if (token.type === "text")
|
|
154
|
+
return token.content;
|
|
155
|
+
index++;
|
|
156
|
+
const props = { ...token.attrs, key: index };
|
|
157
|
+
return token.voidElement ? values[token.name] ? (0, import_react5.createElement)("span", { key: index }, values[token.name]) : (0, import_react5.createElement)(token.name, props) : (0, import_react5.createElement)(token.name, props, renderNodes(token.children, {}));
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/hooks/useDebounce.ts
|
|
162
|
+
var import_react6 = require("react");
|
|
163
|
+
function useDebounce(value, delay) {
|
|
164
|
+
const [debouncedValue, setDebouncedValue] = (0, import_react6.useState)(value);
|
|
165
|
+
(0, import_react6.useEffect)(() => {
|
|
166
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
167
|
+
return () => clearTimeout(handler);
|
|
168
|
+
}, [value, delay]);
|
|
169
|
+
return debouncedValue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/hooks/useEventBus.ts
|
|
173
|
+
var import_react7 = require("react");
|
|
174
|
+
var import_mitt = __toESM(require("mitt"));
|
|
175
|
+
var emitter = (0, import_mitt.default)();
|
|
176
|
+
function useEventBus(key) {
|
|
177
|
+
const onRef = (0, import_react7.useRef)();
|
|
178
|
+
function on(listener) {
|
|
179
|
+
emitter.on(key, listener);
|
|
180
|
+
onRef.current = listener;
|
|
181
|
+
(0, import_react7.useEffect)(() => {
|
|
182
|
+
if (!onRef.current)
|
|
183
|
+
return;
|
|
184
|
+
emitter.off(key, onRef.current);
|
|
185
|
+
emitter.on(key, listener);
|
|
186
|
+
onRef.current = listener;
|
|
187
|
+
return () => emitter.off(key, listener);
|
|
188
|
+
}, [listener]);
|
|
189
|
+
}
|
|
190
|
+
function emit(event) {
|
|
191
|
+
emitter.emit(key, event);
|
|
192
|
+
}
|
|
193
|
+
function off(listener) {
|
|
194
|
+
emitter.off(key, listener);
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
on,
|
|
198
|
+
emit,
|
|
199
|
+
off
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/hooks/useMounted.ts
|
|
204
|
+
var import_react8 = require("react");
|
|
205
|
+
function useMounted() {
|
|
206
|
+
const [mounted, setMounted] = (0, import_react8.useState)(false);
|
|
207
|
+
(0, import_react8.useEffect)(() => setMounted(true), []);
|
|
208
|
+
return mounted;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/hooks/useWatch.ts
|
|
212
|
+
var import_react9 = require("react");
|
|
213
|
+
function useWatch(source, callback, options = {}) {
|
|
214
|
+
const firstUpdate = (0, import_react9.useRef)(false);
|
|
215
|
+
const then = (0, import_react9.useRef)();
|
|
216
|
+
const deps = (0, import_react9.useMemo)(
|
|
217
|
+
() => Array.isArray(source) ? source : [source],
|
|
218
|
+
[source]
|
|
219
|
+
);
|
|
220
|
+
(0, import_react9.useEffect)(() => {
|
|
221
|
+
if (!firstUpdate.current)
|
|
222
|
+
recordFirst();
|
|
223
|
+
else
|
|
224
|
+
callback(source);
|
|
225
|
+
}, deps);
|
|
226
|
+
async function recordFirst() {
|
|
227
|
+
if (then.current)
|
|
228
|
+
return;
|
|
229
|
+
then.current = Promise.resolve(source);
|
|
230
|
+
then.current.then(() => firstUpdate.current = true);
|
|
231
|
+
if (options.immediate)
|
|
232
|
+
then.current.then((value) => callback(value));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/hooks/useWhenever.ts
|
|
237
|
+
function useWhenever(source, cb, options) {
|
|
238
|
+
useWatch(source, () => source && cb(source), options);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/hooks/useAsyncCallback.ts
|
|
242
|
+
var import_react10 = require("react");
|
|
243
|
+
function useAsyncCallback(fun) {
|
|
244
|
+
const [error, setError] = (0, import_react10.useState)();
|
|
245
|
+
const [loading, setLoading] = (0, import_react10.useState)(false);
|
|
246
|
+
async function execute(...args) {
|
|
247
|
+
try {
|
|
248
|
+
setLoading(true);
|
|
249
|
+
const result = await fun(...args);
|
|
250
|
+
setLoading(false);
|
|
251
|
+
return result;
|
|
252
|
+
} catch (error2) {
|
|
253
|
+
setLoading(false);
|
|
254
|
+
setError(error2);
|
|
255
|
+
throw error2;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return [loading, execute, error];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/hooks/useAsyncState.ts
|
|
262
|
+
var import_react_use = require("react-use");
|
|
263
|
+
function useAsyncState(fn, deps, options) {
|
|
264
|
+
const [state, _fn] = (0, import_react_use.useAsyncFn)(fn, deps, options == null ? void 0 : options.initial);
|
|
265
|
+
(0, import_react_use.useMount)(() => (options == null ? void 0 : options.immediate) && _fn());
|
|
266
|
+
return [state, _fn];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/hooks/useFetchIntercept.ts
|
|
270
|
+
var import_react_use2 = require("react-use");
|
|
271
|
+
function useFetchResponseIntercept(intercept) {
|
|
272
|
+
(0, import_react_use2.useMount)(() => fetchResponseIntercept(intercept));
|
|
273
|
+
}
|
|
274
|
+
function useFetchRequestIntercept(intercept) {
|
|
275
|
+
(0, import_react_use2.useMount)(() => fetchRequestIntercept(intercept));
|
|
276
|
+
}
|
|
277
|
+
function fetchResponseIntercept(intercept) {
|
|
278
|
+
const { fetch: originalFetch } = window;
|
|
279
|
+
window.fetch = async (...args) => {
|
|
280
|
+
const [resource, config] = args;
|
|
281
|
+
const response = await originalFetch(resource, config);
|
|
282
|
+
return intercept(response);
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function fetchRequestIntercept(intercept) {
|
|
286
|
+
const { fetch: originalFetch } = window;
|
|
287
|
+
window.fetch = async (...args) => {
|
|
288
|
+
const [resource, config] = args;
|
|
289
|
+
return intercept(originalFetch, resource, config);
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// src/storage/storeToState.ts
|
|
294
|
+
var import_valtio = require("valtio");
|
|
295
|
+
function storeToState(store, key) {
|
|
296
|
+
const snapshot = (0, import_valtio.useSnapshot)(store);
|
|
297
|
+
function get() {
|
|
298
|
+
return snapshot[key];
|
|
299
|
+
}
|
|
300
|
+
function set(value) {
|
|
301
|
+
store[key] = value;
|
|
302
|
+
}
|
|
303
|
+
return [get(), set];
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/storage/proxyWithPersistant.ts
|
|
307
|
+
var import_valtio2 = require("valtio");
|
|
308
|
+
function proxyWithPersistant(key, initialObject, options = {}) {
|
|
309
|
+
const storage = options.storage || (typeof localStorage !== "undefined" ? localStorage : void 0);
|
|
310
|
+
const state = (0, import_valtio2.proxy)(parse(storage == null ? void 0 : storage.getItem(key)) || initialObject);
|
|
311
|
+
(0, import_valtio2.subscribe)(state, () => {
|
|
312
|
+
storage == null ? void 0 : storage.setItem(key, JSON.stringify(state));
|
|
313
|
+
});
|
|
314
|
+
return state;
|
|
315
|
+
}
|
|
316
|
+
function parse(text) {
|
|
317
|
+
try {
|
|
318
|
+
return JSON.parse(text || "");
|
|
319
|
+
} catch (e) {
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/storage/storeToStates.ts
|
|
324
|
+
var import_valtio3 = require("valtio");
|
|
325
|
+
function storeToStates(store) {
|
|
326
|
+
const snapshot = (0, import_valtio3.useSnapshot)(store);
|
|
327
|
+
const states = {};
|
|
328
|
+
function toState(key) {
|
|
329
|
+
const get = () => snapshot[key];
|
|
330
|
+
const set = (value) => {
|
|
331
|
+
store[key] = value;
|
|
332
|
+
};
|
|
333
|
+
return [get(), set];
|
|
334
|
+
}
|
|
335
|
+
for (const key of Object.keys(snapshot))
|
|
336
|
+
states[key] = toState(key);
|
|
337
|
+
return states;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/storage/defineStore.ts
|
|
341
|
+
var import_valtio4 = require("valtio");
|
|
342
|
+
function defineStore(store, options = {}) {
|
|
343
|
+
const state = typeof store.state === "function" ? store.state() : store.state;
|
|
344
|
+
const actions = store.actions || {};
|
|
345
|
+
const $state = options.persistant ? proxyWithPersistant(options.persistant, state) : (0, import_valtio4.proxy)(state);
|
|
346
|
+
const $actions = {};
|
|
347
|
+
for (const key in actions)
|
|
348
|
+
$actions[key] = actions[key].bind($state);
|
|
349
|
+
return {
|
|
350
|
+
$state: state,
|
|
351
|
+
$actions: actions,
|
|
352
|
+
...actions
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function useStore(store) {
|
|
356
|
+
return (0, import_valtio4.useSnapshot)(store.$state);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// src/hooks/defineAsyncStorage.ts
|
|
360
|
+
function defineAsyncStorage(options) {
|
|
361
|
+
const store = defineStore(
|
|
362
|
+
{
|
|
363
|
+
state: () => ({
|
|
364
|
+
promise: void 0,
|
|
365
|
+
value: options.initial,
|
|
366
|
+
loading: false,
|
|
367
|
+
error: void 0
|
|
368
|
+
})
|
|
369
|
+
},
|
|
370
|
+
{ persistant: options.persistant }
|
|
371
|
+
);
|
|
372
|
+
function use() {
|
|
373
|
+
const fn = options.setup();
|
|
374
|
+
const state = useStore(store);
|
|
375
|
+
function fetch(...args) {
|
|
376
|
+
if (state.loading)
|
|
377
|
+
return;
|
|
378
|
+
store.$state.loading = true;
|
|
379
|
+
store.$state.promise = fn(...args);
|
|
380
|
+
store.$state.promise.then((value) => store.$state.value = value).finally(() => store.$state.loading = false).catch((error) => {
|
|
381
|
+
store.$state.error = error;
|
|
382
|
+
throw error;
|
|
383
|
+
});
|
|
384
|
+
return store.$state.promise;
|
|
385
|
+
}
|
|
386
|
+
return [state, fetch];
|
|
387
|
+
}
|
|
388
|
+
return use;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/utils/index.ts
|
|
392
|
+
var hasOwn = {}.hasOwnProperty;
|
|
393
|
+
function cls(...args) {
|
|
394
|
+
let classes = "";
|
|
395
|
+
for (let i = 0; i < arguments.length; i++) {
|
|
396
|
+
const arg = arguments[i];
|
|
397
|
+
if (arg)
|
|
398
|
+
classes = appendClass(classes, parseValue(arg));
|
|
399
|
+
}
|
|
400
|
+
return classes;
|
|
401
|
+
}
|
|
402
|
+
function parseValue(arg) {
|
|
403
|
+
if (typeof arg === "string")
|
|
404
|
+
return arg;
|
|
405
|
+
if (typeof arg !== "object")
|
|
406
|
+
return "";
|
|
407
|
+
if (Array.isArray(arg))
|
|
408
|
+
return cls.apply(null, arg);
|
|
409
|
+
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]"))
|
|
410
|
+
return cls.toString();
|
|
411
|
+
let classes = "";
|
|
412
|
+
for (const key in arg) {
|
|
413
|
+
if (hasOwn.call(arg, key) && arg[key])
|
|
414
|
+
classes = appendClass(classes, key);
|
|
415
|
+
}
|
|
416
|
+
return classes;
|
|
417
|
+
}
|
|
418
|
+
function appendClass(value, newClass) {
|
|
419
|
+
if (!newClass)
|
|
420
|
+
return value;
|
|
421
|
+
return value ? `${value} ${newClass}` : newClass;
|
|
422
|
+
}
|
|
423
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
424
|
+
0 && (module.exports = {
|
|
425
|
+
Case,
|
|
426
|
+
Default,
|
|
427
|
+
Else,
|
|
428
|
+
If,
|
|
429
|
+
Injector,
|
|
430
|
+
Switch,
|
|
431
|
+
Then,
|
|
432
|
+
Trans,
|
|
433
|
+
Unless,
|
|
434
|
+
cls,
|
|
435
|
+
defineAsyncStorage,
|
|
436
|
+
defineStore,
|
|
437
|
+
proxyWithPersistant,
|
|
438
|
+
storeToState,
|
|
439
|
+
storeToStates,
|
|
440
|
+
useAsyncCallback,
|
|
441
|
+
useAsyncState,
|
|
442
|
+
useDebounce,
|
|
443
|
+
useEventBus,
|
|
444
|
+
useFetchRequestIntercept,
|
|
445
|
+
useFetchResponseIntercept,
|
|
446
|
+
useMounted,
|
|
447
|
+
useStore,
|
|
448
|
+
useWatch,
|
|
449
|
+
useWhenever
|
|
450
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { DetailedHTMLProps as DetailedHTMLProps$1, HTMLAttributes, ReactNode, PropsWithChildren, ReactElement, FC, ComponentClass, DependencyList } from 'react';
|
|
3
|
+
import { FunctionReturningPromise, PromiseType } from 'react-use/lib/misc/types';
|
|
4
|
+
import { AsyncState, AsyncFnReturn } from 'react-use/lib/useAsyncFn';
|
|
5
|
+
import { INTERNAL_Snapshot } from 'valtio';
|
|
6
|
+
|
|
7
|
+
type DetailedHTMLProps<T = HTMLDivElement> = DetailedHTMLProps$1<HTMLAttributes<T>, T>;
|
|
8
|
+
type BooleanLike = any;
|
|
9
|
+
|
|
10
|
+
interface CaseProps {
|
|
11
|
+
cond?: BooleanLike;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
declare function Case(props: CaseProps): ReactNode;
|
|
15
|
+
|
|
16
|
+
declare function Default(props: PropsWithChildren): react.ReactNode;
|
|
17
|
+
|
|
18
|
+
declare function Else(props: PropsWithChildren): react.ReactNode;
|
|
19
|
+
|
|
20
|
+
interface IfProps {
|
|
21
|
+
cond?: BooleanLike;
|
|
22
|
+
then?: ReactNode;
|
|
23
|
+
else?: ReactNode;
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
}
|
|
26
|
+
declare function If(props: IfProps): ReactNode;
|
|
27
|
+
|
|
28
|
+
interface SwitchProps extends PropsWithChildren {
|
|
29
|
+
value?: BooleanLike;
|
|
30
|
+
}
|
|
31
|
+
declare function Switch(props: SwitchProps): ReactElement<any, string | react.JSXElementConstructor<any>> | null;
|
|
32
|
+
|
|
33
|
+
declare function Then(props: PropsWithChildren): react.ReactNode;
|
|
34
|
+
|
|
35
|
+
interface UnlessProps {
|
|
36
|
+
cond?: BooleanLike;
|
|
37
|
+
then?: ReactNode;
|
|
38
|
+
else?: ReactNode;
|
|
39
|
+
children?: ReactNode;
|
|
40
|
+
}
|
|
41
|
+
declare function Unless(props: UnlessProps): ReactNode;
|
|
42
|
+
|
|
43
|
+
interface InjectComponent<P> {
|
|
44
|
+
component: FC<P> | ComponentClass<P>;
|
|
45
|
+
props?: P;
|
|
46
|
+
}
|
|
47
|
+
interface InjectorProps {
|
|
48
|
+
install: (FC<any> | InjectComponent<any> | ComponentClass<any>)[];
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
}
|
|
51
|
+
declare function Injector(props: InjectorProps): ReactNode;
|
|
52
|
+
|
|
53
|
+
interface TransProps {
|
|
54
|
+
i18nKey: string;
|
|
55
|
+
[key: string]: ReactNode;
|
|
56
|
+
}
|
|
57
|
+
declare function Trans({ i18nKey, ...additionalProps }: TransProps): ReactNode[];
|
|
58
|
+
|
|
59
|
+
declare function useDebounce<T>(value: T, delay: number): T;
|
|
60
|
+
|
|
61
|
+
interface EventBusListener<T = any> {
|
|
62
|
+
(event: T): void;
|
|
63
|
+
}
|
|
64
|
+
declare function useEventBus<T>(key: string): {
|
|
65
|
+
on: (listener: EventBusListener<T>) => void;
|
|
66
|
+
emit: (event?: T) => void;
|
|
67
|
+
off: (listener: EventBusListener) => void;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
declare function useMounted(): boolean;
|
|
71
|
+
|
|
72
|
+
interface WatchCallback<T> {
|
|
73
|
+
(value: T): void;
|
|
74
|
+
}
|
|
75
|
+
interface WatchOptions {
|
|
76
|
+
immediate?: boolean;
|
|
77
|
+
}
|
|
78
|
+
declare function useWatch<T>(source: T, callback: WatchCallback<T>, options?: WatchOptions): void;
|
|
79
|
+
|
|
80
|
+
declare function useWhenever<T>(source: T, cb: WatchCallback<Exclude<T, null | undefined>>, options?: WatchOptions): void;
|
|
81
|
+
|
|
82
|
+
declare function useAsyncCallback<T extends (...args: any[]) => any>(fun: T): readonly [boolean, T, Error | undefined];
|
|
83
|
+
|
|
84
|
+
type StateFromFunctionReturningPromise<T extends FunctionReturningPromise> = AsyncState<PromiseType<ReturnType<T>>>;
|
|
85
|
+
interface UseAsyncStateOptions<T extends FunctionReturningPromise> {
|
|
86
|
+
immediate?: boolean;
|
|
87
|
+
initial?: StateFromFunctionReturningPromise<T>;
|
|
88
|
+
}
|
|
89
|
+
declare function useAsyncState<T extends FunctionReturningPromise>(fn: T, deps?: DependencyList, options?: UseAsyncStateOptions<T>): AsyncFnReturn<T>;
|
|
90
|
+
|
|
91
|
+
interface FetchResponseInterceptCallback {
|
|
92
|
+
(response: Response): Response | Promise<Response>;
|
|
93
|
+
}
|
|
94
|
+
interface FetchRequestInterceptCallback {
|
|
95
|
+
(fetch: typeof window.fetch, input: RequestInfo | URL, init?: RequestInit | undefined): Response | Promise<Response>;
|
|
96
|
+
}
|
|
97
|
+
declare function useFetchResponseIntercept(intercept: FetchResponseInterceptCallback): void;
|
|
98
|
+
declare function useFetchRequestIntercept(intercept: FetchRequestInterceptCallback): void;
|
|
99
|
+
|
|
100
|
+
interface AsyncStorageOptions<T extends FunctionReturningPromise> {
|
|
101
|
+
initial?: ReturnType<T> extends Promise<infer U> ? U : undefined;
|
|
102
|
+
setup: () => T;
|
|
103
|
+
persistant?: string;
|
|
104
|
+
}
|
|
105
|
+
declare function defineAsyncStorage<T extends FunctionReturningPromise>(options: AsyncStorageOptions<T>): () => readonly [{
|
|
106
|
+
readonly promise: any;
|
|
107
|
+
readonly value: ((ReturnType<T> extends Promise<infer U> ? U : undefined) extends infer T_1 ? T_1 extends (ReturnType<T> extends Promise<infer U> ? U : undefined) ? T_1 extends {
|
|
108
|
+
$$valtioSnapshot: infer S;
|
|
109
|
+
} ? S : T_1 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_1 : T_1 extends Promise<unknown> ? Awaited<T_1> : T_1 extends object ? T_1 extends infer T_2 extends object ? { readonly [K in keyof T_2]: T_1[K] extends infer T_3 ? T_3 extends T_1[K] ? T_3 extends {
|
|
110
|
+
$$valtioSnapshot: infer S;
|
|
111
|
+
} ? S : T_3 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_3 : T_3 extends Promise<unknown> ? Awaited<T_3> : T_3 extends object ? T_3 extends infer T_4 extends object ? { readonly [K_1 in keyof T_4]: T_3[K_1] extends infer T_5 ? T_5 extends T_3[K_1] ? T_5 extends {
|
|
112
|
+
$$valtioSnapshot: infer S;
|
|
113
|
+
} ? S : T_5 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_5 : T_5 extends Promise<unknown> ? Awaited<T_5> : T_5 extends object ? T_5 extends infer T_6 extends object ? { readonly [K_2 in keyof T_6]: T_5[K_2] extends infer T_7 ? T_7 extends T_5[K_2] ? T_7 extends {
|
|
114
|
+
$$valtioSnapshot: infer S;
|
|
115
|
+
} ? S : T_7 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_7 : T_7 extends Promise<unknown> ? Awaited<T_7> : T_7 extends object ? T_7 extends infer T_8 extends object ? { readonly [K_3 in keyof T_8]: T_7[K_3] extends infer T_9 ? T_9 extends T_7[K_3] ? T_9 extends {
|
|
116
|
+
$$valtioSnapshot: infer S;
|
|
117
|
+
} ? S : T_9 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_9 : T_9 extends Promise<unknown> ? Awaited<T_9> : T_9 extends object ? T_9 extends infer T_10 extends object ? { readonly [K_4 in keyof T_10]: T_9[K_4] extends infer T_11 ? T_11 extends T_9[K_4] ? T_11 extends {
|
|
118
|
+
$$valtioSnapshot: infer S;
|
|
119
|
+
} ? S : T_11 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_11 : T_11 extends Promise<unknown> ? Awaited<T_11> : T_11 extends object ? T_11 extends infer T_12 extends object ? { readonly [K_5 in keyof T_12]: T_11[K_5] extends infer T_13 ? T_13 extends T_11[K_5] ? T_13 extends {
|
|
120
|
+
$$valtioSnapshot: infer S;
|
|
121
|
+
} ? S : T_13 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_13 : T_13 extends Promise<unknown> ? Awaited<T_13> : T_13 extends object ? T_13 extends infer T_14 extends object ? { readonly [K_6 in keyof T_14]: T_13[K_6] extends infer T_15 ? T_15 extends T_13[K_6] ? T_15 extends {
|
|
122
|
+
$$valtioSnapshot: infer S;
|
|
123
|
+
} ? S : T_15 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_15 : T_15 extends Promise<unknown> ? Awaited<T_15> : T_15 extends object ? T_15 extends infer T_16 extends object ? { readonly [K_7 in keyof T_16]: T_15[K_7] extends infer T_17 ? T_17 extends T_15[K_7] ? T_17 extends {
|
|
124
|
+
$$valtioSnapshot: infer S;
|
|
125
|
+
} ? S : T_17 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_17 : T_17 extends Promise<unknown> ? Awaited<T_17> : T_17 extends object ? T_17 extends infer T_18 extends object ? { readonly [K_8 in keyof T_18]: T_17[K_8] extends infer T_19 ? T_19 extends T_17[K_8] ? T_19 extends {
|
|
126
|
+
$$valtioSnapshot: infer S;
|
|
127
|
+
} ? S : T_19 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_19 : T_19 extends Promise<unknown> ? Awaited<T_19> : T_19 extends object ? T_19 extends infer T_20 extends object ? { readonly [K_9 in keyof T_20]: T_19[K_9] extends infer T_21 ? T_21 extends T_19[K_9] ? T_21 extends {
|
|
128
|
+
$$valtioSnapshot: infer S;
|
|
129
|
+
} ? S : T_21 extends RegExp | Error | Date | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | ((...args: any[]) => any) | (string | number | bigint | boolean | symbol | null | undefined) ? T_21 : T_21 extends Promise<unknown> ? Awaited<T_21> : T_21 extends object ? any : T_21 : never : never; } : never : T_19 : never : never; } : never : T_17 : never : never; } : never : T_15 : never : never; } : never : T_13 : never : never; } : never : T_11 : never : never; } : never : T_9 : never : never; } : never : T_7 : never : never; } : never : T_5 : never : never; } : never : T_3 : never : never; } : never : T_1 : never : never) | undefined;
|
|
130
|
+
readonly loading: boolean;
|
|
131
|
+
readonly error: Error | undefined;
|
|
132
|
+
}, T];
|
|
133
|
+
|
|
134
|
+
declare function storeToState<T extends object, K extends keyof T>(store: T, key: K): readonly [T[K], (value: T[K]) => void];
|
|
135
|
+
|
|
136
|
+
interface PersistantOptions {
|
|
137
|
+
storage?: Storage;
|
|
138
|
+
}
|
|
139
|
+
declare function proxyWithPersistant<T extends object>(key: string, initialObject?: T, options?: PersistantOptions): T;
|
|
140
|
+
|
|
141
|
+
type StoreToStates<S> = {
|
|
142
|
+
[K in keyof S]: [S[K], (value: S[K]) => void];
|
|
143
|
+
};
|
|
144
|
+
declare function storeToStates<S extends object>(store: S): StoreToStates<S>;
|
|
145
|
+
|
|
146
|
+
interface StoreDefine<S extends object, A extends Actions<S> = Record<string, any>> {
|
|
147
|
+
state: (() => S) | S;
|
|
148
|
+
actions?: A;
|
|
149
|
+
}
|
|
150
|
+
interface StoreOptions {
|
|
151
|
+
persistant?: string;
|
|
152
|
+
}
|
|
153
|
+
type Actions<S> = Record<string, (this: S) => void>;
|
|
154
|
+
type Store<S, A> = {
|
|
155
|
+
$state: S;
|
|
156
|
+
$actions: A;
|
|
157
|
+
} & A;
|
|
158
|
+
declare function defineStore<S extends object, A extends Actions<S>>(store: StoreDefine<S, A>, options?: StoreOptions): Store<S, A>;
|
|
159
|
+
declare function useStore<S extends object, A extends Actions<S>>(store: Store<S, A>): INTERNAL_Snapshot<S>;
|
|
160
|
+
|
|
161
|
+
type Value = string | boolean | undefined | null;
|
|
162
|
+
type Mapping = Record<string, any>;
|
|
163
|
+
interface ArgumentArray extends Array<Argument> {
|
|
164
|
+
}
|
|
165
|
+
interface ReadonlyArgumentArray extends ReadonlyArray<Argument> {
|
|
166
|
+
}
|
|
167
|
+
type Argument = Value | Mapping | ArgumentArray | ReadonlyArgumentArray;
|
|
168
|
+
/**
|
|
169
|
+
* A simple JavaScript utility for conditionally joining classNames together.
|
|
170
|
+
*/
|
|
171
|
+
declare function cls(...args: ArgumentArray): string;
|
|
172
|
+
|
|
173
|
+
export { Argument, ArgumentArray, AsyncStorageOptions, BooleanLike, Case, CaseProps, Default, DetailedHTMLProps, Else, EventBusListener, FetchRequestInterceptCallback, FetchResponseInterceptCallback, If, IfProps, InjectComponent, Injector, InjectorProps, Mapping, PersistantOptions, ReadonlyArgumentArray, StateFromFunctionReturningPromise, StoreToStates, Switch, SwitchProps, Then, Trans, TransProps, Unless, UnlessProps, UseAsyncStateOptions, Value, WatchCallback, WatchOptions, cls, defineAsyncStorage, defineStore, proxyWithPersistant, storeToState, storeToStates, useAsyncCallback, useAsyncState, useDebounce, useEventBus, useFetchRequestIntercept, useFetchResponseIntercept, useMounted, useStore, useWatch, useWhenever };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
// src/components/condition/Case.ts
|
|
2
|
+
function Case(props) {
|
|
3
|
+
return props.children;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// src/components/condition/Default.ts
|
|
7
|
+
function Default(props) {
|
|
8
|
+
return props.children;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/components/condition/Else.ts
|
|
12
|
+
function Else(props) {
|
|
13
|
+
return props.children;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/components/condition/If.ts
|
|
17
|
+
import { Children } from "react";
|
|
18
|
+
|
|
19
|
+
// src/components/condition/Then.ts
|
|
20
|
+
function Then(props) {
|
|
21
|
+
return props.children;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/components/condition/If.ts
|
|
25
|
+
function If(props) {
|
|
26
|
+
const children = props.then || props.children;
|
|
27
|
+
const elements = Children.toArray(children);
|
|
28
|
+
const thenChild = elements.find((c) => c.type === Then);
|
|
29
|
+
const elseChild = elements.find((c) => c.type === Else);
|
|
30
|
+
return thenChild || elseChild ? props.cond ? thenChild : elseChild : props.cond ? children : props.else;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/components/condition/Switch.ts
|
|
34
|
+
import { Children as Children2, isValidElement } from "react";
|
|
35
|
+
function Switch(props) {
|
|
36
|
+
var _a;
|
|
37
|
+
const isUseValue = props.value !== void 0;
|
|
38
|
+
let matchingCase;
|
|
39
|
+
let defaultCase;
|
|
40
|
+
Children2.forEach(props.children, (child) => {
|
|
41
|
+
if (!isValidElement(child) || matchingCase)
|
|
42
|
+
return;
|
|
43
|
+
if (child.type === Case) {
|
|
44
|
+
const cond = child.props.cond;
|
|
45
|
+
if (isUseValue ? props.value === cond : cond) {
|
|
46
|
+
matchingCase = child;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!defaultCase && child.type === Default)
|
|
51
|
+
defaultCase = child;
|
|
52
|
+
});
|
|
53
|
+
return (_a = matchingCase != null ? matchingCase : defaultCase) != null ? _a : null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/components/condition/Unless.ts
|
|
57
|
+
import { Children as Children3 } from "react";
|
|
58
|
+
function Unless(props) {
|
|
59
|
+
const children = props.then || props.children;
|
|
60
|
+
const elements = Children3.toArray(children);
|
|
61
|
+
const thenChild = elements.find((c) => c.type === Then);
|
|
62
|
+
const elseChild = elements.find((c) => c.type === Else);
|
|
63
|
+
return thenChild || elseChild ? !props.cond ? elseChild : thenChild : !props.cond ? props.children : props.else;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/components/utils/Injector.ts
|
|
67
|
+
import { createElement, useMemo } from "react";
|
|
68
|
+
function Injector(props) {
|
|
69
|
+
const installs = useMemo(
|
|
70
|
+
() => props.install.map(repack).reverse(),
|
|
71
|
+
[props.install]
|
|
72
|
+
);
|
|
73
|
+
return installs.reduce(
|
|
74
|
+
(child, { component: Component, props: props2 }) => createElement(Component, props2, child),
|
|
75
|
+
props.children
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function repack(c) {
|
|
79
|
+
return c.component ? c : { component: c };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/components/utils/Trans.ts
|
|
83
|
+
import { useTranslation } from "react-i18next";
|
|
84
|
+
import { createElement as createElement2 } from "react";
|
|
85
|
+
import HTML from "html-parse-stringify";
|
|
86
|
+
function Trans({ i18nKey, ...additionalProps }) {
|
|
87
|
+
const translation = useTranslation().t(i18nKey, additionalProps);
|
|
88
|
+
return renderNodes(HTML.parse(translation), additionalProps);
|
|
89
|
+
}
|
|
90
|
+
var index = 0;
|
|
91
|
+
function renderNodes(tokens, values) {
|
|
92
|
+
return tokens.map((token) => {
|
|
93
|
+
if (token.type === "text")
|
|
94
|
+
return token.content;
|
|
95
|
+
index++;
|
|
96
|
+
const props = { ...token.attrs, key: index };
|
|
97
|
+
return token.voidElement ? values[token.name] ? createElement2("span", { key: index }, values[token.name]) : createElement2(token.name, props) : createElement2(token.name, props, renderNodes(token.children, {}));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/hooks/useDebounce.ts
|
|
102
|
+
import { useEffect, useState } from "react";
|
|
103
|
+
function useDebounce(value, delay) {
|
|
104
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
const handler = setTimeout(() => setDebouncedValue(value), delay);
|
|
107
|
+
return () => clearTimeout(handler);
|
|
108
|
+
}, [value, delay]);
|
|
109
|
+
return debouncedValue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/hooks/useEventBus.ts
|
|
113
|
+
import { useEffect as useEffect2, useRef } from "react";
|
|
114
|
+
import mitt from "mitt";
|
|
115
|
+
var emitter = mitt();
|
|
116
|
+
function useEventBus(key) {
|
|
117
|
+
const onRef = useRef();
|
|
118
|
+
function on(listener) {
|
|
119
|
+
emitter.on(key, listener);
|
|
120
|
+
onRef.current = listener;
|
|
121
|
+
useEffect2(() => {
|
|
122
|
+
if (!onRef.current)
|
|
123
|
+
return;
|
|
124
|
+
emitter.off(key, onRef.current);
|
|
125
|
+
emitter.on(key, listener);
|
|
126
|
+
onRef.current = listener;
|
|
127
|
+
return () => emitter.off(key, listener);
|
|
128
|
+
}, [listener]);
|
|
129
|
+
}
|
|
130
|
+
function emit(event) {
|
|
131
|
+
emitter.emit(key, event);
|
|
132
|
+
}
|
|
133
|
+
function off(listener) {
|
|
134
|
+
emitter.off(key, listener);
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
on,
|
|
138
|
+
emit,
|
|
139
|
+
off
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/hooks/useMounted.ts
|
|
144
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
145
|
+
function useMounted() {
|
|
146
|
+
const [mounted, setMounted] = useState2(false);
|
|
147
|
+
useEffect3(() => setMounted(true), []);
|
|
148
|
+
return mounted;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/hooks/useWatch.ts
|
|
152
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
153
|
+
function useWatch(source, callback, options = {}) {
|
|
154
|
+
const firstUpdate = useRef2(false);
|
|
155
|
+
const then = useRef2();
|
|
156
|
+
const deps = useMemo2(
|
|
157
|
+
() => Array.isArray(source) ? source : [source],
|
|
158
|
+
[source]
|
|
159
|
+
);
|
|
160
|
+
useEffect4(() => {
|
|
161
|
+
if (!firstUpdate.current)
|
|
162
|
+
recordFirst();
|
|
163
|
+
else
|
|
164
|
+
callback(source);
|
|
165
|
+
}, deps);
|
|
166
|
+
async function recordFirst() {
|
|
167
|
+
if (then.current)
|
|
168
|
+
return;
|
|
169
|
+
then.current = Promise.resolve(source);
|
|
170
|
+
then.current.then(() => firstUpdate.current = true);
|
|
171
|
+
if (options.immediate)
|
|
172
|
+
then.current.then((value) => callback(value));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/hooks/useWhenever.ts
|
|
177
|
+
function useWhenever(source, cb, options) {
|
|
178
|
+
useWatch(source, () => source && cb(source), options);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/hooks/useAsyncCallback.ts
|
|
182
|
+
import { useState as useState3 } from "react";
|
|
183
|
+
function useAsyncCallback(fun) {
|
|
184
|
+
const [error, setError] = useState3();
|
|
185
|
+
const [loading, setLoading] = useState3(false);
|
|
186
|
+
async function execute(...args) {
|
|
187
|
+
try {
|
|
188
|
+
setLoading(true);
|
|
189
|
+
const result = await fun(...args);
|
|
190
|
+
setLoading(false);
|
|
191
|
+
return result;
|
|
192
|
+
} catch (error2) {
|
|
193
|
+
setLoading(false);
|
|
194
|
+
setError(error2);
|
|
195
|
+
throw error2;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return [loading, execute, error];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// src/hooks/useAsyncState.ts
|
|
202
|
+
import { useAsyncFn, useMount } from "react-use";
|
|
203
|
+
function useAsyncState(fn, deps, options) {
|
|
204
|
+
const [state, _fn] = useAsyncFn(fn, deps, options == null ? void 0 : options.initial);
|
|
205
|
+
useMount(() => (options == null ? void 0 : options.immediate) && _fn());
|
|
206
|
+
return [state, _fn];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/hooks/useFetchIntercept.ts
|
|
210
|
+
import { useMount as useMount2 } from "react-use";
|
|
211
|
+
function useFetchResponseIntercept(intercept) {
|
|
212
|
+
useMount2(() => fetchResponseIntercept(intercept));
|
|
213
|
+
}
|
|
214
|
+
function useFetchRequestIntercept(intercept) {
|
|
215
|
+
useMount2(() => fetchRequestIntercept(intercept));
|
|
216
|
+
}
|
|
217
|
+
function fetchResponseIntercept(intercept) {
|
|
218
|
+
const { fetch: originalFetch } = window;
|
|
219
|
+
window.fetch = async (...args) => {
|
|
220
|
+
const [resource, config] = args;
|
|
221
|
+
const response = await originalFetch(resource, config);
|
|
222
|
+
return intercept(response);
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function fetchRequestIntercept(intercept) {
|
|
226
|
+
const { fetch: originalFetch } = window;
|
|
227
|
+
window.fetch = async (...args) => {
|
|
228
|
+
const [resource, config] = args;
|
|
229
|
+
return intercept(originalFetch, resource, config);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/storage/storeToState.ts
|
|
234
|
+
import { useSnapshot } from "valtio";
|
|
235
|
+
function storeToState(store, key) {
|
|
236
|
+
const snapshot = useSnapshot(store);
|
|
237
|
+
function get() {
|
|
238
|
+
return snapshot[key];
|
|
239
|
+
}
|
|
240
|
+
function set(value) {
|
|
241
|
+
store[key] = value;
|
|
242
|
+
}
|
|
243
|
+
return [get(), set];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/storage/proxyWithPersistant.ts
|
|
247
|
+
import { proxy, subscribe } from "valtio";
|
|
248
|
+
function proxyWithPersistant(key, initialObject, options = {}) {
|
|
249
|
+
const storage = options.storage || (typeof localStorage !== "undefined" ? localStorage : void 0);
|
|
250
|
+
const state = proxy(parse(storage == null ? void 0 : storage.getItem(key)) || initialObject);
|
|
251
|
+
subscribe(state, () => {
|
|
252
|
+
storage == null ? void 0 : storage.setItem(key, JSON.stringify(state));
|
|
253
|
+
});
|
|
254
|
+
return state;
|
|
255
|
+
}
|
|
256
|
+
function parse(text) {
|
|
257
|
+
try {
|
|
258
|
+
return JSON.parse(text || "");
|
|
259
|
+
} catch (e) {
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/storage/storeToStates.ts
|
|
264
|
+
import { useSnapshot as useSnapshot2 } from "valtio";
|
|
265
|
+
function storeToStates(store) {
|
|
266
|
+
const snapshot = useSnapshot2(store);
|
|
267
|
+
const states = {};
|
|
268
|
+
function toState(key) {
|
|
269
|
+
const get = () => snapshot[key];
|
|
270
|
+
const set = (value) => {
|
|
271
|
+
store[key] = value;
|
|
272
|
+
};
|
|
273
|
+
return [get(), set];
|
|
274
|
+
}
|
|
275
|
+
for (const key of Object.keys(snapshot))
|
|
276
|
+
states[key] = toState(key);
|
|
277
|
+
return states;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/storage/defineStore.ts
|
|
281
|
+
import { proxy as proxy2, useSnapshot as useSnapshot3 } from "valtio";
|
|
282
|
+
function defineStore(store, options = {}) {
|
|
283
|
+
const state = typeof store.state === "function" ? store.state() : store.state;
|
|
284
|
+
const actions = store.actions || {};
|
|
285
|
+
const $state = options.persistant ? proxyWithPersistant(options.persistant, state) : proxy2(state);
|
|
286
|
+
const $actions = {};
|
|
287
|
+
for (const key in actions)
|
|
288
|
+
$actions[key] = actions[key].bind($state);
|
|
289
|
+
return {
|
|
290
|
+
$state: state,
|
|
291
|
+
$actions: actions,
|
|
292
|
+
...actions
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function useStore(store) {
|
|
296
|
+
return useSnapshot3(store.$state);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/hooks/defineAsyncStorage.ts
|
|
300
|
+
function defineAsyncStorage(options) {
|
|
301
|
+
const store = defineStore(
|
|
302
|
+
{
|
|
303
|
+
state: () => ({
|
|
304
|
+
promise: void 0,
|
|
305
|
+
value: options.initial,
|
|
306
|
+
loading: false,
|
|
307
|
+
error: void 0
|
|
308
|
+
})
|
|
309
|
+
},
|
|
310
|
+
{ persistant: options.persistant }
|
|
311
|
+
);
|
|
312
|
+
function use() {
|
|
313
|
+
const fn = options.setup();
|
|
314
|
+
const state = useStore(store);
|
|
315
|
+
function fetch(...args) {
|
|
316
|
+
if (state.loading)
|
|
317
|
+
return;
|
|
318
|
+
store.$state.loading = true;
|
|
319
|
+
store.$state.promise = fn(...args);
|
|
320
|
+
store.$state.promise.then((value) => store.$state.value = value).finally(() => store.$state.loading = false).catch((error) => {
|
|
321
|
+
store.$state.error = error;
|
|
322
|
+
throw error;
|
|
323
|
+
});
|
|
324
|
+
return store.$state.promise;
|
|
325
|
+
}
|
|
326
|
+
return [state, fetch];
|
|
327
|
+
}
|
|
328
|
+
return use;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// src/utils/index.ts
|
|
332
|
+
var hasOwn = {}.hasOwnProperty;
|
|
333
|
+
function cls(...args) {
|
|
334
|
+
let classes = "";
|
|
335
|
+
for (let i = 0; i < arguments.length; i++) {
|
|
336
|
+
const arg = arguments[i];
|
|
337
|
+
if (arg)
|
|
338
|
+
classes = appendClass(classes, parseValue(arg));
|
|
339
|
+
}
|
|
340
|
+
return classes;
|
|
341
|
+
}
|
|
342
|
+
function parseValue(arg) {
|
|
343
|
+
if (typeof arg === "string")
|
|
344
|
+
return arg;
|
|
345
|
+
if (typeof arg !== "object")
|
|
346
|
+
return "";
|
|
347
|
+
if (Array.isArray(arg))
|
|
348
|
+
return cls.apply(null, arg);
|
|
349
|
+
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]"))
|
|
350
|
+
return cls.toString();
|
|
351
|
+
let classes = "";
|
|
352
|
+
for (const key in arg) {
|
|
353
|
+
if (hasOwn.call(arg, key) && arg[key])
|
|
354
|
+
classes = appendClass(classes, key);
|
|
355
|
+
}
|
|
356
|
+
return classes;
|
|
357
|
+
}
|
|
358
|
+
function appendClass(value, newClass) {
|
|
359
|
+
if (!newClass)
|
|
360
|
+
return value;
|
|
361
|
+
return value ? `${value} ${newClass}` : newClass;
|
|
362
|
+
}
|
|
363
|
+
export {
|
|
364
|
+
Case,
|
|
365
|
+
Default,
|
|
366
|
+
Else,
|
|
367
|
+
If,
|
|
368
|
+
Injector,
|
|
369
|
+
Switch,
|
|
370
|
+
Then,
|
|
371
|
+
Trans,
|
|
372
|
+
Unless,
|
|
373
|
+
cls,
|
|
374
|
+
defineAsyncStorage,
|
|
375
|
+
defineStore,
|
|
376
|
+
proxyWithPersistant,
|
|
377
|
+
storeToState,
|
|
378
|
+
storeToStates,
|
|
379
|
+
useAsyncCallback,
|
|
380
|
+
useAsyncState,
|
|
381
|
+
useDebounce,
|
|
382
|
+
useEventBus,
|
|
383
|
+
useFetchRequestIntercept,
|
|
384
|
+
useFetchResponseIntercept,
|
|
385
|
+
useMounted,
|
|
386
|
+
useStore,
|
|
387
|
+
useWatch,
|
|
388
|
+
useWhenever
|
|
389
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hairy/react-lib",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"jsdelivr": "./dist/index.iife.min.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"html-parse-stringify": "^3.0.1",
|
|
14
|
+
"mitt": "^3.0.1",
|
|
15
|
+
"react": "^18.2.0",
|
|
16
|
+
"react-dom": "^18.2.0",
|
|
17
|
+
"react-i18next": "^14.1.2",
|
|
18
|
+
"valtio": "^1.13.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.11.7",
|
|
22
|
+
"@types/react": "^18.2.43",
|
|
23
|
+
"@types/react-dom": "^18.2.17"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "ptsup src/index.ts --dts"
|
|
27
|
+
},
|
|
28
|
+
"module": "./dist/index.mjs",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"unpkg": "./dist/index.iife.min.js",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"import": "./dist/index.mjs",
|
|
34
|
+
"require": "./dist/index.cjs",
|
|
35
|
+
"types": "./dist/index.d.ts"
|
|
36
|
+
},
|
|
37
|
+
"./*": "./*"
|
|
38
|
+
}
|
|
39
|
+
}
|