@react-typed-forms/schemas 15.1.3 → 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.
Files changed (46) hide show
  1. package/lib/RenderForm.d.ts +39 -0
  2. package/lib/controlBuilder.d.ts +3 -7
  3. package/lib/controlRender.d.ts +35 -64
  4. package/lib/index.cjs +438 -2189
  5. package/lib/index.cjs.map +1 -1
  6. package/lib/index.d.ts +3 -13
  7. package/lib/index.js +303 -1681
  8. package/lib/index.js.map +1 -1
  9. package/lib/renderers.d.ts +3 -2
  10. package/lib/types.d.ts +31 -0
  11. package/lib/util.d.ts +4 -48
  12. package/package.json +5 -4
  13. package/src/RenderForm.tsx +301 -0
  14. package/src/controlBuilder.ts +16 -19
  15. package/src/controlRender.tsx +109 -449
  16. package/src/createFormRenderer.tsx +3 -3
  17. package/src/index.ts +3 -13
  18. package/src/renderers.tsx +2 -2
  19. package/src/types.ts +52 -0
  20. package/src/util.ts +52 -113
  21. package/lib/controlDefinition.d.ts +0 -392
  22. package/lib/defaultSchemaInterface.d.ts +0 -28
  23. package/lib/dynamicHooks.d.ts +0 -54
  24. package/lib/entityExpression.d.ts +0 -32
  25. package/lib/formNode.d.ts +0 -46
  26. package/lib/hooks.d.ts +0 -29
  27. package/lib/schemaBuilder.d.ts +0 -67
  28. package/lib/schemaDataNode.d.ts +0 -31
  29. package/lib/schemaField.d.ts +0 -120
  30. package/lib/schemaInterface.d.ts +0 -102
  31. package/lib/schemaNode.d.ts +0 -54
  32. package/lib/schemaValidator.d.ts +0 -27
  33. package/lib/validators.d.ts +0 -19
  34. package/src/controlDefinition.ts +0 -621
  35. package/src/defaultSchemaInterface.ts +0 -201
  36. package/src/dynamicHooks.ts +0 -98
  37. package/src/entityExpression.ts +0 -38
  38. package/src/formNode.ts +0 -253
  39. package/src/hooks.tsx +0 -469
  40. package/src/schemaBuilder.ts +0 -318
  41. package/src/schemaDataNode.ts +0 -129
  42. package/src/schemaField.ts +0 -153
  43. package/src/schemaInterface.ts +0 -135
  44. package/src/schemaNode.ts +0 -279
  45. package/src/schemaValidator.ts +0 -32
  46. package/src/validators.ts +0 -217
@@ -1,52 +1,50 @@
1
1
  import React, {
2
2
  ComponentType,
3
3
  ElementType,
4
- FC,
5
4
  Fragment,
6
5
  HTMLAttributes,
7
6
  Key,
8
7
  ReactElement,
9
8
  ReactNode,
10
- useCallback,
11
- useEffect,
12
9
  } from "react";
13
10
  import {
14
11
  addElement,
15
12
  Control,
16
- newControl,
17
13
  removeElement,
18
14
  RenderArrayElements,
19
- trackedValue,
20
- useComponentTracking,
21
- useComputed,
22
- useControl,
23
- useControlEffect,
24
15
  } from "@react-typed-forms/core";
