Skip to main content

🎨 Block Overriding Guide

✨ Overview

The CreateOrganization component provides powerful customization capabilities through block overriding. This pattern allows you to customize the form structure and UI components while preserving the shared form state handling.

🚀 Basic Overriding Pattern

function Example() {
const defaultData = {
applicationUserName: '',
applicationUserEmail: '',
applicationUserPhoneNumber: '',
companyName: '',
postcode: '',
cityTownVillage: '',
townStreetBuilding: '',
representivePersonName: '',
representativePhoneNumber: '',
companyUrl: '',
additionalInformation: '',
establishmentDate: '',
prefecture: '',
capital: '',
numberOfEmployees: '',
userAgreement: '',
privacyPolicy: '',
};

const [data, setData] = React.useState(defaultData);

return (
<CreateOrganization data={data} onDataChange={setData}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
customNotice: (
<div
style={{
width: '100%',
border: '1px solid #cddcff',
borderRadius: 8,
padding: 12,
background: '#eef4ff',
fontSize: 14,
}}
>
Custom notification added via the block override pattern
</div>
),
},
blockOrder: ['customNotice', ...defaultBlockOrder],
})}
</CreateOrganization>
);
}

🔧 Complete Customization Example

Here's a real-world example showcasing deep nested block overrides with CreateOrganization:

