π οΈ Block Overriding Guide
β¨ Overviewβ
Nodeblocks components provide powerful customization capabilities through block overriding. This pattern allows you to completely customize the structure, styling, and behavior of components while maintaining the underlying functionality.
This guide uses the CreateOrganization component as an example, but the same patterns apply to all Nodeblocks components that support block overriding.
π Basic Overriding Patternβ
The block override pattern uses a render function that receives defaultBlocks and defaultBlockOrder, allowing you to modify or replace any block:
<CreateOrganization onCreateOrganization={handleSubmit}>
{({defaultBlocks, defaultBlockOrder}) => ({
blocks: {
...defaultBlocks,
// Override specific blocks here
},
blockOrder: defaultBlockOrder
})}
</CreateOrganization>
π¨ Styling Customization Exampleβ
Customize the visual appearance of blocks using the sx prop (MUI) or inline style:
function StyledOrganizationForm() { return ( <CreateOrganization onCreateOrganization={console.log} termsOfUseUrl="#terms-of-service" privacyAgreementUrl="#privacy-policy" > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { title: { ...defaultBlocks.title, props: { ...defaultBlocks.title.props, children: 'π’ Organization Registration', sx: { background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', }, }, }, description: { ...defaultBlocks.description, props: { ...defaultBlocks.description.props, children: 'Complete the form below to create your organization profile', }, }, form: { ...defaultBlocks.form, props: { ...defaultBlocks.form.props, sx: { background: 'rgba(255, 255, 255, 0.9)', borderRadius: '20px', padding: '24px', boxShadow: '0 8px 32px rgba(0,0,0,0.08)', }, }, }, }, blockOrder: defaultBlockOrder, })} </CreateOrganization> ); }
π§ Complete Customization Exampleβ
Here's a comprehensive example demonstrating nested block overriding with custom labels, styling, and field configuration:
function AdvancedOrganizationForm() { return ( <CreateOrganization onCreateOrganization={(formData) => { console.log('Organization data:', formData); }} termsOfUseUrl="#terms" privacyAgreementUrl="#privacy" > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { // Custom Title title: { ...defaultBlocks.title, props: { ...defaultBlocks.title.props, children: 'π’ Company Registration', }, }, // Custom Description description: { ...defaultBlocks.description, props: { ...defaultBlocks.description.props, children: 'Please complete all required fields to register your organization', }, }, // Nested Form Override form: { ...defaultBlocks.form, props: { ...defaultBlocks.form.props, children({defaultBlocks, defaultBlockOrder}) { return { blocks: { // Override Account Holder section accountHolder: { ...defaultBlocks.accountHolder, props: { ...defaultBlocks.accountHolder.props, children({defaultBlocks}) { return { blocks: { sectionTitle: { ...defaultBlocks.sectionTitle, props: { ...defaultBlocks.sectionTitle.props, children: 'π€ Account Holder Details', }, }, nameField: { ...defaultBlocks.nameField, props: { ...defaultBlocks.nameField.props, label: 'Full Name', placeholder: 'Enter your full name', }, }, emailField: { ...defaultBlocks.emailField, props: { ...defaultBlocks.emailField.props, label: 'Business Email', placeholder: 'company@example.com', }, }, contactField: { ...defaultBlocks.contactField, props: { ...defaultBlocks.contactField.props, label: 'Contact Number', placeholder: '+1 (555) 000-0000', }, }, }, blockOrder: ['sectionTitle', 'nameField', 'emailField', 'contactField'], }; }, }, }, // Override Company Information section companyInformation: { ...defaultBlocks.companyInformation, props: { ...defaultBlocks.companyInformation.props, children({defaultBlocks}) { return { blocks: { sectionTitle: { ...defaultBlocks.sectionTitle, props: { ...defaultBlocks.sectionTitle.props, children: 'π’ Company Details', }, }, companyName: { ...defaultBlocks.companyName, props: { ...defaultBlocks.companyName.props, label: 'Company Name', placeholder: 'Acme Corporation', }, }, homePageUrl: { ...defaultBlocks.homePageUrl, props: { ...defaultBlocks.homePageUrl.props, label: 'Website URL', placeholder: 'https://www.example.com', }, }, additionalInformation: { ...defaultBlocks.additionalInformation, props: { ...defaultBlocks.additionalInformation.props, label: 'Company Description', placeholder: 'Brief description of your company...', }, }, }, // Custom block order - showing only selected fields blockOrder: ['sectionTitle', 'companyName', 'homePageUrl', 'additionalInformation'], }; }, }, }, // Custom Submit Button submitButton: { ...defaultBlocks.submitButton, props: { ...defaultBlocks.submitButton.props, children: 'π Register Organization', }, }, }, // Custom form section order blockOrder: ['accountHolder', 'companyInformation', 'compliance', 'submitButton'], }; }, }, }, }, blockOrder: defaultBlockOrder, })} </CreateOrganization> ); }
π― Key Overriding Conceptsβ
1. Block Override Structureβ
| Property | Description |
|---|---|
blocks | Object containing component definitions that can be modified or replaced |
blockOrder | Array controlling the render sequence of blocks |
defaultBlocks | Original component structure provided by the library |
defaultBlockOrder | Original render sequence for reference |
2. Nested Overridingβ
For components with nested structures (like forms with sections), use the children prop to access nested blocks:
form: {
...defaultBlocks.form,
props: {
...defaultBlocks.form.props,
children({defaultBlocks, defaultBlockOrder}) {
return {
blocks: {
// Override nested blocks here
},
blockOrder: defaultBlockOrder,
};
}
}
}
3. Complete Block Replacementβ
Replace a default block with a completely custom component:
blocks: {
description: <p className="custom-description">Your custom content here</p>,
}
4. Selective Field Displayβ
Control which fields appear by modifying blockOrder:
// Show only specific fields in AccountHolder section
blockOrder: ['sectionTitle', 'nameField', 'emailField']
// Show only specific fields in CompanyInformation section
blockOrder: ['sectionTitle', 'companyName', 'homePageUrl', 'additionalInformation']
π Best Practicesβ
-
Always spread default props to maintain existing functionality:
props: { ...defaultBlocks.title.props, children: 'Custom Title' } -
Use meaningful block names for better maintainability
-
Maintain blockOrder consistency unless intentionally reordering or removing fields
-
Leverage TypeScript for type safety with block override functions
-
Test thoroughly when customizing validation or form behavior
π Benefitsβ
| Benefit | Description |
|---|---|
| π¨ Complete UI Control | Customize every aspect of the component's appearance |
| π§ Flexible Structure | Reorder, remove, or add blocks as needed |
| π± Preserve Functionality | Keep built-in validation, state management, and accessibility |
| π Progressive Enhancement | Start with defaults and customize incrementally |
Pro Tip: Start with small overrides (like changing labels or styles) and gradually build complexity. The block overriding pattern is powerful but requires careful attention to prop spreading and component structure.