@enerjisaformlibrary/formbuilder-react 1.0.8 → 1.0.22

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
@@ -1,6 +1,22 @@
1
1
  # @enerjisaformlibrary/formbuilder-react
2
2
 
3
- Standalone drag-and-drop form builder React component with CSS included. No additional dependencies required!
3
+ Professional drag-and-drop form builder React component with 20+ field types, multi-step wizard support, conditional logic, undo/redo history, and JSON export/import.
4
+
5
+ ## Features
6
+
7
+ - **20+ Field Types**: Text, textarea, number, email, phone, URL, password, date, time, date range, dropdown, checkbox, radio, toggle, multi-select, file upload, signature pad, star rating, slider, color picker, rich text editor, autocomplete, QR code, pattern format, and more
8
+ - **Drag & Drop**: Intuitive drag-and-drop interface for building forms
9
+ - **Multi-Step Wizard**: Create multi-step forms with progress indicator
10
+ - **Conditional Logic**: Show/hide/enable/disable fields based on conditions
11
+ - **Undo/Redo**: Full undo/redo support with 50-state history
12
+ - **Grid Layout**: 12-column responsive grid system
13
+ - **Containers**: Nested row/column layouts within containers
14
+ - **JSON Export/Import**: Export forms as JSON and import them back
15
+ - **Custom Styling**: Per-field CSS class customization
16
+ - **Form Versioning**: Save and restore form versions
17
+ - **Tooltips**: Help text support for fields
18
+ - **Actions System**: onClick, onChange, onFocus, onBlur event handlers
19
+ - **Tab Index**: Keyboard navigation order for form fields
4
20
 
5
21
  ## Installation
6
22
 
@@ -8,47 +24,490 @@ Standalone drag-and-drop form builder React component with CSS included. No addi
8
24
  npm install @enerjisaformlibrary/formbuilder-react
9
25
  ```
10
26
 
11
- ## Usage
27
+ ## Quick Start
12
28
 
13
29
  ```tsx
14
- import { FormBuilder, useFormStore } from '@enerjisaformlibrary/formbuilder-react';
30
+ import { FormBuilder } from '@enerjisaformlibrary/formbuilder-react';
15
31
  import '@enerjisaformlibrary/formbuilder-react/styles.css';
16
32
 
