@form-instant/react-input-mapping 2.0.4 → 2.2.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 CHANGED
@@ -1,501 +1,577 @@
1
- # Install
1
+ <!-- Documentación empaquetada para consumo por IA. Generado desde README.md + views/*.md -->
2
2
 
3
- ## input-mapping
3
+ ## Quick start guide
4
4
 
5
- <!-- tabs:start -->
5
+ ### 1. Installation and dependency order
6
6
 
7
- #### **npm**
7
+ Install in this order (or all at once in a monorepo):
8
8
 
9
- ```shell
10
- npm i @form-instant/react-input-mapping
11
- ```
9
+ 1. **React** (peer)
12
10
 
13
- #### **bun**
11
+ ```bash
12
+ bun add react react-dom
13
+ # or: npm i react react-dom
14
+ ```
15
+ 2. **Zod** (for defining schemas)
14
16
 
15
- ```shell
16
- bun add @form-instant/react-input-mapping
17
- ```
17
+ ```bash
18
+ bun add zod
19
+ # or: npm i zod
20
+ ```
21
+ 3. **@form-instant/react-input-mapping** (field → component mapping)
18
22
 
19
- <!-- tabs:end -->
23
+ ```bash
24
+ bun add @form-instant/react-input-mapping
25
+ # or: npm i @form-instant/react-input-mapping
26
+ ```
27
+ 4. **@form-instant/react-resolver-zod** (resolves Zod schema and provides `FormInstantProvider` / `FormInstantElement`)
20
28
 
21
- ## resolvers
29
+ ```bash
30
+ bun add @form-instant/react-resolver-zod
31
+ # or: npm i @form-instant/react-resolver-zod
32
+ ```
22
33
 
23
- <!-- tabs:start -->
34
+ This package has as peers: `react`, `@form-instant/react-input-mapping`, and `zod`. Without the mapping installed first, the resolver cannot resolve fields.
24
35
 
25
- #### **zod**
36
+ **Summary:** `react` → `zod` → `@form-instant/react-input-mapping` → `@form-instant/react-resolver-zod`.
26
37
 
27
- <!-- tabs:start -->
28
38
 
29
- #### **npm**
39
+ `<span id="implementation">`
30
40
 
31
- ```shell
32
- npm i @form-instant/react-resolver-zod
33
- ```
41
+ ## Implementation in your project
34
42
 
35
- #### **bun**
36
-
37
- ```shell
38
- bun add @form-instant/react-resolver-zod
39
- ```
43
+ ### 2.1 Creating the Mapping
40
44
 
41
- <!-- tabs:end -->
45
+ The **Mapping** is a dictionary that associates each `fieldType` (string) with a React component. You can use `InputMapping` or **`InputMappingStore`** (recommended: better support for granular re-renders).
42
46
 
43
- <!-- tabs:end -->
47
+ - **Default keys** (`INPUT_COMPONENTS_KEYS`): `'checkbox' | 'date' | 'select' | 'radio' | 'switch' | 'textarea' | 'number' | 'file' | 'text' | 'fallback'`.
48
+ - **Extra keys:** you can extend with your own types (e.g. `email`, `password`, `customSelect`).
49
+ - Each component receives **ParsedField**: `name` (`current`, `history`), `fieldType`, `required`, `default`, `fieldConfig`, and for selects/enums `options` as `[value, label][]`.
44
50
 
45
- # Example
51
+ Minimal example (in a file like `providers/input-mapping.tsx`):
46
52
 
47
- ## react
48
-
49
- ### constructor new InputMapping
50
-
51
- #### \* **_new Input Mapping_**
53
+ ```tsx
54
+ import {
55
+ InputMappingStore,
56
+ createFormInstantContainer,
57
+ type ParsedField,
58
+ type FieldConfig,
59
+ } from '@form-instant/react-input-mapping';
60
+ import type { FC } from 'react';
61
+
62
+ export type MyInputs = {
63
+ text: FieldConfig<{ placeholder?: string; label?: string }>;
64
+ number: FieldConfig<{ placeholder?: string; label?: string; min?: number; max?: number }>;
65
+ textarea: FieldConfig<{ placeholder?: string; label?: string }>;
66
+ date: FieldConfig;
67
+ email: FieldConfig<{ placeholder?: string; label?: string }>;
68
+ password: FieldConfig<{ placeholder?: string; label?: string }>;
69
+ checkbox: FieldConfig;
70
+ select: FieldConfig;
71
+ fallback: FieldConfig;
72
+ };
52
73
 
53
- Is the pillar of this set of tools, it consists of an extraction of the native **_new Map_** method in **_javascript_**, which receives as a parameter an object which works as a mapping of the input types, it also accepts two types as a parameter **_P_** are the parameters that each **_input_** component will accept and **_K_** are additional keys that are added to the input glossary.
74
+ const TextInput: FC<ParsedField<MyInputs['text']>> = ({ name, fieldConfig, required, ...props }) => (
75
+ <div>
76
+ <label htmlFor={name.current}>{(fieldConfig as any)?.label ?? name.current}{required && ' *'}</label>
77
+ <input id={name.current} name={name.history} type="text" required={required} {...props} />
78
+ </div>
79
+ );
54
80
 
55
- ```typescript
56
- import {
57
- InputMapping
58
- } from "@form-instant/react-input-mapping";
59
-
60
- export type ExtendProps = React.InputHTMLAttributes<HTMLInputElement>;
61
- export type P = ParsedField<
62
- ExtendProps,
63
- string
64
- >;
65
- export type K = "email" | "password";
66
-
67
- const inputMapping = new InputMapping<P, K>({
68
- fallback: (props) => {
69
- const { fieldConfig, name, ...prop } = props;
70
-
71
- return <input {...prop} {...fieldConfig} />;
72
- },
73
- textarea: () => <textarea />,
74
- number: (props) => {
75
- const { fieldConfig, name, ...prop } = props;
76
-
77
- return <input {...prop} {...fieldConfig} />;
78
- },
79
- text: (props) => {
80
- const { fieldConfig, name, ...prop } = props;
81
-
82
- return <input {...prop} {...fieldConfig} />;
83
- },
84
- date: () => <input type="date" />,
85
- email: (props) => {
86
- const { fieldConfig, name, ...prop } = props;
87
-
88
- return <input {...prop} {...fieldConfig} />;
89
- },
90
- password: (props) => {
91
- const { fieldConfig, name, ...prop } = props;
92
-
93
- return <input {...prop} {...fieldConfig} />;
94
- },
95
- select: (props) => {
96
- const { options } = props;
97
-
98
- return (
99
- <select>
100
- {options?.map(([k, v]) => (
101
- <option key={k} value={k}>
102
- {v}
103
- </option>
104
- ))}
105
- </select>
106
- );
107
- },
81
+ // Define the rest: NumberInput, TextareaInput, DateInput, EmailInput, PasswordInput,
82
+ // CheckboxInput, SelectInput (uses props.options as [value, label][]), FallbackInput...
83
+
84
+ export const inputMapping = new InputMappingStore<MyInputs>({
85
+ text: TextInput,
86
+ number: NumberInput,
87
+ textarea: TextareaInput,
88
+ date: DateInput,
89
+ email: EmailInput,
90
+ password: PasswordInput,
91
+ checkbox: CheckboxInput,
92
+ select: SelectInput,
93
+ fallback: FallbackInput,
108
94
  });
109
- ```
110
95
 
111
- default keys glossary, all values ​​entered by **_k_** will only understand the default listing.
112
-
113
- ```typescript
114
- export type INPUT_COMPONENTS_KEYS =
115
- | 'checkbox'
116
- | 'date'
117
- | 'select'
118
- | 'radio'
119
- | 'switch'
120
- | 'textarea'
121
- | 'number'
122
- | 'file'
123
- | 'text'
124
- | 'fallback';
96
+ export const { FormInstantInputsProvider, useInputMapping } =
97
+ createFormInstantContainer<MyInputs>(inputMapping);
125
98
  ```
126
99
 
127
- #### \* **_create global provider_**
128
-
129
- We created a global provider to be able to access input mapping.
130
-
131
- ```typescript
132
- import { createFormInstantContainer } from '@form-instant/react-input-mapping';
133
- import { inputMapping, P, K } from './inputMapping.tsx';
134
-
135
- export const { FormInstantInputsProvider, useInputMapping } = createFormInstantContainer<P, K>(
136
- inputMapping,
137
- );
138
- ```
100
+ - **Select:** the component receives `options?: [string, string][]`; you can populate them from an API (data fetch) and keep using the same mapping.
139
101
 
140
- we add our provider in the root of the **_vite_** project "./App.tsx" and **_next.js_** "layout.tsx" in the root.
102
+ ### 2.2 Setting up providers
141
103
 
142
- <!-- tabs:start -->
104
+ - `createFormInstantContainer<MyInputs>(inputMapping)` returns:
105
+ - **`FormInstantInputsProvider`**: provider that should wrap your app (or at least the area where forms are used).
106
+ - **`useInputMapping`**: hook to access the mapping (e.g. for custom components that use `ElementMapping`).
143
107
 
144
- #### **next.js**
108
+ Place it at the root (e.g. `App.tsx` or `layout.tsx`):
145
109
 
146
- ```typescript
147
- import { ReactNode } from "react";
148
- import { FormInstantInputsProvider } from "./components/providers";
110
+ ```tsx
111
+ import { FormInstantInputsProvider } from './providers/input-mapping';
149
112
 
150
- function Layout({ children }: { children: ReactNode }) {
113
+ function App() {
151
114
  return (
152
115
  <FormInstantInputsProvider>
153
- {children}
116
+ {/* routes, forms, etc. */}
154
117
  </FormInstantInputsProvider>
