@rebasepro/formex 0.3.0 → 0.5.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 +87 -147
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,165 +1,105 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @rebasepro/formex
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Lightweight and easy to integrate
|
|
8
|
-
- Supports custom field components
|
|
9
|
-
- Built-in validation handling
|
|
10
|
-
- Provides both field-level and form-level state management
|
|
3
|
+
Lightweight React form state management with undo/redo support.
|
|
11
4
|
|
|
12
5
|
## Installation
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```sh
|
|
17
|
-
npm install @rebasepro/formex
|
|
18
|
-
|
|
19
|
-
# or if you're using yarn
|
|
20
|
-
|
|
21
|
-
yarn add @rebasepro/formex
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @rebasepro/formex
|
|
22
9
|
```
|
|
23
10
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
**Peer dependencies:** `react >= 19.0.0`, `react-dom >= 19.0.0`
|
|
12
|
+
|
|
13
|
+
## What This Package Does
|
|
14
|
+
|
|
15
|
+
Formex is a minimal, Formik-inspired form library used throughout the Rebase admin panel. It manages form values, validation, touched/dirty state, submission, and provides built-in undo/redo history tracking. It uses `fast-equals` for deep equality checks and avoids unnecessary re-renders.
|
|
16
|
+
|
|
17
|
+
## Key Exports
|
|
18
|
+
|
|
19
|
+
| Export | Type | Description |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `useCreateFormex<T>` | Hook | Creates a `FormexController` — the primary way to initialize a form |
|
|
22
|
+
| `Formex` | Component | Context provider — wraps children to share form state via `useFormex` |
|
|
23
|
+
| `useFormex<T>` | Hook | Consumes the nearest `Formex` context, returns `FormexController<T>` |
|
|
24
|
+
| `Field` | Component | Connects an input to the form by `name`. Supports render-prop children, `as` prop, checkbox/radio/select types |
|
|
25
|
+
| `FormexController<T>` | Type | The full form controller object (values, errors, touched, dirty, submit, undo/redo, etc.) |
|
|
26
|
+
| `FormexResetProps<T>` | Type | Options for `resetForm()` (values, errors, touched, submitCount) |
|
|
27
|
+
| `getIn` | Utility | Deep-get a value from an object by dot/bracket path |
|
|
28
|
+
| `setIn` | Utility | Immutably deep-set a value in an object by path |
|
|
29
|
+
|
|
30
|
+
### `useCreateFormex` Options
|
|
31
|
+
|
|
32
|
+
| Option | Type | Default | Description |
|
|
33
|
+
|---|---|---|---|
|
|
34
|
+
| `initialValues` | `T` | *required* | Starting form values |
|
|
35
|
+
| `initialErrors` | `Record<string, string>` | `{}` | Pre-set field errors |
|
|
36
|
+
| `initialDirty` | `boolean` | `false` | Initial dirty flag |
|
|
37
|
+
| `initialTouched` | `Record<string, boolean>` | `{}` | Pre-set touched fields |
|
|
38
|
+
| `validation` | `(values: T) => Record<string, string> \| Promise<...> \| void` | — | Sync or async validation function |
|
|
39
|
+
| `validateOnChange` | `boolean` | `false` | Run validation on every field change |
|
|
40
|
+
| `validateOnInitialRender` | `boolean` | `false` | Run validation on mount |
|
|
41
|
+
| `onSubmit` | `(values: T, controller) => void \| Promise<void>` | — | Submit handler |
|
|
42
|
+
| `onReset` | `(controller) => void \| Promise<void>` | — | Reset callback |
|
|
43
|
+
| `onValuesChangeDeferred` | `(values: T, controller) => void` | — | Debounced (300ms) callback on value changes |
|
|
44
|
+
| `debugId` | `string` | — | Optional identifier for debugging |
|
|
45
|
+
|
|
46
|
+
### `FormexController<T>` Properties
|
|
47
|
+
|
|
48
|
+
| Property | Type | Description |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `values` | `T` | Current form values |
|
|
51
|
+
| `initialValues` | `T` | The initial values the form was created with |
|
|
52
|
+
| `errors` | `Record<string, string>` | Current validation errors |
|
|
53
|
+
| `touched` | `Record<string, boolean>` | Which fields have been touched |
|
|
54
|
+
| `dirty` | `boolean` | Whether values differ from initial |
|
|
55
|
+
| `isSubmitting` | `boolean` | Whether the form is currently submitting |
|
|
56
|
+
| `isValidating` | `boolean` | Whether validation is running |
|
|
57
|
+
| `submitCount` | `number` | How many times submit has been called |
|
|
58
|
+
| `version` | `number` | Incremented on submit and reset |
|
|
59
|
+
| `canUndo` / `canRedo` | `boolean` | Whether undo/redo is available |
|
|
60
|
+
| `setValues`, `setFieldValue`, `setFieldError`, `setFieldTouched`, `setDirty`, `setSubmitting`, `setTouched`, `setSubmitCount` | Functions | State setters |
|
|
61
|
+
| `handleChange`, `handleBlur`, `handleSubmit` | Event handlers | Bind to form/input events |
|
|
62
|
+
| `validate`, `resetForm`, `undo`, `redo` | Functions | Form actions |
|
|
27
63
|
|
|
28
|
-
|
|
64
|
+
## Quick Start
|
|
29
65
|
|
|
30
|
-
```
|
|
31
|
-
import
|
|
32
|
-
import { useCreateFormex } from 'formex-library';
|
|
66
|
+
```tsx
|
|
67
|
+
import { useCreateFormex, Formex, useFormex, Field } from "@rebasepro/formex";
|
|
33
68
|
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
initialValues: {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// validation: values => {
|
|
42
|
-
// const errors = {};
|
|
43
|
-
// if (!values.name) errors.name = 'Name is required';
|
|
44
|
-
// return errors;
|
|
45
|
-
// },
|
|
46
|
-
onSubmit: (values) => {
|
|
47
|
-
console.log('Form Submitted:', values);
|
|
69
|
+
function MyForm() {
|
|
70
|
+
const controller = useCreateFormex({
|
|
71
|
+
initialValues: { name: "", email: "" },
|
|
72
|
+
validation: (values) => {
|
|
73
|
+
const errors: Record<string, string> = {};
|
|
74
|
+
if (!values.name) errors.name = "Required";
|
|
75
|
+
return errors;
|
|
48
76
|
},
|
|
77
|
+
onSubmit: async (values) => {
|
|
78
|
+
await saveToAPI(values);
|
|
79
|
+
}
|
|
49
80
|
});
|
|
50
81
|
|
|
51
82
|
return (
|
|
52
|
-
<
|
|
53
|
-
{
|
|
54
|
-
|
|
83
|
+
<Formex value={controller}>
|
|
84
|
+
<form onSubmit={controller.handleSubmit}>
|
|
85
|
+
<Field name="name" />
|
|
86
|
+
<Field name="email" type="email" />
|
|
87
|
+
<button type="submit" disabled={controller.isSubmitting}>
|
|
88
|
+
Save
|
|
89
|
+
</button>
|
|
90
|
+
</form>
|
|
91
|
+
</Formex>
|
|
55
92
|
);
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Step 2: Use the `<Field />` component
|
|
60
|
-
|
|
61
|
-
```jsx
|
|
62
|
-
import { Field } from 'formex-library';
|
|
63
|
-
|
|
64
|
-
// Inside your form component
|
|
65
|
-
<Field name="name">
|
|
66
|
-
{({ field }) => (
|
|
67
|
-
<input
|
|
68
|
-
{...field}
|
|
69
|
-
placeholder="Your name"
|
|
70
|
-
/>
|
|
71
|
-
)}
|
|
72
|
-
</Field>
|
|
73
|
-
|
|
74
|
-
<Field name="email">
|
|
75
|
-
{({ field }) => (
|
|
76
|
-
<input
|
|
77
|
-
{...field}
|
|
78
|
-
type="email"
|
|
79
|
-
placeholder="Your email"
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
|
-
</Field>
|
|
83
|
-
|
|
84
|
-
<button type="submit">Submit</button>
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Handling Submissions
|
|
88
|
-
|
|
89
|
-
Wrap your form inputs and submit button within a form element and pass the `submitForm` method from your form controller to the form's `onSubmit` event:
|
|
90
|
-
|
|
91
|
-
```jsx
|
|
92
|
-
<form onSubmit={formController.handleSubmit}>
|
|
93
|
-
{/* Fields and submit button */}
|
|
94
|
-
</form>
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## API Reference
|
|
98
|
-
|
|
99
|
-
### `useCreateFormex`
|
|
100
|
-
|
|
101
|
-
Hook to create a form controller.
|
|
93
|
+
}
|
|
102
94
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- `validateOnChange` (optional): If `true`, validates fields whenever they change.
|
|
109
|
-
- `onSubmit`: A function that fires when the form is submitted.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
### `<Field />`
|
|
113
|
-
|
|
114
|
-
A component used to render individual form fields.
|
|
115
|
-
|
|
116
|
-
**Props**
|
|
117
|
-
|
|
118
|
-
- `name`: The name of the form field.
|
|
119
|
-
- `as` (optional): The component or HTML tag that should be rendered. Defaults to `"input"`.
|
|
120
|
-
- `children`: A function that returns the field input component. Receives field props as its parameter.
|
|
121
|
-
|
|
122
|
-
**Example**
|
|
123
|
-
|
|
124
|
-
```jsx
|
|
125
|
-
<Field name="username">
|
|
126
|
-
{({ field }) => <input {...field} />}
|
|
127
|
-
</Field>
|
|
95
|
+
// In a child component:
|
|
96
|
+
function SubmitButton() {
|
|
97
|
+
const { isSubmitting, dirty } = useFormex();
|
|
98
|
+
return <button type="submit" disabled={isSubmitting || !dirty}>Save</button>;
|
|
99
|
+
}
|
|
128
100
|
```
|
|
129
101
|
|
|
130
|
-
##
|
|
131
|
-
|
|
132
|
-
Formex is designed to be flexible. You can create custom field components, use any validation library, or integrate with UI component libraries.
|
|
133
|
-
|
|
134
|
-
### Using with UI Libraries
|
|
135
|
-
|
|
136
|
-
```jsx
|
|
137
|
-
import { Field } from 'formex-library';
|
|
138
|
-
import { TextField } from 'some-ui-library';
|
|
139
|
-
|
|
140
|
-
<Field name="username">
|
|
141
|
-
{({ field }) => (
|
|
142
|
-
<TextField {...field} label="Username" />
|
|
143
|
-
)}
|
|
144
|
-
</Field>
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Custom Validation
|
|
148
|
-
|
|
149
|
-
Leverage the `validation` function in `useCreateFormex` to integrate any validation logic or library.
|
|
150
|
-
|
|
151
|
-
```jsx
|
|
152
|
-
const validate = values => {
|
|
153
|
-
const errors = {};
|
|
154
|
-
if (!values.email.includes('@')) {
|
|
155
|
-
errors.email = 'Invalid email';
|
|
156
|
-
}
|
|
157
|
-
return errors;
|
|
158
|
-
};
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Conclusion
|
|
162
|
-
|
|
163
|
-
Formex provides a simple yet powerful way to manage forms in React applications. It reduces the amount of boilerplate code needed and offers flexibility to work with custom components and validation strategies. Whether you are building simple or complex forms, Formex can help streamline your form management process.
|
|
102
|
+
## Related Packages
|
|
164
103
|
|
|
165
|
-
|
|
104
|
+
- `@rebasepro/admin` — Uses Formex for all entity editing forms
|
|
105
|
+
- `@rebasepro/core` — Core Rebase framework
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/formex",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
"react-dom": ">=19.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"fast-equals": "6.0.0"
|
|
34
|
-
"react-compiler-runtime": "1.0.0"
|
|
33
|
+
"fast-equals": "6.0.0"
|
|
35
34
|
},
|
|
36
35
|
"devDependencies": {
|
|
37
36
|
"@jest/globals": "^30.4.1",
|