@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.
Files changed (2) hide show
  1. package/README.md +87 -147
  2. package/package.json +2 -3
package/README.md CHANGED
@@ -1,165 +1,105 @@
1
- # Formex - React Form Library
1
+ # @rebasepro/formex
2
2
 
3
- Formex is a lightweight, flexible library designed to simplify form handling within React applications. By leveraging React's powerful context and hooks features, Formex allows for efficient form state management with minimal boilerplate code.
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
- To install Formex, you can use either npm or yarn:
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
- ## Quick Start
25
-
26
- To get started with Formex, you first need to create your form context and form controller using the `useCreateFormex` hook. Then, you can structure your form using the `<Field />` components provided by Formex.
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
- ### Step 1: Create your form controller
64
+ ## Quick Start
29
65
 
30
- ```jsx
31
- import React from 'react';
32
- import { useCreateFormex } from 'formex-library';
66
+ ```tsx
67
+ import { useCreateFormex, Formex, useFormex, Field } from "@rebasepro/formex";
33
68
 
34
- const MyForm = () => {
35
- const formController = useCreateFormex({
36
- initialValues: {
37
- name: '',
38
- email: '',
39
- },
40
- // Optionally add a validation function
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
- <form onSubmit={formController.handleSubmit}>
53
- {/* Field components go here */}
54
- </form>
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
- **Parameters**
104
-
105
- - `initialValues`: An object with your form's initial values.
106
- - `initialErrors` (optional): An object for any initial validation errors.
107
- - `validation` (optional): A function for validating form data.
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
- ## Customization
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
- For further examples and advanced usage, refer to the Formex documentation or source code.
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.3.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",