25
16
  import {
26
17
  ActionStyle,
27
18
  AdornmentPlacement,
28
19
  ArrayActionOptions,
29
- ControlActionHandler,
30
20
  ControlAdornment,
31
- ControlAdornmentType,
32
- ControlDataContext,
33
21
  ControlDefinition,
22
+ ControlDefinitionType,
23
+ ControlState,
34
24
  CustomDisplay,
35
25
  DataControlDefinition,
36
- DataRenderType,
26
+ defaultSchemaInterface,
37
27
  DisplayData,
38
28
  DisplayDataType,
39
- DynamicPropertyType,
40
- FormContextData,
29
+ FieldOption,
30
+ FormContextOptions,
31
+ FormNode,
32
+ FormState,
41
33
  GroupRenderOptions,
42
- IconPlacement,
43
- IconReference,
34
+ GroupRenderType,
44
35
  isActionControl,
45
36
  isDataControl,
46
37
  isDisplayControl,
47
38
  isGroupControl,
39
+ JsonPath,
40
+ LengthValidator,
41
+ lookupDataNode,
48
42
  RenderOptions,
49
- } from "./controlDefinition";
43
+ SchemaDataNode,
44
+ SchemaField,
45
+ SchemaInterface,
46
+ ValidatorType,
47
+ } from "@astroapps/forms-core";
50
48
  import {
51
49
  applyLengthRestrictions,
52
50
  ControlClasses,
@@ -54,40 +52,15 @@ import {
54
52
  ExternalEditAction,
55
53
  fieldDisplayName,
56
54
  getExternalEditData,
57
- getGroupClassOverrides,
58
- isControlDisplayOnly,
59
- JsonPath,
60
55
  rendererClass,
61
- useUpdatedRef,
62
56
  } from "./util";
63
57
  import { createAction, dataControl } from "./controlBuilder";
64
58
  import {
65
- defaultUseEvalExpressionHook,
66
- EvalExpressionHook,
67
- useEvalActionHook,
68
- useEvalAllowedOptionsHook,
69
- useEvalDefaultValueHook,
70
- useEvalDisabledHook,
71
- useEvalDisplayHook,
72
- UseEvalExpressionHook,
73
- useEvalLabelText,
74
- useEvalReadonlyHook,
75
- useEvalStyleHook,
76
- useEvalVisibilityHook,
77
- } from "./hooks";
78
- import { useMakeValidationHook, ValidationContext } from "./validators";
79
- import { useDynamicHooks } from "./dynamicHooks";
80
- import { defaultSchemaInterface } from "./defaultSchemaInterface";
81
- import {
82
- LengthValidator,
83
- SchemaValidator,
84
- ValidatorType,
85
- } from "./schemaValidator";
86
- import { FieldOption, SchemaField } from "./schemaField";
87
- import { FormNode, legacyFormNode, lookupDataNode } from "./formNode";
88
- import { SchemaInterface } from "./schemaInterface";
89
- import { makeSchemaDataNode, SchemaDataNode } from "./schemaDataNode";
90
- import { createSchemaTree } from "./schemaNode";
59
+ ActionRendererProps,
60
+ ControlActionHandler,
61
+ ControlDataContext,
62
+ RunExpression,
63
+ } from "./types";
91
64
 
