@react-typed-forms/schemas 6.0.0 → 7.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/.rush/temp/shrinkwrap-deps.json +39 -11
- package/lib/controlRender.d.ts +17 -8
- package/lib/hooks.d.ts +1 -0
- package/lib/index.js +141 -136
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +1 -1
- package/lib/types.d.ts +3 -1
- package/lib/util.d.ts +2 -1
- package/package.json +1 -1
- package/src/controlRender.tsx +92 -103
- package/src/hooks.tsx +18 -0
- package/src/renderers.tsx +31 -24
- package/src/types.ts +2 -0
- package/src/util.ts +16 -11
package/lib/renderers.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface DataRendererRegistration {
|
|
|
25
25
|
options?: boolean;
|
|
26
26
|
collection?: boolean;
|
|
27
27
|
match?: (props: DataRendererProps) => boolean;
|
|
28
|
-
render: (props: DataRendererProps,
|
|
28
|
+
render: (props: DataRendererProps, renderers: FormRenderer) => ReactNode | ((layout: ControlLayoutProps) => ControlLayoutProps);
|
|
29
29
|
}
|
|
30
30
|
export interface LabelRendererRegistration {
|
|
31
31
|
type: "label";
|
package/lib/types.d.ts
CHANGED
|
@@ -72,7 +72,8 @@ export declare enum DynamicPropertyType {
|
|
|
72
72
|
Disabled = "Disabled",
|
|
73
73
|
Display = "Display",
|
|
74
74
|
Style = "Style",
|
|
75
|
-
LayoutStyle = "LayoutStyle"
|
|
75
|
+
LayoutStyle = "LayoutStyle",
|
|
76
|
+
AllowedOptions = "AllowedOptions"
|
|
76
77
|
}
|
|
77
78
|
export interface EntityExpression {
|
|
78
79
|
type: string;
|
|
@@ -143,6 +144,7 @@ export interface DataControlDefinition extends ControlDefinition {
|
|
|
143
144
|
readonly?: boolean | null;
|
|
144
145
|
validators?: SchemaValidator[] | null;
|
|
145
146
|
hideTitle?: boolean | null;
|
|
147
|
+
dontClearHidden?: boolean | null;
|
|
146
148
|
}
|
|
147
149
|
export interface RenderOptions {
|
|
148
150
|
type: string;
|
package/lib/util.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function fieldDisplayName(field: SchemaField): string;
|
|
|
25
25
|
export declare function hasOptions(o: {
|
|
26
26
|
options: FieldOption[] | undefined | null;
|
|
27
27
|
}): boolean;
|
|
28
|
-
export declare function defaultControlForField(sf: SchemaField): DataControlDefinition
|
|
28
|
+
export declare function defaultControlForField(sf: SchemaField): DataControlDefinition;
|
|
29
29
|
export declare function addMissingControls(fields: SchemaField[], controls: ControlDefinition[]): ControlDefinition[];
|
|
30
30
|
export declare function useUpdatedRef<A>(a: A): MutableRefObject<A>;
|
|
31
31
|
export declare function isControlReadonly(c: ControlDefinition): boolean;
|
|
@@ -36,3 +36,4 @@ export declare function visitControlData<A>(definition: ControlDefinition, ctx:
|
|
|
36
36
|
export declare function cleanDataForSchema(v: {
|
|
37
37
|
[k: string]: any;
|
|
38
38
|
} | undefined, fields: SchemaField[]): any;
|
|
39
|
+
export declare function getAllReferencedClasses(c: ControlDefinition): string[];
|
package/package.json
CHANGED
package/src/controlRender.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, {
|
|
2
|
+
CSSProperties,
|
|
2
3
|
FC,
|
|
3
4
|
Fragment,
|
|
4
5
|
Key,
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
import { dataControl } from "./controlBuilder";
|
|
44
45
|
import {
|
|
45
46
|
defaultUseEvalExpressionHook,
|
|
47
|
+
useEvalAllowedOptionsHook,
|
|
46
48
|
useEvalDefaultValueHook,
|
|
47
49
|
useEvalDisabledHook,
|
|
48
50
|
useEvalDisplayHook,
|
|
@@ -58,7 +60,6 @@ import { defaultSchemaInterface } from "./schemaInterface";
|
|
|
58
60
|
export interface FormRenderer {
|
|
59
61
|
renderData: (
|
|
60
62
|
props: DataRendererProps,
|
|
61
|
-
asArray: (() => ReactNode) | undefined,
|
|
62
63
|
) => (layout: ControlLayoutProps) => ControlLayoutProps;
|
|
63
64
|
renderGroup: (
|
|
64
65
|
props: GroupRendererProps,
|
|
@@ -92,10 +93,10 @@ export interface AdornmentRenderer {
|
|
|
92
93
|
export interface ArrayRendererProps {
|
|
93
94
|
addAction?: ActionRendererProps;
|
|
94
95
|
required: boolean;
|
|
95
|
-
removeAction?: (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
removeAction?: (elemIndex: number) => ActionRendererProps;
|
|
97
|
+
elementCount: number;
|
|
98
|
+
renderElement: (elemIndex: number) => ReactNode;
|
|
99
|
+
elementKey: (elemIndex: number) => Key;
|
|
99
100
|
arrayControl?: Control<any[] | undefined | null>;
|
|
100
101
|
className?: string;
|
|
101
102
|
style?: React.CSSProperties;
|
|
@@ -176,6 +177,9 @@ export interface DataRendererProps {
|
|
|
176
177
|
className?: string;
|
|
177
178
|
style?: React.CSSProperties;
|
|
178
179
|
dataContext: ControlDataContext;
|
|
180
|
+
childCount: number;
|
|
181
|
+
renderChild: ChildRenderer;
|
|
182
|
+
toArrayProps?: () => ArrayRendererProps;
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
export interface ActionRendererProps {
|
|
@@ -203,6 +207,10 @@ export interface DataControlProps {
|
|
|
203
207
|
control: Control<any>;
|
|
204
208
|
options: FormContextOptions;
|
|
205
209
|
style: React.CSSProperties | undefined;
|
|
210
|
+
childCount: number;
|
|
211
|
+
renderChild: ChildRenderer;
|
|
212
|
+
allowedOptions?: Control<any[] | undefined>;
|
|
213
|
+
elementRenderer?: (elemProps: Control<any>) => ReactNode;
|
|
206
214
|
}
|
|
207
215
|
export type CreateDataProps = (
|
|
208
216
|
controlProps: DataControlProps,
|
|
@@ -233,6 +241,7 @@ export function useControlRenderer(
|
|
|
233
241
|
const useIsVisible = useEvalVisibilityHook(useExpr, definition, schemaField);
|
|
234
242
|
const useIsReadonly = useEvalReadonlyHook(useExpr, definition);
|
|
235
243
|
const useIsDisabled = useEvalDisabledHook(useExpr, definition);
|
|
244
|
+
const useAllowedOptions = useEvalAllowedOptionsHook(useExpr, definition);
|
|
236
245
|
const useCustomStyle = useEvalStyleHook(
|
|
237
246
|
useExpr,
|
|
238
247
|
DynamicPropertyType.Style,
|
|
@@ -283,6 +292,7 @@ export function useControlRenderer(
|
|
|
283
292
|
},
|
|
284
293
|
);
|
|
285
294
|
|
|
295
|
+
const allowedOptions = useAllowedOptions(dataContext);
|
|
286
296
|
const defaultValueControl = useDefaultValue(dataContext);
|
|
287
297
|
const [control, childContext] = getControlData(
|
|
288
298
|
schemaField,
|
|
@@ -294,14 +304,15 @@ export function useControlRenderer(
|
|
|
294
304
|
defaultValueControl.value,
|
|
295
305
|
control,
|
|
296
306
|
parentControl.isNull,
|
|
307
|
+
isDataControlDefinition(definition) && definition.dontClearHidden,
|
|
297
308
|
],
|
|
298
|
-
([vc, dv, cd, pn]) => {
|
|
309
|
+
([vc, dv, cd, pn, dontClear]) => {
|
|
299
310
|
if (pn) {
|
|
300
311
|
parentControl.value = {};
|
|
301
312
|
}
|
|
302
313
|
if (vc && cd && vc.visible === vc.showing) {
|
|
303
314
|
if (!vc.visible) {
|
|
304
|
-
if (options.clearHidden) cd.value = undefined;
|
|
315
|
+
if (options.clearHidden && !dontClear) cd.value = undefined;
|
|
305
316
|
} else if (cd.value == null) {
|
|
306
317
|
cd.value = dv;
|
|
307
318
|
}
|
|
@@ -346,6 +357,7 @@ export function useControlRenderer(
|
|
|
346
357
|
schemaField,
|
|
347
358
|
displayControl,
|
|
348
359
|
style: customStyle,
|
|
360
|
+
allowedOptions,
|
|
349
361
|
});
|
|
350
362
|
const renderedControl = renderer.renderLayout({
|
|
351
363
|
...labelAndChildren,
|
|
@@ -367,6 +379,7 @@ export function useControlRenderer(
|
|
|
367
379
|
useIsDisabled,
|
|
368
380
|
useCustomStyle,
|
|
369
381
|
useLayoutStyle,
|
|
382
|
+
useAllowedOptions,
|
|
370
383
|
useDynamicDisplay,
|
|
371
384
|
useValidation,
|
|
372
385
|
renderer,
|
|
@@ -406,37 +419,6 @@ export function getControlData(
|
|
|
406
419
|
];
|
|
407
420
|
}
|
|
408
421
|
|
|
409
|
-
function renderArray(
|
|
410
|
-
renderer: FormRenderer,
|
|
411
|
-
noun: string,
|
|
412
|
-
field: SchemaField,
|
|
413
|
-
required: boolean,
|
|
414
|
-
arrayControl: Control<any[] | undefined | null>,
|
|
415
|
-
renderChild: (elemIndex: number, control: Control<any>) => ReactNode,
|
|
416
|
-
className: string | null | undefined,
|
|
417
|
-
style: React.CSSProperties | undefined,
|
|
418
|
-
) {
|
|
419
|
-
const elems = arrayControl.elements ?? [];
|
|
420
|
-
return renderer.renderArray({
|
|
421
|
-
arrayControl,
|
|
422
|
-
childCount: elems.length,
|
|
423
|
-
required,
|
|
424
|
-
addAction: {
|
|
425
|
-
actionId: "add",
|
|
426
|
-
actionText: "Add " + noun,
|
|
427
|
-
onClick: () => addElement(arrayControl, elementValueForField(field)),
|
|
428
|
-
},
|
|
429
|
-
childKey: (i) => elems[i].uniqueId,
|
|
430
|
-
removeAction: (i: number) => ({
|
|
431
|
-
actionId: "",
|
|
432
|
-
actionText: "Remove",
|
|
433
|
-
onClick: () => removeElement(arrayControl, i),
|
|
434
|
-
}),
|
|
435
|
-
renderChild: (i) => renderChild(i, elems[i]),
|
|
436
|
-
className: cc(className),
|
|
437
|
-
style,
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
422
|
function groupProps(
|
|
441
423
|
renderOptions: GroupRenderOptions = { type: "Standard" },
|
|
442
424
|
childCount: number,
|
|
@@ -457,23 +439,75 @@ function groupProps(
|
|
|
457
439
|
export function defaultDataProps({
|
|
458
440
|
definition,
|
|
459
441
|
field,
|
|
460
|
-
dataContext,
|
|
461
442
|
control,
|
|
462
443
|
options,
|
|
444
|
+
elementRenderer,
|
|
463
445
|
style,
|
|
446
|
+
allowedOptions,
|
|
447
|
+
...props
|
|
464
448
|
}: DataControlProps): DataRendererProps {
|
|
449
|
+
const className = cc(definition.styleClass);
|
|
450
|
+
const required = !!definition.required;
|
|
451
|
+
const fieldOptions =
|
|
452
|
+
(field.options?.length ?? 0) === 0 ? null : field.options;
|
|
453
|
+
const allowed = allowedOptions?.value ?? [];
|
|
465
454
|
return {
|
|
466
455
|
control,
|
|
467
456
|
field,
|
|
468
457
|
id: "c" + control.uniqueId,
|
|
469
|
-
options:
|
|
458
|
+
options:
|
|
459
|
+
fieldOptions && allowed.length > 0
|
|
460
|
+
? fieldOptions.filter((x) => allowed.includes(x.value))
|
|
461
|
+
: fieldOptions,
|
|
470
462
|
readonly: !!options.readonly,
|
|
471
463
|
renderOptions: definition.renderOptions ?? { type: "Standard" },
|
|
472
|
-
required
|
|
464
|
+
required,
|
|
473
465
|
hidden: !!options.hidden,
|
|
474
|
-
className
|
|
466
|
+
className,
|
|
467
|
+
style,
|
|
468
|
+
...props,
|
|
469
|
+
toArrayProps: elementRenderer
|
|
470
|
+
? () =>
|
|
471
|
+
defaultArrayProps(
|
|
472
|
+
control,
|
|
473
|
+
field,
|
|
474
|
+
required,
|
|
475
|
+
style,
|
|
476
|
+
className,
|
|
477
|
+
elementRenderer,
|
|
478
|
+
)
|
|
479
|
+
: undefined,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export function defaultArrayProps(
|
|
484
|
+
arrayControl: Control<any[] | undefined | null>,
|
|
485
|
+
field: SchemaField,
|
|
486
|
+
required: boolean,
|
|
487
|
+
style: CSSProperties | undefined,
|
|
488
|
+
className: string | undefined,
|
|
489
|
+
renderElement: (elemProps: Control<any>) => ReactNode,
|
|
490
|
+
): ArrayRendererProps {
|
|
491
|
+
const noun = field.displayName ?? field.field;
|
|
492
|
+
const elems = arrayControl.elements ?? [];
|
|
493
|
+
return {
|
|
494
|
+
arrayControl,
|
|
495
|
+
elementCount: elems.length,
|
|
496
|
+
required,
|
|
497
|
+
addAction: {
|
|
498
|
+
actionId: "add",
|
|
499
|
+
actionText: "Add " + noun,
|
|
500
|
+
onClick: () => addElement(arrayControl, elementValueForField(field)),
|
|
501
|
+
},
|
|
502
|
+
elementKey: (i) => elems[i].uniqueId,
|
|
503
|
+
removeAction: (i: number) => ({
|
|
504
|
+
actionId: "",
|
|
505
|
+
actionText: "Remove",
|
|
506
|
+
onClick: () => removeElement(arrayControl, i),
|
|
507
|
+
}),
|
|
508
|
+
renderElement: (i) => renderElement(elems[i]),
|
|
509
|
+
className: cc(className),
|
|
475
510
|
style,
|
|
476
|
-
dataContext,
|
|
477
511
|
};
|
|
478
512
|
}
|
|
479
513
|
|
|
@@ -495,6 +529,7 @@ export interface RenderControlProps {
|
|
|
495
529
|
schemaField?: SchemaField;
|
|
496
530
|
displayControl?: Control<string | undefined>;
|
|
497
531
|
style?: React.CSSProperties;
|
|
532
|
+
allowedOptions?: Control<any[] | undefined>;
|
|
498
533
|
}
|
|
499
534
|
export function renderControlLayout({
|
|
500
535
|
definition: c,
|
|
@@ -508,6 +543,7 @@ export function renderControlLayout({
|
|
|
508
543
|
createDataProps: dataProps,
|
|
509
544
|
displayControl,
|
|
510
545
|
style,
|
|
546
|
+
allowedOptions,
|
|
511
547
|
}: RenderControlProps): ControlLayoutProps {
|
|
512
548
|
if (isDataControlDefinition(c)) {
|
|
513
549
|
return renderData(c);
|
|
@@ -562,74 +598,30 @@ export function renderControlLayout({
|
|
|
562
598
|
}
|
|
563
599
|
return {};
|
|
564
600
|
|
|
565
|
-
function renderData(c: DataControlDefinition) {
|
|
601
|
+
function renderData(c: DataControlDefinition, elementControl?: Control<any>) {
|
|
566
602
|
if (!schemaField) return { children: "No schema field for: " + c.field };
|
|
567
|
-
if (isCompoundField(schemaField)) {
|
|
568
|
-
const label: LabelRendererProps = {
|
|
569
|
-
hide: c.hideTitle,
|
|
570
|
-
label: controlTitle(c.title, schemaField),
|
|
571
|
-
type: schemaField.collection ? LabelType.Control : LabelType.Group,
|
|
572
|
-
};
|
|
573
|
-
|
|
574
|
-
if (schemaField.collection) {
|
|
575
|
-
return {
|
|
576
|
-
label,
|
|
577
|
-
children: renderArray(
|
|
578
|
-
renderer,
|
|
579
|
-
controlTitle(c.title, schemaField),
|
|
580
|
-
schemaField,
|
|
581
|
-
!!c.required,
|
|
582
|
-
childControl!,
|
|
583
|
-
compoundRenderer,
|
|
584
|
-
c.styleClass,
|
|
585
|
-
style,
|
|
586
|
-
),
|
|
587
|
-
errorControl: childControl,
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
return {
|
|
591
|
-
processLayout: renderer.renderGroup(
|
|
592
|
-
groupProps(
|
|
593
|
-
{ type: "Standard" },
|
|
594
|
-
childCount,
|
|
595
|
-
childRenderer,
|
|
596
|
-
childControl!,
|
|
597
|
-
c.styleClass,
|
|
598
|
-
style,
|
|
599
|
-
),
|
|
600
|
-
),
|
|
601
|
-
label,
|
|
602
|
-
errorControl: childControl,
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
603
|
const props = dataProps({
|
|
606
604
|
definition: c,
|
|
607
605
|
field: schemaField,
|
|
608
606
|
dataContext,
|
|
609
|
-
control: childControl!,
|
|
607
|
+
control: elementControl ?? childControl!,
|
|
610
608
|
options: dataOptions,
|
|
611
609
|
style,
|
|
610
|
+
childCount,
|
|
611
|
+
allowedOptions,
|
|
612
|
+
renderChild: childRenderer,
|
|
613
|
+
elementRenderer:
|
|
614
|
+
elementControl == null && schemaField.collection
|
|
615
|
+
? (element) =>
|
|
616
|
+
renderLayoutParts(renderData(c, element), renderer).children
|
|
617
|
+
: undefined,
|
|
612
618
|
});
|
|
619
|
+
|
|
613
620
|
const labelText = !c.hideTitle
|
|
614
621
|
? controlTitle(c.title, schemaField)
|
|
615
622
|
: undefined;
|
|
616
623
|
return {
|
|
617
|
-
processLayout: renderer.renderData(
|
|
618
|
-
props,
|
|
619
|
-
schemaField.collection
|
|
620
|
-
? () =>
|
|
621
|
-
renderArray(
|
|
622
|
-
renderer,
|
|
623
|
-
controlTitle(c.title, schemaField),
|
|
624
|
-
schemaField,
|
|
625
|
-
!!c.required,
|
|
626
|
-
childControl!,
|
|
627
|
-
scalarRenderer(props),
|
|
628
|
-
c.styleClass,
|
|
629
|
-
style,
|
|
630
|
-
)
|
|
631
|
-
: undefined,
|
|
632
|
-
),
|
|
624
|
+
processLayout: renderer.renderData(props),
|
|
633
625
|
label: {
|
|
634
626
|
type: LabelType.Control,
|
|
635
627
|
label: labelText,
|
|
@@ -661,10 +653,7 @@ export function renderControlLayout({
|
|
|
661
653
|
return (i, control) => {
|
|
662
654
|
return (
|
|
663
655
|
<Fragment key={control.uniqueId}>
|
|
664
|
-
{
|
|
665
|
-
renderer.renderData({ ...dataProps, control }, undefined)({})
|
|
666
|
-
.children
|
|
667
|
-
}
|
|
656
|
+
{renderer.renderData({ ...dataProps, control })({}).children}
|
|
668
657
|
</Fragment>
|
|
669
658
|
);
|
|
670
659
|
};
|
package/src/hooks.tsx
CHANGED
|
@@ -105,6 +105,24 @@ export function useEvalStyleHook(
|
|
|
105
105
|
);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
export function useEvalAllowedOptionsHook(
|
|
109
|
+
useEvalExpressionHook: UseEvalExpressionHook,
|
|
110
|
+
definition: ControlDefinition,
|
|
111
|
+
): EvalExpressionHook<any[]> {
|
|
112
|
+
const dynamicAllowed = useEvalDynamicHook(
|
|
113
|
+
definition,
|
|
114
|
+
DynamicPropertyType.AllowedOptions,
|
|
115
|
+
useEvalExpressionHook,
|
|
116
|
+
);
|
|
117
|
+
return useCallback(
|
|
118
|
+
(ctx) => {
|
|
119
|
+
if (dynamicAllowed) return dynamicAllowed(ctx);
|
|
120
|
+
return useControl([]);
|
|
121
|
+
},
|
|
122
|
+
[dynamicAllowed],
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
108
126
|
export function useEvalDisabledHook(
|
|
109
127
|
useEvalExpressionHook: UseEvalExpressionHook,
|
|
110
128
|
definition: ControlDefinition,
|
package/src/renderers.tsx
CHANGED
|
@@ -78,7 +78,6 @@ export interface DataRendererRegistration {
|
|
|
78
78
|
match?: (props: DataRendererProps) => boolean;
|
|
79
79
|
render: (
|
|
80
80
|
props: DataRendererProps,
|
|
81
|
-
asArray: (() => ReactNode) | undefined,
|
|
82
81
|
renderers: FormRenderer,
|
|
83
82
|
) => ReactNode | ((layout: ControlLayoutProps) => ControlLayoutProps);
|
|
84
83
|
}
|
|
@@ -210,7 +209,6 @@ export function createFormRenderer(
|
|
|
210
209
|
|
|
211
210
|
function renderData(
|
|
212
211
|
props: DataRendererProps,
|
|
213
|
-
asArray: (() => ReactNode) | undefined,
|
|
214
212
|
): (layout: ControlLayoutProps) => ControlLayoutProps {
|
|
215
213
|
const {
|
|
216
214
|
renderOptions: { type: renderType },
|
|
@@ -228,7 +226,7 @@ export function createFormRenderer(
|
|
|
228
226
|
(!x.match || x.match(props)),
|
|
229
227
|
) ?? defaultRenderers.data;
|
|
230
228
|
|
|
231
|
-
const result = renderer.render(props,
|
|
229
|
+
const result = renderer.render(props, formRenderers);
|
|
232
230
|
if (typeof result === "function") return result;
|
|
233
231
|
return (l) => ({ ...l, children: result });
|
|
234
232
|
}
|
|
@@ -332,32 +330,32 @@ export function createDefaultArrayRenderer(
|
|
|
332
330
|
} = options ?? {};
|
|
333
331
|
function render(
|
|
334
332
|
{
|
|
335
|
-
|
|
336
|
-
|
|
333
|
+
elementCount,
|
|
334
|
+
renderElement,
|
|
337
335
|
addAction,
|
|
338
336
|
removeAction,
|
|
339
|
-
|
|
337
|
+
elementKey,
|
|
340
338
|
required,
|
|
341
339
|
}: ArrayRendererProps,
|
|
342
340
|
{ renderAction }: FormRenderer,
|
|
343
341
|
) {
|
|
344
|
-
const showRemove = !required ||
|
|
342
|
+
const showRemove = !required || elementCount > 1;
|
|
345
343
|
return (
|
|
346
344
|
<div>
|
|
347
345
|
<div className={clsx(className, removeAction && removableClass)}>
|
|
348
|
-
{Array.from({ length:
|
|
346
|
+
{Array.from({ length: elementCount }, (_, x) =>
|
|
349
347
|
removeAction ? (
|
|
350
|
-
<Fragment key={
|
|
348
|
+
<Fragment key={elementKey(x)}>
|
|
351
349
|
<div className={clsx(childClass, removableChildClass)}>
|
|
352
|
-
{
|
|
350
|
+
{renderElement(x)}
|
|
353
351
|
</div>
|
|
354
352
|
<div className={removeActionClass}>
|
|
355
353
|
{showRemove && renderAction(removeAction(x))}
|
|
356
354
|
</div>
|
|
357
355
|
</Fragment>
|
|
358
356
|
) : (
|
|
359
|
-
<div key={
|
|
360
|
-
{
|
|
357
|
+
<div key={elementKey(x)} className={childClass}>
|
|
358
|
+
{renderElement(x)}
|
|
361
359
|
</div>
|
|
362
360
|
),
|
|
363
361
|
)}
|
|
@@ -430,8 +428,8 @@ export function createDefaultGroupRenderer(
|
|
|
430
428
|
const { style, className: gcn } = isGridRenderer(renderOptions)
|
|
431
429
|
? gridStyles(renderOptions)
|
|
432
430
|
: isFlexRenderer(renderOptions)
|
|
433
|
-
|
|
434
|
-
|
|
431
|
+
? flexStyles(renderOptions)
|
|
432
|
+
: ({ className: standardClassName } as StyleProps);
|
|
435
433
|
|
|
436
434
|
return (cp: ControlLayoutProps) => {
|
|
437
435
|
return {
|
|
@@ -520,13 +518,25 @@ export function createDefaultDataRenderer(
|
|
|
520
518
|
booleanOptions: DefaultBoolOptions,
|
|
521
519
|
...options,
|
|
522
520
|
};
|
|
523
|
-
return createDataRenderer((props,
|
|
524
|
-
|
|
525
|
-
|
|
521
|
+
return createDataRenderer((props, renderers) => {
|
|
522
|
+
const fieldType = props.field.type;
|
|
523
|
+
if (props.toArrayProps) {
|
|
524
|
+
return (p) => ({
|
|
525
|
+
...p,
|
|
526
|
+
children: renderers.renderArray(props.toArrayProps!()),
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
if (fieldType === FieldType.Compound) {
|
|
530
|
+
return renderers.renderGroup({
|
|
531
|
+
style: props.style,
|
|
532
|
+
className: props.className,
|
|
533
|
+
renderOptions: { type: "Standard", hideTitle: true },
|
|
534
|
+
renderChild: (i) => props.renderChild(i, i, { control: props.control }),
|
|
535
|
+
childCount: props.childCount,
|
|
536
|
+
});
|
|
526
537
|
}
|
|
527
538
|
const renderOptions = props.renderOptions;
|
|
528
539
|
let renderType = renderOptions.type;
|
|
529
|
-
const fieldType = props.field.type;
|
|
530
540
|
if (fieldType == FieldType.Any) return <>No control for Any</>;
|
|
531
541
|
if (isDisplayOnlyRenderer(renderOptions))
|
|
532
542
|
return (p) => ({
|
|
@@ -545,17 +555,14 @@ export function createDefaultDataRenderer(
|
|
|
545
555
|
});
|
|
546
556
|
const isBool = fieldType === FieldType.Bool;
|
|
547
557
|
if (booleanOptions != null && isBool && props.options == null) {
|
|
548
|
-
return renderers.renderData(
|
|
549
|
-
{ ...props, options: booleanOptions },
|
|
550
|
-
undefined,
|
|
551
|
-
);
|
|
558
|
+
return renderers.renderData({ ...props, options: booleanOptions });
|
|
552
559
|
}
|
|
553
560
|
if (renderType === DataRenderType.Standard && hasOptions(props)) {
|
|
554
|
-
return optionRenderer.render(props,
|
|
561
|
+
return optionRenderer.render(props, renderers);
|
|
555
562
|
}
|
|
556
563
|
switch (renderType) {
|
|
557
564
|
case DataRenderType.Dropdown:
|
|
558
|
-
return selectRenderer.render(props,
|
|
565
|
+
return selectRenderer.render(props, renderers);
|
|
559
566
|
}
|
|
560
567
|
return renderType === DataRenderType.Checkbox ? (
|
|
561
568
|
<Fcheckbox
|
package/src/types.ts
CHANGED
|
@@ -90,6 +90,7 @@ export enum DynamicPropertyType {
|
|
|
90
90
|
Display = "Display",
|
|
91
91
|
Style = "Style",
|
|
92
92
|
LayoutStyle = "LayoutStyle",
|
|
93
|
+
AllowedOptions = "AllowedOptions"
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
export interface EntityExpression {
|
|
@@ -174,6 +175,7 @@ export interface DataControlDefinition extends ControlDefinition {
|
|
|
174
175
|
readonly?: boolean | null;
|
|
175
176
|
validators?: SchemaValidator[] | null;
|
|
176
177
|
hideTitle?: boolean | null;
|
|
178
|
+
dontClearHidden?: boolean | null;
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
export interface RenderOptions {
|
package/src/util.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "./types";
|
|
19
19
|
import { MutableRefObject, useRef } from "react";
|
|
20
20
|
import { Control } from "@react-typed-forms/core";
|
|
21
|
+
import clsx from "clsx";
|
|
21
22
|
|
|
22
23
|
export interface ControlDataContext {
|
|
23
24
|
groupControl: Control<any>;
|
|
@@ -146,20 +147,15 @@ export function hasOptions(o: { options: FieldOption[] | undefined | null }) {
|
|
|
146
147
|
return (o.options?.length ?? 0) > 0;
|
|
147
148
|
}
|
|
148
149
|
|
|
149
|
-
export function defaultControlForField(
|
|
150
|
-
sf: SchemaField,
|
|
151
|
-
): DataControlDefinition | GroupedControlsDefinition {
|
|
150
|
+
export function defaultControlForField(sf: SchemaField): DataControlDefinition {
|
|
152
151
|
if (isCompoundField(sf)) {
|
|
153
152
|
return {
|
|
154
|
-
type: ControlDefinitionType.
|
|
153
|
+
type: ControlDefinitionType.Data,
|
|
155
154
|
title: sf.displayName,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
type: GroupRenderType.Grid,
|
|
159
|
-
hideTitle: false,
|
|
160
|
-
} as GridRenderer,
|
|
155
|
+
field: sf.field,
|
|
156
|
+
required: sf.required,
|
|
161
157
|
children: sf.children.map(defaultControlForField),
|
|
162
|
-
}
|
|
158
|
+
};
|
|
163
159
|
} else if (isScalarField(sf)) {
|
|
164
160
|
const htmlEditor = sf.tags?.includes("_HtmlEditor");
|
|
165
161
|
return {
|
|
@@ -170,7 +166,7 @@ export function defaultControlForField(
|
|
|
170
166
|
renderOptions: {
|
|
171
167
|
type: htmlEditor ? DataRenderType.HtmlEditor : DataRenderType.Standard,
|
|
172
168
|
},
|
|
173
|
-
}
|
|
169
|
+
};
|
|
174
170
|
}
|
|
175
171
|
throw "Unknown schema field";
|
|
176
172
|
}
|
|
@@ -378,3 +374,12 @@ export function cleanDataForSchema(
|
|
|
378
374
|
});
|
|
379
375
|
return out;
|
|
380
376
|
}
|
|
377
|
+
|
|
378
|
+
export function getAllReferencedClasses(c: ControlDefinition): string[] {
|
|
379
|
+
const childClasses = c.children?.flatMap(getAllReferencedClasses);
|
|
380
|
+
const tc = clsx(c.styleClass, c.layoutClass);
|
|
381
|
+
if (childClasses && !tc) return childClasses;
|
|
382
|
+
if (!tc) return [];
|
|
383
|
+
if (childClasses) return [tc, ...childClasses];
|
|
384
|
+
return [tc];
|
|
385
|
+
}
|