@bolttech/form-engine 0.11.2 → 0.11.3

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.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./types.js"),r=require("./asFormField-50ffeedd.js");require("react"),require("react/jsx-runtime"),require("credit-card-type"),Object.defineProperty(exports,"TAvailableHooks",{enumerable:!0,get:function(){return e.TAvailableHooks}}),exports.ALL_NAMESPACE_EVENTS=r.ALL_NAMESPACE_EVENTS,exports.BUILD_EVENT=r.BUILD_EVENT,exports.CoreEvents=r.CoreEvents,exports.Form=r.SchemaGuard,exports.FormProvider=r.FormProvider,exports.asFormField=r.asFormField,exports.useForm=r.useForm;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./types.js"),r=require("./asFormField-51a4f002.js");require("react"),require("react/jsx-runtime"),require("credit-card-type"),Object.defineProperty(exports,"TAvailableHooks",{enumerable:!0,get:function(){return e.TAvailableHooks}}),exports.ALL_NAMESPACE_EVENTS=r.ALL_NAMESPACE_EVENTS,exports.BUILD_EVENT=r.BUILD_EVENT,exports.CoreEvents=r.CoreEvents,exports.Form=r.SchemaGuard,exports.FormProvider=r.FormProvider,exports.asFormField=r.asFormField,exports.useForm=r.useForm;
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "A form engine based on form events for react projects",
5
5
  "type": "commonjs",
6
6
  "exports": {
package/react.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./asFormField-50ffeedd.js"),r=require("react");require("./types.js"),require("react/jsx-runtime"),require("credit-card-type");exports.Form=e.SchemaGuard,exports.FormProvider=e.FormProvider,exports.asFormField=e.asFormField,exports.useForm=e.useForm,exports.useFormGroup=({group:s,onData:t,onSubmit:o,ids:a=[]})=>{const[c,i]=r.useState(s?e.getGroupFormsIds(s):a),n=r.useCallback((()=>{const r=c.reduce(((r,s)=>Object.assign(Object.assign({},r),{[s]:e.getFormInstance(s).formData})),{});t&&t(r)}),[t]),u=r=>c.reduce(((s,t)=>(null==r?void 0:r.aggregate)?Object.keys(s).reduce(((o,a)=>Object.assign(Object.assign({},o),{[a]:Object.assign(Object.assign({},s[a]),e.getFormInstance(t,r).formData[a])})),{}):Object.assign(Object.assign({},s),{[t]:e.getFormInstance(t,r).formData})),{formatted:{},erroredFields:{},fields:{},form:{},predictableErroredFields:{},filteredFields:{}});r.useEffect((()=>{!c.length&&s&&i(e.getGroupFormsIds(s))}),[c]),r.useEffect((()=>{c.map((r=>e.getFormInstance(r).subscribe("ON_FIELD_CHANGE",n)))}),[t,c]),r.useEffect((()=>{c.map((r=>e.getFormInstance(r).subscribe("ON_SCOPE_CHANGE",n)))}),[t,c]),r.useEffect((()=>{c.map((r=>e.getFormInstance(r).subscribe(e.ALL_NAMESPACE_EVENTS(e.CoreEvents.ON_FIELD_REHYDRATE),n)))}),[t,c]),r.useEffect((()=>{c.map((r=>e.getFormInstance(r).subscribe(e.CoreEvents.ON_FORM_SUBMIT,(()=>o&&o(u({}))))))}),[o,c]);return{submitForm:()=>c.map((r=>e.getFormInstance(r).publish(e.CoreEvents.ON_FORM_SUBMIT))),formData:u}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./asFormField-51a4f002.js"),r=require("react");require("./types.js"),require("react/jsx-runtime"),require("credit-card-type");exports.Form=e.SchemaGuard,exports.FormProvider=e.FormProvider,exports.asFormField=e.asFormField,exports.useForm=e.useForm,exports.useFormGroup=({group:s,onData:t,onClick:o,onSubmit:a,ids:c=[]})=>{const[n,i]=r.useState(s?e.getGroupFormsIds(s):c),u=r.useCallback((()=>{const r=n.reduce(((r,s)=>Object.assign(Object.assign({},r),{[s]:e.getFormInstance(s).formData})),{});t&&t(r)}),[t]),m=r=>n.reduce(((s,t)=>(null==r?void 0:r.aggregate)?Object.keys(s).reduce(((o,a)=>Object.assign(Object.assign({},o),{[a]:Object.assign(Object.assign({},s[a]),e.getFormInstance(t,r).formData[a])})),{}):Object.assign(Object.assign({},s),{[t]:e.getFormInstance(t,r).formData})),{formatted:{},erroredFields:{},fields:{},form:{},predictableErroredFields:{},filteredFields:{}});r.useEffect((()=>{!n.length&&s&&i(e.getGroupFormsIds(s))}),[n]),r.useEffect((()=>{n.map((r=>e.getFormInstance(r).subscribe("ON_FIELD_CHANGE",u)))}),[t,n]),r.useEffect((()=>{n.map((r=>e.getFormInstance(r).subscribe("ON_SCOPE_CHANGE",u)))}),[t,n]),r.useEffect((()=>{n.map((r=>e.getFormInstance(r).subscribe(e.ALL_NAMESPACE_EVENTS(e.CoreEvents.ON_FIELD_REHYDRATE),u)))}),[t,n]),r.useEffect((()=>{n.map((r=>e.getFormInstance(r).subscribe(e.ALL_NAMESPACE_EVENTS(e.CoreEvents.ON_FIELD_CLICK),o)))}),[o,n]),r.useEffect((()=>{n.map((r=>e.getFormInstance(r).subscribe(e.CoreEvents.ON_FORM_SUBMIT,(()=>a&&a(m({}))))))}),[a,n]);return{submitForm:()=>n.map((r=>e.getFormInstance(r).publish(e.CoreEvents.ON_FORM_SUBMIT))),formData:m}};
2
2
  //# sourceMappingURL=react.js.map