92
65
  export interface HtmlIconProperties {
93
66
  className?: string;
@@ -141,6 +114,10 @@ export interface HtmlButtonProperties {
141
114
  onClick?: () => void;
142
115
  inline?: boolean;
143
116
  children?: ReactNode;
117
+ title?: string;
118
+ notWrapInText?: boolean;
119
+ androidRippleColor?: string;
120
+ nonTextContent?: boolean;
144
121
  }
145
122
  export interface HtmlComponents {
146
123
  Div: ComponentType<HtmlDivProperties>;
@@ -242,7 +219,7 @@ export interface FormRenderer {
242
219
  export interface AdornmentProps {
243
220
  adornment: ControlAdornment;
244
221
  dataContext: ControlDataContext;
245
- useExpr?: UseEvalExpressionHook;
222
+ runExpression?: RunExpression;
246
223
  designMode?: boolean;
247
224
  formOptions: FormContextOptions;
248
225
  }
@@ -408,21 +385,18 @@ export interface DisplayRendererProps {
408
385
  inline?: boolean;
409
386
  }
410
387
 
411
- export type ChildVisibilityFunc = (
412
- child: ControlDefinition,
413
- parentNode?: SchemaDataNode,
414
- dontOverride?: boolean,
415
- ) => EvalExpressionHook<boolean>;
416
388
  export interface ParentRendererProps {
417
389
  formNode: FormNode;
390
+ state: ControlState;
418
391
  renderChild: ChildRenderer;
419
392
  className?: string;
420
393
  textClass?: string;
421
394
  style?: React.CSSProperties;
422
395
  dataContext: ControlDataContext;
423
- useChildVisibility: ChildVisibilityFunc;
424
- useEvalExpression: UseEvalExpressionHook;
396
+ getChildState(node: FormNode, parent?: SchemaDataNode): ControlState;
397
+ runExpression: RunExpression;
425
398
  designMode?: boolean;
399
+ actionOnClick?: ControlActionHandler;
426
400
  }
427
401
 
428
402
  export interface GroupRendererProps extends ParentRendererProps {
@@ -445,383 +419,38 @@ export interface DataRendererProps extends ParentRendererProps {
445
419
  inline: boolean;
446
420
  }
447
421
 
448
- export interface ActionRendererProps {
449
- actionId: string;
450
- actionText: string;
451
- actionData?: any;
452
- actionStyle?: ActionStyle;
453
- icon?: IconReference | null;
454
- iconPlacement?: IconPlacement;
455
- onClick: () => void;
456
- className?: string | null;
457
- textClass?: string | null;
458
- style?: React.CSSProperties;
459
- disabled?: boolean;
460
- inline?: boolean;
461
- }
462
-
463
422
  export interface ControlRenderProps {
464
423
  control: Control<any>;
465
424
  parentPath?: JsonPath[];
466
425
  }
467
426
 
468
- export interface FormContextOptions {
469
- readonly?: boolean | null;
470
- hidden?: boolean | null;
471
- disabled?: boolean | null;
472
- displayOnly?: boolean;
473
- inline?: boolean;
474
- }
475
-
476
427
  export type CreateDataProps = (
477
428
  controlProps: RenderLayoutProps,
478
429
  definition: DataControlDefinition,
479
430
  control: Control<any>,
480
431
  ) => DataRendererProps;
481
432
 
482
- export interface ControlRenderOptions
483
- extends FormContextOptions,
484
- ControlClasses {
433
+ export interface ControlRenderOptions extends ControlClasses {
434
+ formState?: FormState;
485
435
  useDataHook?: (c: ControlDefinition) => CreateDataProps;
486
436
  actionOnClick?: ControlActionHandler;
487
437
  customDisplay?: (
488
438
  customId: string,
489
439
  displayProps: DisplayRendererProps,
490
440
  ) => ReactNode;
491
- useValidationHook?: (
492
- validator: SchemaValidator,
493
- ctx: ValidationContext,
494
- ) => void;
495
- useEvalExpressionHook?: UseEvalExpressionHook;
496
441
  adjustLayout?: (
497
442
  context: ControlDataContext,
498
443
  layout: ControlLayoutProps,
499
444
  ) => ControlLayoutProps;
445
+ readonly?: boolean | null;
446
+ hidden?: boolean | null;
447
+ disabled?: boolean | null;
448
+ displayOnly?: boolean;
449
+ inline?: boolean;
500
450
  clearHidden?: boolean;
451
+ stateKey?: string;
501
452
  schemaInterface?: SchemaInterface;
502
- formData?: FormContextData;
503
- }
504
-
505
- export function useControlRenderer(
506
- definition: ControlDefinition,
507
- fields: SchemaField[],
508
- renderer: FormRenderer,
509
- options: ControlRenderOptions = {},
510
- ): FC<ControlRenderProps> {
511
- const r = useUpdatedRef({ definition, fields, renderer, options });
512
- return useCallback(
513
- ({ control, parentPath }) => {
514
- return (
515
- <ControlRenderer
516
- {...r.current}
517
- control={control}
518
- parentPath={parentPath}
519
- />
520
- );
521
- },
522
- [r],
523
- );
524
- }
525
- export function useControlRendererComponent(
526
- controlOrFormNode: ControlDefinition | FormNode,
527
- renderer: FormRenderer,
528
- options: ControlRenderOptions = {},
529
- parentDataNode: SchemaDataNode,
530
- ): FC<{}> {
531
- const [definition, formNode] =
532
- "definition" in controlOrFormNode
533
- ? [controlOrFormNode.definition, controlOrFormNode]
534
- : [controlOrFormNode, legacyFormNode(controlOrFormNode)];
535
- const dataProps = options.useDataHook?.(definition) ?? defaultDataProps;
536
- const schemaInterface = options.schemaInterface ?? defaultSchemaInterface;
537
- const useExpr = options.useEvalExpressionHook ?? defaultUseEvalExpressionHook;
538
-
539
- let dataNode = lookupDataNode(definition, parentDataNode);
540
- const useValidation = useMakeValidationHook(
541
- definition,
542
- options.useValidationHook,
543
- );
544
- const dynamicHooks = useDynamicHooks({
545
- defaultValueControl: useEvalDefaultValueHook(useExpr, definition),
546
- visibleControl: useEvalVisibilityHook(useExpr, definition),
547
- readonlyControl: useEvalReadonlyHook(useExpr, definition),
548
- disabledControl: useEvalDisabledHook(useExpr, definition),
549
- allowedOptions: useEvalAllowedOptionsHook(useExpr, definition),
550
- labelText: useEvalLabelText(useExpr, definition),
551
- actionData: useEvalActionHook(useExpr, definition),
552
- customStyle: useEvalStyleHook(
553
- useExpr,
554
- DynamicPropertyType.Style,
555
- definition,
556
- ),
557
- layoutStyle: useEvalStyleHook(
558
- useExpr,
559
- DynamicPropertyType.LayoutStyle,
560
- definition,
561
- ),
562
- displayControl: useEvalDisplayHook(useExpr, definition),
563
- });
564
-
565
- const r = useUpdatedRef({
566
- options,
567
- definition,
568
- parentDataNode,
569
- dataNode,
570
- formNode,
571
- });
572
-
573
- if (formNode == null) debugger;
574
- const Component = useCallback(() => {
575
- const stopTracking = useComponentTracking();
576
-
577
- try {
578
- const {
579
- definition: c,
580
- options,
581
- parentDataNode: pdn,
582
- dataNode: dn,
583
- formNode,
584
- } = r.current;
585
- const formData = options.formData ?? {};
586
- const dataContext: ControlDataContext = {
587
- schemaInterface,
588
- dataNode: dn,
589
- parentNode: pdn,
590
- formData,
591
- };
592
- const {
593
- readonlyControl,
594
- disabledControl,
595
- visibleControl,
596
- displayControl,
597
- layoutStyle,
598
- labelText,
599
- customStyle,
600
- allowedOptions,
601
- defaultValueControl,
602
- actionData,
603
- } = dynamicHooks(dataContext);
604
-
605
- const visible = visibleControl.current.value;
606
- const visibility = useControl<Visibility | undefined>(() =>
607
- visible != null
608
- ? {
609
- visible,
610
- showing: visible,
611
- }
612
- : undefined,
613
- );
614
- useControlEffect(
615
- () => visibleControl.value,
616
- (visible) => {
617
- if (visible != null)
618
- visibility.setValue((ex) => ({
619
- visible,
620
- showing: ex ? ex.showing : visible,
621
- }));
622
- },
623
- );
624
-
625
- const parentControl = parentDataNode.control!;
626
- const control = dataNode?.control;
627
- useControlEffect(
628
- () => [
629
- visibility.value,
630
- defaultValueControl.value,
631
- control?.isNull,
632
- isDataControl(definition) && definition.dontClearHidden,
633
- definition.adornments?.some(
634
- (x) => x.type === ControlAdornmentType.Optional,
635
- ) ||
636
- (isDataControl(definition) &&
637
- definition.renderOptions?.type == DataRenderType.NullToggle),
638
- parentControl.isNull,
639
- options.hidden,
640
- readonlyControl.value,
641
- ],
642
- ([vc, dv, _, dontClear, dontDefault, parentNull, hidden, ro]) => {
643
- if (!ro) {
644
- if (control) {
645
- if (vc && vc.visible === vc.showing) {
646
- if (hidden || !vc.visible) {
647
- control.setValue((x) =>
648
- options.clearHidden && !dontClear
649
- ? undefined
650
- : x == null && dontClear && !dontDefault
651
- ? dv
652
- : x,
653
- );
654
- } else if (!dontDefault)
655
- control.setValue((x) => (x != null ? x : dv));
656
- }
657
- } else if (parentNull) {
658
- parentControl.setValue((x) => x ?? {});
659
- }
660
- }
661
- },
662
- true,
663
- );
664
- const myOptionsControl = useComputed<FormContextOptions>(() => ({
665
- hidden: options.hidden || !visibility.fields?.showing.value,
666
- readonly: options.readonly || readonlyControl.value,
667
- disabled: options.disabled || disabledControl.value,
668
- displayOnly: options.displayOnly || isControlDisplayOnly(c),
669
- inline: options.inline,
670
- }));
671
- const myOptions = trackedValue(myOptionsControl);
672
- useValidation({
673
- control: control ?? newControl(null),
674
- hiddenControl: myOptionsControl.fields.hidden,
675
- dataContext,
676
- });
677
- const {
678
- styleClass,
679
- labelClass,
680
- layoutClass,
681
- labelTextClass,
682
- textClass,
683
- ...inheritableOptions
684
- } = options;
685
- const childOptions: ControlRenderOptions = {
686
- ...inheritableOptions,
687
- ...myOptions,
688
- };
689
-
690
- useEffect(() => {
691
- if (
692
- control &&
693
- typeof myOptions.disabled === "boolean" &&
694
- control.disabled != myOptions.disabled
695
- )
696
- control.disabled = myOptions.disabled;
697
- }, [control, myOptions.disabled]);
698
-
699
- const adornments =
700
- definition.adornments?.map((x) =>
701
- renderer.renderAdornment({
702
- adornment: x,
703
- dataContext,
704
- useExpr,
705
- formOptions: myOptions,
706
- }),
707
- ) ?? [];
708
-
709
- const labelAndChildren = renderControlLayout({
710
- formNode,
711
- renderer,
712
- renderChild: (k, child, options) => {
713
- const overrideClasses = getGroupClassOverrides(c);
714
- const { parentDataNode, ...renderOptions } = options ?? {};
715
- const dContext =
716
- parentDataNode ?? dataContext.dataNode ?? dataContext.parentNode;
717
- const allChildOptions = {
718
- ...childOptions,
719
- ...overrideClasses,
720
- ...renderOptions,
721
- };
722
- return (
723
- <NewControlRenderer
724
- key={k}
725
- definition={child}
726
- renderer={renderer}
727
- parentDataNode={dContext}
728
- options={allChildOptions}
729
- />
730
- );
731
- },
732
- createDataProps: dataProps,
733
- formOptions: myOptions,
734
- dataContext,
735
- control: displayControl ?? control,
736
- schemaInterface,
737
- labelText,
738
- displayControl,
739
- style: customStyle.value,
740
- allowedOptions,
741
- customDisplay: options.customDisplay,
742
- actionDataControl: actionData,
743
- actionOnClick: options.actionOnClick,
744
- styleClass: options.styleClass,
745
- labelClass: options.labelClass,
746
- textClass: options.textClass,
747
- useEvalExpression: useExpr,
748
- useChildVisibility: (childDef, parentNode, dontOverride) => {
749
- return useEvalVisibilityHook(
750
- useExpr,
751
- childDef,
752
- !dontOverride
753
- ? lookupDataNode(
754
- childDef,
755
- parentNode ?? dataNode ?? parentDataNode,
756
- )
757
- : undefined,
758
- );
759
- },
760
- });
761
- const layoutProps: ControlLayoutProps = {
762
- ...labelAndChildren,
763
- adornments,
764
- className: rendererClass(options.layoutClass, c.layoutClass),
765
- style: layoutStyle.value,
766
- };
767
- const renderedControl = renderer.renderLayout(
768
- options.adjustLayout?.(dataContext, layoutProps) ?? layoutProps,
769
- );
770
- return renderer.renderVisibility({ visibility, ...renderedControl });
771
- } finally {
772
- stopTracking();
773
- }
774
- }, [r, dataProps, useValidation, renderer, schemaInterface, dynamicHooks]);
775
- (Component as any).displayName = "RenderControl";
776
- return Component;
777
- }
778
-
779
- export function ControlRenderer({
780
- definition,
781
- fields,
782
- renderer,
783
- options,
784
- control,
785
- parentPath,
786
- }: {
787
- definition: ControlDefinition;
788
- fields: SchemaField[];
789
- renderer: FormRenderer;
790
- options?: ControlRenderOptions;
791
- control: Control<any>;
792
- parentPath?: JsonPath[];
793
- }) {
794
- const schemaDataNode = makeSchemaDataNode(
795
- createSchemaTree(fields).rootNode,
796
- control,
797
- );
798
- const Render = useControlRendererComponent(
799
- definition,
800
- renderer,
801
- options,
802
- schemaDataNode,
803
- );
804
- return <Render />;
805
- }
806
-
807
- export function NewControlRenderer({
808
- definition,
809
- renderer,
810
- options,
811
- parentDataNode,
812
- }: {
813
- definition: ControlDefinition | FormNode;
814
- renderer: FormRenderer;
815
- options?: ControlRenderOptions;
816
- parentDataNode: SchemaDataNode;
817
- }) {
818
- const Render = useControlRendererComponent(
819
- definition,
820
- renderer,
821
- options,
822
- parentDataNode,
823
- );
824
- return <Render />;
453
+ variables?: Record<string, any>;
825
454
  }
826
455
 
827
456
  export function defaultDataProps(
@@ -832,6 +461,8 @@ export function defaultDataProps(
832
461
  schemaInterface = defaultSchemaInterface,
833
462
  styleClass,
834
463
  textClass: tc,
464
+ displayOnly,
465
+ inline,
835
466
  ...props
836
467
  }: RenderLayoutProps,
837
468
  definition: DataControlDefinition,
@@ -841,10 +472,9 @@ export function defaultDataProps(
841
472
  const field = dataNode.schema.field;
842
473
  const className = rendererClass(styleClass, definition.styleClass);
843
474
  const textClass = rendererClass(tc, definition.textClass);
844
- const displayOnly = !!formOptions.displayOnly;
845
475
  const required = !!definition.required && !displayOnly;
846
476
  const fieldOptions = schemaInterface.getDataOptions(dataNode);
847
- const _allowed = allowedOptions?.value ?? [];
477
+ const _allowed = allowedOptions ?? [];
848
478
  const allowed = Array.isArray(_allowed) ? _allowed : [_allowed];
849
479
  return {
850
480
  dataNode,
@@ -852,22 +482,22 @@ export function defaultDataProps(
852
482
  control,
853
483
  field,
854
484
  id: "c" + control.uniqueId,
855
- inline: !!formOptions.inline,
485
+ inline: !!inline,
856
486
  options:
857
487
  allowed.length > 0
858
488
  ? allowed
859
489
  .map((x) =>
860
490
  typeof x === "object"
861
491
  ? x
862
- : (fieldOptions?.find((y) => y.value == x) ?? {
492
+ : fieldOptions?.find((y) => y.value == x) ?? {
863
493
  name: x.toString(),
864
494
  value: x,
865
- }),
495
+ },
866
496
  )
867
497
  .filter((x) => x != null)
868
498
  : fieldOptions,
869
499
  readonly: !!formOptions.readonly,
870
- displayOnly,
500
+ displayOnly: !!displayOnly,
871
501
  renderOptions: definition.renderOptions ?? { type: "Standard" },
872
502
  required,
873
503
  hidden: !!formOptions.hidden,
@@ -880,12 +510,15 @@ export function defaultDataProps(
880
510
 
881
511
  export interface ChildRendererOptions {
882
512
  parentDataNode?: SchemaDataNode;
883
- formData?: FormContextData;
884
513
  inline?: boolean;
885
514
  displayOnly?: boolean;
886
515
  styleClass?: string;
887
516
  layoutClass?: string;
888
517
  labelClass?: string;
518
+ labelTextClass?: string;
519
+ actionOnClick?: ControlActionHandler;
520
+ stateKey?: string;
521
+ variables?: Record<string, any>;
889
522
  }
890
523
 
891
524
  export type ChildRenderer = (
@@ -897,18 +530,17 @@ export type ChildRenderer = (
897
530
  export interface RenderLayoutProps {
898
531
  formNode: FormNode;
899
532
  renderer: FormRenderer;
533
+ state: ControlState;
900
534
  renderChild: ChildRenderer;
901
535
  createDataProps: CreateDataProps;
902
536
  formOptions: FormContextOptions;
903
537
  dataContext: ControlDataContext;
904
538
  control?: Control<any>;
905
- labelText?: Control<string | null | undefined>;
906
- displayControl?: Control<string | undefined>;
907
539
  style?: React.CSSProperties;
908
- allowedOptions?: Control<any[] | undefined>;
909
- actionDataControl?: Control<any | undefined | null>;
910
- useChildVisibility: ChildVisibilityFunc;
911
- useEvalExpression: UseEvalExpressionHook;
540
+ allowedOptions?: any[];
541
+ getChildState(node: FormNode, parent?: SchemaDataNode): ControlState;
542
+ runExpression: RunExpression;
543
+
912
544
  actionOnClick?: ControlActionHandler;
913
545
  schemaInterface?: SchemaInterface;
914
546
  designMode?: boolean;
@@ -920,6 +552,8 @@ export interface RenderLayoutProps {
920
552
  labelTextClass?: string;
921
553
  styleClass?: string;
922
554
  textClass?: string;
555
+ inline?: boolean;
556
+ displayOnly?: boolean;
923
557
  }
924
558
  export function renderControlLayout(
925
559
  props: RenderLayoutProps,
@@ -930,21 +564,23 @@ export function renderControlLayout(
930
564
  control,
931
565
  dataContext,
932
566
  createDataProps: dataProps,
933
- displayControl,
934
567
  style,
935
- labelText,
936
- useChildVisibility,
937
568
  designMode,
938
569
  customDisplay,
939
- useEvalExpression,
570
+ runExpression,
940
571
  labelClass,
941
572
  labelTextClass,
942
573
  styleClass,
943
574
  textClass,
944
575
  formNode,
945
576
  formOptions,
577
+ actionOnClick,
578
+ state,
579
+ getChildState,
580
+ inline,
581
+ displayOnly,
946
582
  } = props;
947
- const c = formNode.definition;
583
+ const c = state.definition;
948
584
  if (isDataControl(c)) {
949
585
  return renderData(c);
950
586
  }
@@ -959,22 +595,24 @@ export function renderControlLayout(
959
595
  }
960
596
 
961
597
  return {
962
- inline: formOptions.inline,
598
+ inline,
963
599
  processLayout: renderer.renderGroup({
964
600
  formNode,
601
+ state,
965
602
  definition: c,
966
603
  renderChild,
967
- useEvalExpression,
604
+ runExpression,
968
605
  dataContext,
969
606
  renderOptions: c.groupOptions ?? { type: "Standard" },
970
607
  className: rendererClass(styleClass, c.styleClass),
971
608
  textClass: rendererClass(textClass, c.textClass),
972
- useChildVisibility,
973
609
  style,
974
610
  designMode,
611
+ actionOnClick,
612
+ getChildState,
975
613
  }),
976
614
  label: {
977
- label: labelText?.value ?? c.title,
615
+ label: c.title,
978
616
  className: rendererClass(labelClass, c.labelClass),
979
617
  textClass: rendererClass(labelTextClass, c.labelTextClass),
980
618
  type: LabelType.Group,
@@ -983,17 +621,22 @@ export function renderControlLayout(
983
621
  };
984
622
  }
985
623
  if (isActionControl(c)) {
986
- const actionData = props.actionDataControl?.value ?? c.actionData;
624
+ const actionData = c.actionData;
625
+ const actionStyle = c.actionStyle ?? ActionStyle.Button;
626
+ const actionContent =
627
+ actionStyle == ActionStyle.Group ? renderActionGroup() : undefined;
987
628
  return {
988
- inline: formOptions.inline,
629
+ inline,
989
630
  children: renderer.renderAction({
990
- actionText: labelText?.value ?? c.title ?? c.actionId,
631
+ actionText: c.title ?? c.actionId,
991
632
  actionId: c.actionId,
992
633
  actionData,
993
- actionStyle: c.actionStyle ?? ActionStyle.Button,
634
+ actionContent,
635
+ actionStyle,
994
636
  textClass: rendererClass(textClass, c.textClass),
637
+ iconPlacement: c.iconPlacement,
995
638
  icon: c.icon,
996
- inline: formOptions.inline,
639
+ inline,
997
640
  onClick:
998
641
  props.actionOnClick?.(c.actionId, actionData, dataContext) ??
999
642
  (() => {}),
@@ -1001,6 +644,17 @@ export function renderControlLayout(
1001
644
  style,
1002
645
  }),
1003
646
  };
647
+
648
+ function renderActionGroup() {
649
+ const childDefs = formNode.getResolvedChildren();
650
+ const childDef = {
651
+ type: ControlDefinitionType.Group,
652
+ groupOptions: { type: GroupRenderType.Contents, hideTitle: true },
653
+ children: childDefs,
654
+ };
655
+ const childNode: FormNode = formNode.createChildNode("child", childDef);
656
+ return renderChild("child", childNode, {});
657
+ }
1004
658
  }
1005
659
  if (isDisplayControl(c)) {
1006
660
  const data = c.displayData ?? {};
@@ -1009,18 +663,17 @@ export function renderControlLayout(
1009
663
  className: rendererClass(styleClass, c.styleClass),
1010
664
  textClass: rendererClass(textClass, c.textClass),
1011
665
  style,
1012
- display: displayControl,
1013
666
  dataContext,
1014
- inline: formOptions.inline,
667
+ inline,
1015
668
  };
1016
669
  if (data.type === DisplayDataType.Custom && customDisplay) {
1017
670
  return {
1018
- inline: formOptions.inline,
671
+ inline,
1019
672
  children: customDisplay((data as CustomDisplay).customId, displayProps),
1020
673
  };
1021
674
  }
1022
675
  return {
1023
- inline: formOptions.inline,
676
+ inline,
1024
677
  children: renderer.renderDisplay(displayProps),
1025
678
  };
1026
679
  }
@@ -1030,20 +683,17 @@ export function renderControlLayout(
1030
683
  if (!control) return { children: "No control for: " + c.field };
1031
684
  const rendererProps = dataProps(props, c, control);
1032
685
  const label = !c.hideTitle
1033
- ? controlTitle(
1034
- labelText?.value ?? c.title,
1035
- props.dataContext.dataNode!.schema.field,
1036
- )
686
+ ? controlTitle(c.title, props.dataContext.dataNode!.schema.field)
1037
687
  : undefined;
1038
688
  return {
1039
- inline: formOptions.inline,
689
+ inline,
1040
690
  processLayout: renderer.renderData(rendererProps),
1041
691
  label: {
1042
692
  type:
1043
693
  (c.children?.length ?? 0) > 0 ? LabelType.Group : LabelType.Control,
1044
694
  label,
1045
695
  forId: rendererProps.id,
1046
- required: c.required && !props.formOptions.displayOnly,
696
+ required: c.required && !displayOnly,
1047
697
  hide: c.hideTitle,
1048
698
  className: rendererClass(labelClass, c.labelClass),
1049
699
  textClass: rendererClass(labelTextClass, c.labelTextClass),
@@ -1329,15 +979,25 @@ export function applyArrayLengthRestrictions(
1329
979
  }
1330
980
 
1331
981
  export function fieldOptionAdornment(p: DataRendererProps) {
1332
- return (o: FieldOption, i: number, selected: boolean) => (
982
+ return (o: FieldOption, fieldIndex: number, selected: boolean) => (
1333
983
  <RenderArrayElements
1334
984
  array={p.formNode.getChildNodes()}
1335
985
  children={(cd, i) =>
1336
986
  p.renderChild(i, cd, {
1337
987
  parentDataNode: p.dataContext.parentNode,
1338
- formData: { option: o, optionSelected: selected },
988
+ stateKey: fieldIndex.toString(),
989
+ variables: { formData: { option: o, optionSelected: selected } },
1339
990
  })
1340
991
  }
1341
992
  />
1342
993
  );
1343
994
  }
995
+
996
+ export function lookupChildDataContext(
997
+ dataContext: ControlDataContext,
998
+ c: ControlDefinition,
999
+ ): ControlDataContext {
1000
+ const parentNode = dataContext.dataNode ?? dataContext.parentNode;
1001
+ const dataNode = lookupDataNode(c, parentNode);
1002
+ return { ...dataContext, parentNode, dataNode };
1003
+ }