@bolttech/form-engine 3.0.0-beta.13 → 3.0.0-beta.15

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/index.esm.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { FormGroup, FormCore } from '@bolttech/form-engine-core';
3
3
  import { createContext, useRef, useContext, useState, useEffect, useCallback, useMemo, Suspense, Children } from 'react';
4
+ import { isNil } from 'lodash';
4
5
 
5
6
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6
7
 
@@ -1684,8 +1685,36 @@ const FormGroupContextProvider = ({
1684
1685
  };
1685
1686
  const useFormGroupContext = () => {
1686
1687
  context = useContext(FormGroupContext);
1687
- if (typeof context === 'undefined') {
1688
- throw new Error(`useFormContext must be used within a FormContextProvider`);
1688
+ if (Object.keys(context).length === 0) {
1689
+ return {
1690
+ addFormWithIndex: () => {
1691
+ //simulate context purpose
1692
+ },
1693
+ addForm: () => {
1694
+ //simulate context purpose
1695
+ },
1696
+ getForm: () => new FormCore({
1697
+ index: 'empty',
1698
+ mappers: []
1699
+ }),
1700
+ removeForm: () => {
1701
+ //simulate context purpose
1702
+ },
1703
+ removeField: () => {
1704
+ //simulate context purpose
1705
+ },
1706
+ mappers: [],
1707
+ formGroupInstance: new FormGroup(),
1708
+ printFormGroupInstance: () => {
1709
+ //simulate context purpose
1710
+ },
1711
+ submitMultipleFormsByIndex: () => ({
1712
+ erroredFields: [],
1713
+ isValid: false,
1714
+ values: {}
1715
+ }),
1716
+ debugMode: false
1717
+ };
1689
1718
  }
1690
1719
  return context;
1691
1720
  };
@@ -1693,10 +1722,12 @@ const useFormGroupContext = () => {
1693
1722
  const FieldWrapperComponentRender = ({
1694
1723
  props,
1695
1724
  fieldInstance,
1696
- children
1725
+ children,
1726
+ mapper
1697
1727
  }) => {
1698
- const Component = fieldInstance.mapper.component;
1699
- const Asynccomponent = fieldInstance.mapper.asynccomponent;
1728
+ var _a, _b, _c;
1729
+ const Component = (mapper === null || mapper === void 0 ? void 0 : mapper.component) || ((_a = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _a === void 0 ? void 0 : _a.component);
1730
+ const Asynccomponent = (mapper === null || mapper === void 0 ? void 0 : mapper.asynccomponent) || ((_b = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _b === void 0 ? void 0 : _b.asynccomponent);
1700
1731
  if (Component) return jsx(Component, Object.assign({}, props, {
1701
1732
  children: children && children
1702
1733
  }));
@@ -1706,32 +1737,34 @@ const FieldWrapperComponentRender = ({
1706
1737
  }))
1707
1738
  });
1708
1739
  return jsx("div", {
1709
- children: `failed to render field ${fieldInstance.name} with ${fieldInstance.mapper.componentName}, please check mappers`
1740
+ children: `failed to render field ${fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.name} with ${(_c = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _c === void 0 ? void 0 : _c.componentName}, please check mappers`
1710
1741
  });
1711
1742
  };
1712
1743
  const FieldWrapper = ({
1713
- index,
1714
- formKey,
1715
- children
1744
+ name,
1745
+ formIndex,
1746
+ children,
1747
+ mapper,
1748
+ defaultProps
1716
1749
  }) => {
1717
1750
  var _a;
1718
1751
  const {
1719
1752
  formGroupInstance,
1720
1753
  debugMode
1721
1754
  } = useFormGroupContext();
1722
- const fieldInstance = ((_a = formGroupInstance.getForm({
1723
- key: formKey
1755
+ const fieldInstance = (_a = formGroupInstance.getForm({
1756
+ key: formIndex
1724
1757
  })) === null || _a === void 0 ? void 0 : _a.getField({
1725
- key: index
1726
- })) || {};
1727
- const [valueState, setValueState] = useState(fieldInstance.stateValue);
1758
+ key: name
1759
+ });
1760
+ const [valueState, setValueState] = useState(fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.stateValue);
1728
1761
  const [state, setState] = useState({
1729
- visibility: fieldInstance.visibility,
1730
- props: fieldInstance.props,
1731
- apiResponse: fieldInstance.api
1762
+ visibility: (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.visibility) || true,
1763
+ props: (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.props) || defaultProps,
1764
+ apiResponse: fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.api
1732
1765
  });
1733
1766
  useEffect(() => {
1734
- fieldInstance.mountField({
1767
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mountField({
1735
1768
  valueSubscription: value => {
1736
1769
  setValueState(value);
1737
1770
  },
@@ -1750,22 +1783,23 @@ const FieldWrapper = ({
1750
1783
  }
1751
1784
  });
1752
1785
  return () => {
1753
- fieldInstance.destroyField();
1786
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.destroyField();
1754
1787
  };
1755
1788
  }, []);
1756
1789
  const handleChange = useCallback(event => {
1757
- fieldInstance.emitValue({
1790
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
1758
1791
  value: event,
1759
1792
  event: 'ON_FIELD_CHANGE'
1760
1793
  });
1761
1794
  }, []);
1762
1795
  const handleEvent = useCallback(event => {
1763
- fieldInstance.emitEvents({
1796
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitEvents({
1764
1797
  event
1765
1798
  });
1766
1799
  }, []);
1767
1800
  const mapProps = useMemo(() => {
1768
- const events = fieldInstance.mapper.events;
1801
+ var _a;
1802
+ const events = (_a = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _a === void 0 ? void 0 : _a.events;
1769
1803
  const props = {};
1770
1804
  if (events === null || events === void 0 ? void 0 : events.onBlur) props[events.onBlur] = () => handleEvent('ON_FIELD_BLUR');
1771
1805
  if (events === null || events === void 0 ? void 0 : events.getValue) props[events.getValue] = handleChange;
@@ -1776,7 +1810,8 @@ const FieldWrapper = ({
1776
1810
  return props;
1777
1811
  }, []);
1778
1812
  const mapValue = useMemo(() => {
1779
- const events = fieldInstance.mapper.events;
1813
+ var _a;
1814
+ const events = (_a = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _a === void 0 ? void 0 : _a.events;
1780
1815
  return (events === null || events === void 0 ? void 0 : events.setValue) ? {
1781
1816
  [events.setValue]: valueState
1782
1817
  } : {};
@@ -1788,11 +1823,12 @@ const FieldWrapper = ({
1788
1823
  padding: '0px',
1789
1824
  margin: '0px'
1790
1825
  },
1791
- children: index
1826
+ children: name
1792
1827
  }), jsx("br", {}), jsx("hr", {})]
1793
1828
  }), jsx(FieldWrapperComponentRender, {
1794
1829
  props: Object.assign(Object.assign(Object.assign({}, state.props), mapProps), mapValue),
1795
1830
  fieldInstance: fieldInstance,
1831
+ mapper: mapper,
1796
1832
  children: children && children
1797
1833
  })]
1798
1834
  }) : jsx(Fragment, {});
@@ -1801,7 +1837,7 @@ const FieldWrapper = ({
1801
1837
  const BuildTree = ({
1802
1838
  fields,
1803
1839
  prevPath,
1804
- formKey
1840
+ formIndex
1805
1841
  }) => {
1806
1842
  return Array.from(fields).filter(([, value]) => {
1807
1843
  return value.path === prevPath;
@@ -1810,14 +1846,14 @@ const BuildTree = ({
1810
1846
  const children = BuildTree({
1811
1847
  fields,
1812
1848
  prevPath: `${prevPath ? `${prevPath}.` : ``}${value.name}`,
1813
- formKey
1849
+ formIndex
1814
1850
  });
1815
1851
  const lenght = Children.count(children);
1816
1852
  return jsx(FieldWrapper, {
1817
- index: fieldName,
1818
- formKey: formKey,
1853
+ name: fieldName,
1854
+ formIndex: formIndex,
1819
1855
  children: lenght > 0 ? children : null
1820
- });
1856
+ }, fieldName);
1821
1857
  });
1822
1858
  };
1823
1859
  const BuildAsFormFieldTree = ({
@@ -1840,6 +1876,75 @@ const BuildAsFormFieldTree = ({
1840
1876
  });
1841
1877
  };
1842
1878
 
1879
+ const eventsMapping = {
1880
+ onChange: 'ON_FIELD_CHANGE',
1881
+ onBlur: 'ON_FIELD_BLUR',
1882
+ onFocus: 'ON_FIELD_FOCUS',
1883
+ onKeyDown: 'ON_FIELD_KEYDOWN',
1884
+ onKeyUp: 'ON_FIELD_KEYUP',
1885
+ onMount: 'ON_FIELD_MOUNT',
1886
+ onApiResponse: 'ON_API_FIELD_RESPONSE',
1887
+ onClick: 'ON_FIELD_CLICK'
1888
+ };
1889
+ const subscribeEvents = ({
1890
+ eventsCallbackMappings,
1891
+ formInstance
1892
+ }) => {
1893
+ const subscriptions = [];
1894
+ Object.keys(eventsCallbackMappings).forEach(key => {
1895
+ if (!isNil(eventsCallbackMappings[key])) {
1896
+ const sub = formInstance.subscribeFieldEvent({
1897
+ event: eventsMapping[key],
1898
+ // need to make this assertion even when it's not undefined or null on push ts verification
1899
+ callback: eventsCallbackMappings[key]
1900
+ });
1901
+ subscriptions.push(sub);
1902
+ }
1903
+ });
1904
+ return subscriptions;
1905
+ };
1906
+
1907
+ const useForm = ({
1908
+ id,
1909
+ onApiResponse,
1910
+ onBlur,
1911
+ onChange,
1912
+ onClick,
1913
+ onFocus,
1914
+ onKeyDown,
1915
+ onKeyUp,
1916
+ onMount
1917
+ }) => {
1918
+ const {
1919
+ formGroupInstance
1920
+ } = useFormGroupContext();
1921
+ const subscriptions = useRef([]);
1922
+ useEffect(() => {
1923
+ const formInstance = formGroupInstance.getForm({
1924
+ key: id
1925
+ });
1926
+ if (formInstance) {
1927
+ subscriptions.current = subscribeEvents({
1928
+ eventsCallbackMappings: {
1929
+ onApiResponse,
1930
+ onBlur,
1931
+ onChange,
1932
+ onClick,
1933
+ onFocus,
1934
+ onKeyDown,
1935
+ onKeyUp,
1936
+ onMount
1937
+ },
1938
+ formInstance
1939
+ });
1940
+ }
1941
+ return () => {
1942
+ subscriptions.current.forEach(sub => sub.unsubscribe());
1943
+ };
1944
+ }, [id, onApiResponse, onBlur, onChange, onClick, onFocus, onKeyDown, onKeyUp, onMount]);
1945
+ return;
1946
+ };
1947
+
1843
1948
  const Form = ({
1844
1949
  schema,
1845
1950
  index,
@@ -1849,6 +1954,14 @@ const Form = ({
1849
1954
  method,
1850
1955
  onSubmit,
1851
1956
  onData,
1957
+ onBlur,
1958
+ onChange,
1959
+ onApiResponse,
1960
+ onClick,
1961
+ onFocus,
1962
+ onKeyDown,
1963
+ onKeyUp,
1964
+ onMount,
1852
1965
  children
1853
1966
  }) => {
1854
1967
  const {
@@ -1860,6 +1973,17 @@ const Form = ({
1860
1973
  } = useFormGroupContext();
1861
1974
  const [tree, setTree] = useState();
1862
1975
  const schemaIndex = useMemo(() => index || (schema === null || schema === void 0 ? void 0 : schema.index) || 'defaultChange', [index, schema]);
1976
+ useForm({
1977
+ id: index,
1978
+ onApiResponse,
1979
+ onBlur,
1980
+ onChange,
1981
+ onClick,
1982
+ onFocus,
1983
+ onKeyDown,
1984
+ onKeyUp,
1985
+ onMount
1986
+ });
1863
1987
  useEffect(() => {
1864
1988
  if (schemaIndex === 'defaultChange') {
1865
1989
  console.warn('please, add an unique id to the form, otherwise multiple forms will break');
@@ -1882,9 +2006,11 @@ const Form = ({
1882
2006
  @TODO check if form instance is killed each time it is unmounted
1883
2007
  the management of multiple forms needs to be planned
1884
2008
  */
1885
- return () => removeForm({
1886
- key: index
1887
- });
2009
+ return () => {
2010
+ removeForm({
2011
+ key: index
2012
+ });
2013
+ };
1888
2014
  }, []);
1889
2015
  useEffect(() => {
1890
2016
  var _a;
@@ -1900,7 +2026,7 @@ const Form = ({
1900
2026
  if (fields) {
1901
2027
  const buildTree = BuildTree({
1902
2028
  fields,
1903
- formKey: index
2029
+ formIndex: index
1904
2030
  });
1905
2031
  setTree(buildTree);
1906
2032
  }
@@ -1967,17 +2093,38 @@ const AsFormFieldBuilder = props => {
1967
2093
  } = useFormGroupContext();
1968
2094
  const [field, setField] = useState(jsx(Fragment, {}));
1969
2095
  useEffect(() => {
1970
- var _a;
1971
- if (!formGroupInstance.forms.has(props.formIndex)) {
2096
+ if (!(formGroupInstance === null || formGroupInstance === void 0 ? void 0 : formGroupInstance.forms.has(props.formIndex))) {
1972
2097
  addFormWithIndex(props.formIndex);
1973
2098
  }
1974
2099
  const fieldInstanceProps = Object.assign(Object.assign({}, props), {
2100
+ component: props.mapper.componentName,
1975
2101
  children: undefined
1976
2102
  });
1977
- (_a = formGroupInstance.forms.get(props.formIndex)) === null || _a === void 0 ? void 0 : _a.addField(fieldInstanceProps);
2103
+ const formInstance = formGroupInstance.forms.get(props.formIndex);
2104
+ formInstance === null || formInstance === void 0 ? void 0 : formInstance.addField(fieldInstanceProps, props.mapper);
2105
+ /*
2106
+ some magic happens using this setTimeout and i don't know why...
2107
+ this is executed right before the FieldWrapper mounts as expected
2108
+ but has the blinking problem allowing people to see the template
2109
+ format instead of the prop value
2110
+ */
2111
+ setTimeout(() => {
2112
+ var _a;
2113
+ (_a = formInstance === null || formInstance === void 0 ? void 0 : formInstance.getField({
2114
+ key: props.name
2115
+ })) === null || _a === void 0 ? void 0 : _a.emitEvents({
2116
+ event: 'ON_FIELD_MOUNT'
2117
+ });
2118
+ formInstance === null || formInstance === void 0 ? void 0 : formInstance.refreshTemplates({
2119
+ key: props.name,
2120
+ event: 'ON_FIELDS'
2121
+ });
2122
+ }, 0);
1978
2123
  const field = jsx(FieldWrapper, {
1979
- formKey: props.formIndex,
1980
- index: props.name,
2124
+ mapper: props.mapper,
2125
+ formIndex: props.formIndex,
2126
+ name: props.name,
2127
+ defaultProps: props.props,
1981
2128
  children: props.children && props.children
1982
2129
  });
1983
2130
  setField(field);
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine",
3
- "version": "3.0.0-beta.13",
3
+ "version": "3.0.0-beta.15",
4
4
  "description": "A react adapter for bolttech form engine",
5
5
  "module": "./index.esm.js",
6
6
  "type": "module",
7
7
  "main": "./index.esm.js",
8
8
  "dependencies": {
9
- "@bolttech/form-engine-core": "0.0.1-beta.4",
10
- "react": "18.2.0"
9
+ "@bolttech/form-engine-core": "0.0.1-beta.6",
10
+ "lodash": "4.17.21",
11
+ "react": "18.2.0",
12
+ "rxjs": "7.8.1"
11
13
  },
12
14
  "peerDependencies": {}
13
15
  }
@@ -1,6 +1,5 @@
1
1
  import { IComponentSchema } from '@bolttech/form-engine-core';
2
2
  import { PropsWithChildren, ReactElement } from 'react';
3
- declare const AsFormFieldBuilder: (props: PropsWithChildren<Omit<IComponentSchema, 'children'> & {
4
- formIndex: string;
5
- }>) => ReactElement;
3
+ import { TFieldWrapper } from '../../types';
4
+ declare const AsFormFieldBuilder: (props: PropsWithChildren<Omit<IComponentSchema, 'children' | 'component'> & Required<TFieldWrapper>>) => ReactElement;
6
5
  export default AsFormFieldBuilder;
@@ -1,4 +1,7 @@
1
1
  import { PropsWithChildren, ReactElement } from 'react';
2
2
  import { TFieldWrapper } from '../../types';
3
- declare const FieldWrapper: ({ index, formKey, children, }: PropsWithChildren<TFieldWrapper>) => ReactElement;
3
+ declare const FieldWrapper: ({ name, formIndex, children, mapper, defaultProps, }: PropsWithChildren<TFieldWrapper & {
4
+ name: string;
5
+ defaultProps?: Record<string, unknown> | undefined;
6
+ }>) => ReactElement;
4
7
  export default FieldWrapper;
@@ -1,4 +1,5 @@
1
1
  import { TFormEntry } from '@bolttech/form-engine-core';
2
2
  import { PropsWithChildren } from 'react';
3
- declare const Form: ({ schema, index, initialValues, iVars, action, method, onSubmit, onData, children, }: PropsWithChildren<Omit<TFormEntry, 'mappers'>>) => import("react/jsx-runtime").JSX.Element;
3
+ import { TEventsCallbackProps } from '../../types';
4
+ declare const Form: ({ schema, index, initialValues, iVars, action, method, onSubmit, onData, onBlur, onChange, onApiResponse, onClick, onFocus, onKeyDown, onKeyUp, onMount, children, }: PropsWithChildren<Omit<TFormEntry, 'mappers'> & TEventsCallbackProps>) => import("react/jsx-runtime").JSX.Element;
4
5
  export default Form;
@@ -1,9 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { IFormField, IComponentSchema } from '@bolttech/form-engine-core';
3
- declare const BuildTree: ({ fields, prevPath, formKey, }: {
3
+ declare const BuildTree: ({ fields, prevPath, formIndex, }: {
4
4
  fields: Map<string, IFormField>;
5
5
  prevPath?: string | undefined;
6
- formKey: string;
6
+ formIndex: string;
7
7
  }) => ReactNode;
8
8
  declare const BuildAsFormFieldTree: ({ children, }: {
9
9
  children?: ReactNode;
@@ -0,0 +1,8 @@
1
+ import { TFormCore } from '@bolttech/form-engine-core';
2
+ import { Subscription } from 'rxjs';
3
+ import { TEventsCallbackProps } from '../types';
4
+ declare const subscribeEvents: ({ eventsCallbackMappings, formInstance, }: {
5
+ eventsCallbackMappings: TEventsCallbackProps;
6
+ formInstance: TFormCore;
7
+ }) => Subscription[];
8
+ export { subscribeEvents };
@@ -0,0 +1,5 @@
1
+ import { TEventsCallbackProps } from '../types';
2
+ declare const useForm: ({ id, onApiResponse, onBlur, onChange, onClick, onFocus, onKeyDown, onKeyUp, onMount, }: {
3
+ id: string;
4
+ } & Partial<Record<import("../types").eventProps, ((payload: import("dist/libs/form-engine-core/src/types/event").TFieldEvent) => void) | null | undefined>>) => void;
5
+ export default useForm;
@@ -1,3 +1,5 @@
1
+ import { TFieldEvent, TMapper } from '@bolttech/form-engine-core';
2
+ import { ElementType } from 'react';
1
3
  /**
2
4
  * @type TFieldWrapper
3
5
  * Represents the wrapper for a form field, including the component,
@@ -37,7 +39,10 @@
37
39
  * ```
38
40
  */
39
41
  type TFieldWrapper = {
40
- index: string;
41
- formKey: string;
42
+ name: string;
43
+ formIndex: string;
44
+ mapper?: TMapper<ElementType>;
42
45
  };
43
- export { TFieldWrapper };
46
+ type eventProps = 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onKeyUp' | 'onMount' | 'onApiResponse' | 'onClick';
47
+ type TEventsCallbackProps = Partial<Record<eventProps, ((payload: TFieldEvent) => void) | null | undefined>>;
48
+ export { TFieldWrapper, eventProps, TEventsCallbackProps };