extended-dynamic-forms 0.1.11 → 0.1.13

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/README.md CHANGED
@@ -11,6 +11,7 @@ A comprehensive extension of React JSON Schema Form (RJSF) v5 with shadcn/ui com
11
11
  - 🎯 **Central Event Orchestration**: Unified system capturing all form field events (focus, blur, change)
12
12
  - 🔗 **Webhook Integration**: Configure multiple webhook endpoints with debouncing and retry logic
13
13
  - 🔧 **Enhanced Form Events**: Before/after submit and validation hooks plus field-level events
14
+ - 🚀 **Conditional Logic**: Show/hide fields, make fields required/optional based on complex conditions
14
15
  - 📦 **TypeScript Support**: Fully typed with comprehensive type definitions
15
16
  - ⚡ **Vite Powered**: Fast development and optimized builds
16
17
  - 🎯 **Tailwind CSS**: Utility-first styling with full customization
@@ -518,6 +519,137 @@ const webhooks: WebhookConfig[] = [
518
519
  />
519
520
  ```
520
521
 
522
+ ## Conditional Forms
523
+
524
+ Extended Dynamic Forms includes powerful conditional logic capabilities that allow you to:
525
+ - Show/hide fields based on other field values
526
+ - Make fields required/optional conditionally
527
+ - Enable/disable fields based on complex conditions
528
+ - Support multiple conditions with AND/OR logic
529
+
530
+ ### Basic Conditional Example
531
+
532
+ ```tsx
533
+ import { ConditionalForm, ConditionalRule } from 'extended-dynamic-forms';
534
+
535
+ const schema = {
536
+ type: 'object',
537
+ properties: {
538
+ accountType: {
539
+ type: 'string',
540
+ enum: ['personal', 'business'],
541
+ title: 'Account Type'
542
+ },
543
+ firstName: { type: 'string', title: 'First Name' },
544
+ lastName: { type: 'string', title: 'Last Name' },
545
+ businessName: { type: 'string', title: 'Business Name' },
546
+ taxId: { type: 'string', title: 'Tax ID' }
547
+ }
548
+ };
549
+
550
+ const conditionalRules: ConditionalRule[] = [
551
+ {
552
+ conditions: {
553
+ accountType: { equals: 'personal' }
554
+ },
555
+ event: {
556
+ type: 'show',
557
+ params: { fields: ['firstName', 'lastName'] }
558
+ }
559
+ },
560
+ {
561
+ conditions: {
562
+ accountType: { equals: 'business' }
563
+ },
564
+ event: {
565
+ type: 'show',
566
+ params: { fields: ['businessName', 'taxId'] }
567
+ }
568
+ }
569
+ ];
570
+
571
+ <ConditionalForm
572
+ schema={schema}
573
+ conditionalRules={conditionalRules}
574
+ onSubmit={handleSubmit}
575
+ />
576
+ ```
577
+
578
+ ### Complex Conditions
579
+
580
+ ```tsx
581
+ const complexRules: ConditionalRule[] = [
582
+ {
583
+ // Show state field when country is US AND has address
584
+ conditions: {
585
+ all: [
586
+ { country: { equals: 'US' } },
587
+ { hasAddress: { equals: true } }
588
+ ]
589
+ },
590
+ event: {
591
+ type: 'show',
592
+ params: { fields: ['state', 'zipCode'] }
593
+ }
594
+ },
595
+ {
596
+ // Show verification for high income personal OR business accounts
597
+ conditions: {
598
+ any: [
599
+ {
600
+ all: [
601
+ { accountType: { equals: 'personal' } },
602
+ { income: { greaterThan: 100000 } }
603
+ ]
604
+ },
605
+ {
606
+ accountType: { equals: 'business' }
607
+ }
608
+ ]
609
+ },
610
+ event: {
611
+ type: 'require',
612
+ params: { fields: ['verificationDocument'] }
613
+ }
614
+ }
615
+ ];
616
+ ```
617
+
618
+ ### Available Conditions
619
+
620
+ - `equals` / `notEquals` - Exact value matching
621
+ - `greaterThan` / `lessThan` - Numeric comparisons
622
+ - `greaterThanOrEqual` / `lessThanOrEqual` - Inclusive numeric comparisons
623
+ - `contains` / `notContains` - String contains
624
+ - `in` / `notIn` - Value in array
625
+ - `empty` / `notEmpty` - Check if field has value
626
+
627
+ ### Available Events
628
+
629
+ - `show` / `hide` - Control field visibility
630
+ - `require` / `unrequire` - Make fields required/optional
631
+ - `enable` / `disable` - Enable/disable fields
632
+
633
+ ### Combining with Webhooks
634
+
635
+ ```tsx
636
+ <ConditionalForm
637
+ schema={schema}
638
+ conditionalRules={rules}
639
+ webhooks={[
640
+ {
641
+ url: 'https://api.example.com/validate',
642
+ events: ['change'],
643
+ debounceMs: 500
644
+ }
645
+ ]}
646
+ onFieldChange={(event) => {
647
+ // Local handling alongside conditional logic
648
+ console.log('Field changed:', event);
649
+ }}
650
+ />
651
+ ```
652
+
521
653
  ## API Reference
522
654
 
523
655
  ### ExtendedFormProps
@@ -575,6 +707,39 @@ interface WebhookConfig {
575
707
  }
576
708
  ```
577
709
 
710
+ ### ConditionalRule
711
+
712
+ ```typescript
713
+ interface ConditionalRule {
714
+ conditions: {
715
+ [fieldPath: string]: FieldCondition;
716
+ all?: Array<{ [fieldPath: string]: FieldCondition }>;
717
+ any?: Array<{ [fieldPath: string]: FieldCondition }>;
718
+ };
719
+ event: {
720
+ type: 'show' | 'hide' | 'require' | 'unrequire' | 'disable' | 'enable';
721
+ params: {
722
+ fields: string[];
723
+ };
724
+ };
725
+ }
726
+
727
+ interface FieldCondition {
728
+ equals?: any;
729
+ notEquals?: any;
730
+ greaterThan?: number;
731
+ lessThan?: number;
732
+ greaterThanOrEqual?: number;
733
+ lessThanOrEqual?: number;
734
+ contains?: string;
735
+ notContains?: string;
736
+ in?: any[];
737
+ notIn?: any[];
738
+ empty?: boolean;
739
+ notEmpty?: boolean;
740
+ }
741
+ ```
742
+
578
743
  ## Utility Functions
579
744
 
580
745
  ```tsx
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ import { ConditionalFormProps } from './types';
3
+
4
+ /**
5
+ * Conditional form using json-rules-engine
6
+ */
7
+ export declare const ConditionalForm: React.FC<ConditionalFormProps>;
@@ -0,0 +1,3 @@
1
+ export { ConditionalForm } from './ConditionalForm';
2
+ export * from './types';
3
+ export * from './utils';
@@ -0,0 +1,65 @@
1
+ import { ExtendedFormProps } from '../types';
2
+
3
+ export type ConditionOperator = 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'contains' | 'notContains' | 'in' | 'notIn' | 'empty' | 'notEmpty';
4
+ export interface FieldCondition {
5
+ equals?: any;
6
+ notEquals?: any;
7
+ greaterThan?: number;
8
+ lessThan?: number;
9
+ greaterThanOrEqual?: number;
10
+ lessThanOrEqual?: number;
11
+ contains?: string;
12
+ notContains?: string;
13
+ in?: any[];
14
+ notIn?: any[];
15
+ empty?: boolean;
16
+ notEmpty?: boolean;
17
+ }
18
+ export interface ConditionalRule {
19
+ conditions: {
20
+ [fieldPath: string]: FieldCondition;
21
+ } & {
22
+ all?: Array<{
23
+ [fieldPath: string]: FieldCondition;
24
+ }>;
25
+ any?: Array<{
26
+ [fieldPath: string]: FieldCondition;
27
+ }>;
28
+ };
29
+ event: {
30
+ type: 'show' | 'hide' | 'require' | 'unrequire' | 'disable' | 'enable';
31
+ params: {
32
+ fields: string[];
33
+ };
34
+ };
35
+ }
36
+ export interface ConditionalFormProps extends ExtendedFormProps {
37
+ conditionalRules: ConditionalRule[];
38
+ debug?: boolean;
39
+ }
40
+ export interface RuleEngineEvent {
41
+ type: string;
42
+ params: any;
43
+ }
44
+ export interface RuleEngineCondition {
45
+ fact: string;
46
+ operator: string;
47
+ value: any;
48
+ }
49
+ export interface RuleEngineRule {
50
+ conditions: {
51
+ all?: RuleEngineCondition[];
52
+ any?: RuleEngineCondition[];
53
+ };
54
+ event: RuleEngineEvent;
55
+ }
56
+ export interface ConditionalState {
57
+ hiddenFields: Set<string>;
58
+ disabledFields: Set<string>;
59
+ requiredFields: Set<string>;
60
+ }
61
+ export interface ConditionalContext {
62
+ state: ConditionalState;
63
+ updateState: (updates: Partial<ConditionalState>) => void;
64
+ evaluateRules: (formData: any) => void;
65
+ }
@@ -0,0 +1,22 @@
1
+ import { RJSFSchema, UiSchema } from '@rjsf/utils';
2
+ import { ConditionalRule, ConditionalState } from './types';
3
+
4
+ /**
5
+ * Convert our conditional rules to json-rules-engine format
6
+ */
7
+ export declare function convertToEngineRules(rules: ConditionalRule[]): any[];
8
+ /**
9
+ * Apply conditional state to schema
10
+ */
11
+ export declare function applyConditionalState(schema: RJSFSchema, uiSchema: UiSchema, state: ConditionalState): {
12
+ schema: RJSFSchema;
13
+ uiSchema: UiSchema;
14
+ };
15
+ /**
16
+ * Flatten nested objects for fact extraction
17
+ */
18
+ export declare function flattenFormData(obj: any, prefix?: string, separator?: string): Record<string, any>;
19
+ /**
20
+ * Extract field value from form data using field path
21
+ */
22
+ export declare function getFieldValue(formData: any, fieldPath: string): any;
package/dist/index.d.ts CHANGED
@@ -11,3 +11,5 @@ export type { RJSFSchema, UiSchema, WidgetProps, FieldProps, ArrayFieldTemplateP
11
11
  export { default as validator } from '@rjsf/validator-ajv8';
12
12
  export { generateTheme } from '@rjsf/shadcn';
13
13
  export { ExtendedForm } from './ExtendedForm';
14
+ export { ConditionalForm } from './conditionals';
15
+ export type { ConditionalFormProps, ConditionalRule, FieldCondition, ConditionalState } from './conditionals/types';