155
118
  );
156
119
  }
120
+ ```
121
+
122
+ ### 2.3 Zod schema and `fieldConfig`
123
+
124
+ - Define the schema with **Zod**. With **@form-instant/react-resolver-zod** the package already extends Zod with `.fieldConfig()` on the types used by the parser.
125
+ - **`.fieldConfig(...)`** is used to specify `fieldType` and extra props (placeholder, label, min, max, etc.) that reach the component via `fieldConfig`.
157
126
 
158
- export default Layout;
127
+ Example:
128
+
129
+ ```ts
130
+ import { z } from 'zod';
131
+ // If you use @form-instant/react-resolver-zod, you don't need to call extendZodWithFieldConfig:
132
+ // the module applies the extension on import.
133
+
134
+ const formSchema = z.object({
135
+ name: z.string().min(2).fieldConfig({ fieldType: 'text', placeholder: 'Name', label: 'Name' }),
136
+ email: z.email().fieldConfig({ fieldType: 'email', placeholder: 'email@example.com' }),
137
+ age: z.number().min(18).max(100).fieldConfig({ fieldType: 'number', min: 18, max: 100 }),
138
+ bio: z.string().min(10).fieldConfig({ fieldType: 'textarea' }),
139
+ role: z.enum(['admin', 'user']).fieldConfig({ fieldType: 'select' }),
140
+ });
141
+
142
+ export type FormSchemaType = z.infer<typeof formSchema>;
159
143
  ```
160
144
 
161
- #### **vite**
145
+ - If you omit `fieldConfig`, the resolver infers `fieldType` from the Zod type (string → text, number → number, etc.).
162
146
 
163
- ```typescript
164
- import "./App.css";
165
- import { Router } from "./router";
166
- import { FormInstantInputsProvider } from "./components/providers";
147
+ ### 2.4 Rendering forms
167
148
 
