@aatulwork/customform-renderer 1.2.0 → 1.3.0
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 +61 -26
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @aatulwork/customform-renderer
|
|
2
2
|
|
|
3
3
|
A powerful, reusable form renderer component for React with Material-UI support. This package provides a dynamic form rendering system that can generate forms from JSON schemas with support for multiple field types, validation, file uploads, and more.
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@ A powerful, reusable form renderer component for React with Material-UI support.
|
|
|
16
16
|
## Installation
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npm install @
|
|
19
|
+
npm install @aatulwork/customform-renderer
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
### Peer Dependencies
|
|
@@ -27,9 +27,11 @@ Make sure you have these peer dependencies installed:
|
|
|
27
27
|
npm install react react-dom @mui/material @mui/icons-material @mui/x-date-pickers react-hook-form @tanstack/react-query dayjs @ckeditor/ckeditor5-react
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Peer versions: React ^18, MUI ^6, @mui/x-date-pickers ^7, react-hook-form ^7, @tanstack/react-query ^5, dayjs ^1.11, @ckeditor/ckeditor5-react ^11.
|
|
31
|
+
|
|
30
32
|
### CKEditor Setup
|
|
31
33
|
|
|
32
|
-
The package includes CKEditor in the `lib/ckeditor/` directory. You need to load it before using CKEditor fields.
|
|
34
|
+
The package includes CKEditor in the `lib/ckeditor/` directory. You need to load it before using CKEditor fields. **If the CKEditor field shows "CKEditor failed to load" or stays on "Loading editor...",** the script URL is not reachable—copy `lib/ckeditor/ckeditor.js` to your app’s `public/lib/ckeditor/` or set `services.ckEditorScriptPath`. See [CKEDITOR_SETUP.md](./CKEDITOR_SETUP.md) for details and troubleshooting.
|
|
33
35
|
|
|
34
36
|
**Option 1: Include in HTML (Recommended)**
|
|
35
37
|
```html
|
|
@@ -38,23 +40,34 @@ The package includes CKEditor in the `lib/ckeditor/` directory. You need to load
|
|
|
38
40
|
|
|
39
41
|
**Option 2: Copy to your public directory**
|
|
40
42
|
```bash
|
|
41
|
-
cp node_modules/@
|
|
43
|
+
cp node_modules/@aatulwork/customform-renderer/lib/ckeditor/ckeditor.js public/lib/ckeditor/
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
**Option 3: Use dynamic loading**
|
|
45
47
|
```tsx
|
|
46
|
-
import { useCKEditor } from '@
|
|
48
|
+
import { useCKEditor } from '@aatulwork/customform-renderer';
|
|
47
49
|
|
|
48
50
|
const { isReady } = useCKEditor({ autoLoad: true });
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
See [CKEditor Setup Guide](#ckeditor-setup) for more details.
|
|
52
54
|
|
|
55
|
+
## Package Exports
|
|
56
|
+
|
|
57
|
+
The package exports the following:
|
|
58
|
+
|
|
59
|
+
- **Components:** `FormRenderer`, `FieldRenderer`, `FormViewMode`, `FieldView`
|
|
60
|
+
- **Field components:** `TextField`, `SelectField`, `CheckboxField`, `RadioField`, `ToggleField`, `ColorField`, `DateTimePickerField`, `CKEditorField`, `FileField`, `FormReferenceField`, `ApiReferenceField`
|
|
61
|
+
- **Common:** `SimpleSelect` (and types `SimpleSelectProps`, `SimpleSelectOption`)
|
|
62
|
+
- **Types:** `FormSchema`, `FormField`, `FormSection`, `FormRendererProps`, `FieldRendererProps`, `FormServices`, `FileUploadService`, `FormReferenceService`, `ApiReferenceService`, `DateFormatterService`, `OptionItem`, `FieldType`, `FieldValidation`, `UploadedFile`, `FormColors`
|
|
63
|
+
- **Utils:** `getAllFields`, `normalizeInitialValues`, `transformFormValues`, `getDefaultValue`, `formatFileSize`, `validateFile`, `buildFieldRules`, `normalizeOptions`
|
|
64
|
+
- **CKEditor:** `loadCKEditor`, `isCKEditorAvailable`, `waitForCKEditor`, `useCKEditor`
|
|
65
|
+
- **Default services:** `defaultFileUploadService`, `defaultFormReferenceService`, `defaultApiReferenceService`, `defaultDateFormatterService` (throw if used without override; provide your own via `services`)
|
|
66
|
+
|
|
53
67
|
## Quick Start
|
|
54
68
|
|
|
55
69
|
```tsx
|
|
56
|
-
import { FormRenderer } from '@
|
|
57
|
-
import { FormSchema } from '@custom-form/renderer';
|
|
70
|
+
import { FormRenderer, FormSchema } from '@aatulwork/customform-renderer';
|
|
58
71
|
|
|
59
72
|
const formSchema: FormSchema = {
|
|
60
73
|
title: 'User Registration',
|
|
@@ -103,14 +116,22 @@ function App() {
|
|
|
103
116
|
|
|
104
117
|
```typescript
|
|
105
118
|
interface FormSchema {
|
|
119
|
+
_id?: string;
|
|
120
|
+
id?: string; // Legacy support
|
|
106
121
|
title: string;
|
|
107
|
-
name: string;
|
|
122
|
+
name: string; // Unique identifier (lowercase)
|
|
123
|
+
module?: string | null;
|
|
124
|
+
formType?: 'system' | 'custom';
|
|
125
|
+
collectionName?: string;
|
|
108
126
|
sections?: FormSection[];
|
|
109
127
|
fields?: FormField[]; // Legacy support
|
|
110
128
|
settings?: {
|
|
111
129
|
sectionDisplayMode?: 'panel' | 'stepper';
|
|
112
|
-
fieldsPerRow?: 1
|
|
130
|
+
fieldsPerRow?: number; // 1, 2, or 3
|
|
131
|
+
[key: string]: any;
|
|
113
132
|
};
|
|
133
|
+
createdAt?: string;
|
|
134
|
+
updatedAt?: string;
|
|
114
135
|
}
|
|
115
136
|
```
|
|
116
137
|
|
|
@@ -129,24 +150,32 @@ interface FormSection {
|
|
|
129
150
|
|
|
130
151
|
```typescript
|
|
131
152
|
interface FormField {
|
|
132
|
-
type: 'text' | 'email' | 'number' | 'select' | 'checkbox' | 'radio' |
|
|
133
|
-
'datepicker' | 'file' | 'ckeditor' | 'toggle' | 'color' |
|
|
153
|
+
type: 'text' | 'email' | 'number' | 'select' | 'checkbox' | 'radio' |
|
|
154
|
+
'datepicker' | 'file' | 'ckeditor' | 'toggle' | 'color' |
|
|
134
155
|
'formReference' | 'apiReference';
|
|
135
156
|
name: string;
|
|
136
157
|
label: string;
|
|
137
158
|
required?: boolean;
|
|
138
159
|
placeholder?: string;
|
|
160
|
+
allowFilter?: boolean;
|
|
139
161
|
options?: OptionItem[] | string[]; // For select/radio
|
|
140
162
|
validation?: {
|
|
141
163
|
min?: number;
|
|
142
164
|
max?: number;
|
|
143
165
|
pattern?: string;
|
|
144
|
-
maxFileSize?: number;
|
|
166
|
+
maxFileSize?: number; // For file fields (bytes)
|
|
145
167
|
allowedFileTypes?: string[]; // For file fields
|
|
146
168
|
};
|
|
147
|
-
|
|
169
|
+
// Reference fields
|
|
170
|
+
referenceFormName?: string;
|
|
171
|
+
referenceFieldName?: string;
|
|
172
|
+
apiEndpoint?: string;
|
|
173
|
+
referenceModel?: string;
|
|
174
|
+
apiLabelField?: string;
|
|
175
|
+
apiValueField?: string;
|
|
176
|
+
allowMultiple?: boolean; // For select/file fields
|
|
148
177
|
datePickerMode?: 'date' | 'datetime' | 'time'; // For datepicker
|
|
149
|
-
//
|
|
178
|
+
displayTime?: boolean; // @deprecated Use datePickerMode instead
|
|
150
179
|
}
|
|
151
180
|
```
|
|
152
181
|
|
|
@@ -187,6 +216,8 @@ interface FormField {
|
|
|
187
216
|
|
|
188
217
|
### Date Picker
|
|
189
218
|
|
|
219
|
+
Field type is `datepicker`; the exported component is `DateTimePickerField`.
|
|
220
|
+
|
|
190
221
|
```typescript
|
|
191
222
|
{
|
|
192
223
|
type: 'datepicker',
|
|
@@ -249,7 +280,7 @@ Form Reference fields fetch options from entries of another form in your system.
|
|
|
249
280
|
You must provide a `formReference` service that fetches options from your form entries:
|
|
250
281
|
|
|
251
282
|
```tsx
|
|
252
|
-
import { FormRenderer, FormServices } from '@
|
|
283
|
+
import { FormRenderer, FormServices } from '@aatulwork/customform-renderer';
|
|
253
284
|
|
|
254
285
|
const services: FormServices = {
|
|
255
286
|
formReference: {
|
|
@@ -277,7 +308,7 @@ const services: FormServices = {
|
|
|
277
308
|
**Example: Complete Form Reference Setup**
|
|
278
309
|
|
|
279
310
|
```tsx
|
|
280
|
-
import { FormRenderer, FormServices, FormSchema } from '@
|
|
311
|
+
import { FormRenderer, FormServices, FormSchema } from '@aatulwork/customform-renderer';
|
|
281
312
|
|
|
282
313
|
// Define your form schema with formReference field
|
|
283
314
|
const formSchema: FormSchema = {
|
|
@@ -379,7 +410,7 @@ API Reference fields fetch options from any external API endpoint. This is usefu
|
|
|
379
410
|
You must provide an `apiReference` service that fetches options from your API:
|
|
380
411
|
|
|
381
412
|
```tsx
|
|
382
|
-
import { FormRenderer, FormServices } from '@
|
|
413
|
+
import { FormRenderer, FormServices } from '@aatulwork/customform-renderer';
|
|
383
414
|
|
|
384
415
|
const services: FormServices = {
|
|
385
416
|
apiReference: {
|
|
@@ -408,7 +439,7 @@ const services: FormServices = {
|
|
|
408
439
|
**Example: Complete API Reference Setup**
|
|
409
440
|
|
|
410
441
|
```tsx
|
|
411
|
-
import { FormRenderer, FormServices, FormSchema } from '@
|
|
442
|
+
import { FormRenderer, FormServices, FormSchema } from '@aatulwork/customform-renderer';
|
|
412
443
|
|
|
413
444
|
// Define your form schema with apiReference field
|
|
414
445
|
const formSchema: FormSchema = {
|
|
@@ -600,7 +631,7 @@ The package uses a service injection pattern to handle external dependencies. Yo
|
|
|
600
631
|
### Providing Services
|
|
601
632
|
|
|
602
633
|
```tsx
|
|
603
|
-
import { FormRenderer, FormServices } from '@
|
|
634
|
+
import { FormRenderer, FormServices } from '@aatulwork/customform-renderer';
|
|
604
635
|
|
|
605
636
|
const services: FormServices = {
|
|
606
637
|
// File upload service
|
|
@@ -685,7 +716,11 @@ interface FormRendererProps {
|
|
|
685
716
|
allowResetOnValuesChange?: boolean;
|
|
686
717
|
mode?: 'edit' | 'view';
|
|
687
718
|
services?: FormServices;
|
|
719
|
+
colors?: FormColors; // Override theme colors (primary, secondary, error, etc.)
|
|
688
720
|
}
|
|
721
|
+
|
|
722
|
+
// FormColors: primary?, secondary?, error?, success?, warning?, info?,
|
|
723
|
+
// textPrimary?, textSecondary?, divider?, background?, backgroundPaper?
|
|
689
724
|
```
|
|
690
725
|
|
|
691
726
|
## View Mode
|
|
@@ -921,7 +956,7 @@ If using Vite, Create React App, or similar:
|
|
|
921
956
|
|
|
922
957
|
```bash
|
|
923
958
|
# Copy CKEditor to your public directory
|
|
924
|
-
cp node_modules/@
|
|
959
|
+
cp node_modules/@aatulwork/customform-renderer/lib/ckeditor/ckeditor.js public/lib/ckeditor/ckeditor.js
|
|
925
960
|
```
|
|
926
961
|
|
|
927
962
|
Then include in HTML:
|
|
@@ -934,7 +969,7 @@ Then include in HTML:
|
|
|
934
969
|
Use the provided hook to load CKEditor dynamically:
|
|
935
970
|
|
|
936
971
|
```tsx
|
|
937
|
-
import { useCKEditor } from '@
|
|
972
|
+
import { useCKEditor } from '@aatulwork/customform-renderer';
|
|
938
973
|
|
|
939
974
|
function App() {
|
|
940
975
|
const { isReady, isLoading, error } = useCKEditor({
|
|
@@ -968,12 +1003,12 @@ const services: FormServices = {
|
|
|
968
1003
|
### CKEditor Utilities
|
|
969
1004
|
|
|
970
1005
|
```tsx
|
|
971
|
-
import {
|
|
972
|
-
loadCKEditor,
|
|
973
|
-
isCKEditorAvailable,
|
|
1006
|
+
import {
|
|
1007
|
+
loadCKEditor,
|
|
1008
|
+
isCKEditorAvailable,
|
|
974
1009
|
waitForCKEditor,
|
|
975
|
-
useCKEditor
|
|
976
|
-
} from '@
|
|
1010
|
+
useCKEditor,
|
|
1011
|
+
} from '@aatulwork/customform-renderer';
|
|
977
1012
|
|
|
978
1013
|
// Check if available
|
|
979
1014
|
if (isCKEditorAvailable()) {
|
package/dist/index.js
CHANGED
|
@@ -568,12 +568,20 @@ var loadCKEditor = (scriptPath = "/lib/ckeditor/ckeditor.js") => {
|
|
|
568
568
|
setTimeout(() => {
|
|
569
569
|
clearInterval(checkInterval);
|
|
570
570
|
if (!window.ClassicEditor) {
|
|
571
|
-
reject(
|
|
571
|
+
reject(
|
|
572
|
+
new Error(
|
|
573
|
+
"CKEditor script loaded but ClassicEditor was not found on window. Ensure you are using the package-provided build from lib/ckeditor/ckeditor.js (see CKEDITOR_SETUP.md)."
|
|
574
|
+
)
|
|
575
|
+
);
|
|
572
576
|
}
|
|
573
577
|
}, 1e4);
|
|
574
578
|
};
|
|
575
579
|
script.onerror = () => {
|
|
576
|
-
reject(
|
|
580
|
+
reject(
|
|
581
|
+
new Error(
|
|
582
|
+
`Failed to load CKEditor from ${scriptPath}. Ensure the file exists at that URL (e.g. copy from node_modules/@aatulwork/customform-renderer/lib/ckeditor/ckeditor.js to public/lib/ckeditor/ckeditor.js) or set services.ckEditorScriptPath to a working URL.`
|
|
583
|
+
)
|
|
584
|
+
);
|
|
577
585
|
};
|
|
578
586
|
document.head.appendChild(script);
|
|
579
587
|
});
|
|
@@ -705,9 +713,10 @@ var CKEditorField = ({ field, control, defaultValue, rules, errors, setValue, fo
|
|
|
705
713
|
] });
|
|
706
714
|
}
|
|
707
715
|
if (ckEditorError || !isCKEditorReady) {
|
|
716
|
+
const message = ckEditorError?.message || `CKEditor failed to load. Script path: ${ckEditorScriptPath}. Copy ckeditor.js to public/lib/ckeditor/ or set services.ckEditorScriptPath. See CKEDITOR_SETUP.md.`;
|
|
708
717
|
return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
|
|
709
718
|
/* @__PURE__ */ jsxRuntime.jsx(material.FormLabel, { required: field.required, error: !!errors[field.name], children: field.label }),
|
|
710
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { p: 2, border: "1px solid", borderColor: formColors.error, borderRadius: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(material.FormHelperText, { error: true, children:
|
|
719
|
+
/* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { p: 2, border: "1px solid", borderColor: formColors.error, borderRadius: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(material.FormHelperText, { error: true, children: message }) })
|
|
711
720
|
] });
|
|
712
721
|
}
|
|
713
722
|
return /* @__PURE__ */ jsxRuntime.jsx(
|