finform-react-builder 1.2.1
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 +21 -0
- package/README.md +621 -0
- package/dist/components/FinForm/FieldRenderer.d.ts +3 -0
- package/dist/components/FinForm/FinForm.d.ts +3 -0
- package/dist/components/FinForm/ImageComponent.d.ts +12 -0
- package/dist/components/FinForm/StepNavigation.d.ts +10 -0
- package/dist/components/FinForm/generateSchema.d.ts +7 -0
- package/dist/components/FinForm/index.d.ts +6 -0
- package/dist/components/FinForm/types.d.ts +92 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +9317 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ritik
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
# finform-react-builder
|
|
2
|
+
|
|
3
|
+
A powerful, flexible React form builder with dynamic field rendering, custom validation, and Material-UI integration.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/finform-react-builder)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## 🚨 Migration Notice
|
|
9
|
+
|
|
10
|
+
**If you're currently using this package from GitHub Packages**, you'll need to update your installation:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Remove the old package
|
|
14
|
+
npm uninstall @finflow-analytics/finform-react-builder
|
|
15
|
+
|
|
16
|
+
# Install from public npm registry
|
|
17
|
+
npm install finform-react-builder
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If you have a `.npmrc` file with GitHub Packages configuration, remove the line:
|
|
21
|
+
```
|
|
22
|
+
@finflow-analytics:registry=https://npm.pkg.github.com
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## ✨ Features
|
|
26
|
+
|
|
27
|
+
- 🎨 **Material-UI Integration** - Beautiful, responsive form components
|
|
28
|
+
- 🔧 **Dynamic Field Rendering** - Support for text, email, password, number, select, checkbox, date, and textarea fields
|
|
29
|
+
- ✅ **Advanced Validation** - Built-in validation with custom regex patterns and validation functions
|
|
30
|
+
- 📱 **Responsive Grid System** - Flexible column-based layout system
|
|
31
|
+
- 🎯 **TypeScript Support** - Full type safety and IntelliSense support
|
|
32
|
+
- 🚀 **Easy Integration** - Simple API with sensible defaults
|
|
33
|
+
- 🔄 **Real-time Validation** - Instant feedback with react-hook-form
|
|
34
|
+
- 🎨 **Customizable** - Highly configurable with custom validation rules
|
|
35
|
+
- 🔄 **Multi-Step Forms** - Support for step-by-step form completion with smart navigation
|
|
36
|
+
- 💾 **Stateless Design** - Works with data from backend/config without local storage dependencies
|
|
37
|
+
|
|
38
|
+
## 📦 Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install finform-react-builder
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Peer Dependencies
|
|
45
|
+
|
|
46
|
+
Make sure you have the required peer dependencies installed:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install react react-dom @mui/material @emotion/react @emotion/styled
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 🚀 Quick Start
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import React from 'react';
|
|
56
|
+
import { FinForm, FieldConfig } from 'finform-react-builder';
|
|
57
|
+
|
|
58
|
+
const fields: FieldConfig[] = [
|
|
59
|
+
{
|
|
60
|
+
name: 'firstName',
|
|
61
|
+
label: 'First Name',
|
|
62
|
+
type: 'text',
|
|
63
|
+
placeholder: 'Enter your first name',
|
|
64
|
+
required: true,
|
|
65
|
+
col: 6
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'lastName',
|
|
69
|
+
label: 'Last Name',
|
|
70
|
+
type: 'text',
|
|
71
|
+
placeholder: 'Enter your last name',
|
|
72
|
+
required: true,
|
|
73
|
+
col: 6
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'email',
|
|
77
|
+
label: 'Email',
|
|
78
|
+
type: 'email',
|
|
79
|
+
placeholder: 'Enter your email',
|
|
80
|
+
required: true,
|
|
81
|
+
col: 12
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
function App() {
|
|
86
|
+
const handleSubmit = (data: any) => {
|
|
87
|
+
console.log('Form submitted:', data);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<FinForm
|
|
92
|
+
fields={fields}
|
|
93
|
+
onSubmit={handleSubmit}
|
|
94
|
+
submitButtonText="Submit Form"
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default App;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 📋 Field Types
|
|
103
|
+
|
|
104
|
+
### Text Fields
|
|
105
|
+
```tsx
|
|
106
|
+
{
|
|
107
|
+
name: 'username',
|
|
108
|
+
label: 'Username',
|
|
109
|
+
type: 'text',
|
|
110
|
+
placeholder: 'Enter username',
|
|
111
|
+
validation: {
|
|
112
|
+
pattern: /^[a-zA-Z0-9_]+$/,
|
|
113
|
+
message: 'Username can only contain letters, numbers, and underscores'
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Email Fields
|
|
119
|
+
```tsx
|
|
120
|
+
{
|
|
121
|
+
name: 'email',
|
|
122
|
+
label: 'Email Address',
|
|
123
|
+
type: 'email',
|
|
124
|
+
placeholder: 'Enter your email',
|
|
125
|
+
required: true
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Number Fields
|
|
130
|
+
```tsx
|
|
131
|
+
{
|
|
132
|
+
name: 'age',
|
|
133
|
+
label: 'Age',
|
|
134
|
+
type: 'number',
|
|
135
|
+
placeholder: 'Enter your age',
|
|
136
|
+
validation: {
|
|
137
|
+
min: 18,
|
|
138
|
+
max: 120,
|
|
139
|
+
message: 'Age must be between 18 and 120'
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Select Fields
|
|
145
|
+
```tsx
|
|
146
|
+
{
|
|
147
|
+
name: 'country',
|
|
148
|
+
label: 'Country',
|
|
149
|
+
type: 'select',
|
|
150
|
+
options: [
|
|
151
|
+
{ label: 'United States', value: 'us' },
|
|
152
|
+
{ label: 'Canada', value: 'ca' },
|
|
153
|
+
{ label: 'United Kingdom', value: 'uk' }
|
|
154
|
+
],
|
|
155
|
+
required: true
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Date Fields
|
|
160
|
+
```tsx
|
|
161
|
+
{
|
|
162
|
+
name: 'birthDate',
|
|
163
|
+
label: 'Birth Date',
|
|
164
|
+
type: 'date',
|
|
165
|
+
validation: {
|
|
166
|
+
custom: (value) => {
|
|
167
|
+
const today = new Date();
|
|
168
|
+
const birthDate = new Date(value);
|
|
169
|
+
return birthDate < today;
|
|
170
|
+
},
|
|
171
|
+
message: 'Birth date must be in the past'
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Image Fields
|
|
177
|
+
```tsx
|
|
178
|
+
{
|
|
179
|
+
name: 'profileImage',
|
|
180
|
+
label: 'Profile Image',
|
|
181
|
+
type: 'image',
|
|
182
|
+
src: 'https://example.com/image.jpg',
|
|
183
|
+
alt: 'User profile image',
|
|
184
|
+
width: 300,
|
|
185
|
+
height: 200,
|
|
186
|
+
style: {
|
|
187
|
+
border: '2px solid #e0e0e0',
|
|
188
|
+
borderRadius: '8px'
|
|
189
|
+
},
|
|
190
|
+
onClick: () => {
|
|
191
|
+
console.log('Image clicked!');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Textarea Fields
|
|
197
|
+
```tsx
|
|
198
|
+
{
|
|
199
|
+
name: 'bio',
|
|
200
|
+
label: 'Biography',
|
|
201
|
+
type: 'textarea',
|
|
202
|
+
placeholder: 'Tell us about yourself...',
|
|
203
|
+
validation: {
|
|
204
|
+
maxLength: 500,
|
|
205
|
+
message: 'Biography must be less than 500 characters'
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Checkbox Fields
|
|
211
|
+
```tsx
|
|
212
|
+
{
|
|
213
|
+
name: 'newsletter',
|
|
214
|
+
label: 'Subscribe to Newsletter',
|
|
215
|
+
type: 'checkbox',
|
|
216
|
+
required: true
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 🔧 Advanced Validation
|
|
221
|
+
|
|
222
|
+
### Custom Regex Patterns
|
|
223
|
+
```tsx
|
|
224
|
+
{
|
|
225
|
+
name: 'phoneNumber',
|
|
226
|
+
label: 'Phone Number',
|
|
227
|
+
type: 'text',
|
|
228
|
+
placeholder: '+1 (555) 123-4567',
|
|
229
|
+
validation: {
|
|
230
|
+
pattern: /^\+?[1-9]\d{1,14}$/,
|
|
231
|
+
message: 'Please enter a valid phone number'
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Custom Validation Functions
|
|
237
|
+
```tsx
|
|
238
|
+
{
|
|
239
|
+
name: 'password',
|
|
240
|
+
label: 'Password',
|
|
241
|
+
type: 'password',
|
|
242
|
+
placeholder: 'Enter password',
|
|
243
|
+
validation: {
|
|
244
|
+
minLength: 8,
|
|
245
|
+
custom: (value) => {
|
|
246
|
+
const hasUpperCase = /[A-Z]/.test(value);
|
|
247
|
+
const hasLowerCase = /[a-z]/.test(value);
|
|
248
|
+
const hasNumbers = /\d/.test(value);
|
|
249
|
+
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value);
|
|
250
|
+
|
|
251
|
+
return hasUpperCase && hasLowerCase && hasNumbers && hasSpecialChar;
|
|
252
|
+
},
|
|
253
|
+
message: 'Password must contain uppercase, lowercase, number and special character'
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## 📐 Grid System
|
|
259
|
+
|
|
260
|
+
Use the responsive grid system to control field layout:
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
// Full width field
|
|
264
|
+
{ name: 'description', type: 'textarea', col: 12 }
|
|
265
|
+
|
|
266
|
+
// Half width fields
|
|
267
|
+
{ name: 'firstName', type: 'text', col: 6 }
|
|
268
|
+
{ name: 'lastName', type: 'text', col: 6 }
|
|
269
|
+
|
|
270
|
+
// Responsive breakpoints
|
|
271
|
+
{
|
|
272
|
+
name: 'address',
|
|
273
|
+
type: 'text',
|
|
274
|
+
xs: 12, // Full width on extra small screens
|
|
275
|
+
md: 8, // 8/12 width on medium screens
|
|
276
|
+
lg: 6 // Half width on large screens
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## 🔄 Multi-Step Forms
|
|
281
|
+
|
|
282
|
+
FinForm supports multi-step forms with smart navigation and completion tracking. Perfect for complex forms that need to be broken down into manageable steps.
|
|
283
|
+
|
|
284
|
+
### Basic Multi-Step Form
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
const multiStepFields: FieldConfig[] = [
|
|
288
|
+
// Step 1: Personal Information
|
|
289
|
+
{
|
|
290
|
+
name: 'firstName',
|
|
291
|
+
label: 'First Name',
|
|
292
|
+
type: 'text',
|
|
293
|
+
required: true,
|
|
294
|
+
step: 1,
|
|
295
|
+
col: 6,
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'lastName',
|
|
299
|
+
label: 'Last Name',
|
|
300
|
+
type: 'text',
|
|
301
|
+
required: true,
|
|
302
|
+
step: 1,
|
|
303
|
+
col: 6,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'email',
|
|
307
|
+
label: 'Email Address',
|
|
308
|
+
type: 'email',
|
|
309
|
+
required: true,
|
|
310
|
+
step: 1,
|
|
311
|
+
col: 12,
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
// Step 2: Address Information
|
|
315
|
+
{
|
|
316
|
+
name: 'street',
|
|
317
|
+
label: 'Street Address',
|
|
318
|
+
type: 'text',
|
|
319
|
+
required: true,
|
|
320
|
+
step: 2,
|
|
321
|
+
col: 12,
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: 'city',
|
|
325
|
+
label: 'City',
|
|
326
|
+
type: 'text',
|
|
327
|
+
required: true,
|
|
328
|
+
step: 2,
|
|
329
|
+
col: 6,
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: 'state',
|
|
333
|
+
label: 'State',
|
|
334
|
+
type: 'select',
|
|
335
|
+
required: true,
|
|
336
|
+
step: 2,
|
|
337
|
+
col: 3,
|
|
338
|
+
options: [
|
|
339
|
+
{ label: 'California', value: 'CA' },
|
|
340
|
+
{ label: 'New York', value: 'NY' },
|
|
341
|
+
{ label: 'Texas', value: 'TX' },
|
|
342
|
+
],
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: 'zipCode',
|
|
346
|
+
label: 'ZIP Code',
|
|
347
|
+
type: 'text',
|
|
348
|
+
required: true,
|
|
349
|
+
step: 2,
|
|
350
|
+
col: 3,
|
|
351
|
+
validation: {
|
|
352
|
+
pattern: /^\d{5}(-\d{4})?$/,
|
|
353
|
+
message: 'Please enter a valid ZIP code',
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
// Step 3: Preferences
|
|
358
|
+
{
|
|
359
|
+
name: 'newsletter',
|
|
360
|
+
label: 'Subscribe to Newsletter',
|
|
361
|
+
type: 'checkbox',
|
|
362
|
+
step: 3,
|
|
363
|
+
col: 12,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: 'preferences',
|
|
367
|
+
label: 'Communication Preferences',
|
|
368
|
+
type: 'select',
|
|
369
|
+
step: 3,
|
|
370
|
+
col: 6,
|
|
371
|
+
options: [
|
|
372
|
+
{ label: 'Email', value: 'email' },
|
|
373
|
+
{ label: 'Phone', value: 'phone' },
|
|
374
|
+
{ label: 'Both', value: 'both' },
|
|
375
|
+
],
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
|
|
379
|
+
function MultiStepForm() {
|
|
380
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
381
|
+
|
|
382
|
+
const handleStepChange = (step: number, totalSteps: number) => {
|
|
383
|
+
console.log(`Moving to step ${step} of ${totalSteps}`);
|
|
384
|
+
setCurrentStep(step);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
return (
|
|
388
|
+
<FinForm
|
|
389
|
+
fields={multiStepFields}
|
|
390
|
+
onSubmit={(data) => console.log('Form submitted:', data)}
|
|
391
|
+
isMultiStep={true}
|
|
392
|
+
currentStep={currentStep}
|
|
393
|
+
onStepChange={handleStepChange}
|
|
394
|
+
submitButtonText="Complete Registration"
|
|
395
|
+
stepNavigationProps={{
|
|
396
|
+
showStepNumbers: true,
|
|
397
|
+
showStepTitles: true,
|
|
398
|
+
stepTitles: ['Personal Info', 'Address', 'Preferences'],
|
|
399
|
+
}}
|
|
400
|
+
/>
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Smart Step Navigation with Backend Data
|
|
406
|
+
|
|
407
|
+
The form automatically detects completed steps and starts from the first incomplete step when data is provided:
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
// Data from backend showing user has completed step 1
|
|
411
|
+
const backendData = {
|
|
412
|
+
firstName: 'John',
|
|
413
|
+
lastName: 'Doe',
|
|
414
|
+
email: 'john.doe@example.com',
|
|
415
|
+
// Step 2 and 3 are empty
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
function SmartMultiStepForm() {
|
|
419
|
+
return (
|
|
420
|
+
<FinForm
|
|
421
|
+
fields={multiStepFields}
|
|
422
|
+
onSubmit={(data) => console.log('Form submitted:', data)}
|
|
423
|
+
defaultValues={backendData}
|
|
424
|
+
isMultiStep={true}
|
|
425
|
+
// Form will automatically start at step 2 since step 1 is complete
|
|
426
|
+
submitButtonText="Complete Registration"
|
|
427
|
+
/>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Multi-Step Form Props
|
|
433
|
+
|
|
434
|
+
| Prop | Type | Description | Default |
|
|
435
|
+
|------|------|-------------|---------|
|
|
436
|
+
| `isMultiStep` | `boolean` | Enable multi-step functionality | `false` |
|
|
437
|
+
| `currentStep` | `number` | Current step (controlled by parent) | `1` |
|
|
438
|
+
| `onStepChange` | `(step: number, totalSteps: number) => void` | Step change callback | - |
|
|
439
|
+
| `showStepNavigation` | `boolean` | Show step navigation | `true` |
|
|
440
|
+
| `stepNavigationProps` | `object` | Step navigation configuration | `{}` |
|
|
441
|
+
|
|
442
|
+
### Step Navigation Configuration
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
stepNavigationProps={{
|
|
446
|
+
showStepNumbers: true, // Show step numbers
|
|
447
|
+
showStepTitles: true, // Show step titles
|
|
448
|
+
stepTitles: ['Step 1', 'Step 2', 'Step 3'], // Custom step titles
|
|
449
|
+
}}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Field Step Assignment
|
|
453
|
+
|
|
454
|
+
Add a `step` property to any field to assign it to a specific step:
|
|
455
|
+
|
|
456
|
+
```tsx
|
|
457
|
+
{
|
|
458
|
+
name: 'fieldName',
|
|
459
|
+
label: 'Field Label',
|
|
460
|
+
type: 'text',
|
|
461
|
+
step: 1, // This field will appear in step 1
|
|
462
|
+
required: true,
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## 🎛️ API Reference
|
|
467
|
+
|
|
468
|
+
### FinForm Props
|
|
469
|
+
|
|
470
|
+
| Prop | Type | Description | Required |
|
|
471
|
+
|------|------|-------------|----------|
|
|
472
|
+
| `fields` | `FieldConfig[]` | Array of field configurations | ✅ |
|
|
473
|
+
| `onSubmit` | `(data: any) => void` | Form submission handler | ✅ |
|
|
474
|
+
| `onChange` | `(data: any) => void` | Form change handler | ❌ |
|
|
475
|
+
| `submitButtonText` | `string` | Submit button text | ❌ |
|
|
476
|
+
| `defaultValues` | `Record<string, any>` | Default form values | ❌ |
|
|
477
|
+
| `isMultiStep` | `boolean` | Enable multi-step functionality | ❌ |
|
|
478
|
+
| `currentStep` | `number` | Current step (controlled by parent) | ❌ |
|
|
479
|
+
| `onStepChange` | `(step: number, totalSteps: number) => void` | Step change callback | ❌ |
|
|
480
|
+
| `showStepNavigation` | `boolean` | Show step navigation | ❌ |
|
|
481
|
+
| `stepNavigationProps` | `object` | Step navigation configuration | ❌ |
|
|
482
|
+
|
|
483
|
+
### Field Configuration
|
|
484
|
+
|
|
485
|
+
```tsx
|
|
486
|
+
interface BaseField {
|
|
487
|
+
name: string;
|
|
488
|
+
label: string;
|
|
489
|
+
type: 'text' | 'email' | 'password' | 'number' | 'select' | 'checkbox' | 'date' | 'textarea' | 'image';
|
|
490
|
+
placeholder?: string;
|
|
491
|
+
required?: boolean;
|
|
492
|
+
disabled?: boolean;
|
|
493
|
+
validation?: ValidationRule;
|
|
494
|
+
step?: number; // Step number for multi-step forms (1-based)
|
|
495
|
+
col?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
496
|
+
xs?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
497
|
+
sm?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
498
|
+
md?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
499
|
+
lg?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
500
|
+
xl?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
interface ImageField extends BaseField {
|
|
504
|
+
type: 'image';
|
|
505
|
+
src?: string; // Image source URL
|
|
506
|
+
alt?: string; // Alt text for accessibility
|
|
507
|
+
width?: number | string; // Image width
|
|
508
|
+
height?: number | string; // Image height
|
|
509
|
+
style?: React.CSSProperties; // Custom styles
|
|
510
|
+
className?: string; // Custom CSS class
|
|
511
|
+
onClick?: () => void; // Click handler
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Validation Rules
|
|
516
|
+
|
|
517
|
+
```tsx
|
|
518
|
+
interface ValidationRule {
|
|
519
|
+
pattern?: string | RegExp;
|
|
520
|
+
message?: string;
|
|
521
|
+
required?: boolean;
|
|
522
|
+
minLength?: number;
|
|
523
|
+
maxLength?: number;
|
|
524
|
+
min?: number;
|
|
525
|
+
max?: number;
|
|
526
|
+
custom?: (value: any) => boolean | string;
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
## 💡 Examples
|
|
531
|
+
|
|
532
|
+
### Complete Registration Form
|
|
533
|
+
|
|
534
|
+
```tsx
|
|
535
|
+
const registrationFields: FieldConfig[] = [
|
|
536
|
+
{
|
|
537
|
+
name: 'firstName',
|
|
538
|
+
label: 'First Name',
|
|
539
|
+
type: 'text',
|
|
540
|
+
placeholder: 'Enter first name',
|
|
541
|
+
required: true,
|
|
542
|
+
col: 6
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
name: 'lastName',
|
|
546
|
+
label: 'Last Name',
|
|
547
|
+
type: 'text',
|
|
548
|
+
placeholder: 'Enter last name',
|
|
549
|
+
required: true,
|
|
550
|
+
col: 6
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
name: 'email',
|
|
554
|
+
label: 'Email',
|
|
555
|
+
type: 'email',
|
|
556
|
+
placeholder: 'Enter email address',
|
|
557
|
+
required: true,
|
|
558
|
+
col: 12
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
name: 'password',
|
|
562
|
+
label: 'Password',
|
|
563
|
+
type: 'password',
|
|
564
|
+
placeholder: 'Enter password',
|
|
565
|
+
required: true,
|
|
566
|
+
col: 6,
|
|
567
|
+
validation: {
|
|
568
|
+
minLength: 8,
|
|
569
|
+
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
|
|
570
|
+
message: 'Password must be at least 8 characters with uppercase, lowercase, number and special character'
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
name: 'confirmPassword',
|
|
575
|
+
label: 'Confirm Password',
|
|
576
|
+
type: 'password',
|
|
577
|
+
placeholder: 'Confirm password',
|
|
578
|
+
required: true,
|
|
579
|
+
col: 6
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
name: 'agreeToTerms',
|
|
583
|
+
label: 'I agree to the Terms and Conditions',
|
|
584
|
+
type: 'checkbox',
|
|
585
|
+
required: true,
|
|
586
|
+
col: 12
|
|
587
|
+
}
|
|
588
|
+
];
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## 🛠️ Development
|
|
592
|
+
|
|
593
|
+
### Building the Library
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# Build for production
|
|
597
|
+
npm run build:lib
|
|
598
|
+
|
|
599
|
+
# Build types only
|
|
600
|
+
npm run build:types
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Running Development Server
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
npm run dev
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
## 📄 License
|
|
610
|
+
|
|
611
|
+
MIT © [Ritik](https://github.com/finflow-analytics/finform)
|
|
612
|
+
|
|
613
|
+
## 🤝 Contributing
|
|
614
|
+
|
|
615
|
+
Contributions, issues and feature requests are welcome!
|
|
616
|
+
|
|
617
|
+
Feel free to check [issues page](https://github.com/finflow-analytics/finform/issues).
|
|
618
|
+
|
|
619
|
+
## 📞 Support
|
|
620
|
+
|
|
621
|
+
If you like this project, please ⭐ star it on [GitHub](https://github.com/finflow-analytics/finform)!
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
interface ImageComponentProps {
|
|
3
|
+
src?: string;
|
|
4
|
+
alt?: string;
|
|
5
|
+
width?: number | string;
|
|
6
|
+
height?: number | string;
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
className?: string;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const ImageComponent: React.FC<ImageComponentProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface StepNavigationProps {
|
|
3
|
+
currentStep: number;
|
|
4
|
+
totalSteps: number;
|
|
5
|
+
onStepChange: (step: number) => void;
|
|
6
|
+
stepTitles?: string[];
|
|
7
|
+
showStepTitles?: boolean;
|
|
8
|
+
completedSteps?: number[];
|
|
9
|
+
}
|
|
10
|
+
export declare const StepNavigation: React.FC<StepNavigationProps>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { FinForm } from './FinForm';
|
|
2
|
+
export { FieldRenderer } from './FieldRenderer';
|
|
3
|
+
export { StepNavigation } from './StepNavigation';
|
|
4
|
+
export { ImageComponent } from './ImageComponent';
|
|
5
|
+
export { generateSchema } from './generateSchema';
|
|
6
|
+
export type { FieldConfig, BaseField, TextField, NumberField, SelectField, CheckboxField, DateField, ImageField, FinFormProps, FieldRendererProps, ValidationRule, StepNavigationProps, } from './types';
|