168
- function App() {
149
+ - Wrap the form in **`FormInstantProvider`** with the schema. Pass a stable schema reference (e.g. defined outside the component or memoized with `useMemo`) so the provider does not re-parse the schema on every parent re-render.
150
+ - Use **`FormInstantElement<FormSchemaType> name="..."`** for each **path** in the schema you want to render:
151
+ - **Primitive field:** `name="name"` → a single input.
152
+ - **Nested object:** `name="personalData"` → all fields of `personalData` are rendered (the provider parses the schema and exposes `field.schema`; `FormInstantElement` iterates and uses `ElementMapping` for each child).
153
+
154
+ Minimal example:
155
+
156
+ ```tsx
157
+ import { FormInstantProvider, FormInstantElement } from '@form-instant/react-resolver-zod';
158
+ import { formSchema, type FormSchemaType } from './schema';
159
+
160
+ export function MyForm() {
169
161
  return (
170
- <FormInstantInputsProvider>
171
- <Forms />
172
- </FormInstantInputsProvider>
162
+ <form onSubmit={...}>
163
+ <FormInstantProvider schema={formSchema}>
164
+ <FormInstantElement<FormSchemaType> name="name" />
165
+ <FormInstantElement<FormSchemaType> name="email" />
166
+ <FormInstantElement<FormSchemaType> name="age" />
167
+ <FormInstantElement<FormSchemaType> name="bio" />
168
+ <FormInstantElement<FormSchemaType> name="role" />
169
+ </FormInstantProvider>
170
+ </form>
173
171
  );
174
172
  }
175
-
176
- export default App;
177
173
  ```
178
174
 
179
- <!-- tabs:end -->
175
+ For **nested objects**, one `FormInstantElement` per object:
180
176
 
181
- #### **_use resolver_**
177
+ ```tsx
178
+ <FormInstantProvider schema={objectFormSchema}>
179
+ <FormInstantElement<ObjectFormType> name="personalData" />
180
+ <FormInstantElement<ObjectFormType> name="address" />
181
+ </FormInstantProvider>
182
+ ```
182
183
 
183
- To use our resolver we must add the function **_fieldConfig_**.
184
184
 
185
- <!-- tabs:start -->
185
+ `<span id="form-types">`
186
186
 
187
- #### **zod**
187
+ ## Form types
188
188
 
189
- generate provider and hook by use resolver.
189
+ ### 3.1 Static form
190
190
 
191
- ```typescript
192
- import { createFormInstantContainer } from '@form-instant/react-input-mapping';
193
- import { inputMapping, P, K, extendProps } from './inputMapping.tsx';
191
+ Flat schema, fixed fields. You only need `FormInstantProvider` plus several `FormInstantElement` (one per field or per object group).
194
192
 
195
- export const { FormInstantInputsProvider, useInputMapping } = createFormInstantContainer<P, K>(
196
- inputMapping,
197
- );
193
+ ```tsx
194
+ const schema = z.object({
195
+ name: z.string().min(2),
196
+ email: z.email(),
197
+ age: z.number().min(18).max(100),
198
+ });
199
+ // ...
200
+ <FormInstantProvider schema={schema}>
201
+ <FormInstantElement<FormType> name="name" />
202
+ <FormInstantElement<FormType> name="email" />
203
+ <FormInstantElement<FormType> name="age" />
204
+ </FormInstantProvider>
198
205
  ```
199
206
 
200
- add **_fieldConfig_** in the zod schema.
201
-
202
- ```typescript
203
- import { z } from 'zod';
207
+ ### 3.2 Inputs with data fetch (select / autocomplete)
204
208
 
205
- extendZodWithFieldConfig<React.InputHTMLAttributes<HTMLInputElement>>(z);
209
+ - **Select:** in the schema use `z.enum([...])` or a type the parser turns into `options`; the mapping component receives `options` and can also receive data loaded from an API (store options in state and pass them via context or props to the component that renders the field).
210
+ - **Autocomplete:** you can define your own `fieldType` (e.g. `autocomplete`), map it to a component that uses `useFields` and internally fetches and shows suggestions; the final value is still bound to the same `name`.
206
211
 
207
- export { z };
208
- ```
212
+ The select mapping already uses `options?: [string, string][]`; populating `options` from an API is compatible with the same flow.
209
213
 
210
- <!-- tabs:end -->
214
+ ### 3.3 Dynamic form with `discriminatedUnion`
211
215
 
212
- #### \* **_build form_**
216
+ Schema that changes based on a discriminator (e.g. user type). Steps:
213
217
 
214
- - schema:
218
+ 1. Define the schema with **`z.discriminatedUnion('status', [ z.object({ status: z.literal('ok'), ... }), z.object({ status: z.literal('not'), ... }) ])`**.
219
+ 2. Use **`useSchema`** from `@form-instant/react-resolver-zod`: it receives a callback that returns the schema and a dependencies object; when the **reference** of the dependencies object changes, the schema and initial values are recalculated. Pass a stable dependencies object (e.g. from state or `useMemo`) to avoid unnecessary recalculations on parent re-renders.
220
+ 3. Keep **dependencies** in sync with the current discriminator value in the form (e.g. with `form.watch('data.status')` if you use react-hook-form, or your own state).
221
+ 4. The first field in the union is the discriminator; you can map that field to a select in your mapping (by `fieldType` or by the discriminator key) so the user can switch the variant.
215
222
 
216
- ```typescript
217
- import { z } from 'zod';
223
+ Structure example (submit and form provider depend on your form library):
218
224
 
225
+ ```tsx
219
226
  const formSchema = z.object({
220
- data: z.object({
221
- email: z.string().email(),
222
- password: z.string(),,
223
- confirm: z.string(),
224
- })
227
+ data: z.discriminatedUnion('status', [
228
+ z.object({ status: z.literal('ok'), code: z.string() }),
229
+ z.object({ status: z.literal('not'), birthday: z.coerce.date() }),
230
+ ]),
225
231
  });
226
232
 
227
- export type formSchemaType = Zod.infer<typeof formSchema>;
228
- ```
229
-
230
- - component
233
+ const [dependencies, setDependencies] = useState({ status: 'ok' });
234
+ const { schema } = useSchema(() => formSchema, dependencies);
231
235
 
232
- ```typescript
233
- import {
234
- FormInstantElement,
235
- FormInstantProvider,
236
- } from "@form-instant/react-resolver-zod";
237
- import { z } from "zod";
238
- import { formSchema, formSchemaType } from "./schema";
236
+ // In a useEffect or in the same flow as the form: when data.status changes,
237
+ // update setDependencies({ status: newStatus }) so useSchema returns
238
+ // the correct schema and FormInstantElement shows the fields for that variant.
239
239
 
240
- export const Forms = () => {
241
- return (
242
- <form>
243
- <h1>your form</h1>
244
- <FormInstantProvider schema={formSchema}>
245
- <div>
246
- <FormInstantElement<formSchemaType> name="security_data" />
247
- <br />
248
- <FormInstantElement<formSchemaType> name="personal_data" />
249
- </div>
250
- </FormInstantProvider>
251
-
252
- <button type="submit">submit</button>
253
- </form>
254
- );
255
- };
240
+ <FormInstantProvider schema={schema}>
241
+ <FormInstantElement<FormType> name="data" />
242
+ </FormInstantProvider>
256
243
  ```
257
244
 
258
- ## **_special inputs_**
245
+ ### 3.4 Array with dynamic input creation
259
246
 
260
- ### **use-formInstantField**
247
+ For **arrays of objects** (e.g. list of items or skills):
261
248
 
262
- #### **by object**
249
+ 1. Schema with **`z.array(z.object({ ... }))`** (optionally `.min()`/`.max()`).
250
+ 2. In the **array** component:
251
+ - **`useFields({ key: 'items' })`** (or the array field name) to get the parsed field.
252
+ - **`useInputArray(field)`** (from `@form-instant/react-input-mapping`): returns `inputs`, `append`, `remove`, `fieldConfig`, etc.
253
+ 3. Render each item: for each entry in `inputs`, iterate over properties and use **`ElementMapping formProps={...}`** for each. +/- buttons that call `append()` and `remove(index)`.
263
254
 
264
- ```typescript
265
- import { Fragment } from "react";
266
- import { ElementMapping, ParsedField, useFormInstantField } from "@form-instant/react-input-mapping";
267
- import { P } from "@/providers";
255
+ Condensed example:
256
+
257
+ ```tsx
258
+ const arrayFormSchema = z.object({
259
+ items: z.array(z.object({
260
+ name: z.string().min(2),
261
+ quantity: z.number().min(1),
262
+ price: z.number().min(0),
263
+ })).min(1).max(10),
264
+ });
268
265
 
269
- export const ObjectComp: FC<P> = (props) => {
270
- const { fiends, fieldConfig, ...prop } = useFormInstantField<P>(props);
266
+ function ArrayFieldComponent({ name }: { name: 'items' }) {
267
+ const field = useFields({ key: name });
268
+ const { inputs, append, remove, fieldConfig } = useInputArray(field);
271
269
  const id = useId();
272
270
 
273
271
  return (
274
- <div {...{ ...fieldConfig, ...prop }}>
275
- {fiends.map((prop) => {
276
- return (
277
- <Fragment key={`${id}-${prop.name.history}`}>
278
- <ElementMapping formProps={prop} />
279
- </Fragment>
280
- );
281
- })}
272
+ <div>
273
+ {inputs.map((inputFields, index) => (
274
+ <div key={`${id}-${index}`}>
275
+ {Object.entries(inputFields).map(([key, value]) => (
276
+ <ElementMapping key={key} formProps={value} />
277
+ ))}
278
+ <button type="button" onClick={() => remove(index)}>Remove</button>
279
+ </div>
280
+ ))}
281
+ <button type="button" onClick={append}>+ Add</button>
282
282
  </div>
283
283
  );
284
- };
284
+ }
285
+
286
+ <FormInstantProvider schema={arrayFormSchema}>
287
+ <ArrayFieldComponent name="items" />
288
+ </FormInstantProvider>
285
289
  ```
286
290
 
287
- #### **by array**
291
+ `fieldConfig?.min` / `fieldConfig?.max` can come from the schema (e.g. via `.fieldConfig({ min: 1, max: 10 })`) to disable buttons based on limits.
288
292
 
289
- ```typescript
290
- import { Fragment, useId } from "react";
291
- import { ElementMapping, ParsedField, useFormInstantField } from "@form-instant/react-input-mapping";
292
- import { P } from "@/providers";
293
+ ### 3.5 Nested object
293
294
 
295
+ Schema with **`z.object({ group: z.object({ a: z.string(), b: z.number() }) })`**. No custom component needed: a single **`FormInstantElement<FormType> name="group"`** makes the resolver render all fields of `group` (the parser fills `field.schema` and `FormInstantElement` walks those children with `ElementMapping`).
294
296
 
295
- export const ArrayComp: FC<P> = (props) => {
296
- const { fiends, fieldConfig, ...prop } = useFormInstantField<P>(props);
297
- const id = useId();
297
+ ```tsx
298
+ const objectFormSchema = z.object({
299
+ personalData: z.object({
300
+ firstName: z.string().min(2),
301
+ lastName: z.string().min(2),
302
+ email: z.string().email(),
303
+ }),
304
+ address: z.object({
305
+ street: z.string(),
306
+ city: z.string(),
307
+ zipCode: z.string(),
308
+ }),
309
+ });
298
310
 
299
- return (
300
- <div {...{ ...fieldConfig, ...prop }}>
301
- {fiends.map((prop, index) => {
302
- return (
303
- <Fragment key={`${id}-${prop.name.history}`}>
304
- <div>
305
- <ElementMapping formProps={prop} />
306
- <button onClick={() => append()}>+</button>
307
- <button onClick={() => remove(index)}>-</button>
308
- </div>
309
- <br />
310
- <br />
311
- </Fragment>
312
- );
313
- })}
314
- </div>
315
- );
316
- };
311
+ <FormInstantProvider schema={objectFormSchema}>
312
+ <FormInstantElement<ObjectFormType> name="personalData" />
313
+ <FormInstantElement<ObjectFormType> name="address" />
314
+ </FormInstantProvider>
317
315
  ```
318
316
 
319
- ## **_reactive schemas_**
320
317
 
321
- ### **fieldConfig**
318
+ `<span id="full-example">`
322
319
 
323
- ```typescript
324
- import { Fragment, useId } from "react";
325
- import { ElementMapping, useFormInstantField } from "@form-instant/react-input-mapping";
326
- import { FormInstantElement, FormInstantProvider } from "@form-instant/react-resolver-zod";
327
- import { P } from "@/providers";
328
- import { z } from '@/zod';
320
+ ## Full example: React Hook Form + Shadcn UI + Zod
329
321
 
330
- const formSchema = z.object({
331
- data: z.object({
332
- email: z.string().email().fieldConfig({
333
- fieldType: "email",
334
- placeholder: "example@mal.com",
335
- }),
336
- password: z.string().fieldConfig({
337
- fieldType: "password",
338
- placeholder: "******",
339
- }),
340
- confirm: z.string(),
341
- })
322
+ This example wires **react-hook-form**, **@hookform/resolvers** (Zod resolver), **Zod**, and **shadcn/ui** (or any similar UI primitives) with Form Instant. Validation runs via `zodResolver`; inputs are rendered from your schema and mapping.
323
+
324
+ ### Dependencies
325
+
326
+ ```bash
327
+ bun add react-hook-form @hookform/resolvers zod
328
+ # or: npm i react-hook-form @hookform/resolvers zod
329
+ ```
330
+
331
+ Add **shadcn/ui** with your stack (e.g. `npx shadcn@latest init`) and install the components you need (e.g. `Input`, `Label`, `Button`). You can also use plain HTML elements or your own design system.
332
+
333
+ ### 1. Zod schema
334
+
335
+ ```ts
336
+ // lib/schemas/profile.ts
337
+ import { z } from 'zod';
338
+
339
+ export const profileSchema = z.object({
340
+ username: z.string().min(2, 'At least 2 characters').fieldConfig({ fieldType: 'text', placeholder: 'Username', label: 'Username' }),
341
+ email: z.string().email('Invalid email').fieldConfig({ fieldType: 'email', placeholder: 'you@example.com', label: 'Email' }),
342
+ age: z.number().min(18, 'Must be 18+').max(120).fieldConfig({ fieldType: 'number', label: 'Age', min: 18, max: 120 }),
343
+ bio: z.string().min(10, 'At least 10 characters').fieldConfig({ fieldType: 'textarea', label: 'Bio', placeholder: 'Tell us about yourself' }),
342
344
  });
343
345
 
344
- export const FromComp = (props) => {
346
+ export type ProfileFormValues = z.infer<typeof profileSchema>;
347
+ ```
348
+
349
+ ### 2. Input mapping (with react-hook-form registration)
350
+
351
+ For react-hook-form to validate and submit correctly, each rendered input must be **registered**. Use `useFormContext()` inside your mapping components and spread `register(name.history)` (and optionally show errors from `formState.errors`).
352
+
353
+ ```tsx
354
+ // components/input-mapping.tsx
355
+ import {
356
+ InputMappingStore,
357
+ createFormInstantContainer,
358
+ type ParsedField,
359
+ type FieldConfig,
360
+ } from '@form-instant/react-input-mapping';
361
+ import { useFormContext } from 'react-hook-form';
362
+ import type { FC } from 'react';
363
+ import { Input } from '@/components/ui/input';
364
+ import { Label } from '@/components/ui/label';
365
+ import { Textarea } from '@/components/ui/textarea';
366
+
367
+ export type MyInputs = {
368
+ text: FieldConfig<{ placeholder?: string; label?: string }>;
369
+ number: FieldConfig<{ placeholder?: string; label?: string; min?: number; max?: number }>;
370
+ textarea: FieldConfig<{ placeholder?: string; label?: string }>;
371
+ email: FieldConfig<{ placeholder?: string; label?: string }>;
372
+ fallback: FieldConfig;
373
+ };
374
+
375
+ const TextInput: FC<ParsedField<MyInputs['text']>> = ({ name, fieldConfig, required, ...props }) => {
376
+ const { register, formState: { errors } } = useFormContext();
377
+ const label = (fieldConfig as any)?.label ?? name.current;
378
+ const placeholder = (fieldConfig as any)?.placeholder ?? '';
345
379
 
346
380
  return (
347
- <>
348
- <FormInstantProvider schema={schema}>
349
- <h1>your form </h1>
350
- <div>
351
- <br />
352
- <FormInstantElement<formSchemaType> name="data" />
353
- </div>
354
- <button>
355
- submit
356
- </button>
357
- </FormInstantProvider>
358
- </>
381
+ <div className="space-y-2">
382
+ <Label htmlFor={name.current}>{label}{required && ' *'}</Label>
383
+ <Input
384
+ id={name.current}
385
+ type="text"
386
+ placeholder={placeholder}
387
+ aria-invalid={!!errors[name.history]}
388
+ {...register(name.history)}
389
+ {...props}
390
+ />
391
+ {errors[name.history]?.message && (
392
+ <p className="text-sm text-destructive">{String(errors[name.history]?.message)}</p>
393
+ )}
394
+ </div>
359
395
  );
360
396
  };
361
- ```
362
397
 
363
- ### **use-schema**
398
+ const NumberInput: FC<ParsedField<MyInputs['number']>> = ({ name, fieldConfig, required, ...props }) => {
399
+ const { register, formState: { errors } } = useFormContext();
400
+ const label = (fieldConfig as any)?.label ?? name.current;
364
401
 
365
- **useSchema** is a hook, receives two values, a callback and a dependencies object, the callback will be executed when the dependencies change, similar to a useEffect, the callback receives as a parameter the same dependencies object, the callback must always return a valid zod schema..
366
-
367
- ```typescript
368
- const [dependencies, setDependencies] = useState({ status: "ok" });
402
+ return (
403
+ <div className="space-y-2">
404
+ <Label htmlFor={name.current}>{label}{required && ' *'}</Label>
405
+ <Input
406
+ id={name.current}
407
+ type="number"
408
+ min={fieldConfig?.min}
409
+ max={fieldConfig?.max}
410
+ aria-invalid={!!errors[name.history]}
411
+ {...register(name.history, { valueAsNumber: true })}
412
+ {...props}
413
+ />
414
+ {errors[name.history]?.message && (
415
+ <p className="text-sm text-destructive">{String(errors[name.history]?.message)}</p>
416
+ )}
417
+ </div>
418
+ );
419
+ };
369
420
 
370
- const { schema } = useSchema((dependencies /* is a dependencies object */) => {
371
- return formSchema;
372
- }, dependencies);
373
- ```
421
+ const TextareaInput: FC<ParsedField<MyInputs['textarea']>> = ({ name, fieldConfig, required, ...props }) => {
422
+ const { register, formState: { errors } } = useFormContext();
423
+ const label = (fieldConfig as any)?.label ?? name.current;
424
+ const placeholder = (fieldConfig as any)?.placeholder ?? '';
374
425
 
375
- Example with react-hook-form we must remember that they can use the form hook or form solution that the developer prefers, in this example shows the usage for conditional rendering using the **z.discriminatedUnion** method of **zod**.
426
+ return (
427
+ <div className="space-y-2">
428
+ <Label htmlFor={name.current}>{label}{required && ' *'}</Label>
429
+ <Textarea
430
+ id={name.current}
431
+ placeholder={placeholder}
432
+ aria-invalid={!!errors[name.history]}
433
+ {...register(name.history)}
434
+ {...props}
435
+ />
436
+ {errors[name.history]?.message && (
437
+ <p className="text-sm text-destructive">{String(errors[name.history]?.message)}</p>
438
+ )}
439
+ </div>
440
+ );
441
+ };
376
442
 
377
- When used in **z.discriminatedUnion**, an array of objects is received, where the first object is the input of the discriminant condition and will have the **discriminator** type, with this key or the **fiendType** that you pass in the **fiendConfig** you can capture this value in the mapping.
443
+ const EmailInput: FC<ParsedField<MyInputs['email']>> = ({ name, fieldConfig, required, ...props }) => {
444
+ const { register, formState: { errors } } = useFormContext();
445
+ const label = (fieldConfig as any)?.label ?? name.current;
446
+ const placeholder = (fieldConfig as any)?.placeholder ?? '';
378
447
 
379
- ```typescript
380
- import { Fragment, useId } from "react";
381
- import { ElementMapping, ParsedField, useFormInstantField } from "@form-instant/react-input-mapping";
382
- import { FormInstantElement, FormInstantProvider, useSchema } from "@form-instant/react-resolver-zod";
383
- import { FormInstantInputsProvider, useInputMapping } from "@/resolver";
384
- import { P } from "@/providers";
385
- import { z } from '@/zod';
448
+ return (
449
+ <div className="space-y-2">
450
+ <Label htmlFor={name.current}>{label}{required && ' *'}</Label>
451
+ <Input
452
+ id={name.current}
453
+ type="email"
454
+ placeholder={placeholder}
455
+ aria-invalid={!!errors[name.history]}
456
+ {...register(name.history)}
457
+ {...props}
458
+ />
459
+ {errors[name.history]?.message && (
460
+ <p className="text-sm text-destructive">{String(errors[name.history]?.message)}</p>
461
+ )}
462
+ </div>
463
+ );
464
+ };
386
465
 
387
- const formSchema = z.object({
388
- data: z.discriminatedUnion("status", [
389
- z.object({
390
- status: z.literal("ok"),
466
+ const FallbackInput: FC<ParsedField<MyInputs['fallback']>> = ({ name, fieldConfig, required, ...props }) => {
467
+ const { register, formState: { errors } } = useFormContext();
468
+ const label = (fieldConfig as any)?.label ?? name.current;
391
469
 
392
- code: z.string(),
393
- }),
394
- z.object({
395
- status: z.literal("not"),
470
+ return (
471
+ <div className="space-y-2">
472
+ <Label htmlFor={name.current}>{label}{required && ' *'}</Label>
473
+ <Input
474
+ id={name.current}
475
+ type="text"
476
+ aria-invalid={!!errors[name.history]}
477
+ {...register(name.history)}
478
+ {...props}
479
+ />
480
+ {errors[name.history]?.message && (
481
+ <p className="text-sm text-destructive">{String(errors[name.history]?.message)}</p>
482
+ )}
483
+ </div>
484
+ );
485
+ };
396
486
 
397
- birthday: z.coerce.date(),
398
- }),
399
- ]),
487
+ export const inputMapping = new InputMappingStore<MyInputs>({
488
+ text: TextInput,
489
+ number: NumberInput,
490
+ textarea: TextareaInput,
491
+ email: EmailInput,
492
+ fallback: FallbackInput,
400
493
  });
401
494
 
402
- export const FromComp = (props) => {
495
+ export const { FormInstantInputsProvider, useInputMapping } =
496
+ createFormInstantContainer<MyInputs>(inputMapping);
497
+ ```
403
498
 
404
- // define state by dependecys
405
- const [dependencies, setDependencies] = useState({ status: "" });
499
+ ### 3. Form component
406
500
 
407
- const { schema } = useSchema(() => {
408
- return formSchema;
409
- }, dependencies);
501
+ Use **FormProvider** from react-hook-form, **zodResolver** with your schema, and **FormInstantProvider** + **FormInstantElement** so fields are rendered from the schema and your mapping.
410
502
 
411
- const form = useForm<Zod.infer<typeof schema>>({
412
- resolver: zodResolver(schema),
503
+ ```tsx
504
+ // components/profile-form.tsx
505
+ import { useForm, FormProvider } from 'react-hook-form';
506
+ import { zodResolver } from '@hookform/resolvers/zod';
507
+ import { FormInstantProvider, FormInstantElement } from '@form-instant/react-resolver-zod';
508
+ import { profileSchema, type ProfileFormValues } from '@/lib/schemas/profile';
509
+ import { Button } from '@/components/ui/button';
510
+
511
+ export function ProfileForm() {
512
+ const form = useForm<ProfileFormValues>({
513
+ resolver: zodResolver(profileSchema),
413
514
  defaultValues: {
414
- data: {
415
- status: "ok",
416
- },
515
+ username: '',
516
+ email: '',
517
+ age: undefined,
518
+ bio: '',
417
519
  },
418
520
  });
419
521
 
420
- useEffect(() => {
421
-
422
- /* This way of capturing and formatting form data was
423
- taken from the useFormValues ​​hook
424
- recommended by react-hook-form */
425
- const fromValues = {
426
- ...form.getValues(),
427
- ...form.watch(),
428
- };
429
-
430
- if (
431
- !dependencies.status ||
432
- dependencies.status !== fromValues.data.status
433
- ) {
434
-
435
- setDependencies((prev) => {
436
- return {
437
- ...prev,
438
- status: fromValues.data.status,
439
- };
440
- });
441
- }
442
- }, [form.watch(), dependencies]);
443
-
444
- const onSubmit = form.handleSubmit(
445
- (data) => {
446
- console.log("data", data);
447
- },
448
- (err) => {
449
- console.log("err", err);
450
- }
451
- );
522
+ const onSubmit = (data: ProfileFormValues) => {
523
+ console.log(data);
524
+ };
452
525
 
453
526
  return (
454
- <form onSubmit={onSubmit}>
455
- <FormProvider {...form}>
456
- <FormInstantProvider schema={schema}>
457
- <h1>your form </h1>
458
- <div>
459
- <br />
460
- <FormInstantElement<formSchemaType> name="data" />
461
- </div>
462
- <button
463
- onClick={(e) => {
464
- e.preventDefault();
465
- const pre = form.getValues("personal_data.status");
466
-
467
- form.setValue(
468
- "personal_data.status",
469
- pre === "not" ? "ok" : "not"
470
- );
471
- }}
472
- >
473
- switch
474
- </button>
527
+ <FormProvider {...form}>
528
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
529
+ <FormInstantProvider schema={profileSchema}>
530
+ <FormInstantElement<ProfileFormValues> name="username" />
531
+ <FormInstantElement<ProfileFormValues> name="email" />
532
+ <FormInstantElement<ProfileFormValues> name="age" />
533
+ <FormInstantElement<ProfileFormValues> name="bio" />
475
534
  </FormInstantProvider>
476
- </FormProvider>
477
- </form>
535
+ <Button type="submit">Submit</Button>
536
+ </form>
537
+ </FormProvider>
478
538
  );
479
- };
539
+ }
480
540
  ```
481
541
 
482
- discriminator component example.
542
+ ### 4. App root
483
543
 
484
- ```tsx
485
- import { FC } from "react";
486
- import { P } from "@/providers";
544
+ Ensure **FormInstantInputsProvider** wraps the tree where forms use the mapping (e.g. root layout or App).
487
545
 
488
- const discriminator: FC<P> = (props) => {
489
- const { options } = props;
546
+ ```tsx
547
+ // App.tsx
548
+ import { FormInstantInputsProvider } from '@/components/input-mapping';
549
+ import { ProfileForm } from '@/components/profile-form';
490
550
 
551
+ export default function App() {
491
552
  return (
492
- <select>
493
- {options?.map(([k, v]) => (
494
- <option key={k} value={k}>
495
- {v}
496
- </option>
497
- ))}
498
- </select>
553
+ <FormInstantInputsProvider>
554
+ <ProfileForm />
555
+ </FormInstantInputsProvider>
499
556
  );
500
557
  }
501
558
  ```
559
+
560
+ **Summary:** Use **Zod** for the schema, **zodResolver** in `useForm`, **FormProvider** (react-hook-form) around the form, and **FormInstantProvider** + **FormInstantElement** to render fields from the schema. In your mapping components, call **useFormContext()** and **register(name.history)** (and optionally **formState.errors**) so react-hook-form controls and validates the inputs.
561
+
562
+
563
+ `<span id="api-reference">`
564
+
565
+ ## API reference (minimal)
566
+
567
+ | Concept | Package | Description |
568
+ | -------------------------------------------------------------- | -------------------------------- | --------------------------------------------------------------------- |
569
+ | `InputMapping` / `InputMappingStore` | react-input-mapping | Maps fieldType → React component. |
570
+ | `createFormInstantContainer` | react-input-mapping | Creates `FormInstantInputsProvider` and `useInputMapping`. |
571
+ | `ParsedField`, `FieldConfig` | react-input-mapping | Props types for mapping components. |
572
+ | `ElementMapping` | react-input-mapping | Renders a single field from `formProps` (fieldType, name, etc.). |
573
+ | `useInputArray` | react-input-mapping | For arrays:`inputs`, `append`, `remove`, `fieldConfig`. |
574
+ | `FormInstantProvider`, `FormInstantElement`, `useFields` | react-resolver-zod | Schema provider, element per path, hook for a field. |
575
+ | `useSchema` | react-resolver-zod | Reactive schema (e.g. for `discriminatedUnion`) and initial values. Recalculates when the **reference** of the dependencies object changes; pass a stable object to avoid unnecessary recalculations. |
576
+ | `.fieldConfig(...)` | react-resolver-zod (extends Zod) | Associate `fieldType` and props with a schema field. |
577
+
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- class Z extends Map{appendObj(R){for(let O in R)this.set(O,R[O])}constructor(R){super();if(!R)return;this.appendObj(R)}exists(R){if(!super.has(R))return"fallback";return R}get(R){return super.get(R)}set(R,O){if(!super.has(R))super.set(R,O);return this}extends(R){let O=Object.fromEntries(super.entries()),q=R(this);return new Z({...O,...q})}}import{createContext as x}from"react";var _=x(null);import{createElement as C,memo as I,use as m}from"react";class W{listeners=new Map;subscribe(R,O){if(!this.listeners.has(R))this.listeners.set(R,new Set);return this.listeners.get(R).add(O),()=>this.unsubscribe(R,O)}unsubscribe(R,O){this.listeners.get(R)?.delete(O)}getListeners(R){return this.listeners.get(R)}hasListeners(R){return this.listeners.has(R)&&this.listeners.get(R).size>0}clear(){this.listeners.clear()}}class Q{static notify(R,O){let q=R.getListeners(O);if(q)q.forEach((z)=>z())}static notifyMany(R,O){O.forEach((q)=>this.notify(R,q))}}class L extends Z{_subscriptionManager;get subscriptionManager(){if(!this._subscriptionManager)this._subscriptionManager=new W;return this._subscriptionManager}subscribe(R,O){return this.subscriptionManager.subscribe(R,O)}unsubscribe(R,O){this.subscriptionManager.unsubscribe(R,O)}set(R,O){let q=!super.has(R);if(super.set(R,O),q)Q.notify(this.subscriptionManager,String(R));return this}delete(R){let O=super.delete(R);if(O)Q.notify(this.subscriptionManager,String(R));return O}clear(){let R=Array.from(this.keys()).map((O)=>String(O));super.clear(),Q.notifyMany(this.subscriptionManager,R)}}import{use as M,useSyncExternalStore as h}from"react";function $(R){if(!(R instanceof L))throw Error("InputMapping must be an instance of InputMappingStore for granular rendering")}function T(R,O){let z=M(R);return $(z),h((B)=>z.subscribe(O,B),()=>z.get(O),()=>z.get(O))}import{use as b,useMemo as f}from"react";function N(R){let q=b(R);$(q);let z=q;return f(()=>({set:(B,J)=>{return z.set(B,J)},clear:()=>{z.clear()},delete:(B)=>{return z.delete(B)}}),[z])}function A(R){function O(z){return T(R,z)}function q(){return N(R)}return{useInputComponent:O,useInputMappingActions:q}}var w=A(_),UR=(R)=>{let O=R instanceof L?R:new L(Object.fromEntries(R.entries()));return{FormInstantInputsProvider:(B)=>C(_.Provider,{value:O},B.children),useInputMapping:()=>m(_)}},g=I(({formProps:R})=>{let O=w.useInputComponent(R.fieldType)||w.useInputComponent("fallback");if(!O)return null;return C(O,R)},(R,O)=>{return R.formProps.fieldType===O.formProps.fieldType&&R.formProps.name.history===O.formProps.name.history&&R.formProps.name.current===O.formProps.name.current});g.displayName="ElementMapping";import{useCallback as S,useState as y}from"react";function P(R){return R&&typeof R==="object"&&"name"in R&&"fieldType"in R}function X(R,O,q){if(!P(R)){let D={};for(let K in R){let Y=R[K];if(!Y)continue;D[K]=X(Y,O,q)}return D}let z=R.name.current,B=`${q}.${O}.${z}`,J={...R,name:{current:z,history:B}};if(R.schema&&Array.isArray(R.schema))J.schema=R.schema.map((D)=>X(D,O,q));return J}var jR=(R)=>{let{fieldConfig:O,name:q,...z}=R,B=q.history||q.current,J=z.schema.at(0),[D,K]=y([]),Y=S(()=>{let U=O?.max??1/0;if(Number(D?.length)>=U)return;K((G)=>{let V=G.length,j=X(J,V,B);return[...G,j]})},[D,O?.max,B,J]),v=S((U)=>{let E=O?.min??0;if((D?.length||0)>E)K((V)=>{return V.filter((F,H)=>H!==U).map((F,H)=>{return X(F,H,B)})})},[D,O?.min,B]);return{inputs:D,append:Y,remove:v,setInputs:K,fieldConfig:O,name:q,...z}};import{useReducer as u,useRef as c,use as k}from"react";function PR(R){return function(){let q=k(R);if(!q)throw Error("InputMappingContext not found");let z=c(q),[,B]=u((J)=>J+1,0);return{...z.current,set:(J,D)=>{let K=z.current.set(J,D);return B(),K},clear:()=>{z.current.clear(),B()},delete:(J)=>{let D=z.current.delete(J);return B(),D}}}}export{jR as useInputArray,PR as createInputMappingHook,A as createInputMappingGranularHook,UR as createFormInstantContainer,L as InputMappingStore,_ as InputMappingContext,Z as InputMapping,g as ElementMapping};
1
+ class U extends Map{appendObj(R){for(let O in R)this.set(O,R[O])}constructor(R){super();if(!R)return;this.appendObj(R)}exists(R){if(!super.has(R))return"fallback";return R}get(R){return super.get(R)}set(R,O){if(!super.has(R))super.set(R,O);return this}extends(R){let O=Object.fromEntries(super.entries()),q=R(this);return new U({...O,...q})}}import{createContext as M}from"react";var G=M(null);import{createElement as S,memo as m,use as g}from"react";class E{listeners=new Map;subscribe(R,O){if(!this.listeners.has(R))this.listeners.set(R,new Set);return this.listeners.get(R).add(O),()=>this.unsubscribe(R,O)}unsubscribe(R,O){this.listeners.get(R)?.delete(O)}getListeners(R){return this.listeners.get(R)}hasListeners(R){return this.listeners.has(R)&&this.listeners.get(R).size>0}clear(){this.listeners.clear()}}class Z{static notify(R,O){let q=R.getListeners(O);if(q)q.forEach((z)=>z())}static notifyMany(R,O){O.forEach((q)=>this.notify(R,q))}}class X extends U{_subscriptionManager;get subscriptionManager(){if(!this._subscriptionManager)this._subscriptionManager=new E;return this._subscriptionManager}subscribe(R,O){return this.subscriptionManager.subscribe(R,O)}unsubscribe(R,O){this.subscriptionManager.unsubscribe(R,O)}set(R,O){let q=!super.has(R);if(super.set(R,O),q)Z.notify(this.subscriptionManager,String(R));return this}delete(R){let O=super.delete(R);if(O)Z.notify(this.subscriptionManager,String(R));return O}clear(){let R=Array.from(this.keys()).map((O)=>String(O));super.clear(),Z.notifyMany(this.subscriptionManager,R)}}import{use as b,useSyncExternalStore as h}from"react";function V(R){if(!(R instanceof X))throw Error("InputMapping must be an instance of InputMappingStore for granular rendering")}function w(R,O){let z=b(R);return V(z),h((B)=>z.subscribe(O,B),()=>z.get(O),()=>z.get(O))}import{use as f,useMemo as I}from"react";function C(R){let q=f(R);V(q);let z=q;return I(()=>({set:(B,J)=>{return z.set(B,J)},clear:()=>{z.clear()},delete:(B)=>{return z.delete(B)}}),[z])}function j(R){function O(z){return w(R,z)}function q(){return C(R)}return{useInputComponent:O,useInputMappingActions:q}}var P=j(G),VR=(R)=>{let O=R instanceof X?R:new X(Object.fromEntries(R.entries()));return{FormInstantInputsProvider:(B)=>S(G.Provider,{value:O},B.children),useInputMapping:()=>g(G)}},y=m(({formProps:R})=>{let O=P.useInputComponent(R.fieldType)||P.useInputComponent("fallback");if(!O)return null;return S(O,R)},(R,O)=>{return R.formProps.fieldType===O.formProps.fieldType&&R.formProps.name.history===O.formProps.name.history&&R.formProps.name.current===O.formProps.name.current});y.displayName="ElementMapping";import{useCallback as x,useState as u}from"react";function v(R){return R&&typeof R==="object"&&"name"in R&&"fieldType"in R}function _(R,O,q){if(!v(R)){let D={};for(let K in R){let Y=R[K];if(!Y)continue;D[K]=_(Y,O,q)}return D}let z=R.name.current,B=`${q}.${O}.${z}`,J={...R,name:{current:z,history:B}};if(R.schema&&Array.isArray(R.schema))J.schema=R.schema.map((D)=>_(D,O,q));return J}var TR=(R)=>{let{fieldConfig:O,name:q,...z}=R,B=q.history||q.current,J=z.schema.at(0),[D,K]=u([]),Y=x(()=>{let Q=O?.max??1/0;if(Number(D?.length)>=Q)return;K((H)=>{let W=H.length,T=_(J,W,B);return[...H,T]})},[D,O?.max,B,J]),L=x((Q)=>{let $=O?.min??0;if((D?.length||0)>$)K((W)=>{return W.filter((N,A)=>A!==Q).map((N,A)=>{return _(N,A,B)})})},[D,O?.min,B]);return{inputs:D,append:Y,remove:L,setInputs:K,fieldConfig:O,name:q,...z}};import{useCallback as F,useMemo as c,useReducer as k,useRef as d,use as l}from"react";function vR(R){return function(){let q=l(R);if(!q)throw Error("InputMappingContext not found");let z=d(q),[B,J]=k((L)=>L+1,0),D=F((L,Q)=>{let $=z.current.set(L,Q);return J(),$},[]),K=F(()=>{z.current.clear(),J()},[]),Y=F((L)=>{let Q=z.current.delete(L);return J(),Q},[]);return c(()=>({...z.current,set:D,clear:K,delete:Y}),[B])}}export{TR as useInputArray,vR as createInputMappingHook,j as createInputMappingGranularHook,VR as createFormInstantContainer,X as InputMappingStore,G as InputMappingContext,U as InputMapping,y as ElementMapping};
2
2
 
3
- //# debugId=FEDB4F6DC6D16F3364756E2164756E21
3
+ //# debugId=CC948A0F1B63234064756E2164756E21
package/dist/index.js.map CHANGED
@@ -15,9 +15,9 @@
15
15
  "import { useCallback, useState } from 'react';\nimport type { FieldMetadata } from '../../../InputMapping';\nimport type { UseInputArrayProps } from '../types';\nimport { cloneFieldWithIndex } from '../domain/services/cloneFieldWithIndex';\n\nexport const useInputArray = (data: FieldMetadata) => {\n const { fieldConfig, name, ...prop } = data as UseInputArrayProps;\n const arrayName = name.history || name.current;\n const template = prop.schema.at(0)!;\n\n // Ensure inputs is always an array type\n const [inputs, setInputs] = useState<Record<string, FieldMetadata>[]>([]);\n\n const append = useCallback(() => {\n const max = fieldConfig?.max ?? Infinity;\n // Inputs can be undefined if schema was undefined and initialInputs is [] casted to SchemaArray (which might be strict)\n // But initialInputs is initialized to [] used as fallback.\n const currentLength = Number(inputs?.length);\n if (currentLength >= max) return;\n\n setInputs((pre) => {\n // Clone the template and update names with the new index\n const newIndex = pre.length;\n const newItem = cloneFieldWithIndex(template, newIndex, arrayName) as Record<\n string,\n FieldMetadata\n >;\n\n return [...pre, newItem];\n });\n }, [inputs, fieldConfig?.max, arrayName, template]); // Original deps: [inputs, fieldConfig?.max, arrayName]. Template is closed over. I should probably add it or leave it. Refactoring usually implies fixing linter errors. I'll Include template if linter complains, otherwise keep original. Original deps: [inputs, fieldConfig?.max, arrayName].\n\n const remove = useCallback(\n (index: number) => {\n const min = fieldConfig?.min ?? 0;\n const currentLength = inputs?.length || 0;\n if (currentLength > min) {\n setInputs((pre) => {\n // Ensure pre is always an array\n const filtered = pre.filter((_, i) => i !== index);\n // Update indices for remaining items\n return filtered.map((item, newIndex) => {\n return cloneFieldWithIndex(item, newIndex, arrayName) as Record<\n string,\n FieldMetadata\n >;\n });\n });\n }\n },\n [inputs, fieldConfig?.min, arrayName],\n );\n\n return { inputs, append, remove, setInputs, fieldConfig, name, ...prop };\n};\n",
16
16
  "import type { ParsedField } from '../../../../InputMapping';\n\n/**\n * Type guard to check if a value is a ParsedField\n * @param item - The item to check\n * @returns True if item is a ParsedField\n */\nexport function isParsedField(item: any): item is ParsedField<any, string> {\n return item && typeof item === 'object' && 'name' in item && 'fieldType' in item;\n}\n",
17
17
  "import type { FieldMetadata, ParsedField } from '../../../../InputMapping';\nimport { isParsedField } from '../guards/isParsedField';\n\n/**\n * Helper function to deep clone a ParsedField and update names with new index\n * @param field - The field to clone\n * @param newIndex - The new index to apply\n * @param arrayName - The name of the array\n * @returns The cloned field or record of fields with updated index\n */\nexport function cloneFieldWithIndex(\n field:\n | ParsedField<any, string>\n | Record<string, ParsedField<any, string>>\n | FieldMetadata\n | Record<string, FieldMetadata>,\n newIndex: number,\n arrayName: string,\n): ParsedField<any, string> | Record<string, ParsedField<any, string>> {\n // Handle Record<string, ParsedField>\n if (!isParsedField(field)) {\n const newStructure: Record<string, ParsedField<any, string>> = {};\n for (const key in field) {\n const val = (field as any)[key];\n if (!val) continue;\n // Recursive call - result is ParsedField because val is ParsedField\n // (assuming structure is Record<string, ParsedField>)\n newStructure[key] = cloneFieldWithIndex(val, newIndex, arrayName) as ParsedField<\n any,\n string\n >;\n }\n return newStructure;\n }\n\n // Handle ParsedField\n // Extract the field name from the current history (e.g., \"items.0.name\" -> \"name\")\n const fieldName = field.name.current;\n const newHistory = `${arrayName}.${newIndex}.${fieldName}`;\n\n const cloned = {\n ...field,\n name: {\n current: fieldName,\n history: newHistory,\n },\n } as ParsedField<any, string>;\n\n if (field.schema && Array.isArray(field.schema)) {\n cloned.schema = field.schema.map((subField) =>\n cloneFieldWithIndex(subField as ParsedField<any, string>, newIndex, arrayName),\n );\n }\n\n return cloned;\n}\n",
18
- "import { useReducer, useRef, use } from 'react';\nimport { InputMapping } from '../InputMapping/class';\n\nexport function createInputMappingHook<Ob extends Record<string, any>>(\n\tInputMappingContext: React.Context<InputMapping<Ob> | null>,\n) {\n\treturn function useInputMapping() {\n\t\tconst initialState = use(InputMappingContext);\n\t\tif (!initialState) throw new Error('InputMappingContext not found');\n\t\tconst mapRef = useRef(initialState);\n\t\tconst [, reRender] = useReducer((x) => x + 1, 0);\n\n\t\treturn {\n\t\t\t...mapRef.current,\n\t\t\tset: (key: keyof Ob | string, value: React.FC<any>) => {\n\t\t\t\tconst result = mapRef.current.set(key, value);\n\t\t\t\treRender();\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tclear: () => {\n\t\t\t\tmapRef.current.clear();\n\t\t\t\treRender();\n\t\t\t},\n\t\t\tdelete: (key: keyof Ob | string) => {\n\t\t\t\tconst result = mapRef.current.delete(key);\n\t\t\t\treRender();\n\t\t\t\treturn result;\n\t\t\t},\n\t\t};\n\t};\n}\n"
18
+ "import { useCallback, useMemo, useReducer, useRef, use } from 'react';\nimport { InputMapping } from '../InputMapping/class';\n\nexport function createInputMappingHook<Ob extends Record<string, any>>(\n\tInputMappingContext: React.Context<InputMapping<Ob> | null>,\n) {\n\treturn function useInputMapping() {\n\t\tconst initialState = use(InputMappingContext);\n\t\tif (!initialState) throw new Error('InputMappingContext not found');\n\t\tconst mapRef = useRef(initialState);\n\t\tconst [version, reRender] = useReducer((x) => x + 1, 0);\n\n\t\tconst set = useCallback((key: keyof Ob | string, value: React.FC<any>) => {\n\t\t\tconst result = mapRef.current.set(key, value);\n\t\t\treRender();\n\t\t\treturn result;\n\t\t}, []);\n\n\t\tconst clear = useCallback(() => {\n\t\t\tmapRef.current.clear();\n\t\t\treRender();\n\t\t}, []);\n\n\t\tconst del = useCallback((key: keyof Ob | string) => {\n\t\t\tconst result = mapRef.current.delete(key);\n\t\t\treRender();\n\t\t\treturn result;\n\t\t}, []);\n\n\t\treturn useMemo(\n\t\t\t() => ({\n\t\t\t\t...mapRef.current,\n\t\t\t\tset,\n\t\t\t\tclear,\n\t\t\t\tdelete: del,\n\t\t\t}),\n\t\t\t[version],\n\t\t);\n\t};\n}\n"
19
19
  ],
20
- "mappings": "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",
21
- "debugId": "FEDB4F6DC6D16F3364756E2164756E21",
20
+ "mappings": "AAuBO,MAAM,UAAqD,GAGhE,CAQU,SAAS,CAAC,EAAqC,CACnD,QAAW,KAAK,EAAK,KAAK,IAAI,EAA4B,EAAI,EAAa,EAQ/E,WAAW,CAAC,EAAsC,CAC9C,MAAM,EACN,GAAI,CAAC,EAAK,OACV,KAAK,UAAU,CAAG,EAStB,MAAM,CAAC,EAAW,CAEd,GAAI,CADU,MAAM,IAAI,CAAqC,EACjD,MAAO,WACnB,OAAO,EAUF,GAAgD,CAAC,EAAO,CAC7D,OAAO,MAAM,IAAI,CAAC,EA4Bb,GAAG,CAAC,EAAqC,EAAkB,CAChE,GAAI,CAAC,MAAM,IAAI,CAAC,EAAG,MAAM,IAAI,EAAG,CAAC,EACjC,OAAO,KAWX,OAA4C,CACxC,EACF,CACE,IAAM,EAAM,OAAO,YAAY,MAAM,QAAQ,CAAC,EAGxC,EAAY,EAAG,IAAoD,EACzE,OAAO,IAAI,EAA6C,IACjD,KACA,CACP,CAAC,EAET,CC1HA,wBAAS,cAGF,IAAM,EAAsB,EAAwC,IAAI,ECF/E,wBAAS,UAAe,SAAM,cCOvB,MAAM,CAAoB,CACf,UAAY,IAAI,IASjC,SAAS,CAAC,EAAa,EAAqD,CAC3E,GAAI,CAAC,KAAK,UAAU,IAAI,CAAG,EAC1B,KAAK,UAAU,IAAI,EAAK,IAAI,GAAK,EAGlC,OADA,KAAK,UAAU,IAAI,CAAG,EAAG,IAAI,CAAQ,EAC9B,IAAM,KAAK,YAAY,EAAK,CAAQ,EAS5C,WAAW,CAAC,EAAa,EAAsC,CAC9D,KAAK,UAAU,IAAI,CAAG,GAAG,OAAO,CAAQ,EAUzC,YAAY,CAAC,EAAoD,CAChE,OAAO,KAAK,UAAU,IAAI,CAAG,EAU9B,YAAY,CAAC,EAAsB,CAClC,OAAO,KAAK,UAAU,IAAI,CAAG,GAAK,KAAK,UAAU,IAAI,CAAG,EAAG,KAAO,EAQnE,KAAK,EAAS,CACb,KAAK,UAAU,MAAM,EAEvB,CC1DO,MAAM,CAAoB,OAOzB,OAAM,CAAC,EAA0C,EAAmB,CAC1E,IAAM,EAAY,EAAoB,aAAa,CAAG,EACtD,GAAI,EACH,EAAU,QAAQ,CAAC,IAAa,EAAS,CAAC,QAUrC,WAAU,CAAC,EAA0C,EAAsB,CACjF,EAAK,QAAQ,CAAC,IAAQ,KAAK,OAAO,EAAqB,CAAG,CAAC,EAE7D,CChBO,MAAM,UAA0D,CAAiB,CAC/E,wBAMI,oBAAmB,EAAwB,CACtD,GAAI,CAAC,KAAK,qBACT,KAAK,qBAAuB,IAAI,EAEjC,OAAO,KAAK,qBAUb,SAAS,CAAC,EAAa,EAAqD,CAC3E,OAAO,KAAK,oBAAoB,UAAU,EAAK,CAAQ,EASxD,WAAW,CAAC,EAAa,EAAsC,CAC9D,KAAK,oBAAoB,YAAY,EAAK,CAAQ,EAM1C,GAAG,CAAC,EAAqC,EAAkB,CACnE,IAAM,EAAU,CAAC,MAAM,IAAI,CAAC,EAE5B,GADA,MAAM,IAAI,EAAG,CAAC,EACV,EACH,EAAoB,OAAO,KAAK,oBAAqB,OAAO,CAAC,CAAC,EAE/D,OAAO,KAMC,MAAM,CAAC,EAA8C,CAC7D,IAAM,EAAS,MAAM,OAAO,CAAC,EAC7B,GAAI,EACH,EAAoB,OAAO,KAAK,oBAAqB,OAAO,CAAC,CAAC,EAE/D,OAAO,EAMC,KAAK,EAAS,CACtB,IAAM,EAAO,MAAM,KAAK,KAAK,KAAK,CAAC,EAAE,IAAI,CAAC,IAAM,OAAO,CAAC,CAAC,EACzD,MAAM,MAAM,EACZ,EAAoB,WAAW,KAAK,oBAAqB,CAAI,EAE/D,CCjFA,cAAS,0BAAK,cCUP,SAAS,CAAyD,CACxE,EACyC,CACzC,GAAI,EAAE,aAAiB,GACtB,MAAU,MACT,8EACD,EDDK,SAAS,CAAiD,CAChE,EACA,EACsB,CAGtB,IAAM,EAAQ,EADY,CACS,EAMnC,OAHA,EAAsB,CAAK,EAGpB,EACN,CAAC,IAAmB,EAAgC,UAAU,EAAW,CAAa,EACtF,IAAM,EAAM,IAAI,CAAS,EACzB,IAAM,EAAM,IAAI,CAAS,CAC1B,EE/BD,cAAS,aAAK,cAcP,SAAS,CAAsD,CACrE,EACC,CAGD,IAAM,EAAQ,EADY,CACS,EAGnC,EAAsB,CAAK,EAE3B,IAAM,EAAgB,EAEtB,OAAO,EACN,KAAO,CACN,IAAK,CAAC,EAAwB,IAAyB,CACtD,OAAO,EAAc,IAAI,EAAK,CAAK,GAEpC,MAAO,IAAM,CACZ,EAAc,MAAM,GAErB,OAAQ,CAAC,IAA2B,CACnC,OAAO,EAAc,OAAO,CAAG,EAEjC,GACA,CAAC,CAAa,CACf,EC1BM,SAAS,CAA8D,CAC7E,EACC,CAQD,SAAS,CAAqB,CAAC,EAAmB,CACjD,OAAO,EAAkB,EAAqB,CAAS,EASxD,SAAS,CAA0B,EAAG,CACrC,OAAO,EAAuB,CAAmB,EAGlD,MAAO,CACN,kBAAmB,EACnB,uBAAwB,CACzB,EPrBD,IAAM,EAAgB,EACrB,CACD,EAUa,GAA6B,CACzC,IACI,CAEJ,IAAM,EACL,aAAwB,EACrB,EACA,IAAI,EAAkB,OAAO,YAAY,EAAa,QAAQ,CAAC,CAAQ,EAa3E,MAAO,CACN,0BAZsC,CAAC,IACvC,EACC,EAAoB,SACpB,CACC,MAAO,CACR,EACA,EAAM,QACP,EAMA,gBAJuB,IAAM,EAAI,CAAmB,CAKrD,GASY,EAAmD,EAC/D,EAAG,eAAgB,CAClB,IAAM,EACL,EAAc,kBAAkB,EAAU,SAAS,GACnD,EAAc,kBAAkB,UAAU,EAE3C,GAAI,CAAC,EAAS,OAAO,KAErB,OAAO,EAAc,EAAS,CAAS,GAExC,CAAC,EAAW,IAAc,CAEzB,OACC,EAAU,UAAU,YAAc,EAAU,UAAU,WACtD,EAAU,UAAU,KAAK,UAAY,EAAU,UAAU,KAAK,SAC9D,EAAU,UAAU,KAAK,UAAY,EAAU,UAAU,KAAK,QAGjE,EAEA,EAAe,YAAc,iBQnF7B,sBAAS,cAAa,cCOf,SAAS,CAAa,CAAC,EAA6C,CACvE,OAAO,GAAQ,OAAO,IAAS,UAAY,SAAU,GAAQ,cAAe,ECEzE,SAAS,CAAmB,CAC/B,EAKA,EACA,EACmE,CAEnE,GAAI,CAAC,EAAc,CAAK,EAAG,CACvB,IAAM,EAAyD,CAAC,EAChE,QAAW,KAAO,EAAO,CACrB,IAAM,EAAO,EAAc,GAC3B,GAAI,CAAC,EAAK,SAGV,EAAa,GAAO,EAAoB,EAAK,EAAU,CAAS,EAKpE,OAAO,EAKX,IAAM,EAAY,EAAM,KAAK,QACvB,EAAa,GAAG,KAAa,KAAY,IAEzC,EAAS,IACR,EACH,KAAM,CACF,QAAS,EACT,QAAS,CACb,CACJ,EAEA,GAAI,EAAM,QAAU,MAAM,QAAQ,EAAM,MAAM,EAC1C,EAAO,OAAS,EAAM,OAAO,IAAI,CAAC,IAC9B,EAAoB,EAAsC,EAAU,CAAS,CACjF,EAGJ,OAAO,EFjDJ,IAAM,GAAgB,CAAC,IAAwB,CAClD,IAAQ,cAAa,UAAS,GAAS,EACjC,EAAY,EAAK,SAAW,EAAK,QACjC,EAAW,EAAK,OAAO,GAAG,CAAC,GAG1B,EAAQ,GAAa,EAA0C,CAAC,CAAC,EAElE,EAAS,EAAY,IAAM,CAC7B,IAAM,EAAM,GAAa,KAAO,IAIhC,GADsB,OAAO,GAAQ,MAAM,GACtB,EAAK,OAE1B,EAAU,CAAC,IAAQ,CAEf,IAAM,EAAW,EAAI,OACf,EAAU,EAAoB,EAAU,EAAU,CAAS,EAKjE,MAAO,CAAC,GAAG,EAAK,CAAO,EAC1B,GACF,CAAC,EAAQ,GAAa,IAAK,EAAW,CAAQ,CAAC,EAE5C,EAAS,EACX,CAAC,IAAkB,CACf,IAAM,EAAM,GAAa,KAAO,EAEhC,IADsB,GAAQ,QAAU,GACpB,EAChB,EAAU,CAAC,IAAQ,CAIf,OAFiB,EAAI,OAAO,CAAC,EAAG,IAAM,IAAM,CAAK,EAEjC,IAAI,CAAC,EAAM,IAAa,CACpC,OAAO,EAAoB,EAAM,EAAU,CAAS,EAIvD,EACJ,GAGT,CAAC,EAAQ,GAAa,IAAK,CAAS,CACxC,EAEA,MAAO,CAAE,SAAQ,SAAQ,SAAQ,YAAW,cAAa,UAAS,CAAK,GGrD3E,sBAAS,aAAa,gBAAS,YAAY,SAAQ,cAG5C,SAAS,EAAsD,CACrE,EACC,CACD,OAAO,QAAwB,EAAG,CACjC,IAAM,EAAe,EAAI,CAAmB,EAC5C,GAAI,CAAC,EAAc,MAAU,MAAM,+BAA+B,EAClE,IAAM,EAAS,EAAO,CAAY,GAC3B,EAAS,GAAY,EAAW,CAAC,IAAM,EAAI,EAAG,CAAC,EAEhD,EAAM,EAAY,CAAC,EAAwB,IAAyB,CACzE,IAAM,EAAS,EAAO,QAAQ,IAAI,EAAK,CAAK,EAE5C,OADA,EAAS,EACF,GACL,CAAC,CAAC,EAEC,EAAQ,EAAY,IAAM,CAC/B,EAAO,QAAQ,MAAM,EACrB,EAAS,GACP,CAAC,CAAC,EAEC,EAAM,EAAY,CAAC,IAA2B,CACnD,IAAM,EAAS,EAAO,QAAQ,OAAO,CAAG,EAExC,OADA,EAAS,EACF,GACL,CAAC,CAAC,EAEL,OAAO,EACN,KAAO,IACH,EAAO,QACV,MACA,QACA,OAAQ,CACT,GACA,CAAC,CAAO,CACT",
21
+ "debugId": "CC948A0F1B63234064756E2164756E21",
22
22
  "names": []
23
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@form-instant/react-input-mapping",
3
- "version": "2.0.4",
3
+ "version": "2.2.0",
4
4
  "author": {
5
5
  "name": "leomerida15",
6
6
  "email": "dimasmerida15@gmail.com",