@connect-soft/form-generator 1.0.0 → 1.1.0-alpha3
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 +245 -205
- package/dist/index.js +3577 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3525 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/components/form/field-renderer.d.ts +12 -0
- package/dist/types/components/form/field-renderer.d.ts.map +1 -0
- package/dist/types/components/form/form-generator.d.ts +41 -0
- package/dist/types/components/form/form-generator.d.ts.map +1 -0
- package/dist/types/components/form/index.d.ts +5 -0
- package/dist/types/components/form/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/field-registry.d.ts +114 -0
- package/dist/types/lib/field-registry.d.ts.map +1 -0
- package/dist/types/lib/field-types.d.ts +133 -0
- package/dist/types/lib/field-types.d.ts.map +1 -0
- package/dist/types/lib/index.d.ts +8 -0
- package/dist/types/lib/index.d.ts.map +1 -0
- package/dist/types/setupTests.d.ts +2 -0
- package/dist/types/setupTests.d.ts.map +1 -0
- package/package.json +40 -131
package/README.md
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
# @connect-soft/form-generator
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Headless, type-safe form generator with react-hook-form and Zod validation
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@connect-soft/form-generator)
|
|
6
6
|
[](./LICENSE)
|
|
7
|
-
[](https://bundlephobia.com/package/@connect-soft/form-generator)
|
|
8
|
-
|
|
9
|
-
**v2.0.0** - Complete rewrite with Radix UI + Tailwind CSS
|
|
10
|
-
**50-60% smaller bundle** | **No runtime CSS overhead** | **Modern, accessible UI**
|
|
11
7
|
|
|
12
8
|
---
|
|
13
9
|
|
|
14
10
|
## Features
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
- **Headless**: Bring your own UI components (Radix, MUI, Chakra, or plain HTML)
|
|
13
|
+
- **Type-Safe**: Full TypeScript inference for form values and field types
|
|
14
|
+
- **Field Type Checking**: Compile-time validation of `field.type` with autocomplete
|
|
15
|
+
- **Extensible Types**: Add custom field types via module augmentation
|
|
16
|
+
- **Imperative API**: Control form via ref (`setValues`, `reset`, `submit`, etc.)
|
|
17
|
+
- **Flexible**: Register custom field components with a simple API
|
|
18
|
+
- **Validation**: Built-in Zod validation support
|
|
19
|
+
- **Layouts**: Support for sections and multi-column layouts
|
|
20
|
+
- **Lightweight**: No UI dependencies, minimal footprint
|
|
21
|
+
- **HTML Fallbacks**: Works out of the box with native HTML inputs
|
|
24
22
|
|
|
25
23
|
---
|
|
26
24
|
|
|
27
25
|
## Installation
|
|
28
26
|
|
|
29
27
|
```bash
|
|
30
|
-
npm install @connect-soft/form-generator
|
|
28
|
+
npm install @connect-soft/form-generator
|
|
31
29
|
```
|
|
32
30
|
|
|
33
31
|
### Peer Dependencies
|
|
@@ -36,74 +34,23 @@ npm install @connect-soft/form-generator react-hook-form zod
|
|
|
36
34
|
- `react-dom` ^19.0.0
|
|
37
35
|
- `zod` ^4.0.0
|
|
38
36
|
|
|
39
|
-
### Tailwind CSS Setup
|
|
40
|
-
|
|
41
|
-
This library requires Tailwind CSS. If you don't have it set up:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npm install -D tailwindcss postcss autoprefixer
|
|
45
|
-
npx tailwindcss init -p
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**tailwind.config.js:**
|
|
49
|
-
```javascript
|
|
50
|
-
module.exports = {
|
|
51
|
-
content: [
|
|
52
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
53
|
-
'./node_modules/@connect-soft/form-generator/dist/**/*.{js,mjs}',
|
|
54
|
-
],
|
|
55
|
-
theme: {
|
|
56
|
-
extend: {
|
|
57
|
-
// Your custom theme
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
plugins: [],
|
|
61
|
-
};
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Import the styles in your main file:**
|
|
65
|
-
```typescript
|
|
66
|
-
import '@connect-soft/form-generator/dist/styles.css';
|
|
67
|
-
```
|
|
68
|
-
|
|
69
37
|
---
|
|
70
38
|
|
|
71
39
|
## Quick Start
|
|
72
40
|
|
|
41
|
+
The library works immediately with HTML fallback components:
|
|
42
|
+
|
|
73
43
|
```typescript
|
|
74
|
-
import { FormGenerator
|
|
44
|
+
import { FormGenerator } from '@connect-soft/form-generator';
|
|
75
45
|
|
|
76
|
-
const fields
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
label: '
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
type: 'number',
|
|
87
|
-
name: 'age',
|
|
88
|
-
label: 'Age',
|
|
89
|
-
min: 18,
|
|
90
|
-
max: 120,
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
type: 'select',
|
|
94
|
-
name: 'country',
|
|
95
|
-
label: 'Country',
|
|
96
|
-
options: [
|
|
97
|
-
{ label: 'United States', value: 'us' },
|
|
98
|
-
{ label: 'United Kingdom', value: 'uk' },
|
|
99
|
-
{ label: 'Germany', value: 'de' },
|
|
100
|
-
],
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
type: 'checkbox',
|
|
104
|
-
name: 'subscribe',
|
|
105
|
-
label: 'Subscribe to newsletter',
|
|
106
|
-
},
|
|
46
|
+
const fields = [
|
|
47
|
+
{ type: 'text', name: 'email', label: 'Email', required: true },
|
|
48
|
+
{ type: 'number', name: 'age', label: 'Age', min: 18, max: 120 },
|
|
49
|
+
{ type: 'select', name: 'country', label: 'Country', options: [
|
|
50
|
+
{ label: 'United States', value: 'us' },
|
|
51
|
+
{ label: 'Germany', value: 'de' },
|
|
52
|
+
]},
|
|
53
|
+
{ type: 'checkbox', name: 'subscribe', label: 'Subscribe to newsletter' },
|
|
107
54
|
] as const;
|
|
108
55
|
|
|
109
56
|
function MyForm() {
|
|
@@ -111,13 +58,8 @@ function MyForm() {
|
|
|
111
58
|
<FormGenerator
|
|
112
59
|
fields={fields}
|
|
113
60
|
onSubmit={(values) => {
|
|
114
|
-
|
|
115
|
-
console.log(values.email); // string
|
|
116
|
-
console.log(values.age); // number
|
|
117
|
-
console.log(values.country); // string
|
|
118
|
-
console.log(values.subscribe);// boolean
|
|
61
|
+
console.log(values); // Fully typed!
|
|
119
62
|
}}
|
|
120
|
-
submitText="Create Account"
|
|
121
63
|
/>
|
|
122
64
|
);
|
|
123
65
|
}
|
|
@@ -125,77 +67,137 @@ function MyForm() {
|
|
|
125
67
|
|
|
126
68
|
---
|
|
127
69
|
|
|
70
|
+
## Registering Custom Components
|
|
71
|
+
|
|
72
|
+
Register your own UI components to replace the HTML fallbacks:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { registerFields, registerFormComponents } from '@connect-soft/form-generator';
|
|
76
|
+
import { Input } from './ui/input';
|
|
77
|
+
import { Label } from './ui/label';
|
|
78
|
+
import { Checkbox } from './ui/checkbox';
|
|
79
|
+
import { Button } from './ui/button';
|
|
80
|
+
|
|
81
|
+
// Register field components
|
|
82
|
+
registerFields({
|
|
83
|
+
text: ({ field, formField }) => (
|
|
84
|
+
<Input
|
|
85
|
+
{...formField}
|
|
86
|
+
type={field.fieldType || 'text'}
|
|
87
|
+
placeholder={field.placeholder}
|
|
88
|
+
disabled={field.disabled}
|
|
89
|
+
/>
|
|
90
|
+
),
|
|
91
|
+
number: ({ field, formField }) => (
|
|
92
|
+
<Input
|
|
93
|
+
{...formField}
|
|
94
|
+
type="number"
|
|
95
|
+
min={field.min}
|
|
96
|
+
max={field.max}
|
|
97
|
+
/>
|
|
98
|
+
),
|
|
99
|
+
checkbox: {
|
|
100
|
+
component: ({ field, formField }) => (
|
|
101
|
+
<Checkbox
|
|
102
|
+
checked={formField.value}
|
|
103
|
+
onCheckedChange={formField.onChange}
|
|
104
|
+
disabled={field.disabled}
|
|
105
|
+
/>
|
|
106
|
+
),
|
|
107
|
+
options: {
|
|
108
|
+
className: 'flex items-center gap-2',
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Register form wrapper components
|
|
114
|
+
registerFormComponents({
|
|
115
|
+
FormItem: ({ children, className }) => <div className={className}>{children}</div>,
|
|
116
|
+
FormLabel: Label,
|
|
117
|
+
FormMessage: ({ children }) => <span className="text-red-500 text-sm">{children}</span>,
|
|
118
|
+
SubmitButton: Button,
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
128
124
|
## Field Types
|
|
129
125
|
|
|
126
|
+
Built-in HTML fallback types:
|
|
127
|
+
|
|
130
128
|
| Type | Description | Value Type |
|
|
131
129
|
|------|-------------|------------|
|
|
132
|
-
| `text` | Text input
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
130
|
+
| `text` | Text input | `string` |
|
|
131
|
+
| `email` | Email input | `string` |
|
|
132
|
+
| `password` | Password input | `string` |
|
|
133
|
+
| `number` | Number input with min/max | `number` |
|
|
134
|
+
| `textarea` | Multi-line text | `string` |
|
|
135
|
+
| `checkbox` | Checkbox | `boolean` |
|
|
137
136
|
| `select` | Dropdown select | `string` |
|
|
138
137
|
| `radio` | Radio button group | `string` |
|
|
139
|
-
| `date` | Date
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
138
|
+
| `date` | Date input | `Date` |
|
|
139
|
+
| `time` | Time input | `string` |
|
|
140
|
+
| `file` | File input | `File` |
|
|
141
|
+
| `hidden` | Hidden input | `string` |
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
### Adding Custom Field Types (TypeScript)
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
### MultiSelect
|
|
145
|
+
Extend the `FieldTypeRegistry` interface to add type checking for custom fields:
|
|
148
146
|
|
|
149
147
|
```typescript
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
148
|
+
// types/form-generator.d.ts
|
|
149
|
+
import { CreateFieldType } from '@connect-soft/form-generator';
|
|
150
|
+
|
|
151
|
+
declare module '@connect-soft/form-generator' {
|
|
152
|
+
interface FieldTypeRegistry {
|
|
153
|
+
// Add your custom field types
|
|
154
|
+
'color-picker': CreateFieldType<'color-picker', string, {
|
|
155
|
+
swatches?: string[];
|
|
156
|
+
showAlpha?: boolean;
|
|
157
|
+
}>;
|
|
158
|
+
'rich-text': CreateFieldType<'rich-text', string, {
|
|
159
|
+
toolbar?: ('bold' | 'italic' | 'link')[];
|
|
160
|
+
maxLength?: number;
|
|
161
|
+
}>;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
162
164
|
```
|
|
163
165
|
|
|
164
|
-
|
|
166
|
+
Now TypeScript will recognize your custom field types:
|
|
165
167
|
|
|
166
168
|
```typescript
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
onChange={setColor}
|
|
172
|
-
/>
|
|
169
|
+
const fields = [
|
|
170
|
+
{ type: 'color-picker', name: 'theme', swatches: ['#fff', '#000'] }, // ✅ Valid
|
|
171
|
+
{ type: 'unknown-type', name: 'test' }, // ❌ Type error
|
|
172
|
+
] as const;
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
Don't forget to register the component for your custom field:
|
|
176
176
|
|
|
177
177
|
```typescript
|
|
178
|
-
import {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
/>
|
|
178
|
+
import { registerField } from '@connect-soft/form-generator';
|
|
179
|
+
import { ColorPicker } from './components/ColorPicker';
|
|
180
|
+
|
|
181
|
+
registerField('color-picker', ({ field, formField }) => (
|
|
182
|
+
<ColorPicker
|
|
183
|
+
value={formField.value}
|
|
184
|
+
onChange={formField.onChange}
|
|
185
|
+
swatches={field.swatches}
|
|
186
|
+
showAlpha={field.showAlpha}
|
|
187
|
+
/>
|
|
188
|
+
));
|
|
188
189
|
```
|
|
189
190
|
|
|
190
191
|
---
|
|
191
192
|
|
|
192
193
|
## Custom Validation
|
|
193
194
|
|
|
194
|
-
Use Zod for
|
|
195
|
+
Use Zod for field-level or form-level validation:
|
|
195
196
|
|
|
196
197
|
```typescript
|
|
197
198
|
import { z } from 'zod';
|
|
198
199
|
|
|
200
|
+
// Field-level validation
|
|
199
201
|
const fields = [
|
|
200
202
|
{
|
|
201
203
|
type: 'text',
|
|
@@ -207,106 +209,159 @@ const fields = [
|
|
|
207
209
|
type: 'text',
|
|
208
210
|
name: 'email',
|
|
209
211
|
label: 'Email',
|
|
210
|
-
|
|
211
|
-
validation: z.string().email().endsWith('@company.com'),
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
type: 'number',
|
|
215
|
-
name: 'age',
|
|
216
|
-
label: 'Age',
|
|
217
|
-
validation: z.number().min(18).max(120),
|
|
212
|
+
validation: z.string().email(),
|
|
218
213
|
},
|
|
219
214
|
] as const;
|
|
220
|
-
```
|
|
221
215
|
|
|
222
|
-
|
|
216
|
+
// Or use a full schema for type inference
|
|
217
|
+
const schema = z.object({
|
|
218
|
+
username: z.string().min(3),
|
|
219
|
+
email: z.string().email(),
|
|
220
|
+
});
|
|
223
221
|
|
|
224
|
-
## Styling
|
|
225
|
-
|
|
226
|
-
### Using Tailwind Classes
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
{
|
|
230
|
-
type: 'text',
|
|
231
|
-
name: 'email',
|
|
232
|
-
className: 'bg-blue-50 border-blue-300 focus:ring-blue-500',
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Form-Level Styling
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
222
|
<FormGenerator
|
|
240
223
|
fields={fields}
|
|
241
|
-
|
|
242
|
-
|
|
224
|
+
schema={schema}
|
|
225
|
+
onSubmit={(values) => {
|
|
226
|
+
// values is inferred from schema
|
|
227
|
+
}}
|
|
243
228
|
/>
|
|
244
229
|
```
|
|
245
230
|
|
|
246
|
-
|
|
231
|
+
---
|
|
247
232
|
|
|
248
|
-
|
|
233
|
+
## Layouts
|
|
249
234
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
235
|
+
Organize fields with sections and columns:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const fields = [
|
|
239
|
+
{
|
|
240
|
+
type: 'section',
|
|
241
|
+
title: 'Personal Information',
|
|
242
|
+
children: [
|
|
243
|
+
{ type: 'text', name: 'firstName', label: 'First Name' },
|
|
244
|
+
{ type: 'text', name: 'lastName', label: 'Last Name' },
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
type: 'columns',
|
|
249
|
+
columns: [
|
|
250
|
+
{
|
|
251
|
+
width: '1',
|
|
252
|
+
children: [
|
|
253
|
+
{ type: 'text', name: 'city', label: 'City' },
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
width: '1',
|
|
258
|
+
children: [
|
|
259
|
+
{ type: 'text', name: 'zip', label: 'ZIP Code' },
|
|
260
|
+
],
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
];
|
|
256
265
|
```
|
|
257
266
|
|
|
258
267
|
---
|
|
259
268
|
|
|
260
269
|
## TypeScript Type Inference
|
|
261
270
|
|
|
262
|
-
|
|
271
|
+
Get full type inference from field definitions:
|
|
263
272
|
|
|
264
273
|
```typescript
|
|
265
274
|
const fields = [
|
|
266
|
-
{ type: 'text', name: 'email',
|
|
267
|
-
{ type: 'number', name: 'age' },
|
|
275
|
+
{ type: 'text', name: 'email', required: true },
|
|
276
|
+
{ type: 'number', name: 'age', required: true },
|
|
268
277
|
{ type: 'checkbox', name: 'terms' },
|
|
269
|
-
{ type: 'date', name: 'birthdate' },
|
|
270
278
|
] as const;
|
|
271
279
|
|
|
272
280
|
<FormGenerator
|
|
273
281
|
fields={fields}
|
|
274
282
|
onSubmit={(values) => {
|
|
275
|
-
//
|
|
276
|
-
values.
|
|
277
|
-
values.
|
|
278
|
-
values.terms; // boolean
|
|
279
|
-
values.birthdate; // Date
|
|
283
|
+
values.email; // string
|
|
284
|
+
values.age; // number
|
|
285
|
+
values.terms; // boolean | undefined
|
|
280
286
|
}}
|
|
281
287
|
/>
|
|
282
288
|
```
|
|
283
289
|
|
|
284
|
-
|
|
290
|
+
Or provide an explicit Zod schema:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const schema = z.object({
|
|
294
|
+
email: z.string().email(),
|
|
295
|
+
age: z.number().min(18),
|
|
296
|
+
terms: z.boolean(),
|
|
297
|
+
});
|
|
285
298
|
|
|
286
|
-
|
|
299
|
+
<FormGenerator
|
|
300
|
+
fields={fields}
|
|
301
|
+
schema={schema}
|
|
302
|
+
onSubmit={(values) => {
|
|
303
|
+
// values: { email: string; age: number; terms: boolean }
|
|
304
|
+
}}
|
|
305
|
+
/>
|
|
306
|
+
```
|
|
287
307
|
|
|
288
|
-
|
|
308
|
+
---
|
|
289
309
|
|
|
290
|
-
|
|
310
|
+
## Imperative API (Ref)
|
|
311
|
+
|
|
312
|
+
Access form methods programmatically using a ref:
|
|
291
313
|
|
|
292
314
|
```typescript
|
|
293
|
-
import {
|
|
294
|
-
import {
|
|
315
|
+
import { useRef } from 'react';
|
|
316
|
+
import { FormGenerator, FormGeneratorRef } from '@connect-soft/form-generator';
|
|
295
317
|
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
{
|
|
299
|
-
type: 'textField',
|
|
300
|
-
props: { name: 'email', label: 'Email', required: true },
|
|
301
|
-
},
|
|
302
|
-
];
|
|
318
|
+
function MyForm() {
|
|
319
|
+
const formRef = useRef<FormGeneratorRef>(null);
|
|
303
320
|
|
|
304
|
-
|
|
305
|
-
|
|
321
|
+
const handleExternalSubmit = async () => {
|
|
322
|
+
await formRef.current?.submit();
|
|
323
|
+
};
|
|
306
324
|
|
|
307
|
-
|
|
325
|
+
const handleReset = () => {
|
|
326
|
+
formRef.current?.reset();
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const handleSetValues = () => {
|
|
330
|
+
formRef.current?.setValues({
|
|
331
|
+
email: 'test@example.com',
|
|
332
|
+
age: 25,
|
|
333
|
+
});
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<>
|
|
338
|
+
<FormGenerator
|
|
339
|
+
ref={formRef}
|
|
340
|
+
fields={fields}
|
|
341
|
+
onSubmit={(values) => console.log(values)}
|
|
342
|
+
/>
|
|
343
|
+
<button type="button" onClick={handleExternalSubmit}>Submit Externally</button>
|
|
344
|
+
<button type="button" onClick={handleReset}>Reset Form</button>
|
|
345
|
+
<button type="button" onClick={handleSetValues}>Set Values</button>
|
|
346
|
+
</>
|
|
347
|
+
);
|
|
348
|
+
}
|
|
308
349
|
```
|
|
309
350
|
|
|
351
|
+
### Available Ref Methods
|
|
352
|
+
|
|
353
|
+
| Method | Description |
|
|
354
|
+
|--------|-------------|
|
|
355
|
+
| `setValues(values)` | Set form values (partial update) |
|
|
356
|
+
| `getValues()` | Get current form values |
|
|
357
|
+
| `reset(values?)` | Reset to default or provided values |
|
|
358
|
+
| `submit()` | Programmatically submit the form |
|
|
359
|
+
| `clearErrors()` | Clear all validation errors |
|
|
360
|
+
| `setError(name, error)` | Set error for a specific field |
|
|
361
|
+
| `isValid()` | Check if form passes validation |
|
|
362
|
+
| `isDirty()` | Check if form has unsaved changes |
|
|
363
|
+
| `form` | Access underlying react-hook-form instance |
|
|
364
|
+
|
|
310
365
|
---
|
|
311
366
|
|
|
312
367
|
## API Reference
|
|
@@ -315,12 +370,12 @@ const v2Fields = adaptV1FieldsToV2(v1Fields);
|
|
|
315
370
|
|
|
316
371
|
| Prop | Type | Default | Description |
|
|
317
372
|
|------|------|---------|-------------|
|
|
318
|
-
| `fields` | `
|
|
373
|
+
| `fields` | `FormItem[]` | **required** | Array of field definitions |
|
|
319
374
|
| `onSubmit` | `(values) => void \| Promise<void>` | **required** | Form submission handler |
|
|
320
|
-
| `
|
|
321
|
-
| `
|
|
375
|
+
| `schema` | `ZodType` | - | Optional Zod schema for validation |
|
|
376
|
+
| `defaultValues` | `object` | `{}` | Initial form values |
|
|
377
|
+
| `className` | `string` | - | CSS class for form element |
|
|
322
378
|
| `submitText` | `string` | `'Submit'` | Submit button text |
|
|
323
|
-
| `submitButtonVariant` | `'default' \| 'destructive' \| 'outline' \| 'secondary' \| 'ghost' \| 'link'` | `'default'` | Submit button style |
|
|
324
379
|
| `disabled` | `boolean` | `false` | Disable entire form |
|
|
325
380
|
| `mode` | `'onChange' \| 'onBlur' \| 'onSubmit' \| 'onTouched' \| 'all'` | `'onChange'` | Validation trigger mode |
|
|
326
381
|
|
|
@@ -337,13 +392,12 @@ const v2Fields = adaptV1FieldsToV2(v1Fields);
|
|
|
337
392
|
| `hidden` | `boolean` | Hide field |
|
|
338
393
|
| `defaultValue` | `any` | Default field value |
|
|
339
394
|
| `validation` | `ZodType` | Zod validation schema |
|
|
340
|
-
| `className` | `string` |
|
|
395
|
+
| `className` | `string` | CSS class for field wrapper |
|
|
341
396
|
|
|
342
397
|
---
|
|
343
398
|
|
|
344
399
|
## Links
|
|
345
400
|
|
|
346
|
-
- [Migration Guide](./MIGRATION.md)
|
|
347
401
|
- [GitLab Repository](https://gitlab.com/connect-soft/components/form-generator)
|
|
348
402
|
- [Issues](https://gitlab.com/connect-soft/components/form-generator/issues)
|
|
349
403
|
|
|
@@ -352,17 +406,3 @@ const v2Fields = adaptV1FieldsToV2(v1Fields);
|
|
|
352
406
|
## License
|
|
353
407
|
|
|
354
408
|
ISC © Connect Soft
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## Acknowledgments
|
|
359
|
-
|
|
360
|
-
Built with:
|
|
361
|
-
- [Radix UI](https://www.radix-ui.com/) - Accessible UI primitives
|
|
362
|
-
- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
|
|
363
|
-
- [react-hook-form](https://react-hook-form.com/) - Performant form library
|
|
364
|
-
- [Zod](https://zod.dev/) - TypeScript-first schema validation
|
|
365
|
-
- [react-day-picker](https://react-day-picker.js.org/) - Flexible date picker
|
|
366
|
-
- [lucide-react](https://lucide.dev/) - Beautiful icons
|
|
367
|
-
|
|
368
|
-
Inspired by [shadcn/ui](https://ui.shadcn.com/) component architecture.
|