17
33
  function App() {
18
- const handleChange = (form) => {
19
- console.log('Form changed:', form);
34
+ const handleSave = (formSchema) => {
35
+ console.log('Form saved:', formSchema);
36
+ // Save to your database
20
37
  };
21
38
 
22
- const handleSave = (form) => {
23
- // Save form JSON to your database
24
- console.log('Save form:', JSON.stringify(form));
39
+ const handleChange = (formSchema) => {
40
+ console.log('Form changed:', formSchema);
25
41
  };
26
42
 
27
43
  return (
28
- <div style={{ height: '100vh' }}>
29
- <FormBuilder
30
- onChange={handleChange}
31
- onSave={handleSave}
32
- theme="light"
33
- />
34
- </div>
44
+ <FormBuilder
45
+ onSave={handleSave}
46
+ onChange={handleChange}
47
+ />
35
48
  );
36
49
  }
37
50
  ```
38
51
 
39
- ## Features
52
+ ## Props
53
+
54
+ | Prop | Type | Required | Description |
55
+ |------|------|----------|-------------|
56
+ | `initialSchema` | `FormSchema` | No | Initial form schema to load |
57
+ | `onSave` | `(schema: FormSchema) => void` | No | Called when user clicks Save button |
58
+ | `onChange` | `(schema: FormSchema) => void` | No | Called on every form change |
59
+
60
+ ## Form Schema Structure
61
+
62
+ ```typescript
63
+ interface FormSchema {
64
+ id: string;
65
+ name: string;
66
+ description?: string;
67
+ isMultiStep: boolean;
68
+ currentVersion: number;
69
+ rows: FormRow[]; // For single-page forms
70
+ steps?: FormStep[]; // For multi-step forms
71
+ settings?: FormSettings;
72
+ submissionConfig?: SubmissionConfig;
73
+ versions?: FormVersion[];
74
+ }
75
+
76
+ interface FormRow {
77
+ id: string;
78
+ columns: FormColumn[];
79
+ conditionalLogic?: ConditionalLogic;
80
+ }
81
+
82
+ interface FormColumn {
83
+ id: string;
84
+ width: number; // 1-12 (grid columns)
85
+ fields: FormField[];
86
+ responsiveWidth?: ResponsiveWidth;
87
+ }
88
+
89
+ interface FormField {
90
+ id: string;
91
+ type: FieldType;
92
+ props: FieldProps;
93
+ validation?: FieldValidation;
94
+ conditionalLogic?: ConditionalLogic;
95
+ customStyle?: CustomStyle;
96
+ }
97
+ ```
98
+
99
+ ## Field Types
100
+
101
+ ### Basic Fields
102
+ - `input` - Single line text input
103
+ - `textarea` - Multi-line text area
104
+ - `number` - Numeric input
105
+ - `email` - Email input with validation
106
+ - `password` - Password input
107
+ - `phone` - Phone number input
108
+ - `url` - URL input
109
+
110
+ ### Date & Time
111
+ - `date` - Date picker
112
+ - `time` - Time picker
113
+ - `daterange` - Date range picker
114
+
115
+ ### Selection Fields
116
+ - `dropdown` - Single select dropdown
117
+ - `checkbox` - Checkbox field
118
+ - `radio` - Radio button group
119
+ - `toggle` - Toggle switch
120
+ - `multiselect` - Multi-select with tags
121
+
122
+ ### Advanced Fields
123
+ - `file` - File upload with drag-drop
124
+ - `signature` - Signature pad with canvas drawing
125
+ - `rating` - Star rating (configurable max stars)
126
+ - `slider` - Range slider with min/max
127
+ - `color` - Color picker with hex input
128
+ - `richtext` - Rich text editor
129
+ - `autocomplete` - Autocomplete input
130
+ - `pattern` - Pattern format input (phone, credit card, etc.)
131
+ - `qrcode` - Static QR code display
132
+
133
+ ### Static Elements
134
+ - `header` - Section header
135
+ - `label` - Static label text
136
+ - `paragraph` - Paragraph text
137
+ - `divider` - Horizontal divider
138
+ - `spacer` - Vertical spacer
139
+ - `alert` - Alert/notification box
140
+ - `image` - Image placeholder
141
+ - `button` - Submit/reset/custom action buttons
142
+
143
+ ### Structure
144
+ - `container` - Grouping element with nested rows/columns
145
+
146
+ ## Field Props
147
+
148
+ ```typescript
149
+ interface FieldProps {
150
+ key: string; // Unique field key for form data
151
+ label?: string; // Field label
152
+ placeholder?: string; // Placeholder text
153
+ tooltip?: string; // Help tooltip text
154
+ optionsString?: string; // Options for dropdown/radio/checkbox (one per line)
155
+ size?: 'small' | 'medium' | 'large';
156
+ autoFocus?: boolean;
157
+ tabIndex?: number; // Keyboard navigation order (positive = order, -1 = skip, 0 = natural order)
158
+ htmlAttributes?: Record<string, string>;
159
+
160
+ // Button specific
161
+ buttonConfig?: {
162
+ buttonType: 'submit' | 'reset' | 'button';
163
+ variant: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
164
+ actionType?: 'submit' | 'reset' | 'navigate' | 'custom';
165
+ navigateUrl?: string;
166
+ customAction?: string;
167
+ };
168
+
169
+ // Pattern format specific
170
+ patternConfig?: {
171
+ format: 'phone' | 'creditCard' | 'date' | 'ssn' | 'custom';
172
+ mask?: string;
173
+ customPattern?: string;
174
+ };
175
+
176
+ // QR Code specific
177
+ qrCodeConfig?: {
178
+ value: string;
179
+ size: number;
180
+ };
181
+
182
+ // Container specific
183
+ containerConfig?: {
184
+ rows: ContainerRow[];
185
+ gap?: number;
186
+ padding?: number;
187
+ borderStyle?: 'none' | 'solid' | 'dashed';
188
+ };
189
+
190
+ // Rating specific
191
+ maxRating?: number;
192
+
193
+ // Slider specific
194
+ min?: number;
195
+ max?: number;
196
+ step?: number;
197
+ }
198
+ ```
199
+
200
+ ## Tab Index Usage
201
+
202
+ The `tabIndex` property controls keyboard navigation order when users press Tab to move between form fields:
203
+
204
+ | Value | Behavior |
205
+ |-------|----------|
206
+ | Positive (1, 2, 3...) | Field is focused in order from lowest to highest tabIndex |
207
+ | 0 | Field follows natural DOM order |
208
+ | -1 | Field is skipped during Tab navigation |
209
+
210
+ **Example:** To create a custom tab order:
211
+ - First Name: tabIndex = 1
212
+ - Email: tabIndex = 2
213
+ - Last Name: tabIndex = 3
214
+ - Phone: tabIndex = 4
215
+
216
+ When user presses Tab, they'll move: First Name → Email → Last Name → Phone
217
+
218
+ **Important:** tabIndex only works in **Preview Mode**. In editor mode, fields don't receive focus in the same way.
219
+
220
+ ## Validation
221
+
222
+ ```typescript
223
+ interface FieldValidation {
224
+ required?: boolean;
225
+ minLength?: number;
226
+ maxLength?: number;
227
+ min?: number;
228
+ max?: number;
229
+ pattern?: string;
230
+ customMessage?: string;
231
+ }
232
+ ```
233
+
234
+ ## Conditional Logic
235
+
236
+ ```typescript
237
+ interface ConditionalLogic {
238
+ enabled: boolean;
239
+ action: 'show' | 'hide' | 'enable' | 'disable' | 'require';
240
+ conditions: Condition[];
241
+ logicOperator: 'and' | 'or';
242
+ }
243
+
244
+ interface Condition {
245
+ fieldKey: string;
246
+ operator: 'equals' | 'notEquals' | 'contains' | 'notContains' |
247
+ 'greaterThan' | 'lessThan' | 'isEmpty' | 'isNotEmpty';
248
+ value: string;
249
+ }
250
+ ```
251
+
252
+ ## Custom Styling
253
+
254
+ ```typescript
255
+ interface CustomStyle {
256
+ containerClassName?: string; // CSS class for field container
257
+ labelClassName?: string; // CSS class for label
258
+ inputClassName?: string; // CSS class for input element
259
+ css?: string; // Custom CSS (applied inline)
260
+ }
261
+ ```
262
+
263
+ ## Actions System
264
+
265
+ Each field can have event handlers:
266
+
267
+ ```typescript
268
+ interface FieldActions {
269
+ onClick?: FieldAction;
270
+ onChange?: FieldAction;
271
+ onFocus?: FieldAction;
272
+ onBlur?: FieldAction;
273
+ }
274
+
275
+ interface FieldAction {
276
+ type: 'showMessage' | 'hideField' | 'showField' | 'clearField' |
277
+ 'setFieldValue' | 'focusField' | 'submitForm' | 'custom' | 'code';
278
+ args?: {
279
+ message?: string;
280
+ targetFieldKey?: string;
281
+ value?: string;
282
+ code?: string;
283
+ };
284
+ }
285
+ ```
286
+
287
+ ## Multi-Step Forms
288
+
289
+ ```typescript
290
+ interface FormStep {
291
+ id: string;
292
+ title: string;
293
+ description?: string;
294
+ order: number;
295
+ rows: FormRow[];
296
+ validation?: {
297
+ validateOnNext?: boolean;
298
+ allowSkip?: boolean;
299
+ };
300
+ }
301
+ ```
302
+
303
+ ## Example: Complete Form Schema
304
+
305
+ ```json
306
+ {
307
+ "id": "contact-form",
308
+ "name": "Contact Form",
309
+ "isMultiStep": false,
310
+ "currentVersion": 1,
311
+ "rows": [
312
+ {
313
+ "id": "row-1",
314
+ "columns": [
315
+ {
316
+ "id": "col-1",
317
+ "width": 6,
318
+ "fields": [
319
+ {
320
+ "id": "field-1",
321
+ "type": "input",
322
+ "props": {
323
+ "key": "firstName",
324
+ "label": "First Name",
325
+ "placeholder": "Enter your first name",
326
+ "tabIndex": 1
327
+ },
328
+ "validation": {
329
+ "required": true,
330
+ "minLength": 2
331
+ }
332
+ }
333
+ ]
334
+ },
335
+ {
336
+ "id": "col-2",
337
+ "width": 6,
338
+ "fields": [
339
+ {
340
+ "id": "field-2",
341
+ "type": "input",
342
+ "props": {
343
+ "key": "lastName",
344
+ "label": "Last Name",
345
+ "placeholder": "Enter your last name",
346
+ "tabIndex": 2
347
+ },
348
+ "validation": {
349
+ "required": true
350
+ }
351
+ }
352
+ ]
353
+ }
354
+ ]
355
+ },
356
+ {
357
+ "id": "row-2",
358
+ "columns": [
359
+ {
360
+ "id": "col-3",
361
+ "width": 12,
362
+ "fields": [
363
+ {
364
+ "id": "field-3",
365
+ "type": "email",
366
+ "props": {
367
+ "key": "email",
368
+ "label": "Email Address",
369
+ "placeholder": "you@example.com",
370
+ "tooltip": "We'll never share your email",
371
+ "tabIndex": 3
372
+ },
373
+ "validation": {
374
+ "required": true
375
+ }
376
+ }
377
+ ]
378
+ }
379
+ ]
380
+ },
381
+ {
382
+ "id": "row-3",
383
+ "columns": [
384
+ {
385
+ "id": "col-4",
386
+ "width": 12,
387
+ "fields": [
388
+ {
389
+ "id": "field-4",
390
+ "type": "dropdown",
391
+ "props": {
392
+ "key": "country",
393
+ "label": "Country",
394
+ "optionsString": "USA\nCanada\nUK\nGermany\nFrance\nOther",
395
+ "tabIndex": 4
396
+ }
397
+ }
398
+ ]
399
+ }
400
+ ]
401
+ },
402
+ {
403
+ "id": "row-4",
404
+ "columns": [
405
+ {
406
+ "id": "col-5",
407
+ "width": 12,
408
+ "fields": [
409
+ {
410
+ "id": "field-5",
411
+ "type": "textarea",
412
+ "props": {
413
+ "key": "message",
414
+ "label": "Message",
415
+ "placeholder": "How can we help you?",
416
+ "tabIndex": 5
417
+ },
418
+ "validation": {
419
+ "required": true,
420
+ "minLength": 10,
421
+ "maxLength": 500
422
+ }
423
+ }
424
+ ]
425
+ }
426
+ ]
427
+ },
428
+ {
429
+ "id": "row-5",
430
+ "columns": [
431
+ {
432
+ "id": "col-6",
433
+ "width": 12,
434
+ "fields": [
435
+ {
436
+ "id": "field-6",
437
+ "type": "button",
438
+ "props": {
439
+ "key": "submit",
440
+ "label": "Submit",
441
+ "buttonConfig": {
442
+ "buttonType": "submit",
443
+ "variant": "primary",
444
+ "actionType": "submit"
445
+ }
446
+ }
447
+ }
448
+ ]
449
+ }
450
+ ]
451
+ }
452
+ ]
453
+ }
454
+ ```
455
+
456
+ ## Integration with JetDesk
457
+
458
+ ```tsx
459
+ import { FormBuilder } from '@enerjisaformlibrary/formbuilder-react';
460
+ import '@enerjisaformlibrary/formbuilder-react/styles.css';
461
+
462
+ function FormEditor({ formId }) {
463
+ const [initialSchema, setInitialSchema] = useState(null);
464
+
465
+ useEffect(() => {
466
+ // Load existing form from database
467
+ fetch(`/api/forms/${formId}`)
468
+ .then(res => res.json())
469
+ .then(data => setInitialSchema(data.schema));
470
+ }, [formId]);
471
+
472
+ const handleSave = async (schema) => {
473
+ await fetch(`/api/forms/${formId}`, {
474
+ method: 'PUT',
475
+ headers: { 'Content-Type': 'application/json' },
476
+ body: JSON.stringify({ schema })
477
+ });
478
+ };
479
+
480
+ if (!initialSchema) return <div>Loading...</div>;
481
+
482
+ return (
483
+ <FormBuilder
484
+ initialSchema={initialSchema}
485
+ onSave={handleSave}
486
+ />
487
+ );
488
+ }
489
+ ```
490
+
491
+ ## Keyboard Shortcuts
492
+
493
+ - **Ctrl/Cmd + Z**: Undo
494
+ - **Ctrl/Cmd + Shift + Z**: Redo
495
+
496
+ ## Browser Support
497
+
498
+ - Chrome (latest)
499
+ - Firefox (latest)
500
+ - Safari (latest)
501
+ - Edge (latest)
502
+
503
+ ## Changelog
504
+
505
+ ### 1.0.22
506
+ - Fixed: tabIndex now properly applied to all interactive field types (dropdown, checkbox, radio, toggle, slider, autocomplete, daterange)
40
507
 
41
- - 20+ field types (input, textarea, dropdown, checkbox, radio, date, file, signature, rating, etc.)
42
- - Drag-and-drop interface
43
- - Multi-step wizard forms
44
- - Conditional logic (show/hide/enable/disable fields)
45
- - Custom styling per field
46
- - Form versioning
47
- - JSON export/import
48
- - Responsive grid system (12-column)
49
- - Dark/Light theme support
50
- - **Container support**: Drop fields into containers with multiple columns
51
- - **Column support**: Drop fields into existing columns
508
+ ### 1.0.21
509
+ - Added: Comprehensive undo/redo functionality with 50-state history
510
+ - Each form modification creates a separate history entry
52
511
 
53
512
  ## License
54
513