UNPKG

extended-dynamic-forms

Version:

Extended React JSON Schema Form (RJSF) v6 with custom components, widgets, templates, layouts, and form events

1,156 lines (935 loc) โ€ข 37.4 kB
# Extended Dynamic Forms **A revolutionary extension library for [React JSON Schema Form (RJSF)](https://github.com/rjsf-team/react-jsonschema-form)** that transforms schema-driven forms into sophisticated, enterprise-ready applications with O(N) performance and professional UI components. Built on top of the excellent RJSF v6 foundation, this library introduces the **Three Pillars v2 Architecture** for conditional logic, multi-step wizard orchestration, central event systems with webhook integration, and a comprehensive suite of 25+ Ant Design components. [![npm version](https://img.shields.io/npm/v/extended-dynamic-forms.svg)](https://www.npmjs.com/package/extended-dynamic-forms) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/user/extended-dynamic-forms/blob/main/LICENSE) [![Built on RJSF](https://img.shields.io/badge/built%20on-RJSF%20v6-brightgreen)](https://github.com/rjsf-team/react-jsonschema-form) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![Standalone JS](https://img.shields.io/badge/Vanilla%20JS-Supported-orange.svg)](#standalone-javascript-support) ## Why Extended Dynamic Forms? While [RJSF](https://github.com/rjsf-team/react-jsonschema-form) provides an excellent foundation for generating forms from JSON Schema, enterprise applications demand more sophisticated capabilities: ### ๐Ÿš€ **Performance Revolution** - **O(N) Conditional Logic**: Advanced Three Pillars v2 architecture vs traditional O(Mร—N) systems - **Optimized Array Processing**: Per-item evaluation with dynamic array conditionals - **Memory Efficient**: Immutable schema processing with intelligent caching ### ๐ŸŽฏ **Enterprise-Grade Features** - **Complex Conditional Logic**: Multi-field dependencies, nested conditions, and dynamic validation - **Multi-Step Workflows**: Automatic wizard detection with step-aware conditional logic - **Real-Time Integration**: Production-ready webhooks with retry logic and error isolation - **Professional UI**: Comprehensive suite of enhanced Ant Design components with consistent styling ### ๐Ÿ”„ **Developer Experience** - **Dual Architecture Support**: Modern React hooks + vanilla JavaScript compatibility - **Type-Safe Throughout**: Comprehensive TypeScript interfaces and validation - **Rich Ecosystem**: Interactive playground with comprehensive real-world demos - **Migration Ready**: Automated v1-to-v2 conversion utilities This library transforms RJSF from a simple form generator into a complete enterprise form solution while preserving its declarative approach. ## Core Features ### ๐Ÿš€ Three Pillars v2 Architecture (Recommended) - **UI Logic Pillar**: Control form appearance with JSON Patch operations - **Schema Logic Pillar**: Modify data structure when truly needed - **Validation Logic Pillar**: Dynamic validation rules without schema changes - **O(N) Performance**: Superior array handling vs v1's O(Mร—N) - **React Hooks**: Modern, declarative API with `useConditionalUi`, `useConditionalSchema`, `useConditionalValidation` ### ๐ŸŽฏ Declarative Conditional Logic - Define complex form behavior without code - Dynamic array support with per-item evaluation - Compatible with `json-rules-engine` format - Built-in migration utilities from v1 to v2 For example, you can integrate existing business logic: ```tsx import { engine } from './rules-engine'; // Your configured json-rules-engine instance const uiRules: UiRule[] = [{ name: 'Apply business logic for premium users', // The condition can be a promise-based async function condition: async (formData) => { const { events } = await engine.run(formData); return events.some(event => event.type === 'show-premium-feature'); }, effect: [...] }]; ``` ### ๐Ÿง™โ€โ™‚๏ธ Multi-Step Wizard Forms - Automatic step detection from schema structure - **Full conditional logic support** with step-aware rule processing - Built-in progress indicators and navigation - Per-step validation - Supports both v1 conditions (deprecated) and v2 Three Pillars architecture **Step-Aware Conditional Logic** The `WizardForm` automatically filters and transforms conditional rules to work within the current step's context. This means you can define conditions that reference fields across different steps, and the wizard will intelligently apply only the relevant rules for the active step: ```tsx // Define steps with prefixed field names to avoid collisions const schema = { type: 'object', properties: { STEP_PERSONAL: { type: 'object', title: 'Personal Information', properties: { isUSCitizen: { type: 'boolean', title: 'Are you a US Citizen?' }, ssn: { type: 'string', title: 'Social Security Number' } } } // ... other steps } }; // Use v2 UiRules to handle step-aware conditionals const uiRules: UiRule[] = [{ name: 'Show SSN only for US Citizens in Personal step', condition: (formData) => !formData.STEP_PERSONAL?.isUSCitizen, effect: [ { op: 'add', path: '/STEP_PERSONAL/properties/ssn/ui:widget', value: 'hidden' } ] }]; // The WizardForm handles the step isolation automatically ``` ### ๐Ÿ”— Central Event Orchestration - Unified event system for all field interactions - Webhook integration with retry logic - Real-time form analytics capabilities - Debounced event processing ### ๐ŸŽจ Ant Design Components - Complete widget suite built with Ant Design v5 - Enhanced standard widgets with event integration - Custom widgets: Rating, Color Picker, Range Slider - Professional field components: Address, Phone, Currency ### โšก Form Lifecycle Hooks - Intercept and modify form data at key stages - `beforeSubmit`, `afterSubmit`, `beforeValidation`, `afterValidation` - Ideal for data transformation, logging, or triggering side effects ### ๐Ÿ“ฆ Additional Features - **TypeScript**: Full type safety and IntelliSense with comprehensive interface definitions - **Performance**: Optimized re-renders and memoization with intelligent caching - **Extensible**: Add custom widgets, fields, and actions with clean APIs - **Well-Tested**: Extensive test suite covering all major features and edge cases - **Developer Experience**: Interactive playground with dozens of real-world demos ### ๐ŸŒ Standalone JavaScript Support **Complete vanilla JavaScript compatibility** with a production-ready UMD bundle that includes React, Ant Design, and all dependencies: ```html <!DOCTYPE html> <html> <head> <script src="https://unpkg.com/extended-dynamic-forms/dist/standalone.umd.js"></script> <link rel="stylesheet" href="https://unpkg.com/extended-dynamic-forms/dist/style.css"> </head> <body> <div id="form-container"></div> <script> const { createForm, createWizard } = ExtendedDynamicForms; // Create a complete form without React knowledge const form = createForm({ schema: { type: 'object', properties: { name: { type: 'string', title: 'Full Name' }, email: { type: 'string', format: 'email', title: 'Email' } } }, container: document.getElementById('form-container'), onSubmit: (data) => console.log('Form submitted:', data) }); </script> </body> </html> ``` **Important Notes on Conditional Logic in Vanilla JS:** - **Only v1 conditions are supported** - The Three Pillars v2 architecture requires React hooks - Use the `conditionals` prop with v1 format: `{ rules: [...] }` - Subject to v1's O(Mร—N) performance for array conditionals - For v2 benefits, use the React-based API instead ```javascript // Vanilla JS supports only v1 conditionals ExtendedDynamicForms.createForm({ container: '#my-form', schema: schema, conditionals: { rules: [ { conditions: { showField: true }, event: { type: 'show', params: { field: 'conditionalField' } } } ] } }); ``` **Perfect for:** - WordPress/Drupal integrations - Legacy applications - CMS form builders - No-build environments - PHP/ASP.NET applications ## Credits & Acknowledgments This library is built on top of [React JSON Schema Form (RJSF)](https://github.com/rjsf-team/react-jsonschema-form), an amazing open-source project that provides the core form generation engine. We extend RJSF's capabilities while maintaining full compatibility with its ecosystem. Special thanks to the RJSF team and contributors for creating such a flexible and well-architected foundation. ## Installation ### React Projects ```bash npm install extended-dynamic-forms # or yarn add extended-dynamic-forms # or pnpm add extended-dynamic-forms ``` ### Standalone JavaScript (No Build Required) ```html <!-- Production CDN --> <script src="https://unpkg.com/extended-dynamic-forms@latest/dist/standalone.umd.js"></script> <link rel="stylesheet" href="https://unpkg.com/extended-dynamic-forms@latest/dist/style.css"> <!-- Or download and host locally --> <script src="./path/to/extended-dynamic-forms-standalone.js"></script> ``` ### Peer Dependencies **Current Version**: `0.1.19` - Optimized for **RJSF v6** with Three Pillars v2 architecture. ```json { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "antd": "^5.24.0" } ``` > **React 19 Support**: This library supports both React 18 and React 19. See [REACT-19-COMPATIBILITY.md](./REACT-19-COMPATIBILITY.md) for migration details. **RJSF Dependencies** (automatically handled): - `@rjsf/core`: ^6.0.0+ - `@rjsf/utils`: ^6.0.0+ - `@rjsf/validator-ajv8`: ^6.0.0+ - `@rjsf/antd`: ^6.0.0+ > **Development Note**: This library is currently developed against RJSF v6 and includes all necessary RJSF dependencies. No additional RJSF packages need to be installed separately. **Additional Dependencies**: - `dayjs`: ^1.11.13 (Date handling) - `json-rules-engine-simplified`: ^0.2.0 (v1 conditional logic) > **Note**: This library is specifically built for RJSF v6 to leverage the latest performance improvements and API enhancements. All examples and documentation assume RJSF v6. ## Setup ### CSS Requirements This package uses Ant Design components. Import the CSS in your application: ```tsx // In your main entry file (e.g., App.tsx or index.tsx) import 'extended-dynamic-forms/dist/style.css'; // Or your specific CSS entry point ``` ### Theming & Customization Since Extended Dynamic Forms uses Ant Design components, you can customize the appearance using Ant Design's powerful theming system: ```tsx import { ConfigProvider, theme } from 'antd'; import { ExtendedForm, WizardForm } from 'extended-dynamic-forms'; function App() { return ( <ConfigProvider theme={{ token: { colorPrimary: '#00b96b', borderRadius: 8, fontSize: 16, }, algorithm: theme.darkAlgorithm, // Optional: Use dark theme }} > <WizardForm schema={schema} uiSchema={uiSchema} conditionals={conditionals} /> </ConfigProvider> ); } ``` ## Three Pillars v2 Architecture (Recommended Approach) > โš ๏ธ **IMPORTANT**: The v1 conditional system is deprecated. We strongly recommend using the Three Pillars v2 architecture for all new implementations. The Three Pillars v2 system provides superior performance, cleaner separation of concerns, and better maintainability. It consists of three independent pillars: ### 1. UI Logic Pillar (`useConditionalUi`) Controls form appearance using JSON Patch operations: ```tsx // Note: v2 conditionals require deep import for optimal tree-shaking import { useConditionalUi, UiRule } from 'extended-dynamic-forms/conditionals/v2'; // Define UI rules with JSON Patch operations const uiRules: UiRule[] = [ { name: 'Show shipping address when required', condition: (formData) => formData.requiresShipping === true, effect: [{ op: 'remove', path: '/shippingAddress/ui:widget' }], order: 1 }, { name: 'Dynamic country fields', condition: (formData) => formData.shippingAddress?.country === 'USA', effect: [ { op: 'remove', path: '/shippingAddress/state/ui:widget' }, { op: 'add', path: '/shippingAddress/province/ui:widget', value: 'hidden' } ], order: 2 } ]; const baseUiSchema = { shippingAddress: { 'ui:widget': 'hidden', // Initially hidden state: { 'ui:widget': 'text' }, province: { 'ui:widget': 'hidden' } // Initially hidden } }; // In your component function MyForm() { const [formData, setFormData] = useState({}); // IMPORTANT: Define rules outside render or memoize them! const conditionalUiSchema = useConditionalUi(uiRules, baseUiSchema, formData); return ( <ExtendedForm schema={schema} uiSchema={conditionalUiSchema} formData={formData} onChange={({ formData }) => setFormData(formData)} /> ); } ``` ### 2. Schema Logic Pillar (`useConditionalSchema`) Modifies JSON Schema structure (use sparingly - prefer UI or Validation pillars): ```tsx import { useConditionalSchema, SchemaRule } from 'extended-dynamic-forms/conditionals/v2'; const schemaRules: SchemaRule[] = [ { name: 'Add premium fields', condition: (formData) => formData.accountType === 'premium', effect: [ { op: 'add', path: '/properties/premiumFeatures', value: { type: 'object', properties: { priority: { type: 'string', enum: ['high', 'medium', 'low'] } } } } ] } ]; const conditionalSchema = useConditionalSchema(schemaRules, baseSchema, formData); ``` ### 3. Validation Logic Pillar (`useConditionalValidation`) Adds conditional validation without modifying schema: ```tsx import { useMemo } from 'react'; import { useConditionalValidation, ValidationRule, createCustomValidate } from 'extended-dynamic-forms/conditionals/v2'; const validationRules: ValidationRule[] = [ { name: 'Require consent for minors', condition: (formData) => formData.age < 18, effect: { type: 'validation', validate: (errors, formData) => { if (!formData.parentConsent) { errors.parentConsent.addError('Parent consent is required for minors'); } } } } ]; // In your component function MyForm({ schema }) { const [formData, setFormData] = useState({}); // 1. Get the conditional validation configuration const conditionalValidationConfig = useConditionalValidation(validationRules, {}, formData); // 2. Create the memoized validate function const customValidate = useMemo( () => createCustomValidate(conditionalValidationConfig), [conditionalValidationConfig] ); // 3. Use with ExtendedForm return ( <ExtendedForm schema={schema} formData={formData} onChange={({ formData }) => setFormData(formData)} customValidate={customValidate} /> ); } ``` ### Dynamic Arrays with O(N) Performance #### **The Performance Revolution: `createDynamicArrayItemsUiSchema`** One of the most significant breakthroughs in v2 is the `createDynamicArrayItemsUiSchema` function, which enables **true O(N) performance** for array conditionals. This is a fundamental improvement over traditional form libraries that struggle with dynamic array logic. **How It Works:** - **Per-Item Evaluation**: Each array item's conditionals are evaluated independently during render - **No Rule Explosion**: Unlike v1's wildcard expansion, no rules are multiplied by array size - **React-Optimized**: Leverages React's rendering cycle for optimal performance ```tsx import { createDynamicArrayItemsUiSchema } from 'extended-dynamic-forms/conditionals/v2'; // Define per-item conditional logic - this function runs for each array item const directorItemConditions = (director, index) => ({ shareholdingPercentage: { 'ui:widget': director.hasShareholding ? 'percentage' : 'hidden' }, tfn: { 'ui:widget': director.isAustralianResident ? 'text' : 'hidden' }, passport: { 'ui:widget': !director.isAustralianResident ? 'text' : 'hidden' }, // Add visual indicator for the chairman 'ui:classNames': index === 0 ? 'chairman-director' : 'regular-director' }); // Apply to your array field const uiSchema = { directors: { 'ui:title': 'Company Directors', 'ui:description': 'Add all company directors and their details', items: createDynamicArrayItemsUiSchema(directorItemConditions) } }; ``` **Performance Comparison:** ```typescript // โŒ Traditional approach: O(Mร—N) - Rules ร— Array Items // With 10 rules and 50 directors = 500 evaluations // โœ… v2 approach: O(N) - Per-item evaluation // With 50 directors = 50 evaluations (regardless of rule complexity) ``` **Advanced Patterns:** ```tsx // Complex business logic with multiple conditions const productItemConditions = (product, index) => { const baseConfig = { price: { 'ui:widget': 'currency' }, quantity: { 'ui:widget': 'number' } }; // Category-specific fields if (product.category === 'software') { baseConfig.licenseType = { 'ui:widget': 'select' }; baseConfig.maintenancePeriod = { 'ui:widget': 'hidden' }; } // Subscription-specific logic if (product.billingType === 'subscription') { baseConfig.recurringPrice = { 'ui:widget': 'currency' }; baseConfig.billingCycle = { 'ui:widget': 'select' }; } return baseConfig; }; ``` ### Performance Best Practices > โš ๏ธ **Critical**: Always define rules and base schemas outside render or memoize them! ```tsx // โŒ BAD - Creates new objects every render function MyForm() { const conditionalUiSchema = useConditionalUi( [{ condition: () => true, effect: [...] }], // New array every render! { field: { 'ui:widget': 'text' } }, // New object every render! formData ); } // โœ… GOOD - Stable references const rules = [{ condition: () => true, effect: [...] }]; const baseUiSchema = { field: { 'ui:widget': 'text' } }; function MyForm() { const conditionalUiSchema = useConditionalUi(rules, baseUiSchema, formData); } ``` ### Migration from v1 to v2 ```tsx import { migrateV1ToUiRules, generateMigrationReport, analyzeRules } from 'extended-dynamic-forms/conditionals/v2'; // Analyze existing rules const analysis = analyzeRules(v1Rules); // Auto-migrate UI rules const { rules: migratedRules, report } = migrateV1ToUiRules(v1Rules); // Generate detailed migration report const migrationReport = generateMigrationReport(v1Rules, { includeExamples: true, outputFormat: 'markdown' }); ``` ## Quick Start ### Simple Wizard Form (Recommended) The `WizardForm` component automatically detects multi-step forms and handles navigation. It fully supports conditional logic through either v1 conditions (deprecated) or the recommended Three Pillars v2 architecture: ```tsx import { useState } from 'react'; import { WizardForm } from 'extended-dynamic-forms'; import { useConditionalUi, UiRule } from 'extended-dynamic-forms/conditionals/v2'; import schema from './schema.json'; import baseUiSchema from './ui-schema.json'; import webhooks from './webhooks.json'; // Example: v2 Three Pillars approach (recommended) const uiRules: UiRule[] = [ { name: 'Show tax ID in company step when listed', condition: (formData) => formData.STEP_COMPANY?.isListedCompany === true, effect: [{ op: 'remove', path: '/STEP_COMPANY/taxId/ui:widget' }] }, { name: 'Show shareholding percentage for directors with shares', condition: (formData) => formData.STEP_DIRECTORS?.directors?.some(d => d.hasShareholding), effect: [{ op: 'remove', path: '/STEP_DIRECTORS/directors/items/shareholdingPercentage/ui:widget' }] } ]; function App() { const [formData, setFormData] = useState({}); const conditionalUiSchema = useConditionalUi(uiRules, baseUiSchema, formData); return ( <WizardForm schema={schema} uiSchema={conditionalUiSchema} formData={formData} onChange={({ formData }) => setFormData(formData)} webhooks={webhooks} onSubmit={(data) => console.log('Submitted:', data.formData)} /> ); } // Alternative: v1 conditions approach (deprecated but still supported) const v1Conditions = [ { conditions: { "STEP_COMPANY.isListedCompany": true }, event: { type: "show", params: { field: "STEP_COMPANY.taxId" } } }, { conditions: { "STEP_DIRECTORS.directors[*].hasShareholding": true }, event: { type: "require", params: { field: "STEP_DIRECTORS.directors[*].shareholdingPercentage" } } } ]; // Pass v1 conditions directly to WizardForm <WizardForm schema={schema} uiSchema={uiSchema} conditions={v1Conditions} // WizardForm handles step-aware transformation onSubmit={(data) => console.log('Submitted:', data.formData)} /> ``` ### Basic Form with Three Pillars v2 ```tsx import { ExtendedForm } from 'extended-dynamic-forms'; import { useConditionalUi, UiRule } from 'extended-dynamic-forms/conditionals/v2'; const schema = { type: 'object', properties: { isStudent: { type: 'boolean', title: 'Are you a student?' }, studentId: { type: 'string', title: 'Student ID' }, school: { type: 'string', title: 'School Name' } } }; const baseUiSchema = { studentId: { 'ui:widget': 'text' }, school: { 'ui:widget': 'text' } }; // Define UI rules outside component const uiRules: UiRule[] = [ { name: 'Show student fields when student', condition: (formData) => !formData.isStudent, effect: [ { op: 'add', path: '/studentId/ui:widget', value: 'hidden' }, { op: 'add', path: '/school/ui:widget', value: 'hidden' } ] } ]; function App() { const [formData, setFormData] = useState({}); const conditionalUiSchema = useConditionalUi(uiRules, baseUiSchema, formData); return ( <ExtendedForm schema={schema} uiSchema={conditionalUiSchema} formData={formData} onChange={({ formData }) => setFormData(formData)} /> ); } ``` ## Custom Widgets ### Available Widgets The library includes enhanced versions of all standard RJSF widgets plus custom ones: #### Custom Widgets ```tsx // Color Picker const uiSchema = { favoriteColor: { 'ui:widget': 'color' } }; // Rating Widget const uiSchema = { satisfaction: { 'ui:widget': 'rating', 'ui:options': { max: 10 // default is 5 } } }; // Range Slider const schema = { volume: { type: 'number', minimum: 0, maximum: 100 } }; const uiSchema = { volume: { 'ui:widget': 'range' } }; // File Upload const uiSchema = { documents: { 'ui:widget': 'file', 'ui:options': { accept: '.pdf,.doc,.docx', multiple: true } } }; ``` #### Enhanced Standard Widgets All standard RJSF widgets are enhanced with: - **Event Integration**: Automatic integration with the central event system - **Ant Design Styling**: Modern, consistent appearance - **Error States**: Proper error indication and messaging - **Accessibility**: Enhanced ARIA support ## Central Event Orchestration System ### Field-Level Event Handling ```tsx import { ExtendedForm, type FormFieldEvent } from 'extended-dynamic-forms'; <ExtendedForm schema={schema} uiSchema={uiSchema} formData={formData} // Field-level event handlers onFieldFocus={(event: FormFieldEvent) => { console.log(`Field ${event.fieldId} focused:`, event.fieldValue); }} onFieldChange={(event: FormFieldEvent) => { console.log(`Field ${event.fieldId} changed:`, event.fieldValue); // Real-time validation or processing }} onFieldBlur={(event: FormFieldEvent) => { console.log(`Field ${event.fieldId} blurred:`, event.fieldValue); }} /> ``` ### Webhook Integration Configure multiple webhook endpoints to receive real-time form events: ```tsx import { ExtendedForm, type WebhookConfig } from 'extended-dynamic-forms'; const webhookConfigs: WebhookConfig[] = [ { url: 'https://api.yourapp.com/form-events', method: 'POST', events: ['change', 'blur'], // Only trigger on change and blur debounceMs: 500, // Wait 500ms before sending retries: 3, // Retry failed requests timeout: 5000, // 5 second timeout headers: { 'Authorization': 'Bearer your-api-token', 'X-Form-ID': 'contact-form' } } ]; <ExtendedForm schema={schema} uiSchema={uiSchema} webhooks={webhookConfigs} /> ``` ## V1 Conditional System (Deprecated) > โš ๏ธ **DEPRECATED**: The v1 conditional system is deprecated and will be removed in a future version. Use the Three Pillars v2 system for all new implementations. The v1 system uses imperative engines with O(Mร—N) performance for arrays. While still functional, it has significant limitations compared to v2. ### Basic V1 Usage (Not Recommended) ```tsx import { ExtendedForm } from 'extended-dynamic-forms'; const conditionals = { rules: [ { conditions: { isStudent: true }, event: { type: "require", params: { field: ["studentId", "school"] } } }, { conditions: { isStudent: false }, event: { type: "remove", params: { field: ["studentId", "school"] } } } ] }; <ExtendedForm schema={schema} uiSchema={uiSchema} conditionals={conditionals} /> ``` ### Why Migrate to v2? - **Performance**: O(N) vs O(Mร—N) for arrays - **Maintainability**: Clear separation of concerns - **Type Safety**: Full TypeScript support - **Predictability**: No complex rule interactions - **Modern React**: Hooks-based architecture ## API Reference ### ExtendedFormProps ```typescript interface ExtendedFormProps<T = any, S extends RJSFSchema = RJSFSchema, F = any> extends FormProps<T, S, F> { // Standard RJSF props schema: S; uiSchema?: UiSchema<T, S, F>; formData?: T; onSubmit?: (data: IChangeEvent<T, S, F>, event?: React.FormEvent<HTMLFormElement>) => void; onChange?: (data: IChangeEvent<T, S, F>) => void; // Field-level event handlers onFieldFocus?: (event: FormFieldEvent) => Promise<void> | void; onFieldBlur?: (event: FormFieldEvent) => Promise<void> | void; onFieldChange?: (event: FormFieldEvent) => Promise<void> | void; // Webhook configuration webhooks?: WebhookConfig[]; // Conditional logic (v1 - deprecated) conditionals?: ConditionalConfig; // Form lifecycle events beforeSubmit?: (data: T) => Promise<T> | T; afterSubmit?: (data: T) => Promise<void> | void; beforeValidation?: (data: T) => Promise<T> | T; afterValidation?: (data: T, errors: RJSFValidationError[]) => Promise<void> | void; } ``` ### Three Pillars v2 Hooks ```typescript // UI Logic Pillar function useConditionalUi( rules: UiRule[], baseUiSchema: UiSchema, formData: any ): UiSchema // Schema Logic Pillar function useConditionalSchema( rules: SchemaRule[], baseSchema: RJSFSchema, formData: any ): RJSFSchema // Validation Logic Pillar function useConditionalValidation( rules: ValidationRule[], baseConfig: ValidationConfig, formData: any ): ValidationConfig ``` ## Real-World Use Cases ### ๐Ÿข Enterprise Business Applications **Australian Company Registration** (Featured Demo) ```tsx // Complete 5-step wizard with dynamic conditionals const companyOnboardingSchema = { STEP_COMPANY: { /* Company details */ }, STEP_DIRECTORS: { /* Dynamic director array */ }, STEP_ADDRESS: { /* Address with postal logic */ }, STEP_FINANCIAL: { /* Banking with international support */ }, STEP_COMPLIANCE: { /* Regulatory requirements */ } }; // Per-director conditionals with O(N) performance const uiSchema = { STEP_DIRECTORS: { directors: { items: createDynamicArrayItemsUiSchema((director) => ({ tfn: { 'ui:widget': director.isAustralianResident ? 'text' : 'hidden' }, passport: { 'ui:widget': !director.isAustralianResident ? 'text' : 'hidden' } })) } } }; ``` ### ๐Ÿ’ผ Multi-Step Workflows **Loan Applications** - Conditional document requirements based on loan type - Income verification with employment status logic - Asset declaration with property type conditionals **Employee Onboarding** - Role-based form sections (technical vs. non-technical) - Security clearance workflows - Benefits enrollment with eligibility rules **Grant Applications** - Multi-stage submissions with validation gates - Budget calculations with category-based rules - Compliance checks based on funding type ### ๐Ÿ”„ Dynamic Array Management **Board of Directors Management** ```tsx // Professional-grade array handling with O(N) performance import { createDynamicArrayItemsUiSchema } from 'extended-dynamic-forms'; const uiSchema = { STEP_DIRECTORS: { directors: { items: createDynamicArrayItemsUiSchema((director, index) => ({ shareholdingPercentage: { 'ui:widget': director.hasShareholding ? 'percentage' : 'hidden' }, tfn: { 'ui:widget': director.isAustralianResident ? 'text' : 'hidden' }, passport: { 'ui:widget': !director.isAustralianResident ? 'text' : 'hidden' } })) } } }; ``` **Product Configurations** - Dynamic product options based on category - Pricing calculations with quantity breaks - Feature availability by subscription tier **Address Management** - International vs. domestic address formats - State/province selection based on country - Postal code validation by region ### ๐ŸŒ CMS & Integration Use Cases **WordPress/Drupal Forms** ```html <!-- Standalone JavaScript integration --> <script> const { createWizard } = ExtendedDynamicForms; createWizard({ schema: wpFormSchema, container: '#wp-form-container', onSubmit: (data) => { // Submit to WordPress REST API wp.apiRequest({ path: '/wp/v2/forms', method: 'POST', data }); } }); </script> ``` **Legacy System Modernization** - Drop-in replacement for static HTML forms - Progressive enhancement of existing forms - No-build deployment to production environments ## Architecture Extended Dynamic Forms uses a layered architecture that cleanly extends RJSF: ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Three Pillars v2 (Conditional System) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Application Layer (WizardForm) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Event Layer (FormEventHub) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Component Layer (Widgets/Fields/Templates) โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Base Layer (@rjsf/antd) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ## Feature Comparison | Feature | Basic RJSF | Extended Dynamic Forms | |---------|------------|----------------------| | **Form Generation** | โœ… JSON Schema | โœ… Enhanced JSON Schema | | **UI Components** | Basic HTML | โœ… Comprehensive Ant Design Suite | | **Conditional Logic** | โŒ Manual | โœ… Three Pillars v2 (O(N)) | | **Multi-Step Forms** | โŒ Manual | โœ… Automatic Wizard Detection | | **Event System** | Basic onChange | โœ… Central Event Orchestration | | **Webhook Integration** | โŒ None | โœ… Production-Ready with Retry | | **Array Conditionals** | โŒ None | โœ… Per-Item O(N) Performance | | **TypeScript** | Partial | โœ… Comprehensive Type Definitions | | **Standalone JS** | โŒ React Only | โœ… Complete UMD Bundle | | **Testing** | Basic | โœ… Extensive Test Coverage | | **Performance** | Standard | โœ… Optimized with Caching | | **Validation** | Basic | โœ… Dynamic + Custom Rules | | **Developer Tools** | Limited | โœ… Interactive Playground | ## Development ### ๐Ÿš€ Quick Start ```bash # Clone and setup git clone https://github.com/user/extended-dynamic-forms.git cd extended-dynamic-forms npm install # Start development with playground npm run dev # Launches interactive playground npm run playground # Alternative playground command # Development workflow npm run test # Run complete test suite npm run test:ui # Visual test runner npm run lint # ESLint validation npm run format # Prettier formatting ``` ### ๐Ÿ“ฆ Build Commands ```bash # Library builds npm run build # TypeScript + Vite library build npm run build:vanilla # Standalone UMD bundle npm run build:all # Both library and standalone # Production validation npm run preview # Preview library build npm run serve:examples # Serve vanilla JS examples ``` ### ๐Ÿงช Testing **Test Coverage**: Extensive test suite with focus on: - **Conditional Logic**: Comprehensive coverage for v1 and v2 systems - **Wizard Forms**: Step navigation and validation - **Performance**: Array conditional optimization - **Integration**: Component interaction testing ```bash npm run test # Run complete test suite npm run test -- --grep "conditional" # Test conditional logic npm run test -- --grep "wizard" # Test wizard forms npm run test -- --grep "array" # Test array handling ``` ### ๐Ÿ—๏ธ Architecture **Build Configuration**: - **Library**: ES + UMD via Vite with TypeScript declarations - **Standalone**: Complete UMD bundle with React/antd included - **External Dependencies**: React, antd marked as externals in library build - **Type Generation**: `vite-plugin-dts` for .d.ts files **File Structure**: ``` src/ โ”œโ”€โ”€ ExtendedForm.tsx # Main form wrapper โ”œโ”€โ”€ WizardForm.tsx # Multi-step orchestrator โ”œโ”€โ”€ conditionals/ # v1 + v2 conditional systems โ”‚ โ”œโ”€โ”€ v2/ # Three Pillars architecture โ”‚ โ””โ”€โ”€ DynamicArrayConditionalEngine.ts โ”œโ”€โ”€ events/ # Central event orchestration โ”œโ”€โ”€ widgets/ # Enhanced component suite โ”œโ”€โ”€ components/ # Field and template components โ””โ”€โ”€ utils/ # Form manipulation utilities ``` ## Examples & Demos ### ๐ŸŽฎ Interactive Playground The library includes a comprehensive **interactive playground** with extensive real-world demos demonstrating all features: ```bash # Run the playground locally npm run dev # or npm run playground ``` ### ๐Ÿ“š Demo Categories #### **Three Pillars v2 Demonstrations** - **Global UI Rules**: Dynamic show/hide with JSON Patch operations - **Dynamic Array Items**: Per-item conditional logic with O(N) performance - **Conditional Validation**: Custom validation rules without schema changes - **Migration Examples**: Automated v1-to-v2 rule conversion #### **๐Ÿง™โ€โ™‚๏ธ Wizard Form Showcases** - **Australian Company Onboarding**: 5-step enterprise form with: - Dynamic director arrays with per-item conditionals - Real-time fee calculations based on business rules - Complex validation (ABN/ACN numbers, postcodes) - Step-aware conditional logic - Professional business workflow #### **๐Ÿ”— Event System Demos** - **Real-time Form Analytics**: Webhook integration with retry logic - **Field-Level Event Handling**: Focus/blur/change event orchestration - **Webhook Configuration**: Multiple endpoints with custom headers #### **๐ŸŽจ Widget Showcase** - **Enhanced Standard Widgets**: All RJSF widgets with Ant Design styling - **Custom Widgets**: Color picker, rating, range slider, file upload - **Professional Fields**: Address, currency, phone number components ### ๐Ÿ“ฑ Vanilla JavaScript Examples Complete standalone examples in `/examples/vanilla-js/`: ```html <!-- Basic Form --> basic-form.html <!-- Simple contact form --> conditional-form.html <!-- Dynamic field visibility --> wizard-form.html <!-- Multi-step onboarding --> ``` ### ๐Ÿ”— Live Demo Links - **[Playground](https://extended-dynamic-forms-playground.vercel.app)** - Interactive demo environment - **[Australian Company Onboarding](https://extended-dynamic-forms-playground.vercel.app/wizard/australian-company)** - Full enterprise form showcase - **[Three Pillars v2 Demo](https://extended-dynamic-forms-playground.vercel.app/conditionals/three-pillars)** - Modern conditional logic patterns ## Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. ## Community & Support - ๐Ÿ“š [Documentation](https://extended-dynamic-forms.dev) - ๐Ÿ› [Issue Tracker](https://github.com/user/extended-dynamic-forms/issues) - ๐Ÿ’ฌ [Discussions](https://github.com/user/extended-dynamic-forms/discussions) - ๐Ÿ“ง [Email Support](mailto:support@extended-dynamic-forms.dev) --- <p align="center"> Built with โค๏ธ on top of <a href="https://github.com/rjsf-team/react-jsonschema-form">React JSON Schema Form</a> </p>