df-ae-forms-package 1.0.0 → 1.0.2

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/QUICK-START.md ADDED
@@ -0,0 +1,205 @@
1
+ # Quick Start Guide - Ionic/Angular Integration
2
+
3
+ This is a condensed quick start guide. For detailed documentation, see [INTEGRATION-GUIDE.md](./INTEGRATION-GUIDE.md).
4
+
5
+ ## 1. Install Dependencies
6
+
7
+ ```bash
8
+ npm install df-ae-forms-package react react-dom react-i18next lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
9
+ npm install --save-dev @types/react @types/react-dom
10
+ ```
11
+
12
+ ## 2. Add Styles
13
+
14
+ In `src/global.scss`:
15
+
16
+ ```scss
17
+ @import '~df-ae-forms-package/dist/index.css';
18
+ ```
19
+
20
+ ## 3. Create React Wrapper Service
21
+
22
+ Create `src/app/services/react-wrapper.service.ts`:
23
+
24
+ ```typescript
25
+ import { Injectable, ApplicationRef } from '@angular/core';
26
+ import { createElement } from 'react';
27
+ import { createRoot, Root } from 'react-dom/client';
28
+
29
+ @Injectable({ providedIn: 'root' })
30
+ export class ReactWrapperService {
31
+ private reactRoots: Map<string, Root> = new Map();
32
+
33
+ renderReactComponent(containerId: string, component: any, props: any): void {
34
+ setTimeout(() => {
35
+ try {
36
+ const container = document.getElementById(containerId);
37
+ if (!container) return;
38
+
39
+ container.innerHTML = '';
40
+ let root = this.reactRoots.get(containerId);
41
+ if (root) {
42
+ root.unmount();
43
+ }
44
+ root = createRoot(container);
45
+ this.reactRoots.set(containerId, root);
46
+ root.render(createElement(component, props));
47
+ } catch (error) {
48
+ console.error('Error rendering React component:', error);
49
+ }
50
+ }, 0);
51
+ }
52
+
53
+ unmountReactComponent(containerId: string): void {
54
+ const root = this.reactRoots.get(containerId);
55
+ if (root) {
56
+ root.unmount();
57
+ this.reactRoots.delete(containerId);
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## 4. Setup i18n
64
+
65
+ Create `src/app/services/react-i18n.service.ts`:
66
+
67
+ ```typescript
68
+ import { Injectable } from '@angular/core';
69
+ import i18n from 'i18next';
70
+ import { initReactI18next } from 'react-i18next';
71
+
72
+ @Injectable({ providedIn: 'root' })
73
+ export class ReactI18nService {
74
+ async initialize(): Promise<void> {
75
+ await i18n.use(initReactI18next).init({
76
+ resources: {
77
+ en: { translation: { 'formBuilder.submit': 'Submit' } }
78
+ },
79
+ lng: 'en',
80
+ fallbackLng: 'en'
81
+ });
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## 5. Create Form Component
87
+
88
+ Create `src/app/components/form-preview/form-preview.component.ts`:
89
+
90
+ ```typescript
91
+ import { Component, OnInit, OnDestroy, Input, ViewChild, ElementRef, AfterViewInit, ChangeDetectorRef } from '@angular/core';
92
+ import { ReactWrapperService } from '../../services/react-wrapper.service';
93
+ import { ReactI18nService } from '../../services/react-i18n.service';
94
+ import type { FormComponentType, DfFormPreviewProps } from 'df-ae-forms-package';
95
+
96
+ @Component({
97
+ selector: 'app-form-preview',
98
+ template: `
99
+ <div *ngIf="loading">Loading...</div>
100
+ <div #reactContainer [id]="containerId" [style.display]="loading ? 'none' : 'block'"></div>
101
+ `,
102
+ styles: [`[id^="df-form-container"] { width: 100%; }`]
103
+ })
104
+ export class FormPreviewComponent implements OnInit, AfterViewInit, OnDestroy {
105
+ @Input() formComponents: FormComponentType[] = [];
106
+ @Input() formData: Record<string, any> = {};
107
+ @Input() mode: 'edit' | 'preview' | 'test' = 'test';
108
+
109
+ @ViewChild('reactContainer') container!: ElementRef;
110
+ loading = true;
111
+ containerId = `df-form-container-${Math.random().toString(36).substr(2, 9)}`;
112
+ private DfFormPreview: any = null;
113
+
114
+ constructor(
115
+ private reactWrapper: ReactWrapperService,
116
+ private reactI18n: ReactI18nService,
117
+ private cdr: ChangeDetectorRef
118
+ ) {}
119
+
120
+ async ngOnInit(): Promise<void> {
121
+ await this.reactI18n.initialize();
122
+ // Dynamically import to avoid initialization issues
123
+ const module = await import('df-ae-forms-package');
124
+ this.DfFormPreview = module.DfFormPreview;
125
+ this.loading = false;
126
+ this.cdr.detectChanges();
127
+ }
128
+
129
+ ngAfterViewInit(): void {
130
+ setTimeout(() => this.renderForm(), 0);
131
+ }
132
+
133
+ ngOnDestroy(): void {
134
+ this.reactWrapper.unmountReactComponent(this.containerId);
135
+ }
136
+
137
+ private renderForm(): void {
138
+ if (!this.container || !this.DfFormPreview) return;
139
+
140
+ const props: DfFormPreviewProps = {
141
+ formComponents: this.formComponents,
142
+ initialFormData: this.formData,
143
+ mode: this.mode,
144
+ currentDevice: 'desktop',
145
+ onSubmit: (data) => console.log('Submitted:', data),
146
+ onFormDataChange: (data) => console.log('Changed:', data)
147
+ };
148
+
149
+ this.reactWrapper.renderReactComponent(this.containerId, this.DfFormPreview, props);
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## 6. Use in Your Page
155
+
156
+ ```typescript
157
+ import { Component, OnInit } from '@angular/core';
158
+ import { HttpClient } from '@angular/common/http';
159
+ import type { FormComponentType } from 'df-ae-forms-package';
160
+
161
+ @Component({
162
+ template: `
163
+ <ion-content>
164
+ <app-form-preview
165
+ [formComponents]="formComponents"
166
+ [formData]="formData"
167
+ [mode]="'test'"
168
+ ></app-form-preview>
169
+ </ion-content>
170
+ `
171
+ })
172
+ export class MyPage implements OnInit {
173
+ formComponents: FormComponentType[] = [];
174
+ formData: Record<string, any> = {};
175
+
176
+ constructor(private http: HttpClient) {}
177
+
178
+ ngOnInit(): void {
179
+ // Load form from API
180
+ this.http.get<{ components: FormComponentType[] }>('YOUR_API_URL')
181
+ .subscribe(data => {
182
+ this.formComponents = data.components;
183
+ });
184
+ }
185
+ }
186
+ ```
187
+
188
+ ## 7. Register in Module
189
+
190
+ ```typescript
191
+ import { FormPreviewComponent } from './components/form-preview/form-preview.component';
192
+ import { ReactWrapperService } from './services/react-wrapper.service';
193
+ import { ReactI18nService } from './services/react-i18n.service';
194
+
195
+ @NgModule({
196
+ declarations: [FormPreviewComponent],
197
+ providers: [ReactWrapperService, ReactI18nService]
198
+ })
199
+ export class AppModule {}
200
+ ```
201
+
202
+ That's it! Your form should now render with all styles and functionality.
203
+
204
+ For complete documentation, see [INTEGRATION-GUIDE.md](./INTEGRATION-GUIDE.md).
205
+
package/README.md CHANGED
@@ -10,7 +10,6 @@ A comprehensive React form preview component library with form controls, validat
10
10
  - 🎯 **Conditional Logic**: Show/hide fields based on other field values
11
11
  - 📊 **Threshold Alerts**: Visual alerts when threshold conditions are met
12
12
  - 📝 **Component Actions**: Add notes, attachments, send emails, and raise issues for form components
13
- - 🌐 **Internationalization**: Built-in i18n support via react-i18next
14
13
  - 📱 **Device Preview**: Preview forms in different device sizes
15
14
  - 🎨 **Customizable Styling**: CSS variables for easy theming
16
15
  - 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions
@@ -27,9 +26,11 @@ npm install df-ae-forms-package
27
26
  This package requires the following peer dependencies to be installed in your project:
28
27
 
29
28
  ```bash
30
- npm install react react-dom react-i18next lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
29
+ npm install react react-dom lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
31
30
  ```
32
31
 
32
+ **Note**: Translation dependencies have been removed. The package no longer requires `react-i18next` or `i18next`.
33
+
33
34
  ## Quick Start
34
35
 
35
36
  ### 1. Import CSS
@@ -40,30 +41,7 @@ First, import the package styles in your application:
40
41
  import 'df-ae-forms-package/dist/index.css';
41
42
  ```
42
43
 
43
- ### 2. Setup i18n (Required)
44
-
45
- The package uses `react-i18next` for internationalization. You must set up i18n in your application:
46
-
47
- ```tsx
48
- import i18n from 'i18next';
49
- import { initReactI18next } from 'react-i18next';
50
-
51
- i18n
52
- .use(initReactI18next)
53
- .init({
54
- resources: {
55
- en: {
56
- translation: {
57
- 'formBuilder.submit': 'Submit'
58
- }
59
- }
60
- },
61
- lng: 'en',
62
- fallbackLng: 'en'
63
- });
64
- ```
65
-
66
- ### 3. Use the Component
44
+ ### 2. Use the Component
67
45
 
68
46
  ```tsx
69
47
  import React from 'react';
@@ -394,12 +372,32 @@ npm publish
394
372
 
395
373
  ## Integration with Angular/Ionic
396
374
 
397
- This package is designed to work with Angular/Ionic applications. To use it:
375
+ This package is designed to work with Angular/Ionic applications.
376
+
377
+ ### Documentation
378
+
379
+ - **[Quick Start Guide](./QUICK-START.md)** - Get up and running in 5 minutes
380
+ - **[Complete Integration Guide](./INTEGRATION-GUIDE.md)** - Detailed step-by-step instructions with examples
398
381
 
399
- 1. Install the package and peer dependencies
400
- 2. Import the CSS file in your Angular application
401
- 3. Use React components via `@angular/react` or a similar bridge
402
- 4. Ensure i18n is properly configured
382
+ ### Quick Overview
383
+
384
+ 1. **Install dependencies:**
385
+ ```bash
386
+ npm install df-ae-forms-package react react-dom lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
387
+ ```
388
+
389
+ 2. **Import styles** in `src/global.scss`:
390
+ ```scss
391
+ @import '~df-ae-forms-package/dist/index.css';
392
+ ```
393
+
394
+ 3. **Set up React bridge** (see [Integration Guide](./INTEGRATION-GUIDE.md))
395
+
396
+ 4. **Load form data from API** and pass to the component
397
+
398
+ For complete instructions, code examples, API integration, styling, and troubleshooting, see:
399
+ - **[Quick Start Guide](./QUICK-START.md)** - For a condensed setup guide
400
+ - **[Integration Guide](./INTEGRATION-GUIDE.md)** - For comprehensive documentation
403
401
 
404
402
  ## Troubleshooting
405
403
 
@@ -415,11 +413,6 @@ This package is designed to work with Angular/Ionic applications. To use it:
415
413
  - Verify that conditional logic is not hiding components
416
414
  - Ensure that component IDs are unique
417
415
 
418
- ### i18n Issues
419
-
420
- - Make sure `react-i18next` is properly configured
421
- - Verify that translation keys exist in your i18n resources
422
- - Check that the i18n provider wraps your application
423
416
 
424
417
  ## Contributing
425
418
 
@@ -453,6 +446,5 @@ For issues and questions:
453
446
  - Component actions (notes, attachments, email, raise issue)
454
447
  - Responsive design
455
448
  - TypeScript support
456
- - i18n support
457
449
  - Drag and drop support (edit mode)
458
450
 
@@ -0,0 +1,398 @@
1
+ # Troubleshooting Guide
2
+
3
+ ## Common Issues and Solutions
4
+
5
+ ### Issue: "Cannot access 'qi' before initialization" Error
6
+
7
+ **Error Message:**
8
+ ```
9
+ ReferenceError: Cannot access 'qi' before initialization
10
+ at Module.DfFormPreview
11
+ ```
12
+
13
+ **Cause:**
14
+ This error occurs due to circular dependencies or timing issues when importing the React component in Angular.
15
+
16
+ **Solution:**
17
+
18
+ 1. **Use Dynamic Imports** - Import the component asynchronously:
19
+
20
+ ```typescript
21
+ // In your component
22
+ async ngOnInit(): Promise<void> {
23
+ await this.reactI18n.initialize();
24
+
25
+ // Dynamically import to avoid initialization issues
26
+ const module = await import('df-ae-forms-package');
27
+ this.DfFormPreview = module.DfFormPreview;
28
+ this.loading = false;
29
+ this.cdr.detectChanges();
30
+ }
31
+ ```
32
+
33
+ 2. **Use setTimeout in renderForm**:
34
+
35
+ ```typescript
36
+ ngAfterViewInit(): void {
37
+ setTimeout(() => {
38
+ this.renderForm();
39
+ }, 0);
40
+ }
41
+ ```
42
+
43
+ 3. **Update ReactWrapperService** to use setTimeout:
44
+
45
+ ```typescript
46
+ renderReactComponent(containerId: string, component: any, props: any): void {
47
+ setTimeout(() => {
48
+ // ... rendering code
49
+ }, 0);
50
+ }
51
+ ```
52
+
53
+ 4. **Ensure proper initialization order**:
54
+ - Initialize i18n first
55
+ - Then dynamically import the component
56
+ - Then render after view is initialized
57
+
58
+ ### Issue: Styles Not Applying
59
+
60
+ **Symptoms:**
61
+ - Form components render but without styles
62
+ - CSS variables not working
63
+ - Components look unstyled
64
+
65
+ **Solutions:**
66
+
67
+ 1. **Check CSS Import:**
68
+ ```scss
69
+ // In src/global.scss or src/styles.scss
70
+ @import '~df-ae-forms-package/dist/index.css';
71
+ ```
72
+
73
+ 2. **Verify Build Configuration:**
74
+ - Ensure Angular is configured to include node_modules CSS
75
+ - Check `angular.json`:
76
+ ```json
77
+ "styles": [
78
+ "node_modules/df-ae-forms-package/dist/index.css",
79
+ "src/styles.scss"
80
+ ]
81
+ ```
82
+
83
+ 3. **Check CSS Variables:**
84
+ ```scss
85
+ :root {
86
+ --df-color-primary: #3880ff;
87
+ // ... other variables
88
+ }
89
+ ```
90
+
91
+ 4. **Clear Build Cache:**
92
+ ```bash
93
+ rm -rf .angular
94
+ npm run build
95
+ ```
96
+
97
+ ### Issue: React Components Not Rendering
98
+
99
+ **Symptoms:**
100
+ - Container div is empty
101
+ - No errors in console
102
+ - Component doesn't appear
103
+
104
+ **Solutions:**
105
+
106
+ 1. **Check Container Element:**
107
+ ```typescript
108
+ ngAfterViewInit(): void {
109
+ // Ensure container exists
110
+ if (!this.container?.nativeElement) {
111
+ console.error('Container not found');
112
+ return;
113
+ }
114
+ this.renderForm();
115
+ }
116
+ ```
117
+
118
+ 2. **Verify React Root Creation:**
119
+ ```typescript
120
+ // Check if React root is created
121
+ console.log('Container:', document.getElementById(containerId));
122
+ ```
123
+
124
+ 3. **Check for JavaScript Errors:**
125
+ - Open browser console
126
+ - Look for any React or module errors
127
+ - Check network tab for failed module loads
128
+
129
+ 4. **Ensure i18n is Initialized:**
130
+ ```typescript
131
+ async ngOnInit(): Promise<void> {
132
+ await this.reactI18n.initialize(); // Must complete first
133
+ // Then load component
134
+ }
135
+ ```
136
+
137
+ ### Issue: Form Data Not Loading from API
138
+
139
+ **Symptoms:**
140
+ - Form renders but is empty
141
+ - API call succeeds but form doesn't update
142
+
143
+ **Solutions:**
144
+
145
+ 1. **Check API Response Format:**
146
+ ```typescript
147
+ // Ensure API returns correct format
148
+ {
149
+ components: FormComponentType[] // Array of form components
150
+ }
151
+ ```
152
+
153
+ 2. **Verify Component Update:**
154
+ ```typescript
155
+ this.formService.getFormTemplate(id).subscribe({
156
+ next: (components) => {
157
+ this.formComponents = components;
158
+ this.cdr.detectChanges(); // Trigger change detection
159
+ // Re-render form if needed
160
+ setTimeout(() => this.renderForm(), 100);
161
+ }
162
+ });
163
+ ```
164
+
165
+ 3. **Check Input Binding:**
166
+ ```html
167
+ <app-form-preview
168
+ [formComponents]="formComponents"
169
+ [formData]="formData"
170
+ ></app-form-preview>
171
+ ```
172
+
173
+ ### Issue: Type Errors
174
+
175
+ **Symptoms:**
176
+ - TypeScript compilation errors
177
+ - Type mismatches
178
+
179
+ **Solutions:**
180
+
181
+ 1. **Install Type Definitions:**
182
+ ```bash
183
+ npm install --save-dev @types/react @types/react-dom
184
+ ```
185
+
186
+ 2. **Use Type Imports:**
187
+ ```typescript
188
+ import type { FormComponentType, DfFormPreviewProps } from 'df-ae-forms-package';
189
+ ```
190
+
191
+ 3. **Check TypeScript Configuration:**
192
+ ```json
193
+ {
194
+ "compilerOptions": {
195
+ "skipLibCheck": true,
196
+ "esModuleInterop": true
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### Issue: i18n Not Working
202
+
203
+ **Symptoms:**
204
+ - Translation keys show as-is
205
+ - "formBuilder.submit" instead of "Submit"
206
+
207
+ **Solutions:**
208
+
209
+ 1. **Verify i18n Initialization:**
210
+ ```typescript
211
+ async ngOnInit(): Promise<void> {
212
+ await this.reactI18n.initialize(); // Must be awaited
213
+ }
214
+ ```
215
+
216
+ 2. **Check Translation Resources:**
217
+ ```typescript
218
+ resources: {
219
+ en: {
220
+ translation: {
221
+ 'formBuilder.submit': 'Submit'
222
+ }
223
+ }
224
+ }
225
+ ```
226
+
227
+ 3. **Ensure react-i18next is Installed:**
228
+ ```bash
229
+ npm install react-i18next i18next
230
+ ```
231
+
232
+ ### Issue: Memory Leaks
233
+
234
+ **Symptoms:**
235
+ - Performance degrades over time
236
+ - Multiple form instances in memory
237
+
238
+ **Solutions:**
239
+
240
+ 1. **Always Unmount in ngOnDestroy:**
241
+ ```typescript
242
+ ngOnDestroy(): void {
243
+ this.reactWrapper.unmountReactComponent(this.containerId);
244
+ }
245
+ ```
246
+
247
+ 2. **Clean Up Subscriptions:**
248
+ ```typescript
249
+ private destroy$ = new Subject<void>();
250
+
251
+ ngOnInit(): void {
252
+ this.formService.getFormTemplate(id)
253
+ .pipe(takeUntil(this.destroy$))
254
+ .subscribe(/* ... */);
255
+ }
256
+
257
+ ngOnDestroy(): void {
258
+ this.destroy$.next();
259
+ this.destroy$.complete();
260
+ this.reactWrapper.unmountReactComponent(this.containerId);
261
+ }
262
+ ```
263
+
264
+ ### Issue: Form Submission Not Working
265
+
266
+ **Symptoms:**
267
+ - Submit button doesn't trigger
268
+ - onSubmit callback not called
269
+
270
+ **Solutions:**
271
+
272
+ 1. **Check onSubmit Prop:**
273
+ ```typescript
274
+ const props: DfFormPreviewProps = {
275
+ // ... other props
276
+ onSubmit: (formData: Record<string, any>) => {
277
+ console.log('Form submitted:', formData);
278
+ // Handle submission
279
+ }
280
+ };
281
+ ```
282
+
283
+ 2. **Verify Form Validation:**
284
+ - Check if validation errors are preventing submission
285
+ - Ensure all required fields are filled
286
+
287
+ 3. **Check Mode:**
288
+ ```typescript
289
+ mode: 'test' // Must be 'test' for interactive forms
290
+ ```
291
+
292
+ ### Issue: Conditional Logic Not Working
293
+
294
+ **Symptoms:**
295
+ - Fields don't show/hide based on conditions
296
+ - Conditional logic seems ignored
297
+
298
+ **Solutions:**
299
+
300
+ 1. **Verify Conditional Structure:**
301
+ ```typescript
302
+ conditional: {
303
+ action: 'show', // or 'hide'
304
+ when: 'all', // or 'any'
305
+ conditions: [{
306
+ fieldId: 'other-field-id',
307
+ operator: 'equals', // or other operators
308
+ value: 'expected-value'
309
+ }]
310
+ }
311
+ ```
312
+
313
+ 2. **Check Field IDs:**
314
+ - Ensure fieldId in conditions matches actual component IDs
315
+ - IDs must be unique
316
+
317
+ 3. **Verify Form Values:**
318
+ - Conditional logic uses current form values
319
+ - Ensure values are being tracked correctly
320
+
321
+ ### Issue: Performance Issues
322
+
323
+ **Symptoms:**
324
+ - Slow rendering
325
+ - Laggy interactions
326
+
327
+ **Solutions:**
328
+
329
+ 1. **Use OnPush Change Detection:**
330
+ ```typescript
331
+ @Component({
332
+ changeDetection: ChangeDetectionStrategy.OnPush
333
+ })
334
+ ```
335
+
336
+ 2. **Debounce Form Updates:**
337
+ ```typescript
338
+ import { debounceTime } from 'rxjs/operators';
339
+
340
+ onFormDataChange(formData: Record<string, any>): void {
341
+ // Debounce updates
342
+ this.updateSubject.next(formData);
343
+ }
344
+
345
+ private updateSubject = new Subject<Record<string, any>>();
346
+
347
+ ngOnInit(): void {
348
+ this.updateSubject.pipe(
349
+ debounceTime(300)
350
+ ).subscribe(data => {
351
+ // Handle updates
352
+ });
353
+ }
354
+ ```
355
+
356
+ 3. **Lazy Load Forms:**
357
+ - Only load form when needed
358
+ - Unmount when not visible
359
+
360
+ ## Getting Help
361
+
362
+ If you're still experiencing issues:
363
+
364
+ 1. Check the browser console for detailed error messages
365
+ 2. Verify all dependencies are installed correctly
366
+ 3. Ensure you're using the latest version of the package
367
+ 4. Review the [Integration Guide](./INTEGRATION-GUIDE.md) for complete setup
368
+ 5. Check the [README](./README.md) for package-specific documentation
369
+
370
+ ## Debugging Tips
371
+
372
+ 1. **Enable React DevTools:**
373
+ ```bash
374
+ npm install --save-dev @types/react-dom
375
+ ```
376
+
377
+ 2. **Add Console Logs:**
378
+ ```typescript
379
+ private renderForm(): void {
380
+ console.log('Rendering form with:', {
381
+ components: this.formComponents.length,
382
+ data: this.formData,
383
+ container: this.container?.nativeElement
384
+ });
385
+ // ... rendering code
386
+ }
387
+ ```
388
+
389
+ 3. **Check Network Tab:**
390
+ - Verify module loads
391
+ - Check for failed requests
392
+ - Ensure CSS files load
393
+
394
+ 4. **Inspect DOM:**
395
+ - Check if React root is created
396
+ - Verify container element exists
397
+ - Look for React error boundaries
398
+