Live Editor
function Example() {
  const defaultData = {
    applicationUserName: '',
    applicationUserEmail: '',
    applicationUserPhoneNumber: '',
    companyName: '',
    postcode: '',
    cityTownVillage: '',
    townStreetBuilding: '',
    representivePersonName: '',
    representativePhoneNumber: '',
    companyUrl: '',
    additionalInformation: '',
    establishmentDate: '',
    prefecture: '',
    capital: '',
    numberOfEmployees: '',
    userAgreement: '',
    privacyPolicy: '',
  };

  const [data, setData] = React.useState(defaultData);

  return (
    <CreateOrganization
      data={data}
      onDataChange={setData}
      termsOfUseUrl="/terms-of-use"
      privacyAgreementUrl="/privacy-policy"
      onSearchAddressClick={() => {
        setData((current) => ({ ...current }));
      }}
      onSubmit={(event) => {
        event.preventDefault();
        setData((current) => ({ ...current }));
      }}
    >
      {({ defaultBlocks, defaultBlockOrder }) => ({
        blocks: {
          ...defaultBlocks,
          title: {
            ...defaultBlocks.title,
            props: {
              ...defaultBlocks.title.props,
              children: 'Apply for your organization',
            },
          },
          description: {
            ...defaultBlocks.description,
            props: {
              ...defaultBlocks.description.props,
              children: 'Use the form below to register a new organization.',
            },
          },
          form: {
            ...defaultBlocks.form,
            props: {
              ...defaultBlocks.form.props,
              children({ defaultBlocks: formBlocks, defaultBlockOrder: formBlockOrder }) {
                return {
                  blocks: {
                    ...formBlocks,
                    accountHolder: {
                      ...formBlocks.accountHolder,
                      props: {
                        ...formBlocks.accountHolder.props,
                        children({ defaultBlocks: accountHolderBlocks, defaultBlockOrder: accountHolderBlockOrder }) {
                          return {
                            blocks: {
                              ...accountHolderBlocks,
                              sectionTitle: {
                                ...accountHolderBlocks.sectionTitle,
                                props: {
                                  ...accountHolderBlocks.sectionTitle.props,
                                  children: 'Account holder',
                                },
                              },
                              emailField: {
                                ...accountHolderBlocks.emailField,
                                props: {
                                  ...accountHolderBlocks.emailField.props,
                                  label: 'Email address',
                                },
                              },
                            },
                            blockOrder: accountHolderBlockOrder,
                          };
                        },
                      },
                    },
                    companyInformation: {
                      ...formBlocks.companyInformation,
                      props: {
                        ...formBlocks.companyInformation.props,
                        children({
                          defaultBlocks: companyInformationBlocks,
                          defaultBlockOrder: companyInformationBlockOrder,
                        }) {
                          return {
                            blocks: {
                              ...companyInformationBlocks,
                              sectionTitle: {
                                ...companyInformationBlocks.sectionTitle,
                                props: {
                                  ...companyInformationBlocks.sectionTitle.props,
                                  children: 'Company information',
                                },
                              },
                              companyAddress: {
                                ...companyInformationBlocks.companyAddress,
                                props: {
                                  ...companyInformationBlocks.companyAddress.props,
                                  children({
                                    defaultBlocks: companyAddressBlocks,
                                    defaultBlockOrder: companyAddressBlockOrder,
                                  }) {
                                    return {
                                      blocks: {
                                        ...companyAddressBlocks,
                                        locationTitle: {
                                          ...companyAddressBlocks.locationTitle,
                                          props: {
                                            ...companyAddressBlocks.locationTitle.props,
                                            children: 'Head office location',
                                          },
                                        },
                                        postCode: {
                                          ...companyAddressBlocks.postCode,
                                          props: {
                                            ...companyAddressBlocks.postCode.props,
                                            searchAddressLabel: 'Find address',
                                          },
                                        },
                                        representativeContact: {
                                          ...companyAddressBlocks.representativeContact,
                                          props: {
                                            ...companyAddressBlocks.representativeContact.props,
                                            placeholder: 'Representative phone number',
                                          },
                                        },
                                      },
                                      blockOrder: companyAddressBlockOrder,
                                    };
                                  },
                                },
                              },
                              companyCapital: {
                                ...companyInformationBlocks.companyCapital,
                                props: {
                                  ...companyInformationBlocks.companyCapital.props,
                                  label: 'Paid-in capital',
                                },
                              },
                              companySize: {
                                ...companyInformationBlocks.companySize,
                                props: {
                                  ...companyInformationBlocks.companySize.props,
                                  label: 'Team size',
                                },
                              },
                            },
                            blockOrder: companyInformationBlockOrder,
                          };
                        },
                      },
                    },
                    compliance: {
                      ...formBlocks.compliance,
                      props: {
                        ...formBlocks.compliance.props,
                        children({ defaultBlocks: complianceBlocks, defaultBlockOrder: complianceBlockOrder }) {
                          return {
                            blocks: {
                              ...complianceBlocks,
                              checkUserAgreement: {
                                ...complianceBlocks.checkUserAgreement,
                                props: {
                                  ...complianceBlocks.checkUserAgreement.props,
                                  label: (
                                    <>
                                      I agree to the <strong>terms of use</strong>.
                                    </>
                                  ),
                                },
                              },
                              checkPrivacyAgreement: {
                                ...complianceBlocks.checkPrivacyAgreement,
                                props: {
                                  ...complianceBlocks.checkPrivacyAgreement.props,
                                  label: (
                                    <>
                                      I agree to the <strong>privacy policy</strong>.
                                    </>
                                  ),
                                },
                              },
                            },
                            blockOrder: complianceBlockOrder,
                          };
                        },
                      },
                    },
                    submitButton: {
                      ...formBlocks.submitButton,
                      props: {
                        ...formBlocks.submitButton.props,
                        children: 'Submit organization',
                      },
                    },
                  },
                  blockOrder: formBlockOrder,
                };
              },
            },
          },
        },
        blockOrder: defaultBlockOrder,
      })}
    </CreateOrganization>
  );
}
Result
Loading...

🎯 Key Overriding Concepts

1. Block Override Structure

  • blocks: Object containing component definitions
  • blockOrder: Array controlling render sequence
  • defaultBlocks: Original component structure
  • defaultBlockOrder: Original render sequence

2. Nested Overriding

form: {
...defaultBlocks.form,
props: {
...defaultBlocks.form.props,
children({defaultBlocks, defaultBlockOrder}) {
// Nested block overriding here
}
}
}

3. Custom Components

Replace default blocks with completely custom components:

customField: <MyCustomComponent {...props} />

📐 Best Practices

  1. Always spread default props to maintain existing functionality
  2. Use meaningful block names for better maintainability
  3. Maintain blockOrder consistency unless intentionally reordering
  4. Implement proper validation for custom fields
  5. Handle loading and error states appropriately

🚀 Benefits

  • 🎨 Complete UI Control: Customize every aspect of the form
  • 🔧 Flexible Validation: Implement custom validation logic
  • 📱 Responsive Design: Maintain responsive behavior
  • 🔄 State Management: Full control over form state

Pro Tip: Start with small overrides and gradually build complexity. The block overriding pattern is powerful but requires careful attention to prop spreading and component structure.