ynotsoft-dynamic-form 1.0.55 → 1.0.59

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 ADDED
@@ -0,0 +1,632 @@
1
+ # DynamicForm Component - Complete Field Reference
2
+
3
+ ## Install and Development Setup (Bun Monorepo)
4
+
5
+ This project uses **Bun** as the package manager and **Vite** with custom path aliasing for Hot Module Replacement (HMR) in the monorepo workspace.
6
+
7
+ ### 1\. Prerequisites
8
+
9
+ You **must** have **Bun** installed to manage dependencies and run development scripts.
10
+ ( <https://bun.com/docs/installation> )
11
+
12
+ > Can now use npm instead of bun </br>
13
+ > node ^v22.7.0 required
14
+
15
+ ### 2\. Install Dependencies
16
+
17
+ From the root of the repository (`dynamic-form/`):
18
+
19
+ ```bash
20
+ # Install all dependencies and create workspace symlinks using Bun
21
+ bun install
22
+ ```
23
+
24
+ ### 3\. Build the Library (Initial Setup)
25
+
26
+ Because the library's `package.json` entry points point to files in the `/dist` directory, you must run an initial build so the example app can resolve the dependency.
27
+
28
+ From the root of the repository:
29
+
30
+ ```bash
31
+ npm run build #runs: bun run --filter @ynotsoft/dynamic-form build
32
+ ```
33
+
34
+ or you can use npm commands using the workspace (--workspace) flag and passing in the name of the package
35
+
36
+ ```
37
+ npm run build --workspace ynotsoft-dynamic-form
38
+ ```
39
+
40
+ ### 4\. Start the Example App
41
+
42
+ Run the development server for the example application.
43
+
44
+ From the root of the repository:
45
+
46
+ ```bash
47
+ npm run example #runs: bun --filter example dev
48
+ ```
49
+
50
+ or you can use npm commands using the workspace (--workspace) flag and passing in the name of the package
51
+
52
+ ```
53
+ npm run dev --workspace ynotsoft-dynamic-form
54
+ ```
55
+
56
+ > **IMPORTANT NOTE ON HMR (Hot Module Replacement):**
57
+ > If HMR fails for changes made in the `packages/dynamic-form-lib/` source code, ensure your `example-app/vite.config.js` has the necessary **Path Aliasing** configured to bypass the symlink watcher issue. This is configured to resolve HMR issues and is essential for local development.
58
+
59
+ ### 5\. How to push changes
60
+
61
+ #### For Regular Development Changes:
62
+ ```bash
63
+ # 1. Commit your changes
64
+ git add .
65
+ git commit -m "feat: your change description"
66
+
67
+ # 2. Create tag
68
+ git tag v1.0.[version-number]
69
+ ```
70
+
71
+ #### For NPM Package Releases:
72
+ ```bash
73
+ # 1. Update version in package.json (in packages/dynamic-form-lib/)
74
+ npm version patch # for bug fixes (1.0.0 → 1.0.1)
75
+
76
+ # 2. Build the library
77
+ npm run build
78
+
79
+ # 3. Create and push version tag
80
+ git push origin v1.0.[version-number] # Replace with your actual version
81
+
82
+ # 4. GitHub Actions will automatically publish to NPM
83
+ ```
84
+
85
+ #### Version Management:
86
+ - **Single Source of Truth:** Version is maintained in `packages/dynamic-form-lib/package.json`
87
+ - **Git Tags:** Use format `v1.0.[version-number]` (matches package.json version with "v" prefix)
88
+ - **NPM Registry:** GitHub Actions reads git tag, strips "v" prefix, publishes as `1.0.[version-number]` to NPM
89
+ - **Auto-Sync:** Git tag version must match package.json version for successful deployment
90
+
91
+ **Quick Check:**
92
+ ```bash
93
+ # Verify versions match before pushing
94
+ cat packages/dynamic-form-lib/package.json | grep version
95
+ git tag --list | tail -1
96
+ ```
97
+
98
+ > **Note:** The GitHub Actions workflow automatically publishes to NPM when you push a version tag (e.g., `v1.0.[version-number]`). No manual `npm publish` required unless you are not logged into NPM already.
99
+
100
+ ---
101
+
102
+ ## Overview
103
+
104
+ The DynamicForm component provides a flexible, declarative way to build forms with various field types, validation, conditional logic, and styling options.
105
+
106
+ ## Basic Usage
107
+
108
+ ```javascript
109
+ import { DynamicForm } from "@ynotsoft/dynamic-form"; // Note the package name
110
+
111
+ const formDefinition = {
112
+ fields: [
113
+ // Field definitions here
114
+ ],
115
+ };
116
+
117
+ <DynamicForm
118
+ formDefinition={formDefinition}
119
+ returnType= {false}
120
+ defaultValues={{ name: "John Doe" }}
121
+ sendFormValues={(values) => console.log(values)}
122
+ onFieldsChange={(values) => console.log("Changed:", values)}
123
+ />;
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Field Types
129
+
130
+ ### 1\. Header Field
131
+
132
+ Used for section titles and form organization.
133
+
134
+ ```javascript
135
+ {
136
+ type: 'header',
137
+ label: 'Personal Information',
138
+ size: 'xl', // 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'
139
+ align: 'left', // 'left' | 'center' | 'right'
140
+ underline: true // Boolean - adds bottom border
141
+ }
142
+ ```
143
+
144
+ ### 2\. Input Field
145
+
146
+ Standard text input with shadcn/ui styling.
147
+
148
+ ```javascript
149
+ {
150
+ name: 'fullName',
151
+ label: 'Full Name',
152
+ type: 'input',
153
+ required: true,
154
+ placeholder: 'Enter your name',
155
+ value: 'John Doe',
156
+ disabled: false,
157
+ maxLength: 100,
158
+ validate: (value) => {
159
+ if (value.length < 2) return 'Name must be at least 2 characters';
160
+ return null;
161
+ }
162
+ }
163
+ ```
164
+
165
+ ### 3\. Email Field
166
+
167
+ Email input with validation and shadcn/ui styling.
168
+
169
+ ```javascript
170
+ {
171
+ name: 'email',
172
+ label: 'Email Address',
173
+ type: 'email',
174
+ required: true,
175
+ placeholder: 'you@example.com',
176
+ value: 'john@example.com'
177
+ }
178
+ ```
179
+
180
+ ### 4\. TextArea Field
181
+
182
+ Multi-line text input.
183
+
184
+ ```javascript
185
+ {
186
+ name: 'description',
187
+ label: 'Description',
188
+ type: 'textarea',
189
+ required: false,
190
+ placeholder: 'Enter description...',
191
+ rows: 4,
192
+ maxLength: 500,
193
+ showCharCount: true,
194
+ value: 'Initial description'
195
+ }
196
+ ```
197
+
198
+ ### 5\. Select Field
199
+
200
+ Dropdown selection with single choice.
201
+
202
+ ```javascript
203
+ {
204
+ name: 'country',
205
+ label: 'Country',
206
+ type: 'select',
207
+ required: true,
208
+ value: 'us',
209
+ options: [
210
+ { value: '', label: 'Select a country' },
211
+ { value: 'us', label: 'United States' },
212
+ { value: 'uk', label: 'United Kingdom' },
213
+ { value: 'ca', label: 'Canada' }
214
+ ],
215
+ // Dynamic options from API
216
+ optionsUrl: '/api/countries',
217
+ dependsOn: 'region' // Reload when 'region' changes
218
+ }
219
+ ```
220
+
221
+ ### 6\. MultiSelect Field
222
+
223
+ Multiple selection dropdown.
224
+
225
+ ```javascript
226
+ {
227
+ name: 'interests',
228
+ label: 'Interests',
229
+ type: 'multiselect',
230
+ required: true,
231
+ value: ['sports', 'tech'],
232
+ options: [
233
+ { value: 'sports', label: 'Sports' },
234
+ { value: 'music', label: 'Music' },
235
+ { value: 'tech', label: 'Technology' },
236
+ { value: 'travel', label: 'Travel' }
237
+ ],
238
+ validate: (value) => {
239
+ if (value && value.length > 3) return 'Select up to 3 interests';
240
+ return null;
241
+ }
242
+ }
243
+ ```
244
+
245
+ ### 6\. Search Select Field
246
+
247
+ Search for selections and select multiple/single
248
+
249
+ ```javascript
250
+ {
251
+ name: "username",
252
+ label: "Search for Users",
253
+ type: "searchselect",
254
+ required: true,
255
+ placeholder: "Type to search users...",
256
+ // layout: "inline", // default inline
257
+ layout: "dialog",
258
+ optionsUrl: "/api/users/search", // API endpoint
259
+ minSearchLength: 2, // Minimum characters before search (default: 2)
260
+ selectMode: "single", // 'single' | 'multiple' (default: 'single')
261
+ }
262
+ ```
263
+
264
+ ### 7\. Checkbox Field
265
+
266
+ Single checkbox with flexible layouts and card styling.
267
+
268
+ ```javascript
269
+ {
270
+ name: 'agreeTerms',
271
+ label: 'I agree to terms',
272
+ type: 'checkbox',
273
+ required: true,
274
+ value: false,
275
+ description: 'By checking this, you agree to our terms and conditions',
276
+ options: [
277
+ { value: 'option1', label: 'Option 1', description: '' },
278
+ { value: 'option2', label: 'Option 2', description: '' },
279
+ { value: 'option3', label: 'Option 3', description: '' },
280
+ // Layout options
281
+ layout: 'inline', // 'inline' | 'stacked' | 'default'
282
+
283
+ // Card container styling
284
+ containerStyle: 'card', // Wraps in bordered card
285
+ color: 'blue', // 'green' | 'blue' | 'red' | 'yellow' | 'purple' | 'indigo' | 'gray' | 'pink' | 'orange'
286
+ }
287
+ ```
288
+
289
+ **Checkbox Layouts:**
290
+
291
+ - `default`: Standard checkbox with label above
292
+ - `inline`: Checkbox and label side-by-side
293
+ - `stacked`: Checkbox, label, and description stacked vertically
294
+
295
+ ### 8\. Radio Group Field
296
+
297
+ Single selection from multiple options using Radix UI.
298
+
299
+ ```javascript
300
+ {
301
+ name: 'paymentMethod',
302
+ label: 'Payment Method',
303
+ type: 'radiogroup',
304
+ required: true,
305
+ value: 'card',
306
+ options: [
307
+ { value: 'card', label: 'Credit Card' },
308
+ { value: 'paypal', label: 'PayPal' },
309
+ { value: 'bank', label: 'Bank Transfer' }
310
+ ],
311
+
312
+ // Layout options
313
+ inline: true, // Display options horizontally
314
+
315
+ // Color variants
316
+ color: 'blue', // 'green' | 'blue' | 'red' | 'yellow' | 'purple' | 'indigo' | 'gray' | 'pink' | 'orange'
317
+
318
+ // Card container styling
319
+ containerStyle: 'card',
320
+ color: 'green'
321
+ }
322
+ ```
323
+
324
+ ### 9\. Date Picker Field
325
+
326
+ Single date selection with shadcn/ui calendar.
327
+
328
+ ```javascript
329
+ {
330
+ name: 'birthDate',
331
+ label: 'Birth Date',
332
+ type: 'date',
333
+ required: true,
334
+ placeholder: 'Select date',
335
+ value: new Date('1990-01-01')
336
+ }
337
+ ```
338
+
339
+ **Features:**
340
+
341
+ - Year/month dropdown selectors
342
+ - Clear and Done buttons
343
+ - Blue highlight for selected date
344
+ - Popover interface
345
+
346
+ ### 10\. Date Range Picker Field
347
+
348
+ Select date ranges (from/to).
349
+
350
+ ```javascript
351
+ {
352
+ name: 'projectDates',
353
+ label: 'Project Timeline',
354
+ type: 'dateRange',
355
+ required: true,
356
+ placeholder: 'Select date range',
357
+ value: {
358
+ from: new Date('2025-01-01'),
359
+ to: new Date('2025-12-31')
360
+ }
361
+ }
362
+ ```
363
+
364
+ ### 11\. Time Field
365
+
366
+ Time picker with AM/PM selection.
367
+
368
+ ```javascript
369
+ {
370
+ name: 'appointmentTime',
371
+ label: 'Appointment Time',
372
+ type: 'time',
373
+ required: true,
374
+ placeholder: 'Select time',
375
+ value: '03:45 PM'
376
+ }
377
+ ```
378
+
379
+ **Features:**
380
+
381
+ - Hour/minute spinners
382
+ - AM/PM toggle buttons
383
+ - Clear and Done buttons
384
+ - Format: "HH:MM AM/PM"
385
+
386
+ ### 12\. Date Time Picker Field
387
+
388
+ Combined date and time selection.
389
+
390
+ ```javascript
391
+ {
392
+ name: 'meetingDateTime',
393
+ label: 'Meeting Date & Time',
394
+ type: 'dayTimePicker',
395
+ required: true,
396
+ value: new Date('2025-10-17T15:30:00')
397
+ }
398
+ ```
399
+
400
+ ### 13\. File Upload Field
401
+
402
+ Single or multiple file uploads.
403
+
404
+ ```javascript
405
+ {
406
+ name: 'documents',
407
+ label: 'Upload Documents',
408
+ type: 'file', // or 'multifile' for multiple
409
+ required: true,
410
+ accept: '.pdf,.doc,.docx,.jpg,.jpeg,.png',
411
+ maxSize: 5 * 1024 * 1024, // 5 MB
412
+ multiple: false
413
+ }
414
+ ```
415
+
416
+ ### 14\. Hidden Field
417
+
418
+ Store hidden values in the form.
419
+
420
+ ```javascript
421
+ {
422
+ name: 'userId',
423
+ type: 'hidden',
424
+ value: '12345'
425
+ }
426
+ ```
427
+
428
+ ### 15\. HTML/Literal Field
429
+
430
+ Display rich HTML content (non-editable).
431
+
432
+ ```javascript
433
+ {
434
+ type: 'litertext',
435
+ content: '<div class="alert">Important notice here</div>'
436
+ }
437
+ ```
438
+
439
+ ### 16\. Alert Message Field
440
+
441
+ Display contextual alert messages with icons (info, success, warning, error).
442
+
443
+ ```javascript
444
+ {
445
+ type: 'alert',
446
+ variant: 'info', // 'info' | 'success' | 'warning' | 'error' | 'danger'
447
+ message: 'This is an informational message'
448
+ }
449
+
450
+ // Success alert
451
+ {
452
+ type: 'alert',
453
+ variant: 'success',
454
+ message: 'Your form was submitted successfully!'
455
+ }
456
+ // ... other variants omitted for brevity ...
457
+ ```
458
+
459
+ ### 17\. Line Break Field
460
+
461
+ Add visual spacing between sections.
462
+
463
+ ```javascript
464
+ {
465
+ type: "linebreak";
466
+ }
467
+ ```
468
+
469
+ ---
470
+
471
+ ## Global Field Format Options
472
+
473
+ Apply consistent styling to all fields (except header, html, linebreak, hidden, alert):
474
+
475
+ ```javascript
476
+ {
477
+ name: 'email',
478
+ label: 'Email',
479
+ type: 'email',
480
+
481
+ // Card container
482
+ containerStyle: 'card',
483
+ color: 'blue', // Card border/accent color
484
+
485
+ // Layout for checkbox/radio
486
+ layout: 'inline', // or 'stacked' | 'default'
487
+ inline: true, // For radio groups
488
+ }
489
+ ```
490
+
491
+ ---
492
+
493
+ ## Advanced Features
494
+
495
+ ### Conditional Display
496
+
497
+ Show/hide fields based on other values:
498
+
499
+ ```javascript
500
+ {
501
+ name: 'state',
502
+ label: 'State',
503
+ type: 'select',
504
+ showIf: (values) => values.country === 'us',
505
+ options: [...]
506
+ }
507
+ ```
508
+
509
+ ### Conditional Disable
510
+
511
+ Disable fields based on conditions:
512
+
513
+ ```javascript
514
+ {
515
+ name: 'billingAddress',
516
+ label: 'Billing Address',
517
+ type: 'input',
518
+ disabled: (values) => values.sameAsShipping === true
519
+ }
520
+ ```
521
+
522
+ ### Custom Validation
523
+
524
+ Field-level validation functions:
525
+
526
+ ```javascript
527
+ {
528
+ name: 'password',
529
+ label: 'Password',
530
+ type: 'input',
531
+ validate: (value) => {
532
+ if (value.length < 8) return 'Password must be at least 8 characters';
533
+ if (!/[A-Z]/.test(value)) return 'Must contain uppercase letter';
534
+ if (!/[0-9]/.test(value)) return 'Must contain a number';
535
+ return null;
536
+ }
537
+ }
538
+ ```
539
+
540
+ ### Dynamic Options
541
+
542
+ Load options from API:
543
+
544
+ ```javascript
545
+ {
546
+ name: 'city',
547
+ label: 'City',
548
+ type: 'select',
549
+ optionsUrl: '/api/cities',
550
+ dependsOn: 'state', // Reload when state changes
551
+ }
552
+ ```
553
+
554
+ ---
555
+
556
+ ## Complete Example
557
+
558
+ ```javascript
559
+ // ... formDefinition omitted for brevity ...
560
+
561
+ // Usage
562
+ <DynamicForm
563
+ formDefinition={formDefinition}
564
+ defaultValues={{
565
+ fullName: "John Doe",
566
+ email: "john@example.com",
567
+ contactMethod: "email",
568
+ }}
569
+ sendFormValues={(values) => {
570
+ console.log("Form submitted:", values);
571
+ }}
572
+ onFieldsChange={(values) => {
573
+ console.log("Form changed:", values);
574
+ }}
575
+ />
576
+ ```
577
+
578
+ ---
579
+
580
+ ## Styling Reference
581
+
582
+ ### Card Container Colors
583
+
584
+ Available for `containerStyle='card'`:
585
+
586
+ - `green` - Green border and accent
587
+ - `blue` - Blue border and accent
588
+ - `red` - Red border and accent
589
+ - `yellow` - Yellow border and accent
590
+ - `purple` - Purple border and accent
591
+ - `indigo` - Indigo border and accent
592
+ - `gray` - Gray border and accent
593
+ - `pink` - Pink border and accent
594
+ - `orange` - Orange border and accent
595
+
596
+ ### Header Sizes
597
+
598
+ - `sm` - Small header
599
+ - `md` - Medium header
600
+ - `lg` - Large header
601
+ - `xl` - Extra large (default)
602
+ - `2xl` - 2X large
603
+ - `3xl` - 3X large
604
+ - `4xl` - 4X large
605
+
606
+ ### Layout Options (Checkbox/Radio)
607
+
608
+ - `default` - Standard vertical layout
609
+ - `inline` - Horizontal with label beside control
610
+ - `stacked` - Vertical with description below
611
+
612
+ ---
613
+
614
+ ## Props
615
+
616
+ ### DynamicForm Props
617
+
618
+ - `formDefinition` - Object containing field definitions
619
+ - `defaultValues` - Initial form values
620
+ - `sendFormValues` - Callback when form is submitted
621
+ - `onFieldsChange` - Callback when any field changes
622
+ - `children` - Additional content (e.g., submit button)
623
+
624
+ ---
625
+
626
+ ## Notes
627
+
628
+ - All fields support `required`, `disabled`, `showIf` properties
629
+ - Fields are automatically validated on blur and submit
630
+ - Error messages display below invalid fields
631
+ - Form values are managed internally with React state
632
+ - shadcn/ui components used for consistent styling