package/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sources":["../../../libs/form-engine/src/adapters/react/useFormGroup.tsx"],"sourcesContent":["import { useEffect, useCallback, useState } from 'react';\n\nimport { TFormValues, THookReturn, TUseFormGroupProps } from '@react/types';\n\nimport { CoreEvents, ALL_NAMESPACE_EVENTS } from '@core';\nimport { getFormInstance, getGroupFormsIds } from '@core/managers';\nimport { EEVents } from '@core/constants';\n\nconst useFormGroup = ({\n group,\n onData,\n onSubmit,\n ids = [],\n}: TUseFormGroupProps): THookReturn => {\n const [formIds, setFormIds] = useState(group ? getGroupFormsIds(group) : ids);\n\n const onDataChange = useCallback(() => {\n const data = formIds.reduce(\n (acc, formId) => ({\n ...acc,\n [formId]: getFormInstance(formId).formData,\n }),\n {},\n );\n\n onData && onData(data);\n }, [onData]);\n\n const extractFormsData = (opts) => {\n return formIds.reduce(\n (acc, formId) => {\n if (opts?.aggregate) {\n return Object.keys(acc).reduce(\n (innerAcc, key) => ({\n ...innerAcc,\n [key]: {\n ...acc[key],\n ...getFormInstance(formId, opts).formData[key],\n },\n }),\n {},\n );\n }\n\n return { ...acc, [formId]: getFormInstance(formId, opts).formData };\n },\n {\n formatted: {},\n erroredFields: {},\n fields: {},\n form: {},\n predictableErroredFields: {},\n filteredFields: {},\n } as TFormValues,\n );\n };\n\n useEffect(() => {\n if (formIds.length || !group) return;\n setFormIds(getGroupFormsIds(group));\n }, [formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(EEVents.ON_FIELD_CHANGE, onDataChange),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(EEVents.ON_SCOPE_CHANGE, onDataChange),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(\n ALL_NAMESPACE_EVENTS(CoreEvents.ON_FIELD_REHYDRATE),\n onDataChange,\n ),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(\n CoreEvents.ON_FORM_SUBMIT,\n () => onSubmit && onSubmit(extractFormsData({})),\n ),\n );\n }, [onSubmit, formIds]);\n\n const submitForm = () =>\n formIds.map((formId) =>\n getFormInstance(formId).publish(CoreEvents.ON_FORM_SUBMIT),\n );\n\n return {\n submitForm,\n formData: extractFormsData,\n };\n};\n\nexport { useFormGroup };\n"],"names":["useFormGroup","group","onData","onSubmit","ids","formIds","setFormIds","useState","getGroupFormsIds","onDataChange","useCallback","data","reduce","acc","formId","Object","assign","getFormInstance","formData","extractFormsData","opts","aggregate","keys","innerAcc","key","formatted","erroredFields","fields","form","predictableErroredFields","filteredFields","useEffect","length","map","subscribe","ALL_NAMESPACE_EVENTS","CoreEvents","ON_FIELD_REHYDRATE","ON_FORM_SUBMIT","submitForm","publish"],"mappings":"iWAQqBA,EACnBC,QACAC,SACAC,WACAC,MAAM,OAEN,MAAOC,EAASC,GAAcC,EAAQA,SAACN,EAAQO,mBAAiBP,GAASG,GAEnEK,EAAeC,EAAAA,aAAY,KAC/B,MAAMC,EAAON,EAAQO,QACnB,CAACC,EAAKC,IACDC,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAH,GACH,CAAAC,CAACA,GAASG,EAAAA,gBAAgBH,GAAQI,YAEpC,CAAE,GAGJhB,GAAUA,EAAOS,EAAK,GACrB,CAACT,IAEEiB,EAAoBC,GACjBf,EAAQO,QACb,CAACC,EAAKC,KACAM,eAAAA,EAAMC,WACDN,OAAOO,KAAKT,GAAKD,QACtB,CAACW,EAAUC,IACNT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAO,IACHC,CAACA,GACIT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAH,EAAIW,IACJP,EAAeA,gBAACH,EAAQM,GAAMF,SAASM,OAG9C,CAAE,GAINT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAYH,GAAG,CAAEC,CAACA,GAASG,EAAeA,gBAACH,EAAQM,GAAMF,YAE3D,CACEO,UAAW,CAAE,EACbC,cAAe,CAAE,EACjBC,OAAQ,CAAE,EACVC,KAAM,CAAE,EACRC,yBAA0B,CAAE,EAC5BC,eAAgB,CAAE,IAKxBC,EAAAA,WAAU,MACJ1B,EAAQ2B,QAAW/B,GACvBK,EAAWE,EAAAA,iBAAiBP,GAAO,GAClC,CAACI,IAEJ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,kBAAgBH,GAAQoB,4BAAmCzB,IAC5D,GACA,CAACP,EAAQG,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,kBAAgBH,GAAQoB,4BAAmCzB,IAC5D,GACA,CAACP,EAAQG,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,EAAAA,gBAAgBH,GAAQoB,UACtBC,EAAAA,qBAAqBC,EAAAA,WAAWC,oBAChC5B,IAEH,GACA,CAACP,EAAQG,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,EAAeA,gBAACH,GAAQoB,UACtBE,EAAAA,WAAWE,gBACX,IAAMnC,GAAYA,EAASgB,EAAiB,CAAE,OAEjD,GACA,CAAChB,EAAUE,IAOd,MAAO,CACLkC,WANiBA,IACjBlC,EAAQ4B,KAAKnB,GACXG,EAAAA,gBAAgBH,GAAQ0B,QAAQJ,aAAWE,kBAK7CpB,SAAUC,EACX"}
1
+ {"version":3,"file":"react.js","sources":["../../../libs/form-engine/src/adapters/react/useFormGroup.tsx"],"sourcesContent":["import { useEffect, useCallback, useState } from 'react';\n\nimport { TFormValues, THookReturn, TUseFormGroupProps } from '@react/types';\n\nimport { CoreEvents, ALL_NAMESPACE_EVENTS } from '@core';\nimport { getFormInstance, getGroupFormsIds } from '@core/managers';\nimport { EEVents } from '@core/constants';\n\nconst useFormGroup = ({\n group,\n onData,\n onClick,\n onSubmit,\n ids = [],\n}: TUseFormGroupProps): THookReturn => {\n const [formIds, setFormIds] = useState(group ? getGroupFormsIds(group) : ids);\n\n const onDataChange = useCallback(() => {\n const data = formIds.reduce(\n (acc, formId) => ({\n ...acc,\n [formId]: getFormInstance(formId).formData,\n }),\n {},\n );\n\n onData && onData(data);\n }, [onData]);\n\n const extractFormsData = (opts) => {\n return formIds.reduce(\n (acc, formId) => {\n if (opts?.aggregate) {\n return Object.keys(acc).reduce(\n (innerAcc, key) => ({\n ...innerAcc,\n [key]: {\n ...acc[key],\n ...getFormInstance(formId, opts).formData[key],\n },\n }),\n {},\n );\n }\n\n return { ...acc, [formId]: getFormInstance(formId, opts).formData };\n },\n {\n formatted: {},\n erroredFields: {},\n fields: {},\n form: {},\n predictableErroredFields: {},\n filteredFields: {},\n } as TFormValues,\n );\n };\n\n useEffect(() => {\n if (formIds.length || !group) return;\n setFormIds(getGroupFormsIds(group));\n }, [formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(EEVents.ON_FIELD_CHANGE, onDataChange),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(EEVents.ON_SCOPE_CHANGE, onDataChange),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(\n ALL_NAMESPACE_EVENTS(CoreEvents.ON_FIELD_REHYDRATE),\n onDataChange,\n ),\n );\n }, [onData, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(\n ALL_NAMESPACE_EVENTS(CoreEvents.ON_FIELD_CLICK),\n onClick,\n ),\n );\n }, [onClick, formIds]);\n\n useEffect(() => {\n formIds.map((formId) =>\n getFormInstance(formId).subscribe(\n CoreEvents.ON_FORM_SUBMIT,\n () => onSubmit && onSubmit(extractFormsData({})),\n ),\n );\n }, [onSubmit, formIds]);\n\n const submitForm = () =>\n formIds.map((formId) =>\n getFormInstance(formId).publish(CoreEvents.ON_FORM_SUBMIT),\n );\n\n return {\n submitForm,\n formData: extractFormsData,\n };\n};\n\nexport { useFormGroup };\n"],"names":["useFormGroup","group","onData","onClick","onSubmit","ids","formIds","setFormIds","useState","getGroupFormsIds","onDataChange","useCallback","data","reduce","acc","formId","Object","assign","getFormInstance","formData","extractFormsData","opts","aggregate","keys","innerAcc","key","formatted","erroredFields","fields","form","predictableErroredFields","filteredFields","useEffect","length","map","subscribe","ALL_NAMESPACE_EVENTS","CoreEvents","ON_FIELD_REHYDRATE","ON_FIELD_CLICK","ON_FORM_SUBMIT","submitForm","publish"],"mappings":"iWAQqBA,EACnBC,QACAC,SACAC,UACAC,WACAC,MAAM,OAEN,MAAOC,EAASC,GAAcC,EAAQA,SAACP,EAAQQ,mBAAiBR,GAASI,GAEnEK,EAAeC,EAAAA,aAAY,KAC/B,MAAMC,EAAON,EAAQO,QACnB,CAACC,EAAKC,IACDC,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAH,GACH,CAAAC,CAACA,GAASG,EAAAA,gBAAgBH,GAAQI,YAEpC,CAAE,GAGJjB,GAAUA,EAAOU,EAAK,GACrB,CAACV,IAEEkB,EAAoBC,GACjBf,EAAQO,QACb,CAACC,EAAKC,KACAM,eAAAA,EAAMC,WACDN,OAAOO,KAAKT,GAAKD,QACtB,CAACW,EAAUC,IACNT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAO,IACHC,CAACA,GACIT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAAH,EAAIW,IACJP,EAAeA,gBAACH,EAAQM,GAAMF,SAASM,OAG9C,CAAE,GAINT,OAAAC,OAAAD,OAAAC,OAAA,CAAA,EAAYH,GAAG,CAAEC,CAACA,GAASG,EAAeA,gBAACH,EAAQM,GAAMF,YAE3D,CACEO,UAAW,CAAE,EACbC,cAAe,CAAE,EACjBC,OAAQ,CAAE,EACVC,KAAM,CAAE,EACRC,yBAA0B,CAAE,EAC5BC,eAAgB,CAAE,IAKxBC,EAAAA,WAAU,MACJ1B,EAAQ2B,QAAWhC,GACvBM,EAAWE,EAAAA,iBAAiBR,GAAO,GAClC,CAACK,IAEJ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,kBAAgBH,GAAQoB,4BAAmCzB,IAC5D,GACA,CAACR,EAAQI,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,kBAAgBH,GAAQoB,4BAAmCzB,IAC5D,GACA,CAACR,EAAQI,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,EAAAA,gBAAgBH,GAAQoB,UACtBC,EAAAA,qBAAqBC,EAAAA,WAAWC,oBAChC5B,IAEH,GACA,CAACR,EAAQI,IAEZ0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,EAAAA,gBAAgBH,GAAQoB,UACtBC,EAAAA,qBAAqBC,EAAAA,WAAWE,gBAChCpC,IAEH,GACA,CAACA,EAASG,IAEb0B,EAAAA,WAAU,KACR1B,EAAQ4B,KAAKnB,GACXG,EAAeA,gBAACH,GAAQoB,UACtBE,EAAAA,WAAWG,gBACX,IAAMpC,GAAYA,EAASgB,EAAiB,CAAE,OAEjD,GACA,CAAChB,EAAUE,IAOd,MAAO,CACLmC,WANiBA,IACjBnC,EAAQ4B,KAAKnB,GACXG,EAAAA,gBAAgBH,GAAQ2B,QAAQL,aAAWG,kBAK7CrB,SAAUC,EACX"}
@@ -1,4 +1,4 @@
1
1
  import { ReactElement } from 'react';
