@reactfast/forms 0.1.0 → 0.1.6
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,5 +1,7 @@
|
|
|
1
1
|
# 🎛️ @reactfast/forms
|
|
2
2
|
|
|
3
|
+
test auto publish
|
|
4
|
+
|
|
3
5
|
**Dynamic React forms powered by JSON schemas, modifiers, and subforms.**
|
|
4
6
|
Create complex, adaptive form systems without boilerplate — designed for scale, simplicity, and composability.
|
|
5
7
|
|
|
@@ -47,13 +49,7 @@ export default function App() {
|
|
|
47
49
|
setState: setFormData,
|
|
48
50
|
});
|
|
49
51
|
|
|
50
|
-
return
|
|
51
|
-
<Form
|
|
52
|
-
fields={fields}
|
|
53
|
-
onChange={handleChange}
|
|
54
|
-
formData={formData}
|
|
55
|
-
/>
|
|
56
|
-
);
|
|
52
|
+
return <Form fields={fields} onChange={handleChange} formData={formData} />;
|
|
57
53
|
}
|
|
58
54
|
```
|
|
59
55
|
|
|
@@ -80,35 +76,35 @@ export default function App() {
|
|
|
80
76
|
|
|
81
77
|
Nova Forms comes with 20+ field types ready to use:
|
|
82
78
|
|
|
83
|
-
| Type
|
|
84
|
-
|
|
85
|
-
| `string`
|
|
86
|
-
| `text`
|
|
87
|
-
| `email`
|
|
88
|
-
| `tel`
|
|
89
|
-
| `url`
|
|
90
|
-
| `number`
|
|
91
|
-
| `boolean`
|
|
92
|
-
| `toggle`
|
|
93
|
-
| `date`
|
|
94
|
-
| `datetime`
|
|
95
|
-
| `time`
|
|
96
|
-
| `color`
|
|
97
|
-
| `select`
|
|
98
|
-
| `multiselect`
|
|
99
|
-
| `radio`
|
|
100
|
-
| `file`
|
|
101
|
-
| `fileV2`
|
|
102
|
-
| `uploadToBase` | Base64 image upload
|
|
103
|
-
| `array`
|
|
104
|
-
| `subForm`
|
|
105
|
-
| `signature`
|
|
106
|
-
| `rating`
|
|
107
|
-
| `scale`
|
|
108
|
-
| `captcha`
|
|
109
|
-
| `header`
|
|
110
|
-
| `paragraph`
|
|
111
|
-
| `image`
|
|
79
|
+
| Type | Description | Example |
|
|
80
|
+
| -------------- | --------------------------- | ------------------------------------------- |
|
|
81
|
+
| `string` | Text input | `{ type: "string", title: "Name" }` |
|
|
82
|
+
| `text` | Textarea | `{ type: "text", title: "Description" }` |
|
|
83
|
+
| `email` | Email input with validation | `{ type: "email", title: "Email" }` |
|
|
84
|
+
| `tel` | Phone number input | `{ type: "tel", title: "Phone" }` |
|
|
85
|
+
| `url` | URL input | `{ type: "url", title: "Website" }` |
|
|
86
|
+
| `number` | Number input | `{ type: "number", title: "Age" }` |
|
|
87
|
+
| `boolean` | Checkbox | `{ type: "boolean", title: "Subscribe" }` |
|
|
88
|
+
| `toggle` | Toggle switch | `{ type: "toggle", title: "Enable" }` |
|
|
89
|
+
| `date` | Date picker | `{ type: "date", title: "Birth Date" }` |
|
|
90
|
+
| `datetime` | Date and time picker | `{ type: "datetime", title: "Event Time" }` |
|
|
91
|
+
| `time` | Time picker | `{ type: "time", title: "Start Time" }` |
|
|
92
|
+
| `color` | Color picker | `{ type: "color", title: "Theme Color" }` |
|
|
93
|
+
| `select` | Single select dropdown | `{ type: "select", options: [...] }` |
|
|
94
|
+
| `multiselect` | Multi-select dropdown | `{ type: "multiselect", options: [...] }` |
|
|
95
|
+
| `radio` | Radio button group | `{ type: "radio", options: [...] }` |
|
|
96
|
+
| `file` | File upload | `{ type: "file", title: "Upload" }` |
|
|
97
|
+
| `fileV2` | Enhanced file upload | `{ type: "fileV2", title: "Photo" }` |
|
|
98
|
+
| `uploadToBase` | Base64 image upload | `{ type: "uploadToBase", title: "Avatar" }` |
|
|
99
|
+
| `array` | Dynamic subform/array | `{ type: "array", fields: [...] }` |
|
|
100
|
+
| `subForm` | Nested form group | `{ type: "subForm", fields: [...] }` |
|
|
101
|
+
| `signature` | Signature pad | `{ type: "signature", title: "Signature" }` |
|
|
102
|
+
| `rating` | Star rating | `{ type: "rating", title: "Rating" }` |
|
|
103
|
+
| `scale` | Likert scale | `{ type: "scale", title: "Satisfaction" }` |
|
|
104
|
+
| `captcha` | reCAPTCHA | `{ type: "captcha" }` |
|
|
105
|
+
| `header` | Section header | `{ type: "header", title: "Section" }` |
|
|
106
|
+
| `paragraph` | Static text | `{ type: "paragraph", content: "Text" }` |
|
|
107
|
+
| `image` | Static image | `{ type: "image", image: { src: "..." } }` |
|
|
112
108
|
|
|
113
109
|
---
|
|
114
110
|
|
|
@@ -139,8 +135,8 @@ const fields = [
|
|
|
139
135
|
name: "eventCheckIn",
|
|
140
136
|
title: "Check In",
|
|
141
137
|
type: "qrScanner",
|
|
142
|
-
width: 100
|
|
143
|
-
}
|
|
138
|
+
width: 100,
|
|
139
|
+
},
|
|
144
140
|
];
|
|
145
141
|
```
|
|
146
142
|
|
|
@@ -152,53 +148,53 @@ const fields = [
|
|
|
152
148
|
|
|
153
149
|
Renders a form based on your field array with integrated modifiers and conditions.
|
|
154
150
|
|
|
155
|
-
| Prop | Type
|
|
156
|
-
| -------------- |
|
|
157
|
-
| `fields` | `array`
|
|
158
|
-
| `onChange` | `function`
|
|
159
|
-
| `formData` | `object`
|
|
160
|
-
| `theme` | `object` _(optional)_
|
|
161
|
-
| `isMobileView` | `boolean` _(optional)_ | Force mobile layout (full width)
|
|
151
|
+
| Prop | Type | Description |
|
|
152
|
+
| -------------- | ---------------------- | --------------------------------------- |
|
|
153
|
+
| `fields` | `array` | Array of field definitions |
|
|
154
|
+
| `onChange` | `function` | Change handler (from createFormHandler) |
|
|
155
|
+
| `formData` | `object` | Form data object from parent state |
|
|
156
|
+
| `theme` | `object` _(optional)_ | Custom theme overrides |
|
|
157
|
+
| `isMobileView` | `boolean` _(optional)_ | Force mobile layout (full width) |
|
|
162
158
|
|
|
163
159
|
### `createFormHandler`
|
|
164
160
|
|
|
165
161
|
Creates a change handler that manages state and applies modifiers.
|
|
166
162
|
|
|
167
|
-
| Prop
|
|
168
|
-
|
|
|
169
|
-
| `fields`
|
|
170
|
-
| `setState`
|
|
171
|
-
| `rules`
|
|
163
|
+
| Prop | Type | Description |
|
|
164
|
+
| ---------- | -------------------- | -------------------------------------------- |
|
|
165
|
+
| `fields` | `array` | Array of field definitions |
|
|
166
|
+
| `setState` | `function` | React setState function |
|
|
167
|
+
| `rules` | `array` _(optional)_ | Top-level rules referenced by field triggers |
|
|
172
168
|
|
|
173
169
|
### Field Schema
|
|
174
170
|
|
|
175
171
|
Each field object supports:
|
|
176
172
|
|
|
177
|
-
| Property
|
|
178
|
-
|
|
179
|
-
| `name`
|
|
180
|
-
| `type`
|
|
181
|
-
| `title`
|
|
182
|
-
| `label`
|
|
183
|
-
| `width`
|
|
184
|
-
| `default`
|
|
185
|
-
| `readOnly`
|
|
186
|
-
| `required`
|
|
187
|
-
| `placeholder`
|
|
188
|
-
| `description`
|
|
189
|
-
| `helper`
|
|
190
|
-
| `error`
|
|
191
|
-
| `leadingIcon`
|
|
192
|
-
| `trailingIcon`
|
|
193
|
-
| `modifiers`
|
|
194
|
-
| `triggers`
|
|
195
|
-
| `conditions.hiddenWhen`
|
|
196
|
-
| `conditions.hiddenMode`
|
|
197
|
-
| `conditions.readOnlyWhen` | `array or object`
|
|
198
|
-
| `conditions.readOnlyMode` | `any or all`
|
|
199
|
-
| `pattern`
|
|
200
|
-
| `options`
|
|
201
|
-
| `fields`
|
|
173
|
+
| Property | Type | Description |
|
|
174
|
+
| ------------------------- | --------------------------------------------------------- | ------------------------------------------------- |
|
|
175
|
+
| `name` | `string` | Field name (required) |
|
|
176
|
+
| `type` | `string` | Field type (string, email, boolean, etc.) |
|
|
177
|
+
| `title` | `string` | Display label (preferred over `label`) |
|
|
178
|
+
| `label` | `string` | Display label (legacy, use `title`) |
|
|
179
|
+
| `width` | `number` | Width percentage (25, 50, 75, 100) |
|
|
180
|
+
| `default` | `any` | Default value |
|
|
181
|
+
| `readOnly` | `boolean` | Make field read-only |
|
|
182
|
+
| `required` | `boolean` | Mark field as required |
|
|
183
|
+
| `placeholder` | `string` | Placeholder text |
|
|
184
|
+
| `description` | `string` | Help text below field |
|
|
185
|
+
| `helper` | `string` | Additional help text |
|
|
186
|
+
| `error` | `string` | Error message to display |
|
|
187
|
+
| `leadingIcon` | `Component` | Icon component before input |
|
|
188
|
+
| `trailingIcon` | `Component` | Icon component after input |
|
|
189
|
+
| `modifiers` | `array` | (Legacy) field-local modifiers for values |
|
|
190
|
+
| `triggers` | `array` | Triggers that reference top-level rules |
|
|
191
|
+
| `conditions.hiddenWhen` | `array or object` | Conditions to hide (rendered with `hidden` class) |
|
|
192
|
+
| `conditions.hiddenMode` | `any or all` | Mode for hidden conditions (default any) |
|
|
193
|
+
| `conditions.readOnlyWhen` | `array or object` | Conditions to set readOnly |
|
|
194
|
+
| `conditions.readOnlyMode` | `any or all` | Mode for readOnly conditions (default any) |
|
|
195
|
+
| `pattern` | `RegExp \| string \| Array<{ regex, message } \| string>` | Client-side pattern checks with messages |
|
|
196
|
+
| `options` | `array` | Options for select, radio, multiselect fields |
|
|
197
|
+
| `fields` | `array` | Sub-fields for array/subForm types |
|
|
202
198
|
|
|
203
199
|
### Modifiers (legacy)
|
|
204
200
|
|
|
@@ -252,7 +248,13 @@ const rules = [
|
|
|
252
248
|
{
|
|
253
249
|
name: "fullNameRule",
|
|
254
250
|
effects: [
|
|
255
|
-
{
|
|
251
|
+
{
|
|
252
|
+
targetField: "displayName",
|
|
253
|
+
prop: "value",
|
|
254
|
+
type: "concat",
|
|
255
|
+
kind: "string",
|
|
256
|
+
value: " ",
|
|
257
|
+
},
|
|
256
258
|
{ targetField: "age", prop: "readOnly", value: true },
|
|
257
259
|
],
|
|
258
260
|
},
|
|
@@ -281,9 +283,18 @@ Trigger shape on a field:
|
|
|
281
283
|
Pass `rules` to both `createFormHandler` and `Form`:
|
|
282
284
|
|
|
283
285
|
```jsx
|
|
284
|
-
const handleChange = createFormHandler({
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
const handleChange = createFormHandler({
|
|
287
|
+
fields,
|
|
288
|
+
rules,
|
|
289
|
+
setState: setFormData,
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
<Form
|
|
293
|
+
fields={fields}
|
|
294
|
+
rules={rules}
|
|
295
|
+
onChange={handleChange}
|
|
296
|
+
formData={formData}
|
|
297
|
+
/>;
|
|
287
298
|
```
|
|
288
299
|
|
|
289
300
|
Hidden fields remain mounted and use Tailwind's `hidden` class so values still update.
|
|
@@ -311,8 +322,13 @@ src/
|
|
|
311
322
|
If you're currently mapping fields manually:
|
|
312
323
|
|
|
313
324
|
**Before:**
|
|
325
|
+
|
|
314
326
|
```jsx
|
|
315
|
-
import {
|
|
327
|
+
import {
|
|
328
|
+
ReturnFieldsV2,
|
|
329
|
+
createFormHandler,
|
|
330
|
+
initializeFormData,
|
|
331
|
+
} from "@reactfast/forms";
|
|
316
332
|
|
|
317
333
|
const [formData, setFormData] = useState(() => initializeFormData(fields));
|
|
318
334
|
const handleChange = createFormHandler({ fields, setState: setFormData });
|
|
@@ -320,7 +336,10 @@ const handleChange = createFormHandler({ fields, setState: setFormData });
|
|
|
320
336
|
return (
|
|
321
337
|
<div className="-mx-2 flex flex-wrap">
|
|
322
338
|
{fields.map((field) => (
|
|
323
|
-
<div
|
|
339
|
+
<div
|
|
340
|
+
key={field.name}
|
|
341
|
+
className={`${getWidthClass(field.width)} mb-4 px-2`}
|
|
342
|
+
>
|
|
324
343
|
<ReturnFieldsV2
|
|
325
344
|
field={field}
|
|
326
345
|
value={formData[field.name]}
|
|
@@ -333,19 +352,14 @@ return (
|
|
|
333
352
|
```
|
|
334
353
|
|
|
335
354
|
**After:**
|
|
355
|
+
|
|
336
356
|
```jsx
|
|
337
357
|
import { Form, createFormHandler } from "@reactfast/forms";
|
|
338
358
|
|
|
339
359
|
const [formData, setFormData] = useState({});
|
|
340
360
|
const handleChange = createFormHandler({ fields, setState: setFormData });
|
|
341
361
|
|
|
342
|
-
return
|
|
343
|
-
<Form
|
|
344
|
-
fields={fields}
|
|
345
|
-
onChange={handleChange}
|
|
346
|
-
formData={formData}
|
|
347
|
-
/>
|
|
348
|
-
);
|
|
362
|
+
return <Form fields={fields} onChange={handleChange} formData={formData} />;
|
|
349
363
|
```
|
|
350
364
|
|
|
351
365
|
---
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(ne,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("react"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react","react-dom"],w):(ne=typeof globalThis<"u"?globalThis:ne||self,w(ne.
|
|
1
|
+
(function(ne,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("react"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react","react-dom"],w):(ne=typeof globalThis<"u"?globalThis:ne||self,w(ne.Forms={},ne.React,ne.ReactDOM))})(this,function(ne,w,be){"use strict";var Ep=Object.defineProperty;var yp=(ne,w,be)=>w in ne?Ep(ne,w,{enumerable:!0,configurable:!0,writable:!0,value:be}):ne[w]=be;var Y=(ne,w,be)=>yp(ne,typeof w!="symbol"?w+"":w,be);function sn(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const o=sn(w),jt=sn(be);var ar={exports:{}},st={};/**
|
|
2
2
|
* @license React
|
|
3
3
|
* react-jsx-runtime.production.min.js
|
|
4
4
|
*
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactfast/forms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Dynamic React forms with JSON schema, modifiers, and subforms",
|
|
5
|
-
"main": "dist/
|
|
6
|
-
"module": "dist/
|
|
5
|
+
"main": "dist/forms.cjs",
|
|
6
|
+
"module": "dist/forms.es.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"dev": "vite",
|
|
15
15
|
"build": "vite build",
|
|
16
|
-
"lint": "eslint src --ext .js,.jsx,.ts,.tsx"
|
|
16
|
+
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
|
|
17
|
+
"release:patch": "npm version patch --no-git-tag-version && pnpm build && npm publish --access public",
|
|
18
|
+
"release:minor": "npm version minor --no-git-tag-version && pnpm build && npm publish --access public",
|
|
19
|
+
"release:major": "npm version major --no-git-tag-version && pnpm build && npm publish --access public"
|
|
17
20
|
},
|
|
18
21
|
"browserslist": "defaults, not ie <= 11",
|
|
19
22
|
"keywords": [
|
|
File without changes
|
|
File without changes
|