@explita/formly 0.1.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 (61) hide show
  1. package/README.md +261 -0
  2. package/README.old.md +141 -0
  3. package/dist/components/field-error.d.ts +2 -0
  4. package/dist/components/field-error.js +14 -0
  5. package/dist/components/field.d.ts +4 -0
  6. package/dist/components/field.js +120 -0
  7. package/dist/components/form-spy.d.ts +16 -0
  8. package/dist/components/form-spy.js +66 -0
  9. package/dist/components/index.d.ts +4 -0
  10. package/dist/components/index.js +20 -0
  11. package/dist/components/label.d.ts +2 -0
  12. package/dist/components/label.js +46 -0
  13. package/dist/hooks/use-field.d.ts +21 -0
  14. package/dist/hooks/use-field.js +66 -0
  15. package/dist/hooks/use-form-by-id.d.ts +6 -0
  16. package/dist/hooks/use-form-by-id.js +25 -0
  17. package/dist/hooks/use-form-context.d.ts +5 -0
  18. package/dist/hooks/use-form-context.js +17 -0
  19. package/dist/hooks/use-form.d.ts +43 -0
  20. package/dist/hooks/use-form.js +961 -0
  21. package/dist/index.d.ts +9 -0
  22. package/dist/index.js +25 -0
  23. package/dist/lib/array-helpers.d.ts +6 -0
  24. package/dist/lib/array-helpers.js +281 -0
  25. package/dist/lib/css.d.ts +1 -0
  26. package/dist/lib/css.js +45 -0
  27. package/dist/lib/debounce.d.ts +13 -0
  28. package/dist/lib/debounce.js +28 -0
  29. package/dist/lib/deep-path.d.ts +4 -0
  30. package/dist/lib/deep-path.js +60 -0
  31. package/dist/lib/drafts-helpter.d.ts +31 -0
  32. package/dist/lib/drafts-helpter.js +67 -0
  33. package/dist/lib/form-registry.d.ts +9 -0
  34. package/dist/lib/form-registry.js +24 -0
  35. package/dist/lib/group-helpers.d.ts +9 -0
  36. package/dist/lib/group-helpers.js +29 -0
  37. package/dist/lib/pub-sub.d.ts +13 -0
  38. package/dist/lib/pub-sub.js +38 -0
  39. package/dist/lib/utils.d.ts +17 -0
  40. package/dist/lib/utils.js +190 -0
  41. package/dist/lib/validation.d.ts +22 -0
  42. package/dist/lib/validation.js +46 -0
  43. package/dist/lib/zod-helpers.d.ts +5 -0
  44. package/dist/lib/zod-helpers.js +63 -0
  45. package/dist/providers/form.d.ts +51 -0
  46. package/dist/providers/form.js +63 -0
  47. package/dist/types/array.d.ts +197 -0
  48. package/dist/types/array.js +2 -0
  49. package/dist/types/field.d.ts +61 -0
  50. package/dist/types/field.js +2 -0
  51. package/dist/types/group.d.ts +16 -0
  52. package/dist/types/group.js +2 -0
  53. package/dist/types/path.d.ts +8 -0
  54. package/dist/types/path.js +2 -0
  55. package/dist/types/pub-sub.d.ts +2 -0
  56. package/dist/types/pub-sub.js +2 -0
  57. package/dist/types/utils.d.ts +310 -0
  58. package/dist/types/utils.js +2 -0
  59. package/dist/utils/index.d.ts +4 -0
  60. package/dist/utils/index.js +14 -0
  61. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,261 @@
