|
24 | 24 | import cloneDeep from 'lodash/cloneDeep';
|
25 | 25 | import isEmpty from 'lodash/isEmpty';
|
26 | 26 | import isEqual from 'lodash/isEqual';
|
27 |
| -import {useContext, useRef} from 'react'; |
28 |
| -import {Form} from 'react-formio'; |
| 27 | +import {Suspense, lazy, useContext, useRef} from 'react'; |
29 | 28 | import {useIntl} from 'react-intl';
|
30 | 29 | import {useNavigate, useParams} from 'react-router-dom';
|
31 | 30 | import {useAsync} from 'react-use';
|
@@ -55,6 +54,17 @@ import useTitle from 'hooks/useTitle';
|
55 | 54 |
|
56 | 55 | import {doLogicCheck, getCustomValidationHook, submitStepData} from './data';
|
57 | 56 |
|
| 57 | +// Dynamically import react-formio and use React.lazy to facilitate bundle splitting |
| 58 | +// into separate chunks. |
| 59 | +const Form = lazy(async () => { |
| 60 | + // this should already have been resolved the the sdk.jsx entrypoint :) |
| 61 | + const {Form, initializeFormio} = await import('formio-init'); |
| 62 | + // side effect to ensure our custom templates/module are set up |
| 63 | + initializeFormio(); |
| 64 | + // React.lazy must yield a 'default export' |
| 65 | + return {default: Form}; |
| 66 | +}); |
| 67 | + |
58 | 68 | /**
|
59 | 69 | * Debounce interval in milliseconds (1000ms equals 1s) to prevent excessive amount of logic checks.
|
60 | 70 | * @type {number}
|
@@ -768,64 +778,66 @@ const FormStep = () => {
|
768 | 778 | headingType="subtitle"
|
769 | 779 | modifiers={['padded']}
|
770 | 780 | />
|
771 |
| - <form onSubmit={onReactSubmit} noValidate> |
772 |
| - <Form |
773 |
| - ref={formRef} |
774 |
| - form={configuration} |
775 |
| - onChange={onFormIOChange} |
776 |
| - onSubmit={onFormIOSubmit} |
777 |
| - onInitialized={onFormIOInitialized} |
778 |
| - options={{ |
779 |
| - noAlerts: true, |
780 |
| - baseUrl: config.baseUrl, |
781 |
| - language: formioTranslations.language, |
782 |
| - i18n: formioTranslations.i18n, |
783 |
| - evalContext: { |
784 |
| - ofPrefix: `${PREFIX}-`, |
785 |
| - requiredFieldsWithAsterisk: config.requiredFieldsWithAsterisk, |
786 |
| - }, |
787 |
| - hooks: { |
788 |
| - customValidation: getCustomValidationHook(submissionStep.url, error => |
789 |
| - dispatch({type: 'ERROR', payload: error}) |
790 |
| - ), |
791 |
| - }, |
792 |
| - // custom options |
793 |
| - intl, |
794 |
| - ofContext: { |
795 |
| - form: form, |
796 |
| - submissionUuid: submission.id, |
797 |
| - submissionUrl: submission.url, |
798 |
| - saveStepData: async () => |
799 |
| - await submitStepData(submissionStep.url, {...getCurrentFormData()}), |
800 |
| - verifyEmailCallback: ({key, email}) => { |
801 |
| - // clear the errors from the component |
802 |
| - const formInstance = formRef.current.formio; |
803 |
| - const component = formInstance.getComponent(key); |
804 |
| - component.setCustomValidity(''); |
805 |
| - |
806 |
| - dispatch({ |
807 |
| - type: 'VERIFY_EMAIL', |
808 |
| - payload: {componentKey: key, emailAddress: email}, |
809 |
| - }); |
| 781 | + <Suspense fallback={<Loader modifiers={['centered']} />}> |
| 782 | + <form onSubmit={onReactSubmit} noValidate> |
| 783 | + <Form |
| 784 | + ref={formRef} |
| 785 | + form={configuration} |
| 786 | + onChange={onFormIOChange} |
| 787 | + onSubmit={onFormIOSubmit} |
| 788 | + onInitialized={onFormIOInitialized} |
| 789 | + options={{ |
| 790 | + noAlerts: true, |
| 791 | + baseUrl: config.baseUrl, |
| 792 | + language: formioTranslations.language, |
| 793 | + i18n: formioTranslations.i18n, |
| 794 | + evalContext: { |
| 795 | + ofPrefix: `${PREFIX}-`, |
| 796 | + requiredFieldsWithAsterisk: config.requiredFieldsWithAsterisk, |
| 797 | + }, |
| 798 | + hooks: { |
| 799 | + customValidation: getCustomValidationHook(submissionStep.url, error => |
| 800 | + dispatch({type: 'ERROR', payload: error}) |
| 801 | + ), |
| 802 | + }, |
| 803 | + // custom options |
| 804 | + intl, |
| 805 | + ofContext: { |
| 806 | + form: form, |
| 807 | + submissionUuid: submission.id, |
| 808 | + submissionUrl: submission.url, |
| 809 | + saveStepData: async () => |
| 810 | + await submitStepData(submissionStep.url, {...getCurrentFormData()}), |
| 811 | + verifyEmailCallback: ({key, email}) => { |
| 812 | + // clear the errors from the component |
| 813 | + const formInstance = formRef.current.formio; |
| 814 | + const component = formInstance.getComponent(key); |
| 815 | + component.setCustomValidity(''); |
| 816 | + |
| 817 | + dispatch({ |
| 818 | + type: 'VERIFY_EMAIL', |
| 819 | + payload: {componentKey: key, emailAddress: email}, |
| 820 | + }); |
| 821 | + }, |
810 | 822 | },
|
811 |
| - }, |
812 |
| - }} |
813 |
| - /> |
814 |
| - {config.debug ? <FormStepDebug data={getCurrentFormData()} /> : null} |
815 |
| - <ButtonsToolbar |
816 |
| - canSubmitStep={canSubmit} |
817 |
| - canSubmitForm={submission.submissionAllowed} |
818 |
| - canSuspendForm={form.suspensionAllowed} |
819 |
| - isAuthenticated={submission.isAuthenticated} |
820 |
| - isLastStep={isLastStep(currentStepIndex, submission)} |
821 |
| - isCheckingLogic={logicChecking} |
822 |
| - loginRequired={form.loginRequired} |
823 |
| - onFormSave={onFormSave} |
824 |
| - onNavigatePrevPage={onPrevPage} |
825 |
| - previousPage={previousPage} |
826 |
| - onDestroySession={onDestroySession} |
827 |
| - /> |
828 |
| - </form> |
| 823 | + }} |
| 824 | + /> |
| 825 | + {config.debug ? <FormStepDebug data={getCurrentFormData()} /> : null} |
| 826 | + <ButtonsToolbar |
| 827 | + canSubmitStep={canSubmit} |
| 828 | + canSubmitForm={submission.submissionAllowed} |
| 829 | + canSuspendForm={form.suspensionAllowed} |
| 830 | + isAuthenticated={submission.isAuthenticated} |
| 831 | + isLastStep={isLastStep(currentStepIndex, submission)} |
| 832 | + isCheckingLogic={logicChecking} |
| 833 | + loginRequired={form.loginRequired} |
| 834 | + onFormSave={onFormSave} |
| 835 | + onNavigatePrevPage={onPrevPage} |
| 836 | + previousPage={previousPage} |
| 837 | + onDestroySession={onDestroySession} |
| 838 | + /> |
| 839 | + </form> |
| 840 | + </Suspense> |
829 | 841 | </>
|
830 | 842 | ) : null}
|
831 | 843 | </Card>
|
|
0 commit comments