@react-typed-forms/schemas 15.2.0 → 16.0.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/RenderForm.d.ts +39 -0
- package/lib/controlBuilder.d.ts +3 -6
- package/lib/controlRender.d.ts +107 -87
- package/lib/index.cjs +535 -2117
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +3 -9
- package/lib/index.js +402 -1639
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +3 -3
- package/lib/types.d.ts +31 -0
- package/lib/util.d.ts +8 -54
- package/package.json +5 -4
- package/src/RenderForm.tsx +301 -0
- package/src/controlBuilder.ts +22 -19
- package/src/controlRender.tsx +228 -507
- package/src/createFormRenderer.tsx +4 -5
- package/src/index.ts +3 -9
- package/src/renderers.tsx +2 -3
- package/src/types.ts +52 -0
- package/src/util.ts +149 -183
- package/lib/controlDefinition.d.ts +0 -398
- package/lib/defaultSchemaInterface.d.ts +0 -24
- package/lib/dynamicHooks.d.ts +0 -54
- package/lib/entityExpression.d.ts +0 -32
- package/lib/hooks.d.ts +0 -28
- package/lib/schemaBuilder.d.ts +0 -67
- package/lib/schemaField.d.ts +0 -252
- package/lib/schemaValidator.d.ts +0 -27
- package/lib/validators.d.ts +0 -19
- package/src/controlDefinition.ts +0 -821
- package/src/defaultSchemaInterface.ts +0 -191
- package/src/dynamicHooks.ts +0 -98
- package/src/entityExpression.ts +0 -38
- package/src/hooks.tsx +0 -469
- package/src/schemaBuilder.ts +0 -318
- package/src/schemaField.ts +0 -552
- package/src/schemaValidator.ts +0 -32
- package/src/validators.ts +0 -217
package/src/hooks.tsx
DELETED
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ControlDefinition,
|
|
3
|
-
DynamicPropertyType,
|
|
4
|
-
ControlDataContext,
|
|
5
|
-
getRootDataNode,
|
|
6
|
-
getJsonPath,
|
|
7
|
-
isDataControl,
|
|
8
|
-
} from "./controlDefinition";
|
|
9
|
-
import React, { useEffect, useMemo, useRef } from "react";
|
|
10
|
-
import {
|
|
11
|
-
addAfterChangesCallback,
|
|
12
|
-
collectChanges,
|
|
13
|
-
Control,
|
|
14
|
-
SubscriptionTracker,
|
|
15
|
-
trackedValue,
|
|
16
|
-
useCalculatedControl,
|
|
17
|
-
useComputed,
|
|
18
|
-
useControl,
|
|
19
|
-
useRefState,
|
|
20
|
-
} from "@react-typed-forms/core";
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
defaultValueForField,
|
|
24
|
-
elementValueForField,
|
|
25
|
-
getDisplayOnlyOptions,
|
|
26
|
-
isControlDisabled,
|
|
27
|
-
isControlReadonly,
|
|
28
|
-
JsonPath,
|
|
29
|
-
jsonPathString,
|
|
30
|
-
} from "./util";
|
|
31
|
-
import jsonata from "jsonata";
|
|
32
|
-
import { v4 as uuidv4 } from "uuid";
|
|
33
|
-
import { DynamicHookGenerator, HookDep, toDepString } from "./dynamicHooks";
|
|
34
|
-
import {
|
|
35
|
-
schemaDataForFieldRef,
|
|
36
|
-
SchemaDataNode,
|
|
37
|
-
SchemaInterface,
|
|
38
|
-
} from "./schemaField";
|
|
39
|
-
import {
|
|
40
|
-
DataExpression,
|
|
41
|
-
DataMatchExpression,
|
|
42
|
-
EntityExpression,
|
|
43
|
-
ExpressionType,
|
|
44
|
-
JsonataExpression,
|
|
45
|
-
NotEmptyExpression,
|
|
46
|
-
} from "./entityExpression";
|
|
47
|
-
|
|
48
|
-
export type EvalExpressionHook<A = any> = DynamicHookGenerator<
|
|
49
|
-
Control<A | undefined>,
|
|
50
|
-
ControlDataContext
|
|
51
|
-
>;
|
|
52
|
-
|
|
53
|
-
export type UseEvalExpressionHook = (
|
|
54
|
-
expr: EntityExpression | undefined | null,
|
|
55
|
-
coerce: (v: any) => any,
|
|
56
|
-
) => DynamicHookGenerator<Control<any> | undefined, ControlDataContext>;
|
|
57
|
-
|
|
58
|
-
export function optionalHook(
|
|
59
|
-
expr: EntityExpression | undefined | null,
|
|
60
|
-
useHook: UseEvalExpressionHook,
|
|
61
|
-
coerce: (v: any) => any,
|
|
62
|
-
):
|
|
63
|
-
| DynamicHookGenerator<Control<any> | undefined, ControlDataContext>
|
|
64
|
-
| undefined {
|
|
65
|
-
return expr && expr.type ? useHook(expr, coerce) : undefined;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function useEvalVisibilityHook(
|
|
69
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
70
|
-
definition: ControlDefinition,
|
|
71
|
-
overrideDataNode?: SchemaDataNode,
|
|
72
|
-
): EvalExpressionHook<boolean> {
|
|
73
|
-
const dynamicVisibility = useEvalDynamicBoolHook(
|
|
74
|
-
definition,
|
|
75
|
-
DynamicPropertyType.Visible,
|
|
76
|
-
useEvalExpressionHook,
|
|
77
|
-
);
|
|
78
|
-
return makeDynamicPropertyHook(
|
|
79
|
-
dynamicVisibility,
|
|
80
|
-
(ctx, { definition, overrideDataNode }) =>
|
|
81
|
-
useComputed(() => {
|
|
82
|
-
const dataNode = overrideDataNode ?? ctx.dataNode;
|
|
83
|
-
return (
|
|
84
|
-
!dataNode ||
|
|
85
|
-
(matchesType(dataNode) &&
|
|
86
|
-
!hideDisplayOnly(dataNode, ctx.schemaInterface, definition))
|
|
87
|
-
);
|
|
88
|
-
}),
|
|
89
|
-
{ definition, overrideDataNode },
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function useEvalReadonlyHook(
|
|
94
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
95
|
-
definition: ControlDefinition,
|
|
96
|
-
): EvalExpressionHook<boolean> {
|
|
97
|
-
const dynamicReadonly = useEvalDynamicBoolHook(
|
|
98
|
-
definition,
|
|
99
|
-
DynamicPropertyType.Readonly,
|
|
100
|
-
useEvalExpressionHook,
|
|
101
|
-
);
|
|
102
|
-
return makeDynamicPropertyHook(
|
|
103
|
-
dynamicReadonly,
|
|
104
|
-
(ctx, { definition }) =>
|
|
105
|
-
useCalculatedControl(() => isControlReadonly(definition)),
|
|
106
|
-
{ definition },
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function useEvalStyleHook(
|
|
111
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
112
|
-
property: DynamicPropertyType,
|
|
113
|
-
definition: ControlDefinition,
|
|
114
|
-
): EvalExpressionHook<React.CSSProperties> {
|
|
115
|
-
const dynamicStyle = useEvalDynamicHook(
|
|
116
|
-
definition,
|
|
117
|
-
property,
|
|
118
|
-
useEvalExpressionHook,
|
|
119
|
-
);
|
|
120
|
-
return makeDynamicPropertyHook(
|
|
121
|
-
dynamicStyle,
|
|
122
|
-
() => useControl(undefined),
|
|
123
|
-
undefined,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function useEvalAllowedOptionsHook(
|
|
128
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
129
|
-
definition: ControlDefinition,
|
|
130
|
-
): EvalExpressionHook<any[]> {
|
|
131
|
-
const dynamicAllowed = useEvalDynamicHook(
|
|
132
|
-
definition,
|
|
133
|
-
DynamicPropertyType.AllowedOptions,
|
|
134
|
-
useEvalExpressionHook,
|
|
135
|
-
);
|
|
136
|
-
return makeDynamicPropertyHook(
|
|
137
|
-
dynamicAllowed,
|
|
138
|
-
() => useControl([]),
|
|
139
|
-
undefined,
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export function useEvalDisabledHook(
|
|
144
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
145
|
-
definition: ControlDefinition,
|
|
146
|
-
): EvalExpressionHook<boolean> {
|
|
147
|
-
const dynamicDisabled = useEvalDynamicBoolHook(
|
|
148
|
-
definition,
|
|
149
|
-
DynamicPropertyType.Disabled,
|
|
150
|
-
useEvalExpressionHook,
|
|
151
|
-
);
|
|
152
|
-
return makeDynamicPropertyHook(
|
|
153
|
-
dynamicDisabled,
|
|
154
|
-
(ctx) =>
|
|
155
|
-
useComputed(() => {
|
|
156
|
-
const dataControl = ctx.dataNode?.control;
|
|
157
|
-
const setToNull = dataControl?.meta["nullControl"]?.value === false;
|
|
158
|
-
return setToNull || isControlDisabled(definition);
|
|
159
|
-
}),
|
|
160
|
-
undefined,
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function useEvalDisplayHook(
|
|
165
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
166
|
-
definition: ControlDefinition,
|
|
167
|
-
): DynamicHookGenerator<
|
|
168
|
-
Control<string | undefined> | undefined,
|
|
169
|
-
ControlDataContext
|
|
170
|
-
> {
|
|
171
|
-
return useEvalDynamicHook<string | undefined>(
|
|
172
|
-
definition,
|
|
173
|
-
DynamicPropertyType.Display,
|
|
174
|
-
useEvalExpressionHook,
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
export function useEvalDefaultValueHook(
|
|
178
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
179
|
-
definition: ControlDefinition,
|
|
180
|
-
): EvalExpressionHook {
|
|
181
|
-
const dynamicValue = useEvalDynamicHook(
|
|
182
|
-
definition,
|
|
183
|
-
DynamicPropertyType.DefaultValue,
|
|
184
|
-
useEvalExpressionHook,
|
|
185
|
-
);
|
|
186
|
-
return makeDynamicPropertyHook(
|
|
187
|
-
dynamicValue,
|
|
188
|
-
(ctx, { definition }) => {
|
|
189
|
-
return useComputed(calcDefault);
|
|
190
|
-
function calcDefault() {
|
|
191
|
-
const [required, dcv] = isDataControl(definition)
|
|
192
|
-
? [definition.required, definition.defaultValue]
|
|
193
|
-
: [false, undefined];
|
|
194
|
-
const field = ctx.dataNode?.schema.field;
|
|
195
|
-
return (
|
|
196
|
-
dcv ??
|
|
197
|
-
(field
|
|
198
|
-
? ctx.dataNode!.elementIndex != null
|
|
199
|
-
? elementValueForField(field)
|
|
200
|
-
: defaultValueForField(field, required)
|
|
201
|
-
: undefined)
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
{ definition },
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function useDataExpression(
|
|
210
|
-
fvExpr: DataExpression,
|
|
211
|
-
node: SchemaDataNode,
|
|
212
|
-
coerce: (v: any) => any = (x) => x,
|
|
213
|
-
) {
|
|
214
|
-
const otherField = schemaDataForFieldRef(fvExpr.field, node);
|
|
215
|
-
return useCalculatedControl(() => coerce(otherField.control?.value));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function useDataMatchExpression(
|
|
219
|
-
fvExpr: DataMatchExpression,
|
|
220
|
-
node: SchemaDataNode,
|
|
221
|
-
coerce: (v: any) => any = (x) => x,
|
|
222
|
-
) {
|
|
223
|
-
const otherField = schemaDataForFieldRef(fvExpr.field, node);
|
|
224
|
-
return useCalculatedControl(() => {
|
|
225
|
-
const fv = otherField.control?.value;
|
|
226
|
-
return coerce(
|
|
227
|
-
Array.isArray(fv) ? fv.includes(fvExpr.value) : fv === fvExpr.value,
|
|
228
|
-
);
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function useNotEmptyExpression(
|
|
233
|
-
fvExpr: NotEmptyExpression,
|
|
234
|
-
node: SchemaDataNode,
|
|
235
|
-
schemaInterface: SchemaInterface,
|
|
236
|
-
coerce: (v: any) => any = (x) => x,
|
|
237
|
-
) {
|
|
238
|
-
const otherField = schemaDataForFieldRef(fvExpr.field, node);
|
|
239
|
-
return useCalculatedControl(() => {
|
|
240
|
-
const fv = otherField.control?.value;
|
|
241
|
-
const field = otherField.schema.field;
|
|
242
|
-
return coerce(field && !schemaInterface.isEmptyValue(field, fv));
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export function defaultEvalHooks(
|
|
247
|
-
expr: EntityExpression,
|
|
248
|
-
context: ControlDataContext,
|
|
249
|
-
coerce: (v: any) => any,
|
|
250
|
-
) {
|
|
251
|
-
switch (expr.type) {
|
|
252
|
-
case ExpressionType.Jsonata:
|
|
253
|
-
const bindings = useComputed(() => ({ formData: context.formData }));
|
|
254
|
-
return useJsonataExpression(
|
|
255
|
-
(expr as JsonataExpression).expression,
|
|
256
|
-
getRootDataNode(context.parentNode).control!,
|
|
257
|
-
getJsonPath(context.parentNode),
|
|
258
|
-
bindings,
|
|
259
|
-
coerce,
|
|
260
|
-
);
|
|
261
|
-
case ExpressionType.UUID:
|
|
262
|
-
return useUuidExpression(coerce);
|
|
263
|
-
case ExpressionType.Data:
|
|
264
|
-
return useDataExpression(
|
|
265
|
-
expr as DataExpression,
|
|
266
|
-
context.parentNode,
|
|
267
|
-
coerce,
|
|
268
|
-
);
|
|
269
|
-
case ExpressionType.DataMatch:
|
|
270
|
-
return useDataMatchExpression(
|
|
271
|
-
expr as DataMatchExpression,
|
|
272
|
-
context.parentNode,
|
|
273
|
-
coerce,
|
|
274
|
-
);
|
|
275
|
-
case ExpressionType.NotEmpty:
|
|
276
|
-
return useNotEmptyExpression(
|
|
277
|
-
expr as NotEmptyExpression,
|
|
278
|
-
context.parentNode,
|
|
279
|
-
context.schemaInterface,
|
|
280
|
-
coerce,
|
|
281
|
-
);
|
|
282
|
-
default:
|
|
283
|
-
return useControl(undefined);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
export const defaultUseEvalExpressionHook =
|
|
288
|
-
makeEvalExpressionHook(defaultEvalHooks);
|
|
289
|
-
|
|
290
|
-
export function makeEvalExpressionHook(
|
|
291
|
-
f: (
|
|
292
|
-
expr: EntityExpression,
|
|
293
|
-
context: ControlDataContext,
|
|
294
|
-
coerce: (v: any) => any,
|
|
295
|
-
) => Control<any>,
|
|
296
|
-
): UseEvalExpressionHook {
|
|
297
|
-
return (expr, coerce) => ({
|
|
298
|
-
deps: expr?.type,
|
|
299
|
-
state: expr && expr.type ? expr : undefined,
|
|
300
|
-
runHook: (ctx: ControlDataContext, state: EntityExpression | undefined) => {
|
|
301
|
-
return state ? f(state, ctx, coerce) : undefined;
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
export function useEvalDynamicBoolHook(
|
|
307
|
-
definition: ControlDefinition,
|
|
308
|
-
type: DynamicPropertyType,
|
|
309
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
310
|
-
): DynamicHookGenerator<Control<any> | undefined, ControlDataContext> {
|
|
311
|
-
return useEvalDynamicHook(definition, type, useEvalExpressionHook, (x) =>
|
|
312
|
-
Boolean(x),
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
export function useEvalDynamicHook<V>(
|
|
317
|
-
definition: ControlDefinition,
|
|
318
|
-
type: DynamicPropertyType,
|
|
319
|
-
useEvalExpressionHook: UseEvalExpressionHook,
|
|
320
|
-
coerce: (v: any) => any = (x) => x,
|
|
321
|
-
): DynamicHookGenerator<Control<V> | undefined, ControlDataContext> {
|
|
322
|
-
const expression = definition.dynamic?.find((x) => x.type === type);
|
|
323
|
-
return useEvalExpressionHook(
|
|
324
|
-
expression?.expr,
|
|
325
|
-
coerce,
|
|
326
|
-
) as DynamicHookGenerator<Control<V> | undefined, ControlDataContext>;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export function matchesType(context: SchemaDataNode): boolean {
|
|
330
|
-
const types = context.schema.field.onlyForTypes;
|
|
331
|
-
if (types == null || types.length === 0) return true;
|
|
332
|
-
const parent = context.parent!;
|
|
333
|
-
const typeNode = parent.schema
|
|
334
|
-
.getChildNodes()
|
|
335
|
-
.find((x) => x.field.isTypeField);
|
|
336
|
-
if (typeNode == null) return true;
|
|
337
|
-
const typeField = parent.getChild(typeNode).control as Control<string>;
|
|
338
|
-
return typeField && types.includes(typeField.value);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export function hideDisplayOnly(
|
|
342
|
-
context: SchemaDataNode,
|
|
343
|
-
schemaInterface: SchemaInterface,
|
|
344
|
-
definition: ControlDefinition,
|
|
345
|
-
) {
|
|
346
|
-
const displayOptions = getDisplayOnlyOptions(definition);
|
|
347
|
-
return (
|
|
348
|
-
displayOptions &&
|
|
349
|
-
!displayOptions.emptyText &&
|
|
350
|
-
schemaInterface.isEmptyValue(context.schema.field, context.control?.value)
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
export function useUuidExpression(coerce: (v: any) => any = (x) => x) {
|
|
355
|
-
return useControl(() => coerce(uuidv4()));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
export function useJsonataExpression(
|
|
359
|
-
jExpr: string,
|
|
360
|
-
data: Control<any>,
|
|
361
|
-
path: JsonPath[],
|
|
362
|
-
bindings?: Control<Record<string, any>>,
|
|
363
|
-
coerce: (v: any) => any = (x) => x,
|
|
364
|
-
): Control<any> {
|
|
365
|
-
const pathString = jsonPathString(path, (x) => `#$i[${x}]`);
|
|
366
|
-
const fullExpr = pathString ? pathString + ".(" + jExpr + ")" : jExpr;
|
|
367
|
-
const compiledExpr = useMemo(() => {
|
|
368
|
-
try {
|
|
369
|
-
return jsonata(jExpr ? fullExpr : "null");
|
|
370
|
-
} catch (e) {
|
|
371
|
-
console.error(e);
|
|
372
|
-
return jsonata("null");
|
|
373
|
-
}
|
|
374
|
-
}, [fullExpr]);
|
|
375
|
-
const control = useControl();
|
|
376
|
-
const listenerRef = useRef<() => void>();
|
|
377
|
-
const updateRef = useRef(0);
|
|
378
|
-
const [ref] = useRefState(
|
|
379
|
-
() =>
|
|
380
|
-
new SubscriptionTracker(() => {
|
|
381
|
-
const l = listenerRef.current;
|
|
382
|
-
if (l) {
|
|
383
|
-
listenerRef.current = undefined;
|
|
384
|
-
addAfterChangesCallback(() => {
|
|
385
|
-
listenerRef.current = l;
|
|
386
|
-
l();
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
}),
|
|
390
|
-
);
|
|
391
|
-
useEffect(() => {
|
|
392
|
-
listenerRef.current = apply;
|
|
393
|
-
apply();
|
|
394
|
-
async function apply() {
|
|
395
|
-
const tracker = ref.current;
|
|
396
|
-
try {
|
|
397
|
-
updateRef.current++;
|
|
398
|
-
control.value = coerce(
|
|
399
|
-
await compiledExpr.evaluate(
|
|
400
|
-
trackedValue(data, tracker.collectUsage),
|
|
401
|
-
collectChanges(tracker.collectUsage, () => bindings?.value),
|
|
402
|
-
),
|
|
403
|
-
);
|
|
404
|
-
} finally {
|
|
405
|
-
if (!--updateRef.current) tracker.update();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}, [compiledExpr]);
|
|
409
|
-
useEffect(() => {
|
|
410
|
-
return () => {
|
|
411
|
-
listenerRef.current = undefined;
|
|
412
|
-
ref.current.cleanup();
|
|
413
|
-
};
|
|
414
|
-
}, []);
|
|
415
|
-
return control;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
export function useEvalActionHook(
|
|
419
|
-
useExpr: UseEvalExpressionHook,
|
|
420
|
-
definition: ControlDefinition,
|
|
421
|
-
): EvalExpressionHook<string | null> {
|
|
422
|
-
const dynamicValue = useEvalDynamicHook(
|
|
423
|
-
definition,
|
|
424
|
-
DynamicPropertyType.ActionData,
|
|
425
|
-
useExpr,
|
|
426
|
-
);
|
|
427
|
-
return makeDynamicPropertyHook(
|
|
428
|
-
dynamicValue,
|
|
429
|
-
() => useControl(null),
|
|
430
|
-
undefined,
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
export function useEvalLabelText(
|
|
435
|
-
useExpr: UseEvalExpressionHook,
|
|
436
|
-
definition: ControlDefinition,
|
|
437
|
-
): EvalExpressionHook<string | null> {
|
|
438
|
-
const dynamicValue = useEvalDynamicHook(
|
|
439
|
-
definition,
|
|
440
|
-
DynamicPropertyType.Label,
|
|
441
|
-
useExpr,
|
|
442
|
-
);
|
|
443
|
-
return makeDynamicPropertyHook(
|
|
444
|
-
dynamicValue,
|
|
445
|
-
() => useControl(null),
|
|
446
|
-
undefined,
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
function makeDynamicPropertyHook<A, S = undefined>(
|
|
451
|
-
dynamicValue: DynamicHookGenerator<
|
|
452
|
-
Control<any> | undefined,
|
|
453
|
-
ControlDataContext
|
|
454
|
-
>,
|
|
455
|
-
makeDefault: (ctx: ControlDataContext, s: S) => Control<A | undefined>,
|
|
456
|
-
state: S,
|
|
457
|
-
deps?: HookDep,
|
|
458
|
-
): EvalExpressionHook<A> {
|
|
459
|
-
return {
|
|
460
|
-
deps:
|
|
461
|
-
deps === undefined
|
|
462
|
-
? dynamicValue.deps
|
|
463
|
-
: [deps, dynamicValue.deps].map(toDepString).join(),
|
|
464
|
-
runHook: (ctx, s) => {
|
|
465
|
-
return dynamicValue.runHook(ctx, s[0])?.as() ?? makeDefault(ctx, s[1]);
|
|
466
|
-
},
|
|
467
|
-
state: [dynamicValue.state, state],
|
|
468
|
-
};
|
|
469
|
-
}
|