@faasjs/react 8.0.0-beta.2 → 8.0.0-beta.21
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 +16 -68
- package/dist/index.d.ts +1557 -410
- package/dist/index.mjs +1765 -595
- package/package.json +18 -22
- package/dist/index.cjs +0 -652
package/package.json
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faasjs/react",
|
|
3
|
-
"version": "
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.cjs",
|
|
7
|
-
"module": "dist/index.mjs",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.mjs",
|
|
13
|
-
"require": "./dist/index.cjs"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
3
|
+
"version": "8.0.0-beta.21",
|
|
16
4
|
"homepage": "https://faasjs.com/doc/react/",
|
|
5
|
+
"bugs": {
|
|
6
|
+
"url": "https://github.com/faasjs/faasjs/issues"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
17
9
|
"repository": {
|
|
18
10
|
"type": "git",
|
|
19
11
|
"url": "git+https://github.com/faasjs/faasjs.git",
|
|
20
12
|
"directory": "packages/react"
|
|
21
13
|
},
|
|
22
|
-
"bugs": {
|
|
23
|
-
"url": "https://github.com/faasjs/faasjs/issues"
|
|
24
|
-
},
|
|
25
14
|
"funding": "https://github.com/sponsors/faasjs",
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "tsup src/index.tsx --config ../../tsup.config.ts --external react"
|
|
28
|
-
},
|
|
29
15
|
"files": [
|
|
30
16
|
"dist"
|
|
31
17
|
],
|
|
32
|
-
"
|
|
33
|
-
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "dist/index.mjs",
|
|
20
|
+
"module": "dist/index.mjs",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"default": "./dist/index.mjs"
|
|
26
|
+
}
|
|
34
27
|
},
|
|
35
28
|
"devDependencies": {
|
|
36
|
-
"@faasjs/
|
|
29
|
+
"@faasjs/types": ">=8.0.0-beta.21",
|
|
37
30
|
"@types/react": "^19.0.0",
|
|
38
31
|
"react": "^19.0.0"
|
|
39
32
|
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@faasjs/types": ">=8.0.0-beta.21"
|
|
35
|
+
},
|
|
40
36
|
"engines": {
|
|
41
37
|
"node": ">=24.0.0",
|
|
42
38
|
"npm": ">=11.0.0"
|
package/dist/index.cjs
DELETED
|
@@ -1,652 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var browser = require('@faasjs/browser');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
|
|
7
|
-
// src/client.tsx
|
|
8
|
-
var AsyncFunction = (async () => {
|
|
9
|
-
}).constructor;
|
|
10
|
-
function equal(a, b) {
|
|
11
|
-
if (a === b) return true;
|
|
12
|
-
if ((a === null || a === void 0) && (b === null || b === void 0))
|
|
13
|
-
return true;
|
|
14
|
-
if (typeof a !== typeof b) return false;
|
|
15
|
-
if (a === null || a === void 0 || b === null || b === void 0)
|
|
16
|
-
return false;
|
|
17
|
-
const ctor = a.constructor;
|
|
18
|
-
if (ctor !== b.constructor) return false;
|
|
19
|
-
switch (ctor) {
|
|
20
|
-
case String:
|
|
21
|
-
case Boolean:
|
|
22
|
-
return a === b;
|
|
23
|
-
case Number:
|
|
24
|
-
return Number.isNaN(a) && Number.isNaN(b) || a === b;
|
|
25
|
-
case Array: {
|
|
26
|
-
if (a.length !== b.length) return false;
|
|
27
|
-
for (let i = 0; i < a.length; i++) {
|
|
28
|
-
if (!equal(a[i], b[i])) return false;
|
|
29
|
-
}
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
case Date:
|
|
33
|
-
return a.getTime() === b.getTime();
|
|
34
|
-
case RegExp:
|
|
35
|
-
case Function:
|
|
36
|
-
case AsyncFunction:
|
|
37
|
-
return a.toString() === b.toString();
|
|
38
|
-
case Map:
|
|
39
|
-
case Set:
|
|
40
|
-
return equal(Array.from(a), Array.from(b));
|
|
41
|
-
case Promise:
|
|
42
|
-
return a === b;
|
|
43
|
-
case Object: {
|
|
44
|
-
for (const key of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]))
|
|
45
|
-
if (!equal(a[key], b[key])) return false;
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
default:
|
|
49
|
-
throw Error(`Unsupported type: ${ctor}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function useEqualMemoize(value) {
|
|
53
|
-
const ref = react.useRef(value);
|
|
54
|
-
const signalRef = react.useRef(0);
|
|
55
|
-
if (!equal(value, ref.current)) {
|
|
56
|
-
ref.current = value;
|
|
57
|
-
signalRef.current += 1;
|
|
58
|
-
}
|
|
59
|
-
return react.useMemo(() => ref.current, [signalRef.current]);
|
|
60
|
-
}
|
|
61
|
-
function useEqualEffect(callback, dependencies) {
|
|
62
|
-
return react.useEffect(callback, useEqualMemoize(dependencies));
|
|
63
|
-
}
|
|
64
|
-
function useEqualMemo(callback, dependencies) {
|
|
65
|
-
return react.useMemo(callback, useEqualMemoize(dependencies));
|
|
66
|
-
}
|
|
67
|
-
function useEqualCallback(callback, dependencies) {
|
|
68
|
-
return react.useCallback(
|
|
69
|
-
(...args) => callback(...args),
|
|
70
|
-
useEqualMemoize(dependencies)
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
var fixedForwardRef = react.forwardRef;
|
|
74
|
-
var FaasDataWrapper = fixedForwardRef(
|
|
75
|
-
(props, ref) => {
|
|
76
|
-
const request = getClient(props.baseUrl).useFaas(
|
|
77
|
-
props.action,
|
|
78
|
-
props.params,
|
|
79
|
-
{
|
|
80
|
-
data: props.data,
|
|
81
|
-
setData: props.setData
|
|
82
|
-
}
|
|
83
|
-
);
|
|
84
|
-
const [loaded, setLoaded] = react.useState(false);
|
|
85
|
-
react.useImperativeHandle(ref, () => request, [request]);
|
|
86
|
-
useEqualEffect(() => {
|
|
87
|
-
if (!request.loading) setLoaded((prev) => prev === false ? true : prev);
|
|
88
|
-
}, [request.loading]);
|
|
89
|
-
useEqualEffect(() => {
|
|
90
|
-
if (props.onDataChange) props.onDataChange(request);
|
|
91
|
-
}, [request.data]);
|
|
92
|
-
const child = useEqualMemo(() => {
|
|
93
|
-
if (loaded) {
|
|
94
|
-
if (props.children) return react.cloneElement(props.children, request);
|
|
95
|
-
if (props.render) return props.render(request);
|
|
96
|
-
}
|
|
97
|
-
return props.fallback || null;
|
|
98
|
-
}, [
|
|
99
|
-
loaded,
|
|
100
|
-
request.action,
|
|
101
|
-
request.params,
|
|
102
|
-
request.data,
|
|
103
|
-
request.error,
|
|
104
|
-
request.loading
|
|
105
|
-
]);
|
|
106
|
-
return child;
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
Object.assign(FaasDataWrapper, {
|
|
110
|
-
displayName: "FaasDataWrapper",
|
|
111
|
-
whyDidYouRender: true
|
|
112
|
-
});
|
|
113
|
-
function withFaasData(Component2, faasProps) {
|
|
114
|
-
return (props) => /* @__PURE__ */ jsxRuntime.jsx(FaasDataWrapper, { ...faasProps, children: /* @__PURE__ */ jsxRuntime.jsx(Component2, { ...props }) });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// src/faas.ts
|
|
118
|
-
async function faas(action, params, options) {
|
|
119
|
-
const client = getClient(options?.baseUrl);
|
|
120
|
-
if (client.onError)
|
|
121
|
-
return client.browserClient.action(action, params, options).catch(async (res) => {
|
|
122
|
-
await client.onError(action, params)(res);
|
|
123
|
-
return Promise.reject(res);
|
|
124
|
-
});
|
|
125
|
-
return client.browserClient.action(action, params, options);
|
|
126
|
-
}
|
|
127
|
-
function useFaas(action, defaultParams, options = {}) {
|
|
128
|
-
const [loading, setLoading] = react.useState(true);
|
|
129
|
-
const [data, setData] = react.useState();
|
|
130
|
-
const [error, setError] = react.useState();
|
|
131
|
-
const [params, setParams] = react.useState(defaultParams);
|
|
132
|
-
const [reloadTimes, setReloadTimes] = react.useState(0);
|
|
133
|
-
const [fails, setFails] = react.useState(0);
|
|
134
|
-
const [skip, setSkip] = react.useState(
|
|
135
|
-
typeof options.skip === "function" ? options.skip(defaultParams) : options.skip
|
|
136
|
-
);
|
|
137
|
-
const promiseRef = react.useRef(null);
|
|
138
|
-
const controllerRef = react.useRef(null);
|
|
139
|
-
const pendingReloadsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
140
|
-
const reloadCounterRef = react.useRef(0);
|
|
141
|
-
useEqualEffect(() => {
|
|
142
|
-
setSkip(
|
|
143
|
-
typeof options.skip === "function" ? options.skip(params) : options.skip
|
|
144
|
-
);
|
|
145
|
-
}, [typeof options.skip === "function" ? params : options.skip]);
|
|
146
|
-
useEqualEffect(() => {
|
|
147
|
-
if (!equal(defaultParams, params)) {
|
|
148
|
-
setParams(defaultParams);
|
|
149
|
-
}
|
|
150
|
-
}, [defaultParams]);
|
|
151
|
-
useEqualEffect(() => {
|
|
152
|
-
if (!action || skip) {
|
|
153
|
-
setLoading(false);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
setLoading(true);
|
|
157
|
-
controllerRef.current = new AbortController();
|
|
158
|
-
const client = getClient(options.baseUrl);
|
|
159
|
-
function send() {
|
|
160
|
-
const request = client.faas(
|
|
161
|
-
action,
|
|
162
|
-
options.params || params,
|
|
163
|
-
{ signal: controllerRef.current.signal }
|
|
164
|
-
);
|
|
165
|
-
promiseRef.current = request;
|
|
166
|
-
request.then((r) => {
|
|
167
|
-
setFails(0);
|
|
168
|
-
setError(null);
|
|
169
|
-
options.setData ? options.setData(r.data) : setData(r.data);
|
|
170
|
-
setLoading(false);
|
|
171
|
-
for (const { resolve } of pendingReloadsRef.current.values())
|
|
172
|
-
resolve(r.data);
|
|
173
|
-
pendingReloadsRef.current.clear();
|
|
174
|
-
}).catch(async (e) => {
|
|
175
|
-
if (typeof e?.message === "string" && e.message.toLowerCase().indexOf("aborted") >= 0)
|
|
176
|
-
return;
|
|
177
|
-
if (!fails && typeof e?.message === "string" && e.message.indexOf("Failed to fetch") >= 0) {
|
|
178
|
-
console.warn(`FaasReactClient: ${e.message} retry...`);
|
|
179
|
-
setFails(1);
|
|
180
|
-
return send();
|
|
181
|
-
}
|
|
182
|
-
let error2 = e;
|
|
183
|
-
if (client.onError)
|
|
184
|
-
try {
|
|
185
|
-
await client.onError(action, params)(e);
|
|
186
|
-
} catch (newError) {
|
|
187
|
-
error2 = newError;
|
|
188
|
-
}
|
|
189
|
-
setError(error2);
|
|
190
|
-
setLoading(false);
|
|
191
|
-
for (const { reject } of pendingReloadsRef.current.values())
|
|
192
|
-
reject(error2);
|
|
193
|
-
pendingReloadsRef.current.clear();
|
|
194
|
-
return;
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
if (options.debounce) {
|
|
198
|
-
const timeout = setTimeout(send, options.debounce);
|
|
199
|
-
return () => {
|
|
200
|
-
clearTimeout(timeout);
|
|
201
|
-
controllerRef.current?.abort();
|
|
202
|
-
setLoading(false);
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
send();
|
|
206
|
-
return () => {
|
|
207
|
-
controllerRef.current?.abort();
|
|
208
|
-
setLoading(false);
|
|
209
|
-
};
|
|
210
|
-
}, [action, options.params || params, reloadTimes, skip]);
|
|
211
|
-
const reload = useEqualCallback(
|
|
212
|
-
(params2) => {
|
|
213
|
-
if (skip) setSkip(false);
|
|
214
|
-
if (params2) setParams(params2);
|
|
215
|
-
const reloadCounter = ++reloadCounterRef.current;
|
|
216
|
-
setReloadTimes((prev) => prev + 1);
|
|
217
|
-
return new Promise((resolve, reject) => {
|
|
218
|
-
pendingReloadsRef.current.set(reloadCounter, { resolve, reject });
|
|
219
|
-
setReloadTimes((prev) => prev + 1);
|
|
220
|
-
});
|
|
221
|
-
},
|
|
222
|
-
[params, skip]
|
|
223
|
-
);
|
|
224
|
-
return {
|
|
225
|
-
action,
|
|
226
|
-
params,
|
|
227
|
-
loading,
|
|
228
|
-
data: options.data || data,
|
|
229
|
-
reloadTimes,
|
|
230
|
-
error,
|
|
231
|
-
promise: promiseRef.current,
|
|
232
|
-
reload,
|
|
233
|
-
setData: options.setData || setData,
|
|
234
|
-
setLoading,
|
|
235
|
-
setPromise: (newPromise) => typeof newPromise === "function" ? newPromise(promiseRef.current) : promiseRef.current = newPromise,
|
|
236
|
-
setError
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
var clients = {};
|
|
240
|
-
function FaasReactClient({ baseUrl, options, onError } = {
|
|
241
|
-
baseUrl: "/"
|
|
242
|
-
}) {
|
|
243
|
-
const client = new browser.FaasBrowserClient(baseUrl, options);
|
|
244
|
-
const reactClient = {
|
|
245
|
-
id: client.id,
|
|
246
|
-
faas: async (action, params, options2) => faas(action, params, { baseUrl, ...options2 }),
|
|
247
|
-
useFaas: (action, defaultParams, options2) => useFaas(action, defaultParams, { baseUrl, ...options2 }),
|
|
248
|
-
FaasDataWrapper: (props) => /* @__PURE__ */ jsxRuntime.jsx(FaasDataWrapper, { baseUrl, ...props }),
|
|
249
|
-
onError,
|
|
250
|
-
browserClient: client
|
|
251
|
-
};
|
|
252
|
-
clients[baseUrl] = reactClient;
|
|
253
|
-
return reactClient;
|
|
254
|
-
}
|
|
255
|
-
function getClient(host) {
|
|
256
|
-
const client = clients[host || Object.keys(clients)[0]];
|
|
257
|
-
if (!client) {
|
|
258
|
-
console.warn("FaasReactClient is not initialized manually, use default.");
|
|
259
|
-
return FaasReactClient();
|
|
260
|
-
}
|
|
261
|
-
return client;
|
|
262
|
-
}
|
|
263
|
-
function useConstant(fn) {
|
|
264
|
-
const ref = react.useRef(null);
|
|
265
|
-
if (!ref.current) {
|
|
266
|
-
ref.current = { v: fn() };
|
|
267
|
-
}
|
|
268
|
-
return ref.current.v;
|
|
269
|
-
}
|
|
270
|
-
useConstant.whyDidYouRender = true;
|
|
271
|
-
var ErrorBoundary = class extends react.Component {
|
|
272
|
-
static displayName = "ErrorBoundary";
|
|
273
|
-
static whyDidYouRender = true;
|
|
274
|
-
constructor(props) {
|
|
275
|
-
super(props);
|
|
276
|
-
this.state = {
|
|
277
|
-
error: void 0,
|
|
278
|
-
info: { componentStack: "" }
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
componentDidCatch(error, info) {
|
|
282
|
-
this.setState({
|
|
283
|
-
error,
|
|
284
|
-
info
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
render() {
|
|
288
|
-
const errorMessage = (this.state.error || "").toString();
|
|
289
|
-
const errorDescription = this.state.info?.componentStack ? this.state.info.componentStack : null;
|
|
290
|
-
if (this.state.error) {
|
|
291
|
-
if (this.props.onError)
|
|
292
|
-
this.props.onError(this.state.error, this.state.info);
|
|
293
|
-
if (this.props.errorChildren)
|
|
294
|
-
return react.cloneElement(this.props.errorChildren, {
|
|
295
|
-
error: this.state.error,
|
|
296
|
-
info: this.state.info,
|
|
297
|
-
errorMessage,
|
|
298
|
-
errorDescription
|
|
299
|
-
});
|
|
300
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
301
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { children: errorMessage }),
|
|
302
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { children: errorDescription })
|
|
303
|
-
] });
|
|
304
|
-
}
|
|
305
|
-
return this.props.children;
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
function useStateRef(initialValue) {
|
|
309
|
-
const [state, setState] = react.useState(initialValue ?? null);
|
|
310
|
-
const ref = react.useRef(state);
|
|
311
|
-
react.useEffect(() => {
|
|
312
|
-
ref.current = state;
|
|
313
|
-
}, [state]);
|
|
314
|
-
return [state, setState, ref];
|
|
315
|
-
}
|
|
316
|
-
function useSplittingState(initialStates) {
|
|
317
|
-
const states = {};
|
|
318
|
-
for (const key of Object.keys(initialStates)) {
|
|
319
|
-
const state = react.useState(initialStates[key]);
|
|
320
|
-
Object.assign(states, {
|
|
321
|
-
[key]: state[0],
|
|
322
|
-
[`set${String(key).charAt(0).toUpperCase()}${String(key).slice(1)}`]: state[1]
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
return states;
|
|
326
|
-
}
|
|
327
|
-
function createSplittingContext(defaultValue) {
|
|
328
|
-
const keys = Array.isArray(defaultValue) ? defaultValue : Object.keys(defaultValue);
|
|
329
|
-
const defaultValues = Array.isArray(defaultValue) ? keys.reduce(
|
|
330
|
-
(prev, cur) => {
|
|
331
|
-
prev[cur] = null;
|
|
332
|
-
return prev;
|
|
333
|
-
},
|
|
334
|
-
{}
|
|
335
|
-
) : defaultValue;
|
|
336
|
-
const contexts = {};
|
|
337
|
-
for (const key of keys) contexts[key] = react.createContext(defaultValues[key]);
|
|
338
|
-
function Provider(props) {
|
|
339
|
-
const states = props.initializeStates ? useSplittingState(props.initializeStates) : {};
|
|
340
|
-
let children = props.memo ? useEqualMemo(
|
|
341
|
-
() => props.children,
|
|
342
|
-
props.memo === true ? [] : props.memo
|
|
343
|
-
) : props.children;
|
|
344
|
-
for (const key of keys) {
|
|
345
|
-
const Context = contexts[key];
|
|
346
|
-
const value = props.value?.[key] ?? states[key] ?? defaultValues[key];
|
|
347
|
-
children = /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
|
|
348
|
-
}
|
|
349
|
-
return children;
|
|
350
|
-
}
|
|
351
|
-
Provider.displayName = "SplittingContextProvider";
|
|
352
|
-
Provider.whyDidYouRender = true;
|
|
353
|
-
function use() {
|
|
354
|
-
return useConstant(() => {
|
|
355
|
-
const obj = /* @__PURE__ */ Object.create(null);
|
|
356
|
-
for (const key of Object.keys(contexts)) {
|
|
357
|
-
Object.defineProperty(obj, key, {
|
|
358
|
-
get: () => {
|
|
359
|
-
if (!contexts[key]) {
|
|
360
|
-
throw new Error(`Context for key "${key}" is undefined`);
|
|
361
|
-
}
|
|
362
|
-
return react.useContext(contexts[key]);
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
return Object.freeze(obj);
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
use.whyDidYouRender = true;
|
|
370
|
-
return {
|
|
371
|
-
Provider,
|
|
372
|
-
use
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// src/Form/context.tsx
|
|
377
|
-
var FormContext = createSplittingContext([
|
|
378
|
-
"items",
|
|
379
|
-
"onSubmit",
|
|
380
|
-
"Elements",
|
|
381
|
-
"lang",
|
|
382
|
-
"rules",
|
|
383
|
-
"submitting",
|
|
384
|
-
"setSubmitting",
|
|
385
|
-
"values",
|
|
386
|
-
"setValues",
|
|
387
|
-
"errors",
|
|
388
|
-
"setErrors",
|
|
389
|
-
"valuesRef"
|
|
390
|
-
]);
|
|
391
|
-
var FormContextProvider = FormContext.Provider;
|
|
392
|
-
var useFormContext = FormContext.use;
|
|
393
|
-
function processValue(input, rules) {
|
|
394
|
-
switch (rules?.type) {
|
|
395
|
-
case "number":
|
|
396
|
-
return Number(input);
|
|
397
|
-
case "string":
|
|
398
|
-
return String(input);
|
|
399
|
-
default:
|
|
400
|
-
return input;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
function FormInput({
|
|
404
|
-
name,
|
|
405
|
-
rules,
|
|
406
|
-
...rest
|
|
407
|
-
}) {
|
|
408
|
-
const { Elements, values, setValues } = useFormContext();
|
|
409
|
-
const value = values?.[name];
|
|
410
|
-
if (rest.Input) {
|
|
411
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
412
|
-
rest.Input,
|
|
413
|
-
{
|
|
414
|
-
name,
|
|
415
|
-
value,
|
|
416
|
-
onChange: (v) => setValues((prev) => ({
|
|
417
|
-
...prev,
|
|
418
|
-
[name]: processValue(v, rules)
|
|
419
|
-
})),
|
|
420
|
-
...rest.props
|
|
421
|
-
}
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
425
|
-
Elements.Input,
|
|
426
|
-
{
|
|
427
|
-
name,
|
|
428
|
-
value,
|
|
429
|
-
onChange: (v) => setValues((prev) => ({
|
|
430
|
-
...prev,
|
|
431
|
-
[name]: processValue(v, rules)
|
|
432
|
-
})),
|
|
433
|
-
...rest.props
|
|
434
|
-
}
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
FormInput.displayName = "FormInput";
|
|
438
|
-
FormInput.whyDidYouRender = true;
|
|
439
|
-
function FormItem(props) {
|
|
440
|
-
const { Elements, errors } = useFormContext();
|
|
441
|
-
const Label = props.label?.Label ?? Elements.Label;
|
|
442
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Label, { name: props.name, ...props.label, error: errors[props.name], children: /* @__PURE__ */ jsxRuntime.jsx(FormInput, { name: props.name, rules: props.rules, ...props.input }) });
|
|
443
|
-
}
|
|
444
|
-
FormItem.displayName = "FormItem";
|
|
445
|
-
FormItem.whyDidYouRender = true;
|
|
446
|
-
function FormBody() {
|
|
447
|
-
const { items } = useFormContext();
|
|
448
|
-
return items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(FormItem, { ...item }, item.name));
|
|
449
|
-
}
|
|
450
|
-
FormBody.displayName = "FormBody";
|
|
451
|
-
FormBody.whyDidYouRender = true;
|
|
452
|
-
var FormButtonElement = react.forwardRef(({ children, submit, submitting, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
453
|
-
"button",
|
|
454
|
-
{
|
|
455
|
-
type: "button",
|
|
456
|
-
disabled: submitting,
|
|
457
|
-
onClick: submit,
|
|
458
|
-
...props,
|
|
459
|
-
ref,
|
|
460
|
-
children
|
|
461
|
-
}
|
|
462
|
-
));
|
|
463
|
-
FormButtonElement.displayName = "FormButtonElement";
|
|
464
|
-
Object.assign(FormButtonElement, { whyDidYouRender: true });
|
|
465
|
-
var FormInputElement = react.forwardRef(({ onChange, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("input", { ...props, onChange: (e) => onChange(e.target.value), ref }));
|
|
466
|
-
FormInputElement.displayName = "FormInputElement";
|
|
467
|
-
Object.assign(FormInputElement, { whyDidYouRender: true });
|
|
468
|
-
var FormLabelElement = ({
|
|
469
|
-
name,
|
|
470
|
-
title,
|
|
471
|
-
description,
|
|
472
|
-
error,
|
|
473
|
-
children
|
|
474
|
-
}) => {
|
|
475
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
476
|
-
title ?? name,
|
|
477
|
-
children,
|
|
478
|
-
description,
|
|
479
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "red" }, children: error.message })
|
|
480
|
-
] });
|
|
481
|
-
};
|
|
482
|
-
FormLabelElement.displayName = "FormLabelElement";
|
|
483
|
-
FormLabelElement.whyDidYouRender = true;
|
|
484
|
-
|
|
485
|
-
// src/Form/elements/index.ts
|
|
486
|
-
var FormDefaultElements = {
|
|
487
|
-
Label: FormLabelElement,
|
|
488
|
-
Input: FormInputElement,
|
|
489
|
-
Button: FormButtonElement
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
// src/Form/rules.ts
|
|
493
|
-
var FormDefaultRules = {
|
|
494
|
-
required: async (value, _, lang) => {
|
|
495
|
-
if (value === null || value === void 0 || value === "" || Number.isNaN(value)) {
|
|
496
|
-
throw Error(lang?.required);
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
type: async (value, options, lang) => {
|
|
500
|
-
switch (options) {
|
|
501
|
-
case "string":
|
|
502
|
-
if (typeof value !== "string") throw Error(lang?.string);
|
|
503
|
-
break;
|
|
504
|
-
case "number":
|
|
505
|
-
if (Number.isNaN(Number(value))) throw Error(lang?.number);
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
},
|
|
509
|
-
custom: async (value, options) => {
|
|
510
|
-
return options(value);
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
async function validValues(rules, items, values, lang) {
|
|
514
|
-
const errors = {};
|
|
515
|
-
for (const item of items) {
|
|
516
|
-
const value = values[item.name];
|
|
517
|
-
const rulesOptions = item.rules;
|
|
518
|
-
if (rulesOptions) {
|
|
519
|
-
for (const [name, options] of Object.entries(rulesOptions)) {
|
|
520
|
-
try {
|
|
521
|
-
await rules[name](value, options, lang);
|
|
522
|
-
} catch (error) {
|
|
523
|
-
errors[item.name] = error;
|
|
524
|
-
break;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return errors;
|
|
530
|
-
}
|
|
531
|
-
function FormFooter() {
|
|
532
|
-
const {
|
|
533
|
-
submitting,
|
|
534
|
-
setSubmitting,
|
|
535
|
-
onSubmit,
|
|
536
|
-
valuesRef,
|
|
537
|
-
Elements,
|
|
538
|
-
items,
|
|
539
|
-
setErrors,
|
|
540
|
-
lang,
|
|
541
|
-
rules
|
|
542
|
-
} = useFormContext();
|
|
543
|
-
const handleSubmit = react.useCallback(async () => {
|
|
544
|
-
setSubmitting(true);
|
|
545
|
-
setErrors({});
|
|
546
|
-
const errors = await validValues(rules, items, valuesRef.current, lang);
|
|
547
|
-
if (Object.keys(errors).length) {
|
|
548
|
-
setErrors(errors);
|
|
549
|
-
setSubmitting(false);
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
onSubmit(valuesRef.current).finally(() => setSubmitting(false));
|
|
553
|
-
}, [setSubmitting, setErrors, rules, items, lang, onSubmit]);
|
|
554
|
-
const MemoizedButton = react.useMemo(
|
|
555
|
-
() => /* @__PURE__ */ jsxRuntime.jsx(Elements.Button, { submitting, submit: handleSubmit, children: lang.submit }),
|
|
556
|
-
[submitting, handleSubmit, lang.submit, Elements.Button]
|
|
557
|
-
);
|
|
558
|
-
return MemoizedButton;
|
|
559
|
-
}
|
|
560
|
-
FormFooter.displayName = "FormFooter";
|
|
561
|
-
FormFooter.whyDidYouRender = true;
|
|
562
|
-
|
|
563
|
-
// src/Form/lang.ts
|
|
564
|
-
var FormDefaultLang = {
|
|
565
|
-
submit: "Submit",
|
|
566
|
-
required: "This field is required",
|
|
567
|
-
string: "This field must be a string",
|
|
568
|
-
number: "This field must be a number"
|
|
569
|
-
};
|
|
570
|
-
function mergeValues(items, defaultValues = {}) {
|
|
571
|
-
const values = {};
|
|
572
|
-
for (const item of items)
|
|
573
|
-
values[item.name] = defaultValues[item.name] ?? "";
|
|
574
|
-
return values;
|
|
575
|
-
}
|
|
576
|
-
function FormContainer({
|
|
577
|
-
defaultValues,
|
|
578
|
-
Elements,
|
|
579
|
-
rules,
|
|
580
|
-
lang,
|
|
581
|
-
items,
|
|
582
|
-
...props
|
|
583
|
-
}) {
|
|
584
|
-
const [values, setValues, valuesRef] = useStateRef(
|
|
585
|
-
mergeValues(items, defaultValues)
|
|
586
|
-
);
|
|
587
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
588
|
-
FormContextProvider,
|
|
589
|
-
{
|
|
590
|
-
initializeStates: {
|
|
591
|
-
errors: {},
|
|
592
|
-
submitting: false
|
|
593
|
-
},
|
|
594
|
-
value: {
|
|
595
|
-
Elements: Object.assign(FormDefaultElements, Elements),
|
|
596
|
-
lang: Object.assign(FormDefaultLang, lang),
|
|
597
|
-
rules: Object.assign(FormDefaultRules, rules),
|
|
598
|
-
items,
|
|
599
|
-
values,
|
|
600
|
-
setValues,
|
|
601
|
-
valuesRef,
|
|
602
|
-
...props
|
|
603
|
-
},
|
|
604
|
-
memo: true,
|
|
605
|
-
children: [
|
|
606
|
-
/* @__PURE__ */ jsxRuntime.jsx(FormBody, {}),
|
|
607
|
-
/* @__PURE__ */ jsxRuntime.jsx(FormFooter, {})
|
|
608
|
-
]
|
|
609
|
-
}
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
FormContainer.displayName = "FormContainer";
|
|
613
|
-
FormContainer.whyDidYouRender = true;
|
|
614
|
-
var OptionalWrapper = ({ condition, Wrapper, wrapperProps, children }) => {
|
|
615
|
-
return condition ? /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { ...wrapperProps, children }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
616
|
-
};
|
|
617
|
-
OptionalWrapper.displayName = "OptionalWrapper";
|
|
618
|
-
OptionalWrapper.whyDidYouRender = true;
|
|
619
|
-
function usePrevious(value) {
|
|
620
|
-
const ref = react.useRef(void 0);
|
|
621
|
-
react.useEffect(() => {
|
|
622
|
-
ref.current = value;
|
|
623
|
-
});
|
|
624
|
-
return ref.current;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
exports.ErrorBoundary = ErrorBoundary;
|
|
628
|
-
exports.FaasDataWrapper = FaasDataWrapper;
|
|
629
|
-
exports.FaasReactClient = FaasReactClient;
|
|
630
|
-
exports.Form = FormContainer;
|
|
631
|
-
exports.FormContextProvider = FormContextProvider;
|
|
632
|
-
exports.FormDefaultElements = FormDefaultElements;
|
|
633
|
-
exports.FormDefaultLang = FormDefaultLang;
|
|
634
|
-
exports.FormDefaultRules = FormDefaultRules;
|
|
635
|
-
exports.FormItem = FormItem;
|
|
636
|
-
exports.OptionalWrapper = OptionalWrapper;
|
|
637
|
-
exports.createSplittingContext = createSplittingContext;
|
|
638
|
-
exports.equal = equal;
|
|
639
|
-
exports.faas = faas;
|
|
640
|
-
exports.getClient = getClient;
|
|
641
|
-
exports.useConstant = useConstant;
|
|
642
|
-
exports.useEqualCallback = useEqualCallback;
|
|
643
|
-
exports.useEqualEffect = useEqualEffect;
|
|
644
|
-
exports.useEqualMemo = useEqualMemo;
|
|
645
|
-
exports.useEqualMemoize = useEqualMemoize;
|
|
646
|
-
exports.useFaas = useFaas;
|
|
647
|
-
exports.useFormContext = useFormContext;
|
|
648
|
-
exports.usePrevious = usePrevious;
|
|
649
|
-
exports.useSplittingState = useSplittingState;
|
|
650
|
-
exports.useStateRef = useStateRef;
|
|
651
|
-
exports.validValues = validValues;
|
|
652
|
-
exports.withFaasData = withFaasData;
|