@algodomain/smart-forms 0.1.1 → 0.1.3
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/LICENSE +3 -0
- package/README.md +243 -0
- package/dist/{SmartFormProvider-DyJoDBjQ.d.cts → SmartFormProvider-BdyRQakk.d.cts} +1 -0
- package/dist/{SmartFormProvider-DyJoDBjQ.d.ts → SmartFormProvider-BdyRQakk.d.ts} +1 -0
- package/dist/{SmartTags-HmvmCJPT.d.cts → SmartTags-DPqw9PG1.d.cts} +12 -1
- package/dist/{SmartTags-HmvmCJPT.d.ts → SmartTags-DPqw9PG1.d.ts} +12 -1
- package/dist/{chunk-EE6VZXWC.js → chunk-3L7TKJIB.js} +58 -45
- package/dist/chunk-3L7TKJIB.js.map +1 -0
- package/dist/{chunk-5A5WAAED.js → chunk-CT6GW6PK.js} +44 -11
- package/dist/chunk-CT6GW6PK.js.map +1 -0
- package/dist/{chunk-LRMJP5OJ.cjs → chunk-MBC5TYXA.cjs} +58 -45
- package/dist/chunk-MBC5TYXA.cjs.map +1 -0
- package/dist/{chunk-Y3H6MI5D.cjs → chunk-TJ6EFR2O.cjs} +120 -87
- package/dist/chunk-TJ6EFR2O.cjs.map +1 -0
- package/dist/fields.cjs +172 -124
- package/dist/fields.cjs.map +1 -1
- package/dist/fields.d.cts +14 -2
- package/dist/fields.d.ts +14 -2
- package/dist/fields.js +70 -22
- package/dist/fields.js.map +1 -1
- package/dist/index.cjs +36 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +14 -8
- package/dist/index.js.map +1 -1
- package/dist/opinionated.cjs +18 -18
- package/dist/opinionated.d.cts +1 -1
- package/dist/opinionated.d.ts +1 -1
- package/dist/opinionated.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-5A5WAAED.js.map +0 -1
- package/dist/chunk-EE6VZXWC.js.map +0 -1
- package/dist/chunk-LRMJP5OJ.cjs.map +0 -1
- package/dist/chunk-Y3H6MI5D.cjs.map +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -35,6 +35,7 @@ Built with TypeScript, Tailwind CSS, Zod validation, and shadcn/ui components.
|
|
|
35
35
|
- 🔄 **API Integration** - Automatic form submission with authentication support
|
|
36
36
|
- 🔗 **Query Params** - Include URL query parameters in form submissions
|
|
37
37
|
- 💾 **Auto-Save** - LocalStorage support for draft saving
|
|
38
|
+
- 🎛️ **Conditional Disabling** - Disable fields and submit buttons based on form data
|
|
38
39
|
- 🎨 **Customizable** - Full theme control via CSS variables
|
|
39
40
|
- 🌙 **Dark Mode** - Built-in support for light and dark themes
|
|
40
41
|
- ♿ **Accessible** - Built on Radix UI primitives
|
|
@@ -479,6 +480,7 @@ All form components (`SmartForm`, `MultiTabSmartForm`, `BaseSmartForm`) support
|
|
|
479
480
|
| `authentication` | `AuthenticationConfig` | - | Authentication configuration |
|
|
480
481
|
| `includeQueryParams` | `boolean` | `false` | Include URL query parameters |
|
|
481
482
|
| `queryParamsToInclude` | `string[]` | - | Filter specific query params |
|
|
483
|
+
| `submitDisabled` | `boolean \| ((formData: any) => boolean)` | `false` | Disable submit button statically or conditionally based on form data |
|
|
482
484
|
| `children` | `ReactNode` | - | Form content |
|
|
483
485
|
|
|
484
486
|
### Authentication Configuration
|
|
@@ -522,6 +524,8 @@ All field components support these props:
|
|
|
522
524
|
| `className` | `string` | - | Custom CSS class |
|
|
523
525
|
| `info` | `string` | - | Info tooltip text |
|
|
524
526
|
| `subLabel` | `string` | - | Additional helper text |
|
|
527
|
+
| `disabled` | `boolean \| ((formData: any) => boolean)` | `false` | Disable field statically or conditionally based on form data |
|
|
528
|
+
| `hidden` | `boolean \| ((formData: any) => boolean)` | `false` | Hide field conditionally based on form data |
|
|
525
529
|
|
|
526
530
|
### Field-Specific Props
|
|
527
531
|
|
|
@@ -594,6 +598,237 @@ All field components support these props:
|
|
|
594
598
|
|
|
595
599
|
## 🚀 Advanced Features
|
|
596
600
|
|
|
601
|
+
### Conditional Field Disabling
|
|
602
|
+
|
|
603
|
+
Disable fields or submit buttons based on form data values. Supports both static boolean values and dynamic functions.
|
|
604
|
+
|
|
605
|
+
#### Disable Fields Conditionally
|
|
606
|
+
|
|
607
|
+
**Static Disable:**
|
|
608
|
+
```tsx
|
|
609
|
+
<SmartInput
|
|
610
|
+
field="username"
|
|
611
|
+
label="Username"
|
|
612
|
+
disabled={true}
|
|
613
|
+
/>
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**Conditional Disable Based on Form Data:**
|
|
617
|
+
```tsx
|
|
618
|
+
<SmartForm api="/api/submit">
|
|
619
|
+
<SmartCombobox
|
|
620
|
+
field="country"
|
|
621
|
+
label="Country"
|
|
622
|
+
options={[
|
|
623
|
+
{ value: 'us', label: 'United States' },
|
|
624
|
+
{ value: 'ca', label: 'Canada' }
|
|
625
|
+
]}
|
|
626
|
+
placeholder="Please select the country"
|
|
627
|
+
/>
|
|
628
|
+
|
|
629
|
+
<SmartCombobox
|
|
630
|
+
field="state"
|
|
631
|
+
label="State"
|
|
632
|
+
options={stateOptions}
|
|
633
|
+
disabled={(formData) => !formData.country || formData.country === ""}
|
|
634
|
+
/>
|
|
635
|
+
|
|
636
|
+
<SmartInput
|
|
637
|
+
field="zipCode"
|
|
638
|
+
label="Zip Code"
|
|
639
|
+
disabled={(formData) => !formData.state}
|
|
640
|
+
/>
|
|
641
|
+
</SmartForm>
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
**How it works:**
|
|
645
|
+
- The `disabled` function receives the current `formData` object
|
|
646
|
+
- It re-evaluates automatically when form data changes
|
|
647
|
+
- Returns `true` to disable, `false` to enable
|
|
648
|
+
- Empty strings, `null`, and `undefined` are all falsy in JavaScript
|
|
649
|
+
|
|
650
|
+
**Example: Disable until checkbox is checked:**
|
|
651
|
+
```tsx
|
|
652
|
+
<SmartForm api="/api/submit">
|
|
653
|
+
<SmartCheckbox
|
|
654
|
+
field="agreeToTerms"
|
|
655
|
+
label="I agree to the terms and conditions"
|
|
656
|
+
/>
|
|
657
|
+
|
|
658
|
+
<SmartInput
|
|
659
|
+
field="comments"
|
|
660
|
+
label="Additional Comments"
|
|
661
|
+
disabled={(formData) => !formData.agreeToTerms}
|
|
662
|
+
/>
|
|
663
|
+
</SmartForm>
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
**Example: Complex conditional logic:**
|
|
667
|
+
```tsx
|
|
668
|
+
<SmartInput
|
|
669
|
+
field="phone"
|
|
670
|
+
label="Phone Number"
|
|
671
|
+
disabled={(formData) => {
|
|
672
|
+
// Disable if email is not provided OR if user is under 18
|
|
673
|
+
return !formData.email || (formData.age && formData.age < 18)
|
|
674
|
+
}}
|
|
675
|
+
/>
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
#### Disable Submit Button Conditionally
|
|
679
|
+
|
|
680
|
+
**Static Disable:**
|
|
681
|
+
```tsx
|
|
682
|
+
<SmartForm
|
|
683
|
+
api="/api/submit"
|
|
684
|
+
submitDisabled={true}
|
|
685
|
+
>
|
|
686
|
+
{/* Fields */}
|
|
687
|
+
</SmartForm>
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
**Conditional Disable:**
|
|
691
|
+
```tsx
|
|
692
|
+
<SmartForm
|
|
693
|
+
api="/api/submit"
|
|
694
|
+
submitDisabled={(formData) => !formData.agreeToTerms}
|
|
695
|
+
>
|
|
696
|
+
<SmartInput field="name" label="Name" required />
|
|
697
|
+
<SmartCheckbox
|
|
698
|
+
field="agreeToTerms"
|
|
699
|
+
label="I agree to the terms"
|
|
700
|
+
/>
|
|
701
|
+
</SmartForm>
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
**Example: Disable submit until all required fields are filled:**
|
|
705
|
+
```tsx
|
|
706
|
+
<SmartForm
|
|
707
|
+
api="/api/submit"
|
|
708
|
+
submitDisabled={(formData) => {
|
|
709
|
+
return !formData.name || !formData.email || !formData.agreeToTerms
|
|
710
|
+
}}
|
|
711
|
+
>
|
|
712
|
+
<SmartInput field="name" label="Name" required />
|
|
713
|
+
<SmartInput field="email" label="Email" required />
|
|
714
|
+
<SmartCheckbox field="agreeToTerms" label="I agree" required />
|
|
715
|
+
</SmartForm>
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
**Note:** The submit button is automatically disabled when `isLoading` is `true`. The `submitDisabled` prop is combined with the loading state: `disabled={isLoading || isSubmitDisabled}`.
|
|
719
|
+
|
|
720
|
+
#### Combining Disabled and Hidden
|
|
721
|
+
|
|
722
|
+
You can use both `disabled` and `hidden` together for different scenarios:
|
|
723
|
+
|
|
724
|
+
```tsx
|
|
725
|
+
<SmartForm api="/api/submit">
|
|
726
|
+
<SmartSelect
|
|
727
|
+
field="userType"
|
|
728
|
+
label="User Type"
|
|
729
|
+
options={[
|
|
730
|
+
{ value: 'admin', label: 'Admin' },
|
|
731
|
+
{ value: 'user', label: 'User' }
|
|
732
|
+
]}
|
|
733
|
+
/>
|
|
734
|
+
|
|
735
|
+
{/* Hidden for non-admin users */}
|
|
736
|
+
<SmartInput
|
|
737
|
+
field="adminCode"
|
|
738
|
+
label="Admin Code"
|
|
739
|
+
hidden={(formData) => formData.userType !== 'admin'}
|
|
740
|
+
/>
|
|
741
|
+
|
|
742
|
+
{/* Disabled (but visible) for admin users */}
|
|
743
|
+
<SmartInput
|
|
744
|
+
field="userNotes"
|
|
745
|
+
label="User Notes"
|
|
746
|
+
disabled={(formData) => formData.userType === 'admin'}
|
|
747
|
+
/>
|
|
748
|
+
</SmartForm>
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
#### Hide Fields Conditionally
|
|
752
|
+
|
|
753
|
+
Hide fields completely from the form based on form data. When a field is hidden, it's not rendered at all (unlike `disabled` which shows the field but makes it non-interactive).
|
|
754
|
+
|
|
755
|
+
**Static Hide:**
|
|
756
|
+
```tsx
|
|
757
|
+
<SmartInput
|
|
758
|
+
field="optionalField"
|
|
759
|
+
label="Optional Field"
|
|
760
|
+
hidden={true}
|
|
761
|
+
/>
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
**Conditional Hide:**
|
|
765
|
+
```tsx
|
|
766
|
+
<SmartForm api="/api/submit">
|
|
767
|
+
<SmartSelect
|
|
768
|
+
field="accountType"
|
|
769
|
+
label="Account Type"
|
|
770
|
+
options={[
|
|
771
|
+
{ value: 'personal', label: 'Personal' },
|
|
772
|
+
{ value: 'business', label: 'Business' }
|
|
773
|
+
]}
|
|
774
|
+
/>
|
|
775
|
+
|
|
776
|
+
{/* Only show business fields when account type is business */}
|
|
777
|
+
<SmartInput
|
|
778
|
+
field="businessName"
|
|
779
|
+
label="Business Name"
|
|
780
|
+
hidden={(formData) => formData.accountType !== 'business'}
|
|
781
|
+
/>
|
|
782
|
+
|
|
783
|
+
<SmartInput
|
|
784
|
+
field="taxId"
|
|
785
|
+
label="Tax ID"
|
|
786
|
+
hidden={(formData) => formData.accountType !== 'business'}
|
|
787
|
+
/>
|
|
788
|
+
</SmartForm>
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
**Example: Show/hide based on checkbox:**
|
|
792
|
+
```tsx
|
|
793
|
+
<SmartForm api="/api/submit">
|
|
794
|
+
<SmartCheckbox
|
|
795
|
+
field="hasSpecialRequirements"
|
|
796
|
+
label="I have special requirements"
|
|
797
|
+
/>
|
|
798
|
+
|
|
799
|
+
<SmartInput
|
|
800
|
+
field="specialRequirements"
|
|
801
|
+
label="Please describe your requirements"
|
|
802
|
+
type="textarea"
|
|
803
|
+
hidden={(formData) => !formData.hasSpecialRequirements}
|
|
804
|
+
/>
|
|
805
|
+
</SmartForm>
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
**Difference between `disabled` and `hidden`:**
|
|
809
|
+
- `disabled`: Field is visible but grayed out and non-interactive
|
|
810
|
+
- `hidden`: Field is completely removed from the DOM (not rendered)
|
|
811
|
+
|
|
812
|
+
**When to use each:**
|
|
813
|
+
- Use `disabled` when you want to show the field exists but is temporarily unavailable
|
|
814
|
+
- Use `hidden` when you want to completely hide fields that aren't relevant to the current form state
|
|
815
|
+
|
|
816
|
+
#### All Supported Components
|
|
817
|
+
|
|
818
|
+
Both `disabled` and `hidden` props are available on all smart field components:
|
|
819
|
+
- `SmartInput`
|
|
820
|
+
- `SmartSelect`
|
|
821
|
+
- `SmartCombobox`
|
|
822
|
+
- `SmartCheckbox`
|
|
823
|
+
- `SmartRadioGroup`
|
|
824
|
+
- `SmartDatePicker`
|
|
825
|
+
- `SmartSlider`
|
|
826
|
+
- `SmartDualRangeSlider`
|
|
827
|
+
- `SmartTags`
|
|
828
|
+
- `SmartFileUpload`
|
|
829
|
+
- `SmartAutoSuggestTags`
|
|
830
|
+
- `SmartBasicRichTextbox`
|
|
831
|
+
|
|
597
832
|
### Query Parameters
|
|
598
833
|
|
|
599
834
|
Automatically include URL query parameters in form submissions.
|
|
@@ -843,6 +1078,7 @@ export function RegistrationForm() {
|
|
|
843
1078
|
api="https://api.example.com/register"
|
|
844
1079
|
method="POST"
|
|
845
1080
|
submitButtonText="Register"
|
|
1081
|
+
submitDisabled={(formData) => !formData.agreeToTerms}
|
|
846
1082
|
onSuccess={(data) => {
|
|
847
1083
|
toast.success('Account created successfully!')
|
|
848
1084
|
}}
|
|
@@ -871,6 +1107,13 @@ export function RegistrationForm() {
|
|
|
871
1107
|
required
|
|
872
1108
|
/>
|
|
873
1109
|
|
|
1110
|
+
<SmartSelect
|
|
1111
|
+
field="state"
|
|
1112
|
+
label="State"
|
|
1113
|
+
options={stateOptions}
|
|
1114
|
+
disabled={(formData) => !formData.country}
|
|
1115
|
+
/>
|
|
1116
|
+
|
|
874
1117
|
<SmartDatePicker
|
|
875
1118
|
field="birthDate"
|
|
876
1119
|
label="Date of Birth"
|
|
@@ -11,6 +11,8 @@ interface SmartInputProps {
|
|
|
11
11
|
defaultValue?: any;
|
|
12
12
|
info?: string;
|
|
13
13
|
subLabel?: string;
|
|
14
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
15
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
14
16
|
}
|
|
15
17
|
declare const SmartInput: React__default.FC<SmartInputProps>;
|
|
16
18
|
|
|
@@ -23,6 +25,8 @@ interface SmartCheckboxProps {
|
|
|
23
25
|
defaultValue?: boolean;
|
|
24
26
|
info?: string;
|
|
25
27
|
subLabel?: string;
|
|
28
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
29
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
26
30
|
}
|
|
27
31
|
declare const SmartCheckbox: React__default.FC<SmartCheckboxProps>;
|
|
28
32
|
|
|
@@ -42,6 +46,8 @@ interface SmartRadioGroupProps {
|
|
|
42
46
|
defaultValue?: string;
|
|
43
47
|
info?: string;
|
|
44
48
|
subLabel?: string;
|
|
49
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
50
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
45
51
|
}
|
|
46
52
|
declare const SmartRadioGroup: React__default.FC<SmartRadioGroupProps>;
|
|
47
53
|
|
|
@@ -60,6 +66,8 @@ interface SmartSelectProps {
|
|
|
60
66
|
defaultValue?: string;
|
|
61
67
|
info?: string;
|
|
62
68
|
subLabel?: string;
|
|
69
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
70
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
63
71
|
}
|
|
64
72
|
declare const SmartSelect: React__default.FC<SmartSelectProps>;
|
|
65
73
|
|
|
@@ -85,6 +93,8 @@ interface SmartDatePickerProps {
|
|
|
85
93
|
defaultValue?: Date | string;
|
|
86
94
|
info?: string;
|
|
87
95
|
subLabel?: string;
|
|
96
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
97
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
88
98
|
}
|
|
89
99
|
declare const SmartDatePicker: React__default.FC<SmartDatePickerProps>;
|
|
90
100
|
|
|
@@ -100,7 +110,8 @@ interface SmartTagsProps {
|
|
|
100
110
|
maxLength?: number;
|
|
101
111
|
minLength?: number;
|
|
102
112
|
allowDuplicates?: boolean;
|
|
103
|
-
disabled?: boolean;
|
|
113
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
114
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
104
115
|
onTagAdd?: (tagText: string) => void;
|
|
105
116
|
onTagRemove?: (tagText: string) => void;
|
|
106
117
|
info?: string;
|
|
@@ -11,6 +11,8 @@ interface SmartInputProps {
|
|
|
11
11
|
defaultValue?: any;
|
|
12
12
|
info?: string;
|
|
13
13
|
subLabel?: string;
|
|
14
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
15
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
14
16
|
}
|
|
15
17
|
declare const SmartInput: React__default.FC<SmartInputProps>;
|
|
16
18
|
|
|
@@ -23,6 +25,8 @@ interface SmartCheckboxProps {
|
|
|
23
25
|
defaultValue?: boolean;
|
|
24
26
|
info?: string;
|
|
25
27
|
subLabel?: string;
|
|
28
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
29
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
26
30
|
}
|
|
27
31
|
declare const SmartCheckbox: React__default.FC<SmartCheckboxProps>;
|
|
28
32
|
|
|
@@ -42,6 +46,8 @@ interface SmartRadioGroupProps {
|
|
|
42
46
|
defaultValue?: string;
|
|
43
47
|
info?: string;
|
|
44
48
|
subLabel?: string;
|
|
49
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
50
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
45
51
|
}
|
|
46
52
|
declare const SmartRadioGroup: React__default.FC<SmartRadioGroupProps>;
|
|
47
53
|
|
|
@@ -60,6 +66,8 @@ interface SmartSelectProps {
|
|
|
60
66
|
defaultValue?: string;
|
|
61
67
|
info?: string;
|
|
62
68
|
subLabel?: string;
|
|
69
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
70
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
63
71
|
}
|
|
64
72
|
declare const SmartSelect: React__default.FC<SmartSelectProps>;
|
|
65
73
|
|
|
@@ -85,6 +93,8 @@ interface SmartDatePickerProps {
|
|
|
85
93
|
defaultValue?: Date | string;
|
|
86
94
|
info?: string;
|
|
87
95
|
subLabel?: string;
|
|
96
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
97
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
88
98
|
}
|
|
89
99
|
declare const SmartDatePicker: React__default.FC<SmartDatePickerProps>;
|
|
90
100
|
|
|
@@ -100,7 +110,8 @@ interface SmartTagsProps {
|
|
|
100
110
|
maxLength?: number;
|
|
101
111
|
minLength?: number;
|
|
102
112
|
allowDuplicates?: boolean;
|
|
103
|
-
disabled?: boolean;
|
|
113
|
+
disabled?: boolean | ((formData: any) => boolean);
|
|
114
|
+
hidden?: boolean | ((formData: any) => boolean);
|
|
104
115
|
onTagAdd?: (tagText: string) => void;
|
|
105
116
|
onTagRemove?: (tagText: string) => void;
|
|
106
117
|
info?: string;
|
|
@@ -222,46 +222,40 @@ var SmartFormProvider = ({
|
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const result = await response.json();
|
|
231
|
-
if (config.onSuccess) {
|
|
232
|
-
config.onSuccess(result);
|
|
225
|
+
let responseBody;
|
|
226
|
+
try {
|
|
227
|
+
responseBody = await response.json();
|
|
228
|
+
} catch {
|
|
229
|
+
responseBody = await response.text();
|
|
233
230
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
231
|
+
const responseData = {
|
|
232
|
+
status: response.status,
|
|
233
|
+
statusText: response.statusText,
|
|
234
|
+
body: responseBody
|
|
235
|
+
};
|
|
236
|
+
if (response.status >= 200 && response.status < 300) {
|
|
237
|
+
if (config.onSuccess) {
|
|
238
|
+
config.onSuccess(responseData);
|
|
239
|
+
}
|
|
240
|
+
for (const hook of submitHooksRef.current.values()) {
|
|
241
|
+
try {
|
|
242
|
+
await hook();
|
|
243
|
+
} catch (hookError) {
|
|
244
|
+
console.error("Submit hook error:", hookError);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
if (config.onError) {
|
|
249
|
+
config.onError(responseData);
|
|
239
250
|
}
|
|
240
251
|
}
|
|
241
252
|
} catch (error) {
|
|
242
253
|
if (config.onError) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (error.message === "Failed to fetch" || error.message?.includes("Failed to fetch")) {
|
|
249
|
-
userFriendlyMessage = "This service is temporarily unavailable. Please try again after some time.";
|
|
250
|
-
} else if (error.message?.includes("Network Error")) {
|
|
251
|
-
userFriendlyMessage = "Network error occurred. Please check your connection and try again.";
|
|
252
|
-
} else if (error.message?.includes("timeout")) {
|
|
253
|
-
userFriendlyMessage = "Request timed out. Please try again.";
|
|
254
|
-
} else if (error.message?.includes("CORS")) {
|
|
255
|
-
userFriendlyMessage = "Connection error. Please contact support if this persists.";
|
|
256
|
-
} else if (error.message && error.message !== "An error occurred") {
|
|
257
|
-
userFriendlyMessage = error.message;
|
|
258
|
-
}
|
|
259
|
-
errorData = {
|
|
260
|
-
message: userFriendlyMessage,
|
|
261
|
-
details: []
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
config.onError(errorData);
|
|
254
|
+
config.onError({
|
|
255
|
+
status: 0,
|
|
256
|
+
statusText: "Network Error",
|
|
257
|
+
body: error.message || "An error occurred"
|
|
258
|
+
});
|
|
265
259
|
}
|
|
266
260
|
console.error("Form submission error:", error);
|
|
267
261
|
} finally {
|
|
@@ -350,11 +344,21 @@ var SmartFormProvider = ({
|
|
|
350
344
|
});
|
|
351
345
|
}
|
|
352
346
|
}
|
|
353
|
-
|
|
354
|
-
|
|
347
|
+
let responseBody;
|
|
348
|
+
try {
|
|
349
|
+
responseBody = await response.json();
|
|
350
|
+
} catch {
|
|
351
|
+
responseBody = await response.text();
|
|
352
|
+
}
|
|
353
|
+
if (response.status >= 200 && response.status < 300) {
|
|
354
|
+
console.log("Draft saved successfully:", responseBody);
|
|
355
|
+
} else {
|
|
356
|
+
console.error("Draft save failed:", {
|
|
357
|
+
status: response.status,
|
|
358
|
+
statusText: response.statusText,
|
|
359
|
+
body: responseBody
|
|
360
|
+
});
|
|
355
361
|
}
|
|
356
|
-
const result = await response.json();
|
|
357
|
-
console.log("Draft saved successfully:", result);
|
|
358
362
|
} catch (error) {
|
|
359
363
|
console.error("Draft save error:", error);
|
|
360
364
|
} finally {
|
|
@@ -518,13 +522,19 @@ var SmartInput = ({
|
|
|
518
522
|
required = false,
|
|
519
523
|
defaultValue,
|
|
520
524
|
info,
|
|
521
|
-
subLabel
|
|
525
|
+
subLabel,
|
|
526
|
+
disabled,
|
|
527
|
+
hidden
|
|
522
528
|
}) => {
|
|
529
|
+
const { formData } = useSmartForm();
|
|
523
530
|
const { value, error, onChange, fieldRef, registerValidation } = useFormField(field);
|
|
524
531
|
const fieldDetection = useFieldDetection();
|
|
525
532
|
const hasRegistered = useRef(false);
|
|
526
533
|
const hasSetDefault = useRef(false);
|
|
527
534
|
const [showPassword, setShowPassword] = useState(false);
|
|
535
|
+
const isDisabled = typeof disabled === "function" ? disabled(formData) : disabled || false;
|
|
536
|
+
const isHidden = typeof hidden === "function" ? hidden(formData) : hidden || false;
|
|
537
|
+
if (isHidden) return null;
|
|
528
538
|
const togglePasswordVisibility = () => {
|
|
529
539
|
setShowPassword(!showPassword);
|
|
530
540
|
};
|
|
@@ -564,7 +574,8 @@ var SmartInput = ({
|
|
|
564
574
|
className: `w-full ${error ? "border-destructive" : ""} ${className}`,
|
|
565
575
|
placeholder: getPlaceholder(),
|
|
566
576
|
rows: 4,
|
|
567
|
-
"data-field": field
|
|
577
|
+
"data-field": field,
|
|
578
|
+
disabled: isDisabled
|
|
568
579
|
}
|
|
569
580
|
);
|
|
570
581
|
case "password":
|
|
@@ -578,7 +589,8 @@ var SmartInput = ({
|
|
|
578
589
|
onChange: (e) => onChange(e.target.value),
|
|
579
590
|
className: `w-full pr-10 ${error ? "border-destructive" : ""} ${className}`,
|
|
580
591
|
placeholder: getPlaceholder(),
|
|
581
|
-
"data-field": field
|
|
592
|
+
"data-field": field,
|
|
593
|
+
disabled: isDisabled
|
|
582
594
|
}
|
|
583
595
|
),
|
|
584
596
|
/* @__PURE__ */ jsx(
|
|
@@ -601,7 +613,8 @@ var SmartInput = ({
|
|
|
601
613
|
onChange: (e) => onChange(e.target.value),
|
|
602
614
|
className: `w-full ${error ? "border-destructive" : ""} ${className}`,
|
|
603
615
|
placeholder: getPlaceholder(),
|
|
604
|
-
"data-field": field
|
|
616
|
+
"data-field": field,
|
|
617
|
+
disabled: isDisabled
|
|
605
618
|
}
|
|
606
619
|
);
|
|
607
620
|
}
|
|
@@ -627,5 +640,5 @@ var SmartInput = ({
|
|
|
627
640
|
};
|
|
628
641
|
|
|
629
642
|
export { FieldDetectionContext, Input, Label, SmartFormProvider, SmartInput, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, cn, useFieldDetection, useFormField, useSmartForm };
|
|
630
|
-
//# sourceMappingURL=chunk-
|
|
631
|
-
//# sourceMappingURL=chunk-
|
|
643
|
+
//# sourceMappingURL=chunk-3L7TKJIB.js.map
|
|
644
|
+
//# sourceMappingURL=chunk-3L7TKJIB.js.map
|