kiru 0.44.4 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/appContext.d.ts +38 -0
- package/dist/appContext.d.ts.map +1 -0
- package/dist/appContext.js +143 -0
- package/dist/appContext.js.map +1 -0
- package/dist/cloneVNode.d.ts +2 -0
- package/dist/cloneVNode.d.ts.map +1 -0
- package/dist/cloneVNode.js +14 -0
- package/dist/cloneVNode.js.map +1 -0
- package/dist/constants.d.ts +31 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +127 -0
- package/dist/constants.js.map +1 -0
- package/dist/context.d.ts +3 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +50 -0
- package/dist/context.js.map +1 -0
- package/dist/dom.d.ts +8 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +582 -0
- package/dist/dom.js.map +1 -0
- package/dist/element.d.ts +6 -0
- package/dist/element.d.ts.map +1 -0
- package/dist/element.js +41 -0
- package/dist/element.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +6 -0
- package/dist/env.js.map +1 -0
- package/dist/error.d.ts +19 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +63 -0
- package/dist/error.js.map +1 -0
- package/dist/flags.d.ts +6 -0
- package/dist/flags.d.ts.map +1 -0
- package/dist/flags.js +16 -0
- package/dist/flags.js.map +1 -0
- package/dist/form/index.d.ts +4 -0
- package/dist/form/index.d.ts.map +1 -0
- package/dist/form/index.js +509 -0
- package/dist/form/index.js.map +1 -0
- package/dist/form/types.d.ts +121 -0
- package/dist/form/types.d.ts.map +1 -0
- package/dist/form/types.js +2 -0
- package/dist/form/types.js.map +1 -0
- package/dist/form/utils.d.ts +3 -0
- package/dist/form/utils.d.ts.map +1 -0
- package/dist/form/utils.js +16 -0
- package/dist/form/utils.js.map +1 -0
- package/dist/generateId.d.ts +8 -0
- package/dist/generateId.d.ts.map +1 -0
- package/dist/generateId.js +15 -0
- package/dist/generateId.js.map +1 -0
- package/dist/globalContext.d.ts +37 -0
- package/dist/globalContext.d.ts.map +1 -0
- package/dist/globalContext.js +85 -0
- package/dist/globalContext.js.map +1 -0
- package/dist/globals.d.ts +16 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +15 -0
- package/dist/globals.js.map +1 -0
- package/dist/hmr.d.ts +32 -0
- package/dist/hmr.d.ts.map +1 -0
- package/dist/hmr.js +125 -0
- package/dist/hmr.js.map +1 -0
- package/dist/hooks/index.d.ts +15 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +15 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useAsync.d.ts +29 -0
- package/dist/hooks/useAsync.d.ts.map +1 -0
- package/dist/hooks/useAsync.js +96 -0
- package/dist/hooks/useAsync.js.map +1 -0
- package/dist/hooks/useCallback.d.ts +7 -0
- package/dist/hooks/useCallback.d.ts.map +1 -0
- package/dist/hooks/useCallback.js +29 -0
- package/dist/hooks/useCallback.js.map +1 -0
- package/dist/hooks/useContext.d.ts +7 -0
- package/dist/hooks/useContext.d.ts.map +1 -0
- package/dist/hooks/useContext.js +59 -0
- package/dist/hooks/useContext.js.map +1 -0
- package/dist/hooks/useEffect.d.ts +8 -0
- package/dist/hooks/useEffect.d.ts.map +1 -0
- package/dist/hooks/useEffect.js +33 -0
- package/dist/hooks/useEffect.js.map +1 -0
- package/dist/hooks/useEffectEvent.d.ts +8 -0
- package/dist/hooks/useEffectEvent.d.ts.map +1 -0
- package/dist/hooks/useEffectEvent.js +22 -0
- package/dist/hooks/useEffectEvent.js.map +1 -0
- package/dist/hooks/useId.d.ts +8 -0
- package/dist/hooks/useId.d.ts.map +1 -0
- package/dist/hooks/useId.js +35 -0
- package/dist/hooks/useId.js.map +1 -0
- package/dist/hooks/useLayoutEffect.d.ts +8 -0
- package/dist/hooks/useLayoutEffect.d.ts.map +1 -0
- package/dist/hooks/useLayoutEffect.js +33 -0
- package/dist/hooks/useLayoutEffect.js.map +1 -0
- package/dist/hooks/useMemo.d.ts +8 -0
- package/dist/hooks/useMemo.d.ts.map +1 -0
- package/dist/hooks/useMemo.js +30 -0
- package/dist/hooks/useMemo.js.map +1 -0
- package/dist/hooks/useReducer.d.ts +7 -0
- package/dist/hooks/useReducer.d.ts.map +1 -0
- package/dist/hooks/useReducer.js +44 -0
- package/dist/hooks/useReducer.js.map +1 -0
- package/dist/hooks/useRef.d.ts +10 -0
- package/dist/hooks/useRef.d.ts.map +1 -0
- package/dist/hooks/useRef.js +28 -0
- package/dist/hooks/useRef.js.map +1 -0
- package/dist/hooks/useState.d.ts +7 -0
- package/dist/hooks/useState.d.ts.map +1 -0
- package/dist/hooks/useState.js +54 -0
- package/dist/hooks/useState.js.map +1 -0
- package/dist/hooks/useSyncExternalStore.d.ts +8 -0
- package/dist/hooks/useSyncExternalStore.d.ts.map +1 -0
- package/dist/hooks/useSyncExternalStore.js +50 -0
- package/dist/hooks/useSyncExternalStore.js.map +1 -0
- package/dist/hooks/useViewTransition.d.ts +10 -0
- package/dist/hooks/useViewTransition.d.ts.map +1 -0
- package/dist/hooks/useViewTransition.js +28 -0
- package/dist/hooks/useViewTransition.js.map +1 -0
- package/dist/hooks/utils.d.ts +69 -0
- package/dist/hooks/utils.d.ts.map +1 -0
- package/dist/hooks/utils.js +163 -0
- package/dist/hooks/utils.js.map +1 -0
- package/dist/hydration.d.ts +17 -0
- package/dist/hydration.d.ts.map +1 -0
- package/dist/hydration.js +59 -0
- package/dist/hydration.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx.d.ts +6 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/jsx.js +8 -0
- package/dist/jsx.js.map +1 -0
- package/dist/lazy.d.ts +11 -0
- package/dist/lazy.d.ts.map +1 -0
- package/dist/lazy.js +177 -0
- package/dist/lazy.js.map +1 -0
- package/dist/memo.d.ts +9 -0
- package/dist/memo.d.ts.map +1 -0
- package/dist/memo.js +25 -0
- package/dist/memo.js.map +1 -0
- package/dist/portal.d.ts +10 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +34 -0
- package/dist/portal.js.map +1 -0
- package/dist/profiling.d.ts +26 -0
- package/dist/profiling.d.ts.map +1 -0
- package/dist/profiling.js +83 -0
- package/dist/profiling.js.map +1 -0
- package/dist/props.d.ts +4 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/props.js +27 -0
- package/dist/props.js.map +1 -0
- package/dist/reconciler.d.ts +4 -0
- package/dist/reconciler.d.ts.map +1 -0
- package/dist/reconciler.js +466 -0
- package/dist/reconciler.js.map +1 -0
- package/dist/renderToString.d.ts +2 -0
- package/dist/renderToString.d.ts.map +1 -0
- package/dist/renderToString.js +74 -0
- package/dist/renderToString.js.map +1 -0
- package/dist/router/index.d.ts +3 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +3 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/route.d.ts +46 -0
- package/dist/router/route.d.ts.map +1 -0
- package/dist/router/route.js +8 -0
- package/dist/router/route.js.map +1 -0
- package/dist/router/router.d.ts +62 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/router.js +178 -0
- package/dist/router/router.js.map +1 -0
- package/dist/router/routerUtils.d.ts +5 -0
- package/dist/router/routerUtils.d.ts.map +1 -0
- package/dist/router/routerUtils.js +39 -0
- package/dist/router/routerUtils.js.map +1 -0
- package/dist/scheduler.d.ts +14 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +457 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/signals/base.d.ts +36 -0
- package/dist/signals/base.d.ts.map +1 -0
- package/dist/signals/base.js +205 -0
- package/dist/signals/base.js.map +1 -0
- package/dist/signals/computed.d.ts +16 -0
- package/dist/signals/computed.d.ts.map +1 -0
- package/dist/signals/computed.js +116 -0
- package/dist/signals/computed.js.map +1 -0
- package/dist/signals/effect.d.ts +18 -0
- package/dist/signals/effect.d.ts.map +1 -0
- package/dist/signals/effect.js +43 -0
- package/dist/signals/effect.js.map +1 -0
- package/dist/signals/globals.d.ts +9 -0
- package/dist/signals/globals.d.ts.map +1 -0
- package/dist/signals/globals.js +9 -0
- package/dist/signals/globals.js.map +1 -0
- package/dist/signals/index.d.ts +12 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +12 -0
- package/dist/signals/index.js.map +1 -0
- package/dist/signals/jsx.d.ts +16 -0
- package/dist/signals/jsx.d.ts.map +1 -0
- package/dist/signals/jsx.js +11 -0
- package/dist/signals/jsx.js.map +1 -0
- package/dist/signals/types.d.ts +9 -0
- package/dist/signals/types.d.ts.map +1 -0
- package/dist/signals/types.js +2 -0
- package/dist/signals/types.js.map +1 -0
- package/dist/signals/utils.d.ts +4 -0
- package/dist/signals/utils.d.ts.map +1 -0
- package/dist/signals/utils.js +12 -0
- package/dist/signals/utils.js.map +1 -0
- package/dist/signals/watch.d.ts +24 -0
- package/dist/signals/watch.d.ts.map +1 -0
- package/dist/signals/watch.js +104 -0
- package/dist/signals/watch.js.map +1 -0
- package/dist/ssr/client.d.ts +4 -0
- package/dist/ssr/client.d.ts.map +1 -0
- package/dist/ssr/client.js +12 -0
- package/dist/ssr/client.js.map +1 -0
- package/dist/ssr/hydrationBoundary.d.ts +27 -0
- package/dist/ssr/hydrationBoundary.d.ts.map +1 -0
- package/dist/ssr/hydrationBoundary.js +30 -0
- package/dist/ssr/hydrationBoundary.js.map +1 -0
- package/dist/ssr/index.d.ts +2 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +2 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/server.d.ts +3 -0
- package/dist/ssr/server.d.ts.map +1 -0
- package/dist/ssr/server.js +101 -0
- package/dist/ssr/server.js.map +1 -0
- package/dist/store.d.ts +28 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +166 -0
- package/dist/store.js.map +1 -0
- package/dist/swr.d.ts +74 -0
- package/dist/swr.d.ts.map +1 -0
- package/dist/swr.js +228 -0
- package/dist/swr.js.map +1 -0
- package/dist/transition.d.ts +18 -0
- package/dist/transition.d.ts.map +1 -0
- package/dist/transition.js +48 -0
- package/dist/transition.js.map +1 -0
- package/dist/types.d.ts +143 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.dom.d.ts +920 -0
- package/dist/types.dom.d.ts.map +1 -0
- package/dist/types.dom.js +2 -0
- package/dist/types.dom.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/types.utils.d.ts +41 -0
- package/dist/types.utils.d.ts.map +1 -0
- package/dist/types.utils.js +2 -0
- package/dist/types.utils.js.map +1 -0
- package/dist/utils.d.ts +61 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +478 -0
- package/dist/utils.js.map +1 -0
- package/dist/warning.d.ts +2 -0
- package/dist/warning.d.ts.map +1 -0
- package/dist/warning.js +4 -0
- package/dist/warning.js.map +1 -0
- package/package.json +1 -1
- package/src/appContext.ts +7 -7
- package/src/cloneVNode.ts +1 -1
- package/src/constants.ts +9 -9
- package/src/context.ts +7 -7
- package/src/dom.ts +13 -15
- package/src/element.ts +4 -4
- package/src/error.ts +11 -13
- package/src/globalContext.ts +6 -10
- package/src/globals.ts +3 -3
- package/src/hmr.ts +4 -4
- package/src/hooks/useContext.ts +5 -5
- package/src/hooks/useId.ts +1 -1
- package/src/hooks/useReducer.ts +1 -1
- package/src/hooks/useRef.ts +4 -4
- package/src/hooks/useState.ts +4 -4
- package/src/hooks/useSyncExternalStore.ts +2 -2
- package/src/hooks/utils.ts +7 -9
- package/src/index.ts +4 -4
- package/src/jsx.ts +2 -2
- package/src/lazy.ts +11 -11
- package/src/memo.ts +1 -1
- package/src/portal.ts +4 -4
- package/src/props.ts +5 -7
- package/src/reconciler.ts +6 -6
- package/src/renderToString.ts +1 -1
- package/src/router/route.ts +1 -1
- package/src/router/router.ts +4 -4
- package/src/scheduler.ts +14 -14
- package/src/signals/base.ts +1 -1
- package/src/signals/types.ts +1 -1
- package/src/signals/watch.ts +2 -2
- package/src/ssr/hydrationBoundary.ts +1 -1
- package/src/ssr/server.ts +1 -1
- package/src/store.ts +7 -7
- package/src/swr.ts +2 -2
- package/src/types.dom.ts +1 -1
- package/src/types.ts +13 -13
- package/src/types.utils.ts +5 -5
- package/src/utils.ts +7 -10
- package/src/warning.ts +1 -1
package/dist/env.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const NODE_ENV = process.env.NODE_ENV;
|
|
2
|
+
if (NODE_ENV !== "development" && NODE_ENV !== "production") {
|
|
3
|
+
throw new Error("NODE_ENV must either be set to development or production.");
|
|
4
|
+
}
|
|
5
|
+
export const __DEV__ = NODE_ENV === "development";
|
|
6
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAA;AACrC,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;IAC5D,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;AAC9E,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,KAAK,aAAa,CAAA"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { $KIRU_ERROR } from "./constants.js";
|
|
2
|
+
type KiruErrorOptions = string | {
|
|
3
|
+
message: string;
|
|
4
|
+
/** Used to indicate that the error is fatal and should crash the application */
|
|
5
|
+
fatal?: boolean;
|
|
6
|
+
/** Used to generate custom node stack */
|
|
7
|
+
vNode?: Kiru.VNode;
|
|
8
|
+
};
|
|
9
|
+
export declare class KiruError extends Error {
|
|
10
|
+
[$KIRU_ERROR]: boolean;
|
|
11
|
+
/** Indicates whether the error is fatal and should crash the application */
|
|
12
|
+
fatal?: boolean;
|
|
13
|
+
/** Present if vNode is provided */
|
|
14
|
+
customNodeStack?: string;
|
|
15
|
+
constructor(optionsOrMessage: KiruErrorOptions);
|
|
16
|
+
static isKiruError(error: unknown): error is KiruError;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAI5C,KAAK,gBAAgB,GACjB,MAAM,GACN;IACE,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAA;CACnB,CAAA;AAEL,qBAAa,SAAU,SAAQ,KAAK;IAClC,CAAC,WAAW,CAAC,UAAO;IACpB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mCAAmC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAA;gBACZ,gBAAgB,EAAE,gBAAgB;IAgB9C,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS;CAGvD"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { $KIRU_ERROR } from "./constants.js";
|
|
3
|
+
import { __DEV__ } from "./env.js";
|
|
4
|
+
import { findParent, noop } from "./utils.js";
|
|
5
|
+
export class KiruError extends Error {
|
|
6
|
+
constructor(optionsOrMessage) {
|
|
7
|
+
const message = typeof optionsOrMessage === "string"
|
|
8
|
+
? optionsOrMessage
|
|
9
|
+
: optionsOrMessage.message;
|
|
10
|
+
super(message);
|
|
11
|
+
this[_a] = true;
|
|
12
|
+
if (typeof optionsOrMessage !== "string") {
|
|
13
|
+
if (__DEV__) {
|
|
14
|
+
if (optionsOrMessage?.vNode) {
|
|
15
|
+
this.customNodeStack = captureErrorStack(optionsOrMessage.vNode);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
this.fatal = optionsOrMessage?.fatal;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
static isKiruError(error) {
|
|
22
|
+
return error instanceof Error && error[$KIRU_ERROR] === true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
_a = $KIRU_ERROR;
|
|
26
|
+
function captureErrorStack(vNode) {
|
|
27
|
+
let n = vNode;
|
|
28
|
+
let componentFns = [];
|
|
29
|
+
while (n) {
|
|
30
|
+
if (!n.parent)
|
|
31
|
+
break; // skip root node
|
|
32
|
+
if (typeof n.type === "function") {
|
|
33
|
+
componentFns.push(getComponentErrorDisplayText(n.type));
|
|
34
|
+
}
|
|
35
|
+
else if (typeof n.type === "string") {
|
|
36
|
+
componentFns.push(n.type);
|
|
37
|
+
}
|
|
38
|
+
n = n.parent;
|
|
39
|
+
}
|
|
40
|
+
const componentNode = (typeof vNode.type === "function"
|
|
41
|
+
? vNode
|
|
42
|
+
: findParent(vNode, (n) => typeof n.type === "function"));
|
|
43
|
+
return `The above error occurred in the <${getFunctionName(componentNode?.type || noop)}> component:
|
|
44
|
+
|
|
45
|
+
${componentFns.map((x) => ` at ${x}`).join("\n")}\n`;
|
|
46
|
+
}
|
|
47
|
+
function getComponentErrorDisplayText(fn) {
|
|
48
|
+
let str = getFunctionName(fn);
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
const fileLink = getComponentFileLink(fn);
|
|
51
|
+
if (fileLink) {
|
|
52
|
+
str = `${str} (${fileLink})`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return str;
|
|
56
|
+
}
|
|
57
|
+
function getFunctionName(fn) {
|
|
58
|
+
return fn.displayName ?? (fn.name || "Anonymous Function");
|
|
59
|
+
}
|
|
60
|
+
function getComponentFileLink(fn) {
|
|
61
|
+
return fn.toString().match(/\/\/ \[kiru_devtools\]:(.*)/)?.[1] ?? null;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
|
package/dist/flags.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../src/flags.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK;0BAEL,MAAM,QAAQ,MAAM,KAAG,MAAM;0BAI7B,MAAM,KAAK,MAAM,KAAG,OAAO;iCAIpB,MAAM,SAAS,MAAM,OAAO,MAAM,KAAG,MAAM;CAIrD,CAAA"}
|
package/dist/flags.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const flags = {
|
|
2
|
+
// Set the flag at position `n` (0-based index)
|
|
3
|
+
set(field, flag) {
|
|
4
|
+
return (field |= 1 << flag);
|
|
5
|
+
},
|
|
6
|
+
// Check if the flag at position `n` is set (true) or not (false)
|
|
7
|
+
get(field, n) {
|
|
8
|
+
return (field & (1 << n)) !== 0;
|
|
9
|
+
},
|
|
10
|
+
// Unset all flags between `start` and `end`
|
|
11
|
+
unsetRange(field, start, end) {
|
|
12
|
+
const mask = ((1 << (end - start + 1)) - 1) << start;
|
|
13
|
+
return field & ~mask;
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../src/flags.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,+CAA+C;IAC/C,GAAG,CAAC,KAAa,EAAE,IAAY;QAC7B,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAA;IAC7B,CAAC;IACD,iEAAiE;IACjE,GAAG,CAAC,KAAa,EAAE,CAAS;QAC1B,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC;IACD,4CAA4C;IAC5C,UAAU,CAAC,KAAa,EAAE,KAAa,EAAE,GAAW;QAClD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAA;QACpD,OAAO,KAAK,GAAG,CAAC,IAAI,CAAA;IACtB,CAAC;CACO,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/form/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAaV,aAAa,EAEb,YAAY,EACb,MAAM,SAAS,CAAA;AAEhB,mBAAmB,SAAS,CAAA;AAkf5B,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,EAC5D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,YAAY,CAAC,CAAC,CAAC,CAsIjB"}
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
import { __DEV__ } from "../env.js";
|
|
2
|
+
import { Fragment } from "../element.js";
|
|
3
|
+
import { generateRandomID } from "../generateId.js";
|
|
4
|
+
import { safeStringify, shallowCompare } from "../utils.js";
|
|
5
|
+
import { useEffect } from "../hooks/useEffect.js";
|
|
6
|
+
import { useMemo } from "../hooks/useMemo.js";
|
|
7
|
+
import { useRef } from "../hooks/useRef.js";
|
|
8
|
+
import { useHook, useRequestUpdate } from "../hooks/utils.js";
|
|
9
|
+
import { objGet, objSet } from "./utils.js";
|
|
10
|
+
function createFormController(config) {
|
|
11
|
+
let isSubmitting = false;
|
|
12
|
+
const subscribers = new Set();
|
|
13
|
+
const state = structuredClone(config.initialValues ?? {});
|
|
14
|
+
const formFieldValidators = {};
|
|
15
|
+
const formFieldDependencies = {};
|
|
16
|
+
const formFieldsTouched = {};
|
|
17
|
+
const formFieldUpdaters = new Map();
|
|
18
|
+
const asyncFormFieldValidators = {};
|
|
19
|
+
const formFieldErrors = {};
|
|
20
|
+
const canSubmit = () => {
|
|
21
|
+
return isAnyFieldValidating() === false && getErrors().length === 0;
|
|
22
|
+
};
|
|
23
|
+
const getSelectorState = () => {
|
|
24
|
+
return {
|
|
25
|
+
values: state,
|
|
26
|
+
canSubmit: canSubmit(),
|
|
27
|
+
isSubmitting,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const updateSubscribers = () => {
|
|
31
|
+
const selectorState = getSelectorState();
|
|
32
|
+
for (const sub of subscribers) {
|
|
33
|
+
const { selector, selection, update } = sub;
|
|
34
|
+
const newSelection = selector(selectorState);
|
|
35
|
+
if (shallowCompare(selection, newSelection))
|
|
36
|
+
continue;
|
|
37
|
+
sub.selection = newSelection;
|
|
38
|
+
update();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const updateFieldComponents = (name) => {
|
|
42
|
+
if (!formFieldUpdaters.has(name))
|
|
43
|
+
return;
|
|
44
|
+
for (const update of formFieldUpdaters.get(name))
|
|
45
|
+
update();
|
|
46
|
+
};
|
|
47
|
+
const validateField = async (name, evt) => {
|
|
48
|
+
const fieldErrors = (formFieldErrors[name] ?? (formFieldErrors[name] = {}));
|
|
49
|
+
const asyncFieldValidatorStates = (asyncFormFieldValidators[name] ?? (asyncFormFieldValidators[name] = {}));
|
|
50
|
+
const fieldValidators = formFieldValidators[name] ?? {};
|
|
51
|
+
const validatorCtx = { value: getFieldValue(name) };
|
|
52
|
+
switch (evt) {
|
|
53
|
+
case "onMount": {
|
|
54
|
+
if (!fieldValidators.onMount)
|
|
55
|
+
return;
|
|
56
|
+
fieldErrors.onMount = fieldValidators.onMount(validatorCtx);
|
|
57
|
+
updateSubscribers();
|
|
58
|
+
updateFieldComponents(name);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "onChange": {
|
|
62
|
+
if (fieldErrors.onMount)
|
|
63
|
+
delete fieldErrors.onMount;
|
|
64
|
+
formFieldsTouched[name] = true;
|
|
65
|
+
if (!fieldValidators.onChange)
|
|
66
|
+
return;
|
|
67
|
+
fieldErrors.onChange = fieldValidators.onChange(validatorCtx);
|
|
68
|
+
if (asyncFieldValidatorStates.onChangeAsync &&
|
|
69
|
+
asyncFieldValidatorStates.onChangeAsync.timeout !== -1) {
|
|
70
|
+
window.clearTimeout(asyncFieldValidatorStates.onChangeAsync.timeout);
|
|
71
|
+
asyncFieldValidatorStates.onChangeAsync.abortController?.abort();
|
|
72
|
+
asyncFieldValidatorStates.onChangeAsync = {
|
|
73
|
+
epoch: asyncFieldValidatorStates.onChangeAsync.epoch,
|
|
74
|
+
timeout: -1,
|
|
75
|
+
abortController: null,
|
|
76
|
+
};
|
|
77
|
+
delete fieldErrors.onChangeAsync;
|
|
78
|
+
}
|
|
79
|
+
else if (fieldErrors.onChangeAsync) {
|
|
80
|
+
delete fieldErrors.onChangeAsync;
|
|
81
|
+
}
|
|
82
|
+
updateSubscribers();
|
|
83
|
+
updateFieldComponents(name);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "onBlur": {
|
|
87
|
+
formFieldsTouched[name] = true;
|
|
88
|
+
if (!fieldValidators.onBlur)
|
|
89
|
+
return;
|
|
90
|
+
fieldErrors.onBlur = fieldValidators.onBlur(validatorCtx);
|
|
91
|
+
updateSubscribers();
|
|
92
|
+
updateFieldComponents(name);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "onChangeAsync": {
|
|
96
|
+
if (fieldErrors.onChange || !fieldValidators.onChangeAsync)
|
|
97
|
+
return;
|
|
98
|
+
window.clearTimeout(asyncFieldValidatorStates.onChangeAsync?.timeout);
|
|
99
|
+
const epoch = (asyncFieldValidatorStates.onChangeAsync?.epoch ?? 0) + 1;
|
|
100
|
+
const debounceMs = fieldValidators.onChangeAsyncDebounceMs ?? 0;
|
|
101
|
+
const abortController = new AbortController();
|
|
102
|
+
const asyncValidatorCtx = {
|
|
103
|
+
...validatorCtx,
|
|
104
|
+
abortSignal: abortController.signal,
|
|
105
|
+
};
|
|
106
|
+
if (debounceMs <= 0) {
|
|
107
|
+
fieldErrors.onChangeAsync = await fieldValidators.onChangeAsync(asyncValidatorCtx);
|
|
108
|
+
updateSubscribers();
|
|
109
|
+
updateFieldComponents(name);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
asyncFieldValidatorStates.onChangeAsync = {
|
|
113
|
+
abortController,
|
|
114
|
+
timeout: window.setTimeout(() => {
|
|
115
|
+
fieldValidators
|
|
116
|
+
.onChangeAsync?.(asyncValidatorCtx)
|
|
117
|
+
.then((result) => {
|
|
118
|
+
if (fieldErrors.onChange)
|
|
119
|
+
return;
|
|
120
|
+
if (epoch !== asyncFieldValidatorStates.onChangeAsync?.epoch) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
fieldErrors.onChangeAsync = result;
|
|
124
|
+
asyncFieldValidatorStates.onChangeAsync = {
|
|
125
|
+
timeout: -1,
|
|
126
|
+
epoch,
|
|
127
|
+
abortController,
|
|
128
|
+
};
|
|
129
|
+
updateSubscribers();
|
|
130
|
+
updateFieldComponents(name);
|
|
131
|
+
});
|
|
132
|
+
}, debounceMs),
|
|
133
|
+
epoch,
|
|
134
|
+
};
|
|
135
|
+
updateSubscribers();
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "onSubmit": {
|
|
139
|
+
fieldErrors.onSubmit = fieldValidators.onSubmit?.(validatorCtx);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const getFieldValue = (name) => {
|
|
144
|
+
return objGet(state, name.split("."));
|
|
145
|
+
};
|
|
146
|
+
const getFieldState = (name) => {
|
|
147
|
+
let errors = [];
|
|
148
|
+
let isValidating = false;
|
|
149
|
+
const fieldErrors = formFieldErrors[name] ?? {};
|
|
150
|
+
const asyncMeta = asyncFormFieldValidators[name] ?? {};
|
|
151
|
+
if (asyncMeta.onChangeAsync && asyncMeta.onChangeAsync.timeout !== -1) {
|
|
152
|
+
isValidating = true;
|
|
153
|
+
}
|
|
154
|
+
if (!isValidating) {
|
|
155
|
+
errors.push(...[
|
|
156
|
+
fieldErrors.onChangeAsync,
|
|
157
|
+
fieldErrors.onMount,
|
|
158
|
+
fieldErrors.onChange,
|
|
159
|
+
fieldErrors.onBlur,
|
|
160
|
+
].filter(Boolean));
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
value: getFieldValue(name),
|
|
164
|
+
errors,
|
|
165
|
+
isTouched: !!formFieldsTouched[name],
|
|
166
|
+
isValidating,
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
const onFieldChanged = (name) => {
|
|
170
|
+
validateField(name, "onChange");
|
|
171
|
+
if (formFieldValidators[name]?.onChangeAsync) {
|
|
172
|
+
validateField(name, "onChangeAsync");
|
|
173
|
+
}
|
|
174
|
+
if (formFieldDependencies[name]) {
|
|
175
|
+
for (const dependentOn of formFieldDependencies[name]) {
|
|
176
|
+
validateField(dependentOn, "onChange");
|
|
177
|
+
if (formFieldValidators[dependentOn]?.onChangeAsync) {
|
|
178
|
+
validateField(dependentOn, "onChangeAsync");
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
formFieldUpdaters.get(name)?.forEach((update) => update());
|
|
183
|
+
};
|
|
184
|
+
const setFieldValue = (name, value) => {
|
|
185
|
+
objSet(state, name.split("."), value);
|
|
186
|
+
onFieldChanged(name);
|
|
187
|
+
};
|
|
188
|
+
const removeFieldMeta = (name) => {
|
|
189
|
+
for (const metaMap of [
|
|
190
|
+
formFieldErrors,
|
|
191
|
+
asyncFormFieldValidators,
|
|
192
|
+
formFieldsTouched,
|
|
193
|
+
formFieldValidators,
|
|
194
|
+
]) {
|
|
195
|
+
delete metaMap[name];
|
|
196
|
+
for (const key in metaMap) {
|
|
197
|
+
if (key.startsWith(`${name}.`)) {
|
|
198
|
+
delete metaMap[key];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
formFieldUpdaters.delete(name);
|
|
203
|
+
for (const key in formFieldUpdaters) {
|
|
204
|
+
if (key.startsWith(`${name}.`)) {
|
|
205
|
+
formFieldUpdaters.delete(key);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
const arrayFieldReplace = (name, index, value) => {
|
|
210
|
+
const path = [...name.split("."), index.toString()];
|
|
211
|
+
objSet(state, path, value);
|
|
212
|
+
removeFieldMeta(`${name}.${index}`);
|
|
213
|
+
onFieldChanged(name);
|
|
214
|
+
updateFieldComponents(name);
|
|
215
|
+
};
|
|
216
|
+
const arrayFieldPush = (name, value) => {
|
|
217
|
+
const path = [...name.split(".")];
|
|
218
|
+
const arr = objGet(state, path);
|
|
219
|
+
arr.push(value);
|
|
220
|
+
onFieldChanged(name);
|
|
221
|
+
updateFieldComponents(name);
|
|
222
|
+
};
|
|
223
|
+
const arrayFieldRemove = (name, index) => {
|
|
224
|
+
const path = [...name.split(".")];
|
|
225
|
+
const arr = objGet(state, path);
|
|
226
|
+
arr.splice(index, 1);
|
|
227
|
+
removeFieldMeta(`${name}.${index}`);
|
|
228
|
+
onFieldChanged(name);
|
|
229
|
+
updateFieldComponents(name);
|
|
230
|
+
};
|
|
231
|
+
const getErrors = () => {
|
|
232
|
+
const errors = [];
|
|
233
|
+
for (const fieldName in formFieldErrors) {
|
|
234
|
+
const meta = formFieldErrors[fieldName];
|
|
235
|
+
errors.push(...[
|
|
236
|
+
meta.onChangeAsync,
|
|
237
|
+
meta.onMount,
|
|
238
|
+
meta.onChange,
|
|
239
|
+
meta.onBlur,
|
|
240
|
+
].filter(Boolean));
|
|
241
|
+
}
|
|
242
|
+
return errors;
|
|
243
|
+
};
|
|
244
|
+
const isAnyFieldValidating = () => {
|
|
245
|
+
for (const fieldName in asyncFormFieldValidators) {
|
|
246
|
+
const fieldValidators = asyncFormFieldValidators[fieldName];
|
|
247
|
+
if (fieldValidators.onChangeAsync &&
|
|
248
|
+
fieldValidators.onChangeAsync.timeout !== -1) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return false;
|
|
253
|
+
};
|
|
254
|
+
const connectField = (name, update) => {
|
|
255
|
+
if (!formFieldUpdaters.has(name)) {
|
|
256
|
+
formFieldUpdaters.set(name, new Set());
|
|
257
|
+
}
|
|
258
|
+
formFieldUpdaters.get(name).add(update);
|
|
259
|
+
};
|
|
260
|
+
const disconnectField = (name, update) => {
|
|
261
|
+
if (!formFieldUpdaters.has(name))
|
|
262
|
+
return;
|
|
263
|
+
formFieldUpdaters.get(name).delete(update);
|
|
264
|
+
const asyncValidators = asyncFormFieldValidators[name] ?? {};
|
|
265
|
+
const { abortController, timeout } = asyncValidators.onChangeAsync ?? {};
|
|
266
|
+
window.clearTimeout(timeout);
|
|
267
|
+
abortController?.abort();
|
|
268
|
+
};
|
|
269
|
+
const reset = (values) => {
|
|
270
|
+
if (values) {
|
|
271
|
+
for (const key in values) {
|
|
272
|
+
state[key] = values[key];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
const initialValues = (config.initialValues ?? {});
|
|
277
|
+
const keys = new Set([
|
|
278
|
+
...Object.keys(state),
|
|
279
|
+
...Object.keys(initialValues),
|
|
280
|
+
]);
|
|
281
|
+
for (const key of keys) {
|
|
282
|
+
if (key in initialValues) {
|
|
283
|
+
state[key] = structuredClone(initialValues[key]);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
delete state[key];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (const fieldName in formFieldsTouched) {
|
|
291
|
+
delete formFieldsTouched[fieldName];
|
|
292
|
+
}
|
|
293
|
+
for (const fieldName in asyncFormFieldValidators) {
|
|
294
|
+
const asyncFieldValidators = asyncFormFieldValidators[fieldName];
|
|
295
|
+
const { timeout, abortController } = asyncFieldValidators?.onChangeAsync ?? {};
|
|
296
|
+
if (timeout !== -1) {
|
|
297
|
+
window.clearTimeout(timeout);
|
|
298
|
+
}
|
|
299
|
+
abortController?.abort();
|
|
300
|
+
delete asyncFormFieldValidators[fieldName];
|
|
301
|
+
}
|
|
302
|
+
for (const fieldName in formFieldErrors) {
|
|
303
|
+
delete formFieldErrors[fieldName];
|
|
304
|
+
}
|
|
305
|
+
updateSubscribers();
|
|
306
|
+
formFieldUpdaters.forEach((updaters) => {
|
|
307
|
+
updaters.forEach((update) => update());
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
const validateForm = async () => {
|
|
311
|
+
var _a;
|
|
312
|
+
for (const fieldName in formFieldValidators) {
|
|
313
|
+
const fieldValidators = formFieldValidators[fieldName];
|
|
314
|
+
if (fieldValidators?.onChange) {
|
|
315
|
+
await validateField(fieldName, "onChange");
|
|
316
|
+
}
|
|
317
|
+
if (fieldValidators?.onSubmit) {
|
|
318
|
+
await validateField(fieldName, "onSubmit");
|
|
319
|
+
}
|
|
320
|
+
if (!formFieldErrors[fieldName]?.onChange &&
|
|
321
|
+
fieldValidators?.onChangeAsync) {
|
|
322
|
+
const value = state[fieldName];
|
|
323
|
+
const abortController = new AbortController();
|
|
324
|
+
const asyncValidators = (asyncFormFieldValidators[_a = fieldName] ?? (asyncFormFieldValidators[_a] = {}));
|
|
325
|
+
const epoch = asyncValidators.onChangeAsync?.epoch ?? 0;
|
|
326
|
+
asyncValidators.onChangeAsync = {
|
|
327
|
+
timeout: 0,
|
|
328
|
+
epoch,
|
|
329
|
+
abortController,
|
|
330
|
+
};
|
|
331
|
+
const ctx = {
|
|
332
|
+
value,
|
|
333
|
+
abortSignal: abortController.signal,
|
|
334
|
+
};
|
|
335
|
+
formFieldErrors[fieldName].onChangeAsync =
|
|
336
|
+
await fieldValidators.onChangeAsync(ctx);
|
|
337
|
+
asyncValidators.onChangeAsync = {
|
|
338
|
+
timeout: -1,
|
|
339
|
+
epoch,
|
|
340
|
+
abortController: null,
|
|
341
|
+
};
|
|
342
|
+
updateFieldComponents(fieldName);
|
|
343
|
+
updateSubscribers();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return getErrors();
|
|
347
|
+
};
|
|
348
|
+
const deleteField = (name) => {
|
|
349
|
+
delete state[name];
|
|
350
|
+
delete formFieldErrors[name];
|
|
351
|
+
delete asyncFormFieldValidators[name];
|
|
352
|
+
delete formFieldsTouched[name];
|
|
353
|
+
delete formFieldValidators[name];
|
|
354
|
+
formFieldUpdaters.delete(name);
|
|
355
|
+
updateSubscribers();
|
|
356
|
+
};
|
|
357
|
+
const resetField = (name) => {
|
|
358
|
+
if (config.initialValues?.[name]) {
|
|
359
|
+
state[name] = config.initialValues[name];
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
delete state[name];
|
|
363
|
+
}
|
|
364
|
+
delete formFieldErrors[name];
|
|
365
|
+
delete asyncFormFieldValidators[name];
|
|
366
|
+
delete formFieldsTouched[name];
|
|
367
|
+
updateSubscribers();
|
|
368
|
+
};
|
|
369
|
+
const getFormContext = () => {
|
|
370
|
+
return {
|
|
371
|
+
deleteField,
|
|
372
|
+
resetField,
|
|
373
|
+
setFieldValue,
|
|
374
|
+
validateForm,
|
|
375
|
+
state,
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
const setFieldValidators = (name, validators) => {
|
|
379
|
+
formFieldValidators[name] = validators;
|
|
380
|
+
if (validators.dependentOn && validators.dependentOn.length > 0) {
|
|
381
|
+
for (const dependentOn of validators.dependentOn) {
|
|
382
|
+
if (!formFieldDependencies[dependentOn]) {
|
|
383
|
+
formFieldDependencies[dependentOn] = new Set();
|
|
384
|
+
}
|
|
385
|
+
formFieldDependencies[dependentOn].add(name);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
return {
|
|
390
|
+
subscribers,
|
|
391
|
+
state,
|
|
392
|
+
validateField,
|
|
393
|
+
getFieldState,
|
|
394
|
+
setFieldValue,
|
|
395
|
+
arrayFieldReplace,
|
|
396
|
+
arrayFieldPush,
|
|
397
|
+
arrayFieldRemove,
|
|
398
|
+
connectField,
|
|
399
|
+
disconnectField,
|
|
400
|
+
setFieldValidators,
|
|
401
|
+
getSelectorState,
|
|
402
|
+
validateForm,
|
|
403
|
+
reset,
|
|
404
|
+
getFormContext,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
export function useForm(config) {
|
|
408
|
+
return useHook("useForm", {}, ({ hook, isInit, isHMR }) => {
|
|
409
|
+
if (__DEV__) {
|
|
410
|
+
if (isInit) {
|
|
411
|
+
hook.dev = {
|
|
412
|
+
initialArgs: [config],
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
if (isHMR) {
|
|
416
|
+
const [c] = hook.dev.initialArgs;
|
|
417
|
+
if (safeStringify(c) !== safeStringify(config)) {
|
|
418
|
+
hook.cleanup?.();
|
|
419
|
+
isInit = true;
|
|
420
|
+
hook.dev.initialArgs = [config];
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (isInit) {
|
|
425
|
+
const $controller = (hook.formController = createFormController(config));
|
|
426
|
+
hook.Field = function Field(props) {
|
|
427
|
+
const didMount = useRef(false);
|
|
428
|
+
const update = useRequestUpdate();
|
|
429
|
+
if (props.validators) {
|
|
430
|
+
$controller.setFieldValidators(props.name, props.validators);
|
|
431
|
+
}
|
|
432
|
+
useEffect(() => {
|
|
433
|
+
$controller.connectField(props.name, update);
|
|
434
|
+
if (props.validators?.onMount && !didMount.current) {
|
|
435
|
+
didMount.current = true;
|
|
436
|
+
$controller.validateField(props.name, "onMount");
|
|
437
|
+
}
|
|
438
|
+
return () => {
|
|
439
|
+
$controller.disconnectField(props.name, update);
|
|
440
|
+
};
|
|
441
|
+
}, []);
|
|
442
|
+
const fieldState = $controller.getFieldState(props.name);
|
|
443
|
+
const childProps = {
|
|
444
|
+
name: props.name,
|
|
445
|
+
state: fieldState,
|
|
446
|
+
handleChange: (value) => {
|
|
447
|
+
$controller.setFieldValue(props.name, value);
|
|
448
|
+
},
|
|
449
|
+
handleBlur: () => {
|
|
450
|
+
$controller.validateField(props.name, "onBlur");
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
if (props.array) {
|
|
454
|
+
const asArrayProps = childProps;
|
|
455
|
+
asArrayProps.items = {
|
|
456
|
+
replace: (index, value) => {
|
|
457
|
+
$controller.arrayFieldReplace(props.name, index, value);
|
|
458
|
+
},
|
|
459
|
+
push: (value) => {
|
|
460
|
+
$controller.arrayFieldPush(props.name, value);
|
|
461
|
+
},
|
|
462
|
+
remove: (index) => {
|
|
463
|
+
$controller.arrayFieldRemove(props.name, index);
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
return Fragment({
|
|
468
|
+
key: useMemo(generateRandomID, []),
|
|
469
|
+
children: props.children(childProps),
|
|
470
|
+
});
|
|
471
|
+
};
|
|
472
|
+
hook.Subscribe = function Subscribe(props) {
|
|
473
|
+
const selection = useHook("useFormSubscription", { sub: null }, ({ hook, isInit, isHMR, update }) => {
|
|
474
|
+
if (__DEV__) {
|
|
475
|
+
if (isHMR) {
|
|
476
|
+
isInit = true;
|
|
477
|
+
hook.cleanup?.();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (isInit) {
|
|
481
|
+
hook.sub = {
|
|
482
|
+
selector: props.selector,
|
|
483
|
+
selection: props.selector($controller.getSelectorState()),
|
|
484
|
+
update,
|
|
485
|
+
};
|
|
486
|
+
$controller.subscribers.add(hook.sub);
|
|
487
|
+
hook.cleanup = () => $controller.subscribers.delete(hook.sub);
|
|
488
|
+
}
|
|
489
|
+
return hook.sub.selection;
|
|
490
|
+
});
|
|
491
|
+
return props.children(selection);
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
Field: hook.Field,
|
|
496
|
+
Subscribe: hook.Subscribe,
|
|
497
|
+
handleSubmit: async () => {
|
|
498
|
+
const errors = await hook.formController.validateForm();
|
|
499
|
+
const formCtx = hook.formController.getFormContext();
|
|
500
|
+
if (errors.length)
|
|
501
|
+
return config.onSubmitInvalid?.(formCtx);
|
|
502
|
+
await config.onSubmit?.(formCtx);
|
|
503
|
+
},
|
|
504
|
+
reset: (values) => hook.formController.reset(values),
|
|
505
|
+
getFieldState: (name) => hook.formController.getFieldState(name),
|
|
506
|
+
};
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
//# sourceMappingURL=index.js.map
|