@bolttech/form-engine 3.1.2-beta.3 → 3.1.2-beta.5

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/README.md CHANGED
@@ -1232,6 +1232,7 @@ Props:
1232
1232
  | addFieldName | string | name of the button in the RepeaterComponent to add forms |
1233
1233
  | removeFieldName | string | name of the button in the RepeaterComponent to remove forms |
1234
1234
  | existingElements | Record<string, unknown>[] | existing values emmitted from stateUpdater to restore previous used values |
1235
+ | initialElements | number | elements to be pre-rendered when the form is presented |
1235
1236
  | stateUpdater | (payload: TFormGroupOnDataEventPayload<unknown>) => void; | callback function that reacts to RepeaterComponet values changes |
1236
1237
  | formPrefix | string | prefix for form names ex, prefix: foo, forms: ["foo1","foo2","foo3"] |
1237
1238
  | RepeaterFooter | ElementType<{ formIndex: string }> | Component with a button to add forms on the last position |
package/index.esm.js CHANGED
@@ -2808,12 +2808,10 @@ function useFormGroup({
2808
2808
  return;
2809
2809
  }
2810
2810
 
2811
- const REPEATER_FOOTER_ID = 'repeaterFooter';
2812
2811
  /**
2813
- * Component Wrapper to render form fields without the Form component, gets additional formId and mapper since
2814
- * it won't rely on them and needs to be manually declared
2812
+ * Adapter do manage repeated list elements on form
2815
2813
  *
2816
- * @param {TAsFormFieldBuilderProps} props JSON schema props along with FieldWrapper props and mapper props
2814
+ * @param {TAsFormFieldRepeaterProps} props Repeater properties to configure the elements repeater
2817
2815
  * @returns {ReactElement}
2818
2816
  */
2819
2817
  const AsFormFieldRepeater = ({
@@ -2821,6 +2819,7 @@ const AsFormFieldRepeater = ({
2821
2819
  addFieldName,
2822
2820
  removeFieldName,
2823
2821
  existingElements,
2822
+ initialElements,
2824
2823
  stateUpdater,
2825
2824
  formPrefix,
2826
2825
  RepeaterFooter
@@ -2829,9 +2828,10 @@ const AsFormFieldRepeater = ({
2829
2828
  getForm,
2830
2829
  formGroupInstance
2831
2830
  } = useFormGroupContext();
2832
- const [elements, setElements] = useState(existingElements ? Object.keys(existingElements).map(() => uniqueIdGen()) : [uniqueIdGen()]);
2831
+ const [elements, setElements] = useState(typeof existingElements === 'object' && existingElements !== null ? Object.keys(existingElements).map(() => uniqueIdGen()) : typeof initialElements === 'number' ? Array.from(Array(initialElements), () => uniqueIdGen()) : []);
2833
2832
  const mountedRef = useRef(false);
2834
2833
  const prevElements = useRef(0);
2834
+ const REPEATER_FOOTER_ID = useMemo(() => uniqueIdGen(), []);
2835
2835
  const listeningElements = useMemo(() => {
2836
2836
  return [...elements, REPEATER_FOOTER_ID];
2837
2837
  }, [elements]);
@@ -2881,6 +2881,13 @@ const AsFormFieldRepeater = ({
2881
2881
  fieldInstance
2882
2882
  }) {
2883
2883
  if (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.formIndex) {
2884
+ if (event === 'ON_FIELD_CLICK' && fieldInstance.formIndex === REPEATER_FOOTER_ID) {
2885
+ setElements(prev => {
2886
+ prev.push(uniqueIdGen());
2887
+ return [...prev];
2888
+ });
2889
+ return;
2890
+ }
2884
2891
  if (event === 'ON_FIELD_CLICK' && fieldName === addFieldName) {
2885
2892
  setElements(prev => {
2886
2893
  const index = prev.indexOf(fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.formIndex);
@@ -2889,18 +2896,12 @@ const AsFormFieldRepeater = ({
2889
2896
  });
2890
2897
  }
2891
2898
  if (event === 'ON_FIELD_CLICK' && fieldName === removeFieldName) {
2892
- if ((fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.formIndex) && elements.length > 1) setElements(prev => {
2899
+ if ((fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.formIndex) && elements.length > 0) setElements(prev => {
2893
2900
  const index = prev.indexOf(fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.formIndex);
2894
2901
  prev.splice(index, 1);
2895
2902
  return [...prev];
2896
2903
  });
2897
2904
  }
2898
- if (event === 'ON_FIELD_CLICK' && fieldInstance.formIndex === REPEATER_FOOTER_ID) {
2899
- setElements(prev => {
2900
- prev.push(uniqueIdGen());
2901
- return [...prev];
2902
- });
2903
- }
2904
2905
  }
2905
2906
  }
2906
2907
  });
@@ -2916,8 +2917,9 @@ const AsFormFieldRepeater = ({
2916
2917
  display: 'flex',
2917
2918
  flexDirection: 'column'
2918
2919
  },
2919
- children: [elements.map(el => jsx(RepeaterComponent, {
2920
- formIndex: el
2920
+ children: [elements.map((el, index) => jsx(RepeaterComponent, {
2921
+ formIndex: el,
2922
+ index: index
2921
2923
  }, el)), RepeaterFooter && jsx(RepeaterFooter, {
2922
2924
  formIndex: REPEATER_FOOTER_ID
2923
2925
  })]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine",
3
- "version": "3.1.2-beta.3",
3
+ "version": "3.1.2-beta.5",
4
4
  "description": "A react adapter for bolttech form engine",
5
5
  "module": "./index.esm.js",
6
6
  "type": "module",
@@ -1,23 +1,10 @@
1
- import { ElementType, ReactNode } from 'react';
2
- import { TFormGroupOnDataEventPayload } from '@bolttech/form-engine-core';
1
+ import { ReactNode } from 'react';
2
+ import { TAsFormFieldRepeaterProps } from './AsFormFieldRepeater.type';
3
3
  /**
4
- * Component Wrapper to render form fields without the Form component, gets additional formId and mapper since
5
- * it won't rely on them and needs to be manually declared
4
+ * Adapter do manage repeated list elements on form
6
5
  *
7
- * @param {TAsFormFieldBuilderProps} props JSON schema props along with FieldWrapper props and mapper props
6
+ * @param {TAsFormFieldRepeaterProps} props Repeater properties to configure the elements repeater
8
7
  * @returns {ReactElement}
9
8
  */
10
- declare const AsFormFieldRepeater: ({ RepeaterComponent, addFieldName, removeFieldName, existingElements, stateUpdater, formPrefix, RepeaterFooter, }: {
11
- RepeaterComponent: ElementType<{
12
- formIndex: string;
13
- }>;
14
- addFieldName?: string | undefined;
15
- removeFieldName?: string | undefined;
16
- existingElements?: Record<string, unknown>[] | undefined;
17
- stateUpdater?: ((payload: TFormGroupOnDataEventPayload<unknown>) => void) | undefined;
18
- formPrefix?: string | undefined;
19
- RepeaterFooter: ElementType<{
20
- formIndex: string;
21
- }>;
22
- }) => ReactNode;
9
+ declare const AsFormFieldRepeater: ({ RepeaterComponent, addFieldName, removeFieldName, existingElements, initialElements, stateUpdater, formPrefix, RepeaterFooter, }: TAsFormFieldRepeaterProps) => ReactNode;
23
10
  export default AsFormFieldRepeater;
@@ -0,0 +1,34 @@
1
+ import { TFormGroupOnDataEventPayload } from '@bolttech/form-engine-core';
2
+ import { OneOf } from '@bolttech/form-engine-core/src/types/utility';
3
+ import { ElementType } from 'react';
4
+ type TRepeaterProps = {
5
+ formIndex: string;
6
+ index: number;
7
+ };
8
+ type TRepeaterFooterProps = Pick<TRepeaterProps, 'formIndex'>;
9
+ /**
10
+ * AsFormFieldRepeater props needed to build a repeater to build forms
11
+ * @property {ElementType<TRepeaterProps>} RepeaterComponent element to use as repeater
12
+ * @property {string} addFieldName field name button that will add an element on a position on a repeater
13
+ * @property {string} removeFieldName field name button that will remove an element on a position on a repeater
14
+ * @property {Record<string, unknown>[]} existingElements elements to restore a repeater list
15
+ * @property {number} initialElements elements to be pre-rendered when the form is presented
16
+ * @property {(payload: TFormGroupOnDataEventPayload<unknown>) => void} stateUpdater similar to onData for the group of form managed by the repeater
17
+ * @property {string} formPrefix prefix to use on the repeated forms ex: (person- will go person-1, person-2, ...)
18
+ * @property {ElementType<TRepeaterFooterProps>} RepeaterFooter component with a button that will add an element to the bottom of the list
19
+ * @see {@link TMapper}
20
+ * @see {@link IComponentSchema}
21
+ * @see {@link TFieldWrapper}
22
+ */
23
+ type TAsFormFieldRepeaterProps = {
24
+ RepeaterComponent: ElementType<TRepeaterProps>;
25
+ addFieldName?: string;
26
+ removeFieldName?: string;
27
+ stateUpdater?: (payload: TFormGroupOnDataEventPayload<unknown>) => void;
28
+ formPrefix?: string;
29
+ RepeaterFooter: ElementType<TRepeaterFooterProps>;
30
+ } & OneOf<{
31
+ existingElements?: Record<string, unknown>[];
32
+ initialElements?: number;
33
+ }>;
34
+ export type { TAsFormFieldRepeaterProps, TRepeaterProps, TRepeaterFooterProps };