1
+ # @explita/formly
2
+
3
+ A lightweight, type-safe form toolkit for React built with developer ergonomics in mind. Provides a flexible form management solution with built-in validation, array manipulation, and nested form support.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Type-safe** with TypeScript support
8
+ - 🧩 **Composable** form components and hooks
9
+ - 🔄 **Form State Management** with minimal re-renders
10
+ - ✅ **Built-in Validation** with Zod integration
11
+ - 📋 **Array & Nested Fields** support
12
+ - 🔍 **Form Context** for easy access to form state
13
+ - 🎯 **Field-level** and **Form-level** validation
14
+ - ⚡ **Optimized Performance** with smart re-rendering
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @explita/formly
20
+ # or
21
+ yarn add @explita/formly
22
+ # or
23
+ pnpm add @explita/formly
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```tsx
29
+ import { Form, Field, useForm, useField } from "@explita/formly";
30
+ import { z } from "zod";
31
+
32
+ // Define your form schema with Zod
33
+ const userSchema = z.object({
34
+ name: z.string().min(1, "Name is required"),
35
+ email: z.string().email("Invalid email"),
36
+ contacts: z
37
+ .array(
38
+ z.object({
39
+ phone: z.string().min(1, "Phone is required"),
40
+ type: z.enum(["home", "work", "mobile"]),
41
+ })
42
+ )
43
+ .min(1, "At least one contact is required"),
44
+ });
45
+
46
+ function UserForm() {
47
+ const form = useForm({
48
+ defaultValues: {
49
+ name: "",
50
+ email: "",
51
+ contacts: [{ phone: "", type: "mobile" }],
52
+ },
53
+ // Optional: Uncomment to enable Zod validation
54
+ // schema: userSchema,
55
+ onSubmit: (data) => {
56
+ console.log("Form submitted:", data);
57
+ },
58
+ });
59
+
60
+ const contacts = form.array("contacts");
61
+
62
+ return (
63
+ <Form use={form}>
64
+ <Field name="name" label="Full Name" />
65
+ <Field name="email" type="email" label="Email" />
66
+
67
+ {/* Dynamic array fields */}
68
+ {contacts.value.map((contact, index) => (
69
+ <div key={index}>
70
+ <Field
71
+ name={`contacts.${index}.phone`}
72
+ label={`Phone ${index + 1}`}
73
+ />
74
+ <Field name={`contacts.${index}.type`} as="select" label="Type">
75
+ <option value="home">Home</option>
76
+ <option value="work">Work</option>
77
+ <option value="mobile">Mobile</option>
78
+ </Field>
79
+ <button type="button" onClick={() => contacts.remove(index)}>
80
+ Remove
81
+ </button>
82
+ </div>
83
+ ))}
84
+
85
+ <button
86
+ type="button"
87
+ onClick={() => contacts.push({ phone: "", type: "mobile" })}
88
+ >
89
+ Add Contact
90
+ </button>
91
+
92
+ <button type="submit">Submit</button>
93
+ </Form>
94
+ );
95
+ }
96
+ ```
97
+
98
+ ## Core Concepts
99
+
100
+ ### `useForm` Hook
101
+
102
+ The `useForm` hook is the heart of Formly. It manages the form state and provides methods to interact with the form.
103
+
104
+ ```tsx
105
+ const form = useForm({
106
+ defaultValues: {
107
+ /* ... */
108
+ },
109
+ // Optional: Zod schema for validation
110
+ schema: userSchema,
111
+ // Optional: Custom validation function
112
+ check: (values) => {
113
+ const errors = {};
114
+ if (!values.name) errors.name = "Name is required";
115
+ return errors;
116
+ },
117
+ // Form submission handler
118
+ onSubmit: async (values, ctx) => {
119
+ console.log("Form values:", values);
120
+ },
121
+ // Persist form state
122
+ persistKey: "myFormState",
123
+ });
124
+ ```
125
+
126
+ ### `Field` Component
127
+
128
+ Render form inputs with automatic state management and validation.
129
+
130
+ ```tsx
131
+ <Field
132
+ name="email"
133
+ label="Email Address"
134
+ placeholder="Enter your email"
135
+ required
136
+ render={(props, ctx) => <input {...props} type="email" />}
137
+ />
138
+ ```
139
+
140
+ ### `useField` Hook
141
+
142
+ Access and modify a specific field's state and helpers.
143
+
144
+ ```tsx
145
+ function EmailField() {
146
+ const { value, setValue, error, touched } = useField("email");
147
+
148
+ return (
149
+ <div>
150
+ <input
151
+ type="email"
152
+ value={value || ""}
153
+ onChange={(e) => setValue(e.target.value)}
154
+ className={touched && error ? "error" : ""}
155
+ />
156
+ {touched && error && <div className="error-message">{error}</div>}
157
+ </div>
158
+ );
159
+ }
160
+ ```
161
+
162
+ ### Array Fields
163
+
164
+ Easily manage dynamic arrays of fields.
165
+
166
+ ```tsx
167
+ const todos = form.array("todos");
168
+
169
+ // Add item
170
+ todos.push({ text: "", completed: false });
171
+
172
+ // Update item
173
+ todos.update(0, { text: "Updated todo", completed: true });
174
+
175
+ // Remove item
176
+ todos.remove(0);
177
+
178
+ // Move item
179
+ todos.move(0, 1);
180
+ ```
181
+
182
+ ## Advanced Usage
183
+
184
+ ### Conditional Fields
185
+
186
+ ```tsx
187
+ const showAddress = form.watch("hasAddress");
188
+
189
+ return (
190
+ <>
191
+ <Field name="hasAddress" type="checkbox" label="Add address?" />
192
+
193
+ {showAddress && (
194
+ <div className="address-fields">
195
+ <Field name="address.street" label="Street" />
196
+ <Field name="address.city" label="City" />
197
+ <Field name="address.zip" label="ZIP Code" />
198
+ </div>
199
+ )}
200
+ </>
201
+ );
202
+ ```
203
+
204
+ ## API Reference
205
+
206
+ ### `useForm` Options
207
+
208
+ | Option | Type | Description |
209
+ | ------------------ | ----------------------- | ----------------------------------------- |
210
+ | `defaultValues` | `object` | Initial form values |
211
+ | `schema` | `z.ZodSchema` | Zod schema for validation |
212
+ | `check` | `(values) => object` | Custom validation function |
213
+ | `onSubmit` | `(values, ctx) => void` | Form submission handler |
214
+ | `persistKey` | `string` | Key to persist form state in localStorage |
215
+ | `autoFocusOnError` | `boolean` | Auto-focus first invalid field |
216
+
217
+ ### Form Methods
218
+
219
+ | Method | Description |
220
+ | ---------------------------- | ---------------------------------------- |
221
+ | `submit()` | Submit the form programmatically |
222
+ | `reset(values?)` | Reset form to initial or provided values |
223
+ | `setValues(values)` | Set multiple field values |
224
+ | `setFieldValue(path, value)` | Set a single field value |
225
+ | `setErrors(errors)` | Set form errors |
226
+ | `setFieldError(path, error)` | Set error for a specific field |
227
+ | `validate()` | Trigger validation |
228
+ | `watch(path?)` | Watch form or specific field values |
229
+ | `array(path)` | Get array field helpers |
230
+ | `group(path)` | Get nested form group helpers |
231
+
232
+ ## TypeScript Support
233
+
234
+ Formly is built with TypeScript and provides excellent type safety:
235
+
236
+ ```ts
237
+ interface UserForm {
238
+ name: string;
239
+ email: string;
240
+ contacts: {
241
+ phone: string;
242
+ type: "home" | "work" | "mobile";
243
+ }[];
244
+ }
245
+
246
+ const form = useForm<UserForm>({
247
+ defaultValues: {
248
+ name: "",
249
+ email: "",
250
+ contacts: [],
251
+ },
252
+ });
253
+ ```
254
+
255
+ ## License
256
+
257
+ MIT © [Explita](https://github.com/explita)
258
+
259
+ ## Contributing
260
+
261
+ Contributions are welcome! Please open an issue or submit a pull request.
package/README.old.md ADDED
@@ -0,0 +1,141 @@
1
+ ⚠️ Using register() is convenient for quick input wiring, but for large forms where performance matters, prefer useField or Field to avoid unnecessary re-renders.
2
+
3
+ For performance and clarity, here’s the usual pattern I’d recommend:
4
+
5
+ <form.Field /> (from form instance) or standalone <Field />
6
+
7
+ Best for most use cases.
8
+
9
+ Handles binding, errors, and local reactivity automatically.
10
+
11
+ Encapsulates the field logic, so the parent form doesn’t rerender on every change.
12
+
13
+ Easy to drop into JSX and add labels, wrappers, or custom styling.
14
+
15
+ useField() inside a separate component
16
+
17
+ Great when you want full programmatic control over the field.
18
+
19
+ Can wrap a custom input or a complex component.
20
+
21
+ Keeps reactivity local to the component.
22
+
23
+ Allows you to do more advanced things like computed values, conditional logic, or side effects specific to that field.
24
+
25
+ ✅ Rule of thumb:
26
+
27
+ If you just need a simple form input, use <Field /> — minimal boilerplate, good defaults.
28
+
29
+ If you need custom behavior or a completely custom component, wrap it with a component using useField().
30
+
31
+ This way, the form itself stays light and doesn’t rerender unnecessarily, while each field manages its own state efficiently.
32
+
33
+ # @explita/formly
34
+
35
+ A powerful and extensible React form hook for building scalable forms with Zod validation, persistence, and full control.
36
+
37
+ ## ✨ Features
38
+
39
+ - ✅ Built-in Zod schema validation
40
+ - ✅ Controlled and uncontrolled modes
41
+ - ✅ Persistent form state via `localStorage`
42
+ - ✅ Field-level error handling and parsing
43
+ - ✅ Debounced input validation
44
+ - ✅ Works seamlessly with any UI library (e.g. shadcn/ui)
45
+
46
+ ## 📦 Installation
47
+
48
+ ```bash
49
+ npm install @explita/formly
50
+ # or
51
+ yarn add @explita/formly
52
+ # or
53
+ pnpm add @explita/formly
54
+ ```
55
+
56
+ ## 🧪 Usage
57
+
58
+ ```tsx
59
+ import { z } from "zod";
60
+ import { useForm, Form, Field } from "@explita/formly";
61
+ import { Input } from "@/components/ui/input";
62
+
63
+ const schema = z.object({
64
+ email: z.email({ error: "Invalid email" }),
65
+ password: z
66
+ .string()
67
+ .min(6, { error: "Password must be at least 6 characters" }),
68
+ });
69
+
70
+ export default function LoginForm() {
71
+ const form = useForm({
72
+ schema,
73
+ defaultValues: { email: "", password: "" },
74
+ onSubmit: async (values) => {
75
+ console.log("Submitted", values);
76
+ // call server action here or perform an HTTP request
77
+ // const response = await login(values)
78
+ // return response
79
+ return values;
80
+ },
81
+ onSuccess: (result, ctx) => {
82
+ console.log("Success", result);
83
+ // result is the result of onSubmit
84
+ // ctx.reset(); - reset the form, you don't need this if resetOnSuccess is true
85
+ },
86
+ onError: (error, ctx) => {
87
+ console.log("Error", error, ctx);
88
+ // error - the error object (usually from schema or server)
89
+ // ctx.setErrors({ email: "Email is required" }); - useful for server errors
90
+ },
91
+ persistKey: "login-form", // Optional – saves input across reloads
92
+ errorParser: (msg) => msg, // Optional – customize error messages
93
+ mode: "controlled", // Optional – "controlled" is the default
94
+ resetOnSuccess: true, // Optional – clears the form on success
95
+ });
96
+
97
+ //Field meta is an object that contains the value, error, and hasError properties
98
+
99
+ return (
100
+ <Form use={form}>
101
+ <Field name="email" label="Email" isRequired>
102
+ {(props, meta) => <Input {...props} />}
103
+ </Field>
104
+
105
+ <Field name="password" label="Password" isRequired>
106
+ {(props, meta) => <Input type="password" {...props} />}
107
+ </Field>
108
+
109
+ <button type="submit" disabled={form.isSubmitting}>
110
+ Submit
111
+ </button>
112
+ </Form>
113
+ );
114
+ }
115
+ ```
116
+
117
+ ## 🧩 API Overview
118
+
119
+ ### `useForm(options)`
120
+
121
+ | Option | Type | Description |
122
+ | ---------------- | ------------------------------------- | ------------------------------------------- |
123
+ | `schema` | `ZodObject` | Optional Zod schema for validation |
124
+ | `defaultValues` | `Partial<T>` | Initial form values |
125
+ | `onSubmit` | `(values, formData) => Promise<void>` | Async submission handler |
126
+ | `onSuccess` | `(result) => void` | Called on successful submission |
127
+ | `onError` | `(error, ctx) => void` | Called on error, with access to `setErrors` |
128
+ | `persistKey` | `string` | Key to store form values under |
129
+ | `errorParser` | `(msg: string) => string` | Optional formatter for error messages |
130
+ | `mode` | `controlled`\|`uncontrolled` | Default to controlled |
131
+ | `resetOnSuccess` | `boolean` | Clear the form on successful submission |
132
+
133
+ ### `useFormContext()`
134
+
135
+ Can be used in any component nested inside the `Form` component to access the form context.
136
+
137
+ ##
138
+
139
+ ### 📄 License
140
+
141
+ MIT — Made with ❤️ by [Explita](https://explita.ng)
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare function FieldError(): React.JSX.Element | null;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FieldError = FieldError;
7
+ const react_1 = __importDefault(require("react"));
8
+ const __1 = require("../");
9
+ function FieldError() {
10
+ const { message } = (0, __1.useFieldContext)();
11
+ if (!message)
12
+ return null;
13
+ return (react_1.default.createElement("p", { "data-error": "true", style: { color: "red", fontSize: "0.75rem" } }, message));
14
+ }
@@ -0,0 +1,4 @@
1
+ import { JSX } from "react";
2
+ import { FieldContextType, FieldProps } from "../types/utils";
3
+ export declare function useFieldContext(): FieldContextType;
4
+ export declare function Field<T>({ name, id, label, as, required, hideError, className, children, render, ...rest }: FieldProps<T>): JSX.Element;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.useFieldContext = useFieldContext;
37
+ exports.Field = Field;
38
+ const react_1 = __importStar(require("react"));
39
+ const __1 = require("../");
40
+ const FieldContext = (0, react_1.createContext)(null);
41
+ function useFieldContext() {
42
+ const fieldContext = (0, react_1.use)(FieldContext);
43
+ if (!fieldContext) {
44
+ return {
45
+ name: "",
46
+ label: "",
47
+ id: "",
48
+ message: "",
49
+ required: false,
50
+ hasError: false,
51
+ };
52
+ }
53
+ return fieldContext;
54
+ }
55
+ function Field({ name, id, label, as, required, hideError = false, className, children, render, ...rest }) {
56
+ //@ts-ignore
57
+ const field = (0, __1.useField)(name, { ...rest });
58
+ // Pick whichever function/render prop is provided
59
+ const renderFn = children || render;
60
+ if (!renderFn)
61
+ return react_1.default.createElement(react_1.default.Fragment, null);
62
+ const bind = {
63
+ ...field.bind(),
64
+ id: id !== null && id !== void 0 ? id : field.refId,
65
+ };
66
+ const value = field.value;
67
+ const error = field.error;
68
+ const hasFieldError = error && (error === null || error === void 0 ? void 0 : error.length) > 0 ? true : false;
69
+ const hasError = !hideError && hasFieldError;
70
+ const setValue = field.setValue;
71
+ const isBoolean = as === "checkbox";
72
+ const fieldContextValue = {
73
+ name: name === null || name === void 0 ? void 0 : name.toString(),
74
+ label,
75
+ id: bind.id,
76
+ message: error,
77
+ required,
78
+ hasError,
79
+ };
80
+ const meta = {
81
+ internalRef: field.refId,
82
+ name,
83
+ value,
84
+ error,
85
+ hasError: hasFieldError !== null && hasFieldError !== void 0 ? hasFieldError : false,
86
+ onChange: field.setValue,
87
+ };
88
+ if (isBoolean) {
89
+ return (react_1.default.createElement(FieldContext, { value: fieldContextValue }, renderFn({
90
+ ...bind,
91
+ //@ts-ignore
92
+ checked: !!value,
93
+ onCheckedChange: (val) => {
94
+ setValue(val);
95
+ },
96
+ }, meta)));
97
+ }
98
+ if (as === "select" || as === "date") {
99
+ return (react_1.default.createElement(FieldContext, { value: fieldContextValue },
100
+ react_1.default.createElement("div", { "data-slot": "field", style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, className: className },
101
+ react_1.default.createElement(__1.Label, null),
102
+ renderFn({
103
+ ...bind,
104
+ //@ts-ignore
105
+ onValueChange: (val) => {
106
+ setValue(val);
107
+ },
108
+ "data-input-error": hasError,
109
+ }, meta),
110
+ hasError && react_1.default.createElement(__1.FieldError, null))));
111
+ }
112
+ return (react_1.default.createElement(FieldContext, { value: fieldContextValue },
113
+ react_1.default.createElement("div", { "data-slot": "field", style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, className: className },
114
+ react_1.default.createElement(__1.Label, null),
115
+ renderFn({
116
+ ...bind,
117
+ "data-input-error": hasError,
118
+ }, meta),
119
+ hasError && react_1.default.createElement(__1.FieldError, null))));
120
+ }
@@ -0,0 +1,16 @@
1
+ import { JSX, ReactNode } from "react";
2
+ import { FormContextValue } from "../providers/form";
3
+ import { Path, PathValue } from "../types/path";
4
+ export declare function FormSpy<DefaultValues extends Record<string, any>, P extends Path<DefaultValues>>({ form, watch, render, }: {
5
+ form: FormContextValue<undefined, DefaultValues>;
6
+ render: (selected: PathValue<DefaultValues, P>) => ReactNode;
7
+ watch: P;
8
+ }): JSX.Element;
9
+ export declare function FormSpy<DefaultValues extends Record<string, any>, P extends Path<DefaultValues>>({ form, render, }: {
10
+ form: FormContextValue<undefined, DefaultValues>;
11
+ render: (selected: DefaultValues) => ReactNode;
12
+ }): JSX.Element;
13
+ export declare function FormSpyDebug<DefaultValues extends Record<string, any>>({ form, watch, }: {
14
+ form: FormContextValue<undefined, DefaultValues>;
15
+ watch?: Path<DefaultValues>;
16
+ }): JSX.Element;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FormSpy = FormSpy;
37
+ exports.FormSpyDebug = FormSpyDebug;
38
+ const react_1 = __importStar(require("react"));
39
+ function FormSpy({ form, watch, render, }) {
40
+ const [selected, setSelected] = (0, react_1.useState)(() => watch ? form.field(watch).get() : form.values);
41
+ const prevRef = (0, react_1.useRef)(selected);
42
+ (0, react_1.useEffect)(() => {
43
+ const unsubscribe = form.subscribe((values) => {
44
+ const next = watch ? form.field(watch).get() : values;
45
+ if (JSON.stringify(prevRef.current) !== JSON.stringify(next)) {
46
+ prevRef.current = next;
47
+ setSelected(next);
48
+ }
49
+ });
50
+ return unsubscribe;
51
+ }, [form, watch]);
52
+ return react_1.default.createElement(react_1.default.Fragment, null, render(selected));
53
+ }
54
+ function FormSpyDebug({ form, watch, }) {
55
+ return (react_1.default.createElement(FormSpy, { form: form,
56
+ //@ts-ignore
57
+ watch: watch, render: (v) => (react_1.default.createElement("pre", { style: {
58
+ whiteSpace: "pre-wrap", // allow wrapping
59
+ wordBreak: "break-word", // break long words
60
+ overflowWrap: "break-word", // extra safety
61
+ background: "#f5f5f5",
62
+ padding: "10px",
63
+ borderRadius: "4px",
64
+ width: "100%",
65
+ } }, JSON.stringify(v, null, 2))) }));
66
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./field";
2
+ export * from "./field-error";
3
+ export * from "./form-spy";
4
+ export * from "./label";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./field"), exports);
18
+ __exportStar(require("./field-error"), exports);
19
+ __exportStar(require("./form-spy"), exports);
20
+ __exportStar(require("./label"), exports);
@@ -0,0 +1,2 @@
1
+ import * as React from "react";
2
+ export declare function Label({ className, ...props }: React.ComponentProps<"label">): React.JSX.Element | undefined;