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 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
+ [![npm version](https://badge.fury.io/js/finform-react-builder.svg)](https://www.npmjs.com/package/finform-react-builder)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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,3 @@
1
+ import { default as React } from 'react';
2
+ import { FieldRendererProps } from './types';
3
+ export declare const FieldRenderer: React.FC<FieldRendererProps>;
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+ import { FinFormProps } from './types';
3
+ export declare const FinForm: React.FC<FinFormProps>;
@@ -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,7 @@
1
+ import { FieldConfig } from './types';
2
+ import * as yup from 'yup';
3
+ export declare const generateSchema: (fields: FieldConfig[]) => yup.ObjectSchema<{
4
+ [x: string]: any;
5
+ }, yup.AnyObject, {
6
+ [x: string]: any;
7
+ }, "">;
@@ -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';