@astroapps/forms-core 1.0.2 → 1.1.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/lib/formNode.d.ts +7 -0
- package/lib/formState.d.ts +3 -0
- package/lib/index.cjs +46 -3
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +46 -5
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/formNode.ts +45 -0
- package/src/formState.ts +30 -3
package/package.json
CHANGED
package/src/formNode.ts
CHANGED
|
@@ -247,3 +247,48 @@ export function visitFormDataInContext<A>(
|
|
|
247
247
|
const dataNode = lookupDataNode(node.definition, parentContext);
|
|
248
248
|
return visitFormData(node, dataNode ?? parentContext, cb, !dataNode);
|
|
249
249
|
}
|
|
250
|
+
|
|
251
|
+
export interface FormDataNode {
|
|
252
|
+
parent?: FormDataNode;
|
|
253
|
+
formNode: FormNode;
|
|
254
|
+
parentData: SchemaDataNode;
|
|
255
|
+
childIndex?: number;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function visitFormDataNode<A>(
|
|
259
|
+
node: FormDataNode,
|
|
260
|
+
visitFn: (node: FormDataNode, data?: SchemaDataNode) => A | undefined,
|
|
261
|
+
): A | undefined {
|
|
262
|
+
const dataNode = lookupDataNode(node.formNode.definition, node.parentData);
|
|
263
|
+
const v = visitFn(node, dataNode);
|
|
264
|
+
if (v !== undefined) return v;
|
|
265
|
+
|
|
266
|
+
const parentData = dataNode ?? node.parentData;
|
|
267
|
+
if (parentData.schema.field.collection && parentData.elementIndex == null) {
|
|
268
|
+
const elemCount = parentData.control.elements.length;
|
|
269
|
+
for (let i = 0; i < elemCount; i++) {
|
|
270
|
+
const v = visitChildren(parentData.getChildElement(i));
|
|
271
|
+
if (v !== undefined) return v;
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
} else {
|
|
275
|
+
return visitChildren(parentData);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function visitChildren(parentData: SchemaDataNode) {
|
|
279
|
+
const children = node.formNode.getChildNodes();
|
|
280
|
+
for (let i = 0; i < children.length; i++) {
|
|
281
|
+
const child = children[i];
|
|
282
|
+
const res = visitFormDataNode(
|
|
283
|
+
{
|
|
284
|
+
formNode: child,
|
|
285
|
+
parent: node,
|
|
286
|
+
parentData,
|
|
287
|
+
childIndex: i,
|
|
288
|
+
},
|
|
289
|
+
visitFn,
|
|
290
|
+
);
|
|
291
|
+
if (res !== undefined) return res;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
package/src/formState.ts
CHANGED
|
@@ -24,15 +24,14 @@ import { SchemaInterface } from "./schemaInterface";
|
|
|
24
24
|
import { FieldOption } from "./schemaField";
|
|
25
25
|
import {
|
|
26
26
|
CleanupScope,
|
|
27
|
-
clearMetaValue,
|
|
28
27
|
Control,
|
|
29
28
|
createScopedEffect,
|
|
30
29
|
createSyncEffect,
|
|
31
30
|
ensureMetaValue,
|
|
32
31
|
getControlPath,
|
|
33
32
|
getCurrentFields,
|
|
33
|
+
getMetaValue,
|
|
34
34
|
newControl,
|
|
35
|
-
trackedValue,
|
|
36
35
|
unsafeRestoreControl,
|
|
37
36
|
updateComputedValue,
|
|
38
37
|
} from "@astroapps/controls";
|
|
@@ -58,6 +57,7 @@ export interface ControlState {
|
|
|
58
57
|
disabled: boolean;
|
|
59
58
|
clearHidden: boolean;
|
|
60
59
|
variables: Record<string, any>;
|
|
60
|
+
meta: Control<Record<string, any>>;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export interface FormContextOptions {
|
|
@@ -88,10 +88,24 @@ export interface FormState {
|
|
|
88
88
|
cleanup(): void;
|
|
89
89
|
|
|
90
90
|
evalExpression(expr: EntityExpression, context: ExpressionEvalContext): void;
|
|
91
|
+
|
|
92
|
+
getExistingControlState(
|
|
93
|
+
parent: SchemaDataNode,
|
|
94
|
+
formNode: FormNode,
|
|
95
|
+
stateKey?: string,
|
|
96
|
+
): ControlState | undefined;
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
const formStates: FormState[] = [];
|
|
94
100
|
|
|
101
|
+
export function getControlStateId(
|
|
102
|
+
parent: SchemaDataNode,
|
|
103
|
+
formNode: FormNode,
|
|
104
|
+
stateKey?: string,
|
|
105
|
+
): string {
|
|
106
|
+
return parent.id + "$" + formNode.id + (stateKey ?? "");
|
|
107
|
+
}
|
|
108
|
+
|
|
95
109
|
export function createFormState(
|
|
96
110
|
schemaInterface: SchemaInterface,
|
|
97
111
|
evaluators: Record<string, ExpressionEval<any>> = defaultEvaluators,
|
|
@@ -113,13 +127,25 @@ export function createFormState(
|
|
|
113
127
|
// console.log("Cleanup form state");
|
|
114
128
|
controlStates.cleanup();
|
|
115
129
|
},
|
|
130
|
+
getExistingControlState(
|
|
131
|
+
parent: SchemaDataNode,
|
|
132
|
+
formNode: FormNode,
|
|
133
|
+
stateKey?: string,
|
|
134
|
+
): ControlState | undefined {
|
|
135
|
+
const stateId = getControlStateId(parent, formNode, stateKey);
|
|
136
|
+
const control = getCurrentFields(controlStates)[stateId];
|
|
137
|
+
if (control) {
|
|
138
|
+
return getMetaValue<Control<ControlState>>(control, "impl")?.value;
|
|
139
|
+
}
|
|
140
|
+
return undefined;
|
|
141
|
+
},
|
|
116
142
|
getControlState(
|
|
117
143
|
parent: SchemaDataNode,
|
|
118
144
|
formNode: FormNode,
|
|
119
145
|
context: FormContextOptions,
|
|
120
146
|
runAsync: (af: () => void) => void,
|
|
121
147
|
): ControlState {
|
|
122
|
-
const stateId = parent
|
|
148
|
+
const stateId = getControlStateId(parent, formNode, context.stateKey);
|
|
123
149
|
const controlImpl = controlStates.fields[stateId];
|
|
124
150
|
controlImpl.value = context;
|
|
125
151
|
function evalExpr<A>(
|
|
@@ -281,6 +307,7 @@ export function createFormState(
|
|
|
281
307
|
hidden: false,
|
|
282
308
|
variables: controlImpl.fields.variables.current.value ?? {},
|
|
283
309
|
stateId,
|
|
310
|
+
meta: newControl({}),
|
|
284
311
|
});
|
|
285
312
|
|
|
286
313
|
const {
|