@react-typed-forms/schemas 4.1.0 → 5.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/.rush/temp/operation/build/state.json +1 -1
- package/lib/controlBuilder.d.ts +3 -1
- package/lib/controlRender.d.ts +8 -4
- package/lib/hooks.d.ts +8 -4
- package/lib/index.js +98 -40
- package/lib/index.js.map +1 -1
- package/lib/internal.d.ts +2 -0
- package/lib/renderers.d.ts +1 -2
- package/lib/types.d.ts +3 -1
- package/lib/util.d.ts +1 -0
- package/package.json +1 -1
- package/src/controlBuilder.ts +10 -1
- package/src/controlRender.tsx +57 -19
- package/src/hooks.tsx +89 -26
- package/src/internal.ts +7 -0
- package/src/renderers.tsx +1 -4
- package/src/types.ts +2 -0
- package/src/util.ts +5 -1
package/lib/renderers.d.ts
CHANGED
|
@@ -164,8 +164,7 @@ export declare function DefaultVisibility({ visibility, children, }: {
|
|
|
164
164
|
visibility: Control<Visibility | undefined>;
|
|
165
165
|
children: () => ReactNode;
|
|
166
166
|
}): string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
|
|
167
|
-
export declare function DefaultLayout({ className, errorClass,
|
|
168
|
-
errorControl?: Control<any>;
|
|
167
|
+
export declare function DefaultLayout({ className, errorClass, layout: { controlEnd, controlStart, label, children, errorControl }, }: DefaultLayoutRendererOptions & {
|
|
169
168
|
layout: RenderedLayout;
|
|
170
169
|
}): React.JSX.Element;
|
|
171
170
|
export {};
|
package/lib/types.d.ts
CHANGED
|
@@ -61,7 +61,9 @@ export interface DynamicProperty {
|
|
|
61
61
|
}
|
|
62
62
|
export declare enum DynamicPropertyType {
|
|
63
63
|
Visible = "Visible",
|
|
64
|
-
DefaultValue = "DefaultValue"
|
|
64
|
+
DefaultValue = "DefaultValue",
|
|
65
|
+
Readonly = "Readonly",
|
|
66
|
+
Disabled = "Disabled"
|
|
65
67
|
}
|
|
66
68
|
export interface EntityExpression {
|
|
67
69
|
type: string;
|
package/lib/util.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare function hasOptions(o: {
|
|
|
27
27
|
export declare function defaultControlForField(sf: SchemaField): DataControlDefinition | GroupedControlsDefinition;
|
|
28
28
|
export declare function addMissingControls(fields: SchemaField[], controls: ControlDefinition[]): ControlDefinition[];
|
|
29
29
|
export declare function useUpdatedRef<A>(a: A): MutableRefObject<A>;
|
|
30
|
+
export declare function isControlReadonly(c: ControlDefinition): boolean;
|
|
30
31
|
export declare function getTypeField(context: ControlGroupContext): Control<string> | undefined;
|
|
31
32
|
export declare function visitControlDataArray<A>(controls: ControlDefinition[] | undefined | null, context: ControlGroupContext, cb: (definition: DataControlDefinition, field: SchemaField, control: Control<any>, element: boolean) => A | undefined): A | undefined;
|
|
32
33
|
export declare function visitControlData<A>(definition: ControlDefinition, ctx: ControlGroupContext, cb: (definition: DataControlDefinition, field: SchemaField, control: Control<any>, element: boolean) => A | undefined): A | undefined;
|
package/package.json
CHANGED
package/src/controlBuilder.ts
CHANGED
|
@@ -53,10 +53,19 @@ export function htmlDisplayControl(
|
|
|
53
53
|
export function dynamicDefaultValue(expr: EntityExpression): DynamicProperty {
|
|
54
54
|
return { type: DynamicPropertyType.DefaultValue, expr };
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
export function dynamicReadonly(expr: EntityExpression): DynamicProperty {
|
|
58
|
+
return { type: DynamicPropertyType.Readonly, expr };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function dynamicVisibility(expr: EntityExpression): DynamicProperty {
|
|
57
62
|
return { type: DynamicPropertyType.Visible, expr };
|
|
58
63
|
}
|
|
59
64
|
|
|
65
|
+
export function dynamicDisabled(expr: EntityExpression): DynamicProperty {
|
|
66
|
+
return { type: DynamicPropertyType.Disabled, expr };
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
export function fieldEqExpr(field: string, value: any): FieldValueExpression {
|
|
61
70
|
return { type: ExpressionType.FieldValue, field, value };
|
|
62
71
|
}
|
package/src/controlRender.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import React, {
|
|
|
4
4
|
Key,
|
|
5
5
|
ReactNode,
|
|
6
6
|
useCallback,
|
|
7
|
-
|
|
7
|
+
useEffect,
|
|
8
8
|
} from "react";
|
|
9
9
|
import {
|
|
10
10
|
addElement,
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
newControl,
|
|
13
13
|
removeElement,
|
|
14
14
|
useComponentTracking,
|
|
15
|
-
useComputed,
|
|
16
15
|
useControl,
|
|
17
16
|
useControlEffect,
|
|
18
17
|
} from "@react-typed-forms/core";
|
|
@@ -40,8 +39,16 @@ import {
|
|
|
40
39
|
useUpdatedRef,
|
|
41
40
|
} from "./util";
|
|
42
41
|
import { dataControl } from "./controlBuilder";
|
|
43
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
defaultUseEvalExpressionHook,
|
|
44
|
+
useEvalDefaultValueHook,
|
|
45
|
+
useEvalDisabledHook,
|
|
46
|
+
UseEvalExpressionHook,
|
|
47
|
+
useEvalReadonlyHook,
|
|
48
|
+
useEvalVisibilityHook,
|
|
49
|
+
} from "./hooks";
|
|
44
50
|
import { useValidationHook } from "./validators";
|
|
51
|
+
import { useCalculatedControl } from "./internal";
|
|
45
52
|
|
|
46
53
|
export interface FormRenderer {
|
|
47
54
|
renderData: (
|
|
@@ -102,6 +109,7 @@ export interface RenderedLayout {
|
|
|
102
109
|
controlEnd?: ReactNode;
|
|
103
110
|
label?: ReactNode;
|
|
104
111
|
children?: ReactNode;
|
|
112
|
+
errorControl?: Control<any>;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
export interface ControlLayoutProps {
|
|
@@ -152,7 +160,8 @@ export interface ControlRenderProps {
|
|
|
152
160
|
|
|
153
161
|
export interface FormContextOptions {
|
|
154
162
|
readonly?: boolean | null;
|
|
155
|
-
hidden?: boolean;
|
|
163
|
+
hidden?: boolean | null;
|
|
164
|
+
disabled?: boolean | null;
|
|
156
165
|
}
|
|
157
166
|
|
|
158
167
|
export type CreateDataProps = (
|
|
@@ -164,6 +173,7 @@ export type CreateDataProps = (
|
|
|
164
173
|
) => DataRendererProps;
|
|
165
174
|
export interface ControlRenderOptions extends FormContextOptions {
|
|
166
175
|
useDataHook?: (c: ControlDefinition) => CreateDataProps;
|
|
176
|
+
useEvalExpressionHook?: UseEvalExpressionHook;
|
|
167
177
|
clearHidden?: boolean;
|
|
168
178
|
}
|
|
169
179
|
export function useControlRenderer(
|
|
@@ -173,10 +183,17 @@ export function useControlRenderer(
|
|
|
173
183
|
options: ControlRenderOptions = {},
|
|
174
184
|
): FC<ControlRenderProps> {
|
|
175
185
|
const dataProps = options.useDataHook?.(definition) ?? defaultDataProps;
|
|
186
|
+
const useExpr = options.useEvalExpressionHook ?? defaultUseEvalExpressionHook;
|
|
176
187
|
|
|
177
188
|
const schemaField = lookupSchemaField(definition, fields);
|
|
178
|
-
const useDefaultValue = useEvalDefaultValueHook(
|
|
179
|
-
|
|
189
|
+
const useDefaultValue = useEvalDefaultValueHook(
|
|
190
|
+
useExpr,
|
|
191
|
+
definition,
|
|
192
|
+
schemaField,
|
|
193
|
+
);
|
|
194
|
+
const useIsVisible = useEvalVisibilityHook(useExpr, definition, schemaField);
|
|
195
|
+
const useIsReadonly = useEvalReadonlyHook(useExpr, definition);
|
|
196
|
+
const useIsDisabled = useEvalDisabledHook(useExpr, definition);
|
|
180
197
|
const useValidation = useValidationHook(definition);
|
|
181
198
|
const r = useUpdatedRef({ options, definition, fields, schemaField });
|
|
182
199
|
|
|
@@ -189,6 +206,8 @@ export function useControlRenderer(
|
|
|
189
206
|
groupControl: parentControl,
|
|
190
207
|
fields,
|
|
191
208
|
};
|
|
209
|
+
const readonlyControl = useIsReadonly(groupContext);
|
|
210
|
+
const disabledControl = useIsDisabled(groupContext);
|
|
192
211
|
const visibleControl = useIsVisible(groupContext);
|
|
193
212
|
const visible = visibleControl.current.value;
|
|
194
213
|
const visibility = useControl<Visibility | undefined>(() =>
|
|
@@ -236,16 +255,23 @@ export function useControlRenderer(
|
|
|
236
255
|
},
|
|
237
256
|
true,
|
|
238
257
|
);
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
258
|
+
const myOptions = useCalculatedControl<FormContextOptions>(() => ({
|
|
259
|
+
hidden: options.hidden || !visibility.fields?.showing.value,
|
|
260
|
+
readonly: options.readonly || readonlyControl.value,
|
|
261
|
+
disabled: options.disabled || disabledControl.value,
|
|
262
|
+
})).value;
|
|
263
|
+
useValidation(control!, !!myOptions.hidden, groupContext);
|
|
245
264
|
const childRenderers: FC<ControlRenderProps>[] =
|
|
246
265
|
c.children?.map((cd) =>
|
|
247
|
-
useControlRenderer(cd, childContext.fields, renderer,
|
|
266
|
+
useControlRenderer(cd, childContext.fields, renderer, {
|
|
267
|
+
...options,
|
|
268
|
+
...myOptions,
|
|
269
|
+
}),
|
|
248
270
|
) ?? [];
|
|
271
|
+
useEffect(() => {
|
|
272
|
+
if (control && typeof myOptions.disabled === "boolean")
|
|
273
|
+
control.disabled = myOptions.disabled;
|
|
274
|
+
}, [control, myOptions.disabled]);
|
|
249
275
|
if (parentControl.isNull) return <></>;
|
|
250
276
|
const adornments =
|
|
251
277
|
definition.adornments?.map((x) =>
|
|
@@ -272,7 +298,16 @@ export function useControlRenderer(
|
|
|
272
298
|
stopTracking();
|
|
273
299
|
}
|
|
274
300
|
},
|
|
275
|
-
[
|
|
301
|
+
[
|
|
302
|
+
r,
|
|
303
|
+
dataProps,
|
|
304
|
+
useIsVisible,
|
|
305
|
+
useDefaultValue,
|
|
306
|
+
useIsReadonly,
|
|
307
|
+
useIsDisabled,
|
|
308
|
+
useValidation,
|
|
309
|
+
renderer,
|
|
310
|
+
],
|
|
276
311
|
);
|
|
277
312
|
(Component as any).displayName = "RenderControl";
|
|
278
313
|
return Component;
|
|
@@ -358,7 +393,7 @@ export const defaultDataProps: CreateDataProps = (
|
|
|
358
393
|
field,
|
|
359
394
|
id: "c" + control.uniqueId,
|
|
360
395
|
options: (field.options?.length ?? 0) === 0 ? null : field.options,
|
|
361
|
-
readonly: options.readonly
|
|
396
|
+
readonly: !!options.readonly,
|
|
362
397
|
renderOptions: definition.renderOptions ?? { type: "Standard" },
|
|
363
398
|
required: !!definition.required,
|
|
364
399
|
hidden: !!options.hidden,
|
|
@@ -523,7 +558,7 @@ export function renderControlLayout(
|
|
|
523
558
|
}
|
|
524
559
|
|
|
525
560
|
export function appendMarkup(
|
|
526
|
-
k: keyof RenderedLayout,
|
|
561
|
+
k: keyof Omit<RenderedLayout, "errorControl">,
|
|
527
562
|
markup: ReactNode,
|
|
528
563
|
): (layout: RenderedLayout) => void {
|
|
529
564
|
return (layout) =>
|
|
@@ -536,7 +571,7 @@ export function appendMarkup(
|
|
|
536
571
|
}
|
|
537
572
|
|
|
538
573
|
export function wrapMarkup(
|
|
539
|
-
k: keyof RenderedLayout,
|
|
574
|
+
k: keyof Omit<RenderedLayout, "errorControl">,
|
|
540
575
|
wrap: (ex: ReactNode) => ReactNode,
|
|
541
576
|
): (layout: RenderedLayout) => void {
|
|
542
577
|
return (layout) => (layout[k] = wrap(layout[k]));
|
|
@@ -544,7 +579,7 @@ export function wrapMarkup(
|
|
|
544
579
|
|
|
545
580
|
export function layoutKeyForPlacement(
|
|
546
581
|
pos: AdornmentPlacement,
|
|
547
|
-
): keyof RenderedLayout {
|
|
582
|
+
): keyof Omit<RenderedLayout, "errorControl"> {
|
|
548
583
|
switch (pos) {
|
|
549
584
|
case AdornmentPlacement.ControlEnd:
|
|
550
585
|
return "controlEnd";
|
|
@@ -576,7 +611,10 @@ export function renderLayoutParts(
|
|
|
576
611
|
renderer: FormRenderer,
|
|
577
612
|
): RenderedLayout {
|
|
578
613
|
const processed = props.processLayout?.(props) ?? props;
|
|
579
|
-
const layout: RenderedLayout = {
|
|
614
|
+
const layout: RenderedLayout = {
|
|
615
|
+
children: processed.children,
|
|
616
|
+
errorControl: processed.errorControl,
|
|
617
|
+
};
|
|
580
618
|
(processed.adornments ?? [])
|
|
581
619
|
.sort((a, b) => a.priority - b.priority)
|
|
582
620
|
.forEach((x) => x.apply(layout));
|
package/src/hooks.tsx
CHANGED
|
@@ -21,17 +21,25 @@ import {
|
|
|
21
21
|
defaultValueForField,
|
|
22
22
|
findField,
|
|
23
23
|
getTypeField,
|
|
24
|
+
isControlReadonly,
|
|
24
25
|
useUpdatedRef,
|
|
25
26
|
} from "./util";
|
|
26
27
|
import jsonata from "jsonata";
|
|
28
|
+
import { useCalculatedControl } from "./internal";
|
|
29
|
+
|
|
30
|
+
export type UseEvalExpressionHook = (
|
|
31
|
+
expr: EntityExpression | undefined,
|
|
32
|
+
) => EvalExpressionHook | undefined;
|
|
27
33
|
|
|
28
34
|
export function useEvalVisibilityHook(
|
|
35
|
+
useEvalExpressionHook: UseEvalExpressionHook,
|
|
29
36
|
definition: ControlDefinition,
|
|
30
37
|
schemaField?: SchemaField,
|
|
31
38
|
): EvalExpressionHook<boolean> {
|
|
32
39
|
const dynamicVisibility = useEvalDynamicHook(
|
|
33
40
|
definition,
|
|
34
41
|
DynamicPropertyType.Visible,
|
|
42
|
+
useEvalExpressionHook,
|
|
35
43
|
);
|
|
36
44
|
const r = useUpdatedRef(schemaField);
|
|
37
45
|
return useCallback(
|
|
@@ -46,13 +54,52 @@ export function useEvalVisibilityHook(
|
|
|
46
54
|
);
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
export function useEvalReadonlyHook(
|
|
58
|
+
useEvalExpressionHook: UseEvalExpressionHook,
|
|
59
|
+
definition: ControlDefinition,
|
|
60
|
+
): EvalExpressionHook<boolean> {
|
|
61
|
+
const dynamicReadonly = useEvalDynamicHook(
|
|
62
|
+
definition,
|
|
63
|
+
DynamicPropertyType.Readonly,
|
|
64
|
+
useEvalExpressionHook,
|
|
65
|
+
);
|
|
66
|
+
const r = useUpdatedRef(definition);
|
|
67
|
+
return useCallback(
|
|
68
|
+
(ctx) => {
|
|
69
|
+
if (dynamicReadonly) return dynamicReadonly(ctx);
|
|
70
|
+
return useCalculatedControl(() => isControlReadonly(r.current));
|
|
71
|
+
},
|
|
72
|
+
[dynamicReadonly, r],
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function useEvalDisabledHook(
|
|
77
|
+
useEvalExpressionHook: UseEvalExpressionHook,
|
|
78
|
+
definition: ControlDefinition,
|
|
79
|
+
): EvalExpressionHook<boolean> {
|
|
80
|
+
const dynamicDisabled = useEvalDynamicHook(
|
|
81
|
+
definition,
|
|
82
|
+
DynamicPropertyType.Disabled,
|
|
83
|
+
useEvalExpressionHook,
|
|
84
|
+
);
|
|
85
|
+
return useCallback(
|
|
86
|
+
(ctx) => {
|
|
87
|
+
if (dynamicDisabled) return dynamicDisabled(ctx);
|
|
88
|
+
return useControl(false);
|
|
89
|
+
},
|
|
90
|
+
[dynamicDisabled],
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
49
94
|
export function useEvalDefaultValueHook(
|
|
95
|
+
useEvalExpressionHook: UseEvalExpressionHook,
|
|
50
96
|
definition: ControlDefinition,
|
|
51
97
|
schemaField?: SchemaField,
|
|
52
98
|
): EvalExpressionHook {
|
|
53
99
|
const dynamicValue = useEvalDynamicHook(
|
|
54
100
|
definition,
|
|
55
101
|
DynamicPropertyType.DefaultValue,
|
|
102
|
+
useEvalExpressionHook,
|
|
56
103
|
);
|
|
57
104
|
const r = useUpdatedRef({ definition, schemaField });
|
|
58
105
|
return useCallback(
|
|
@@ -91,37 +138,53 @@ function useFieldValueExpression(
|
|
|
91
138
|
return Array.isArray(fv) ? fv.includes(fvExpr.value) : fv === fvExpr.value;
|
|
92
139
|
});
|
|
93
140
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
|
|
142
|
+
function defaultEvalHooks(
|
|
143
|
+
expr: EntityExpression,
|
|
144
|
+
context: ControlGroupContext,
|
|
145
|
+
) {
|
|
146
|
+
switch (expr.type) {
|
|
147
|
+
case ExpressionType.Jsonata:
|
|
148
|
+
return useJsonataExpression(
|
|
149
|
+
(expr as JsonataExpression).expression,
|
|
150
|
+
context.groupControl,
|
|
151
|
+
);
|
|
152
|
+
case ExpressionType.FieldValue:
|
|
153
|
+
return useFieldValueExpression(
|
|
154
|
+
expr as FieldValueExpression,
|
|
155
|
+
context.fields,
|
|
156
|
+
context.groupControl,
|
|
157
|
+
);
|
|
158
|
+
default:
|
|
159
|
+
return useControl(undefined);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const defaultUseEvalExpressionHook =
|
|
164
|
+
makeEvalExpressionHook(defaultEvalHooks);
|
|
165
|
+
|
|
166
|
+
function makeEvalExpressionHook(
|
|
167
|
+
f: (expr: EntityExpression, context: ControlGroupContext) => Control<any>,
|
|
168
|
+
): (expr: EntityExpression | undefined) => EvalExpressionHook | undefined {
|
|
169
|
+
return (expr) => {
|
|
170
|
+
const r = useUpdatedRef(expr);
|
|
171
|
+
const cb = useCallback(
|
|
172
|
+
(ctx: ControlGroupContext) => {
|
|
173
|
+
const expr = r.current!;
|
|
174
|
+
return f(expr, ctx);
|
|
175
|
+
},
|
|
176
|
+
[expr?.type, r],
|
|
177
|
+
);
|
|
178
|
+
return expr ? cb : undefined;
|
|
179
|
+
};
|
|
120
180
|
}
|
|
121
181
|
|
|
122
182
|
export function useEvalDynamicHook(
|
|
123
183
|
definition: ControlDefinition,
|
|
124
184
|
type: DynamicPropertyType,
|
|
185
|
+
useEvalExpressionHook: (
|
|
186
|
+
expr: EntityExpression | undefined,
|
|
187
|
+
) => EvalExpressionHook | undefined,
|
|
125
188
|
): EvalExpressionHook | undefined {
|
|
126
189
|
const expression = definition.dynamic?.find((x) => x.type === type);
|
|
127
190
|
return useEvalExpressionHook(expression?.expr);
|
package/src/internal.ts
ADDED
package/src/renderers.tsx
CHANGED
|
@@ -564,7 +564,6 @@ function createDefaultLayoutRenderer(
|
|
|
564
564
|
return createLayoutRenderer((props, renderers) => {
|
|
565
565
|
return (
|
|
566
566
|
<DefaultLayout
|
|
567
|
-
errorControl={props.errorControl}
|
|
568
567
|
layout={renderLayoutParts(props, renderers)}
|
|
569
568
|
{...options}
|
|
570
569
|
/>
|
|
@@ -820,10 +819,8 @@ export function DefaultVisibility({
|
|
|
820
819
|
export function DefaultLayout({
|
|
821
820
|
className,
|
|
822
821
|
errorClass,
|
|
823
|
-
errorControl,
|
|
824
|
-
layout: { controlEnd, controlStart, label, children },
|
|
822
|
+
layout: { controlEnd, controlStart, label, children, errorControl },
|
|
825
823
|
}: DefaultLayoutRendererOptions & {
|
|
826
|
-
errorControl?: Control<any>;
|
|
827
824
|
layout: RenderedLayout;
|
|
828
825
|
}) {
|
|
829
826
|
const ec = errorControl;
|
package/src/types.ts
CHANGED
package/src/util.ts
CHANGED
|
@@ -79,7 +79,7 @@ export function defaultValueForField(
|
|
|
79
79
|
return sf.notNullable ? (sf.collection ? [] : {}) : undefined;
|
|
80
80
|
}
|
|
81
81
|
if (sf.collection) {
|
|
82
|
-
return
|
|
82
|
+
return [];
|
|
83
83
|
}
|
|
84
84
|
return undefined;
|
|
85
85
|
}
|
|
@@ -234,6 +234,10 @@ export function useUpdatedRef<A>(a: A): MutableRefObject<A> {
|
|
|
234
234
|
return r;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
export function isControlReadonly(c: ControlDefinition): boolean {
|
|
238
|
+
return isDataControl(c) && !!c.readonly;
|
|
239
|
+
}
|
|
240
|
+
|
|
237
241
|
export function getTypeField(
|
|
238
242
|
context: ControlGroupContext,
|
|
239
243
|
): Control<string> | undefined {
|