2
- import { TAsFormFieldProps, TDecoratorProps } from '@react/types';
3
- declare const asFormField: <OriginalComponentProps>({ Comp, propsMapping }: TAsFormFieldProps) => ({ name, validations, errorMessages, masks, filter, formatters, visibilityConditions, formId, visibility, value, ...props }: TDecoratorProps<OriginalComponentProps>) => ReactElement;
2
+ import { TAsFormFieldProps, TDecoratorProps } from '../react/types';
3
+ declare const asFormField: <OriginalComponentProps>({ Comp, propsMapping }: TAsFormFieldProps) => ({ name, validations, errorMessages, masks, clearFields, api, filter, formatters, visibilityConditions, formId, visibility, value, ...props }: TDecoratorProps<OriginalComponentProps>) => ReactElement;
4
4
  export default asFormField;
@@ -1,5 +1,5 @@
1
1
  import React, { ReactElement } from 'react';
2
- import { TComponent, TErrorMessages, TSchemaValidation, TSchemaValidations, TSchema, THooks, TIVars, TFormValues, TField, TChildrenOptions, TPropsMapping, TComponentPropsMapping, TScope } from '@core/types';
2
+ import { TComponent, TErrorMessages, TSchemaValidation, TSchemaValidations, TSchema, THooks, TIVars, TFormValues, TField, TChildrenOptions, TPropsMapping, TComponentPropsMapping, TScope } from '../../core/types';
3
3
  import { TLoggingEvent } from '@core/events/events.types';
4
4
  declare type TFormProps = {
5
5
  /**
@@ -226,6 +226,12 @@ declare type TUseFormProps = {
226
226
  * @param data All the available form data
227
227
  */
228
228
  onData?(data: TFormValues | Record<string, TFormValues>): void;
229
+ /**
230
+ * Callback to be called when the form generates some new data
231
+ * @param data All the available form data
232
+ * @param field Current field which has clicked
233
+ */
234
+ onClick?(data: TFormValues | Record<string, TFormValues>, field: TField): void;
229
235
  /**
230
236
  * Callback to be called when the form submits
231
237
  * @param data All the available form data
@@ -246,6 +252,12 @@ declare type TUseFormGroupProps = {
246
252
  * @param data All the available form data
247
253
  */
248
254
  onData?(data: Record<string, TFormValues>): void;
255
+ /**
256
+ * Callback to be called when the form generates some new data
257
+ * @param data All the available form data
258
+ * @param field Current field which has clicked
259
+ */
260
+ onClick?(data: Record<string, TFormValues>, field: TField): void;
249
261
  /**
250
262
  * Callback to be called when the form submits
251
263
  * @param data All the available form data
@@ -272,9 +284,9 @@ interface TAsFormFieldProps {
272
284
  */
273
285
  Comp: (new () => React.Component) | any;
274
286
  /**
275
- * Link for the TPropsMapping likely props mapper from default form.
287
+ * Link for the TComponentPropsMapping likely props mapper from default form.
276
288
  */
277
- propsMapping: TPropsMapping;
289
+ propsMapping: TComponentPropsMapping;
278
290
  }
279
291
  declare type TDecorator = {
280
292
  /**
@@ -8,5 +8,5 @@ import { THookReturn, TUseFormProps } from '@react/types';
8
8
  * - A group of forms
9
9
  *
10
10
  */
11
- declare const useForm: ({ onValid, onData, onSubmit, id, ids, }: TUseFormProps) => THookReturn;
11
+ declare const useForm: ({ onValid, onData, onClick, onSubmit, id, ids, }: TUseFormProps) => THookReturn;
12
12
  export default useForm;
@@ -1,3 +1,3 @@
1
1
  import { THookReturn, TUseFormGroupProps } from '@react/types';
2
- declare const useFormGroup: ({ group, onData, onSubmit, ids, }: TUseFormGroupProps) => THookReturn;
2
+ declare const useFormGroup: ({ group, onData, onClick, onSubmit, ids, }: TUseFormGroupProps) => THookReturn;
3
3
  export { useFormGroup };