form-hook-kit 1.2.0 → 1.2.2

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 (46) hide show
  1. package/README.md +28 -372
  2. package/dist/devtools/FormContext.d.ts +8 -0
  3. package/dist/devtools/FormContext.d.ts.map +1 -0
  4. package/dist/devtools/FormDevTools.d.ts.map +1 -1
  5. package/dist/devtools/FormProvider.d.ts +33 -0
  6. package/dist/devtools/FormProvider.d.ts.map +1 -0
  7. package/dist/devtools/devtools/FormDevTools.d.ts +86 -0
  8. package/dist/devtools/devtools/FormDevTools.d.ts.map +1 -0
  9. package/dist/devtools/devtools/index.d.ts +3 -0
  10. package/dist/devtools/devtools/index.d.ts.map +1 -0
  11. package/dist/devtools/hooks/index.d.ts +4 -0
  12. package/dist/devtools/hooks/index.d.ts.map +1 -0
  13. package/dist/devtools/hooks/useForm.d.ts +30 -0
  14. package/dist/devtools/hooks/useForm.d.ts.map +1 -0
  15. package/dist/devtools/hooks/useFormField.d.ts +40 -0
  16. package/dist/devtools/hooks/useFormField.d.ts.map +1 -0
  17. package/dist/devtools/hooks/useFormPerformance.d.ts +57 -0
  18. package/dist/devtools/hooks/useFormPerformance.d.ts.map +1 -0
  19. package/dist/devtools/index.esm.js +203 -0
  20. package/dist/devtools/index.esm.js.map +1 -0
  21. package/dist/devtools/index.js +205 -0
  22. package/dist/devtools/index.js.map +1 -0
  23. package/dist/devtools/package.json +6 -0
  24. package/dist/devtools/types/index.d.ts +94 -0
  25. package/dist/devtools/types/index.d.ts.map +1 -0
  26. package/dist/devtools/utils/debounce.d.ts +6 -0
  27. package/dist/devtools/utils/debounce.d.ts.map +1 -0
  28. package/dist/devtools/utils/errors.d.ts +11 -0
  29. package/dist/devtools/utils/errors.d.ts.map +1 -0
  30. package/dist/devtools/utils/formActions.d.ts +57 -0
  31. package/dist/devtools/utils/formActions.d.ts.map +1 -0
  32. package/dist/devtools/utils/formReducer.d.ts +7 -0
  33. package/dist/devtools/utils/formReducer.d.ts.map +1 -0
  34. package/dist/devtools/utils/index.d.ts +7 -0
  35. package/dist/devtools/utils/index.d.ts.map +1 -0
  36. package/dist/devtools/utils/performance.d.ts +7 -0
  37. package/dist/devtools/utils/performance.d.ts.map +1 -0
  38. package/dist/devtools/utils/validation.d.ts +25 -0
  39. package/dist/devtools/utils/validation.d.ts.map +1 -0
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.esm.js +128 -2
  43. package/dist/index.esm.js.map +1 -1
  44. package/dist/index.js +128 -0
  45. package/dist/index.js.map +1 -1
  46. package/package.json +2 -1
@@ -0,0 +1,40 @@
1
+ import { FormFieldRef } from '../types';
2
+ /**
3
+ * Hook for managing a single form field
4
+ *
5
+ * Provides field-specific state and handlers for common field operations.
6
+ *
7
+ * @param name - Field name
8
+ * @returns Field state and handlers
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function EmailField() {
13
+ * const {value, error, onChange, onBlur} = useFormField('email');
14
+ *
15
+ * return (
16
+ * <div>
17
+ * <input
18
+ * type="email"
19
+ * value={value || ''}
20
+ * onChange={onChange}
21
+ * onBlur={onBlur}
22
+ * />
23
+ * {error && <span className="error">{error}</span>}
24
+ * </div>
25
+ * );
26
+ * }
27
+ * ```
28
+ */
29
+ export declare function useFormField(name: string): {
30
+ value: import("../types").FormFieldValue;
31
+ error: string | null;
32
+ onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
33
+ onChangeValue: (newValue: string | number | boolean | null | undefined) => void;
34
+ onBlur: () => void;
35
+ onFocus: () => void;
36
+ setRef: (ref: FormFieldRef) => void;
37
+ name: string;
38
+ };
39
+ export default useFormField;
40
+ //# sourceMappingURL=useFormField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormField.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormField.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM;;;kBAQjC,KAAK,CAAC,WAAW,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;8BAOlD,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS;;;kBAejD,YAAY;;EAkBrB;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { FormFieldValue } from '../types';
2
+ export interface PerformanceMetrics {
3
+ renderCount: number;
4
+ lastRenderTime: number;
5
+ fieldChangeCount: number;
6
+ }
7
+ /**
8
+ * Hook to monitor form performance metrics
9
+ *
10
+ * Useful for debugging and optimizing form performance.
11
+ *
12
+ * @returns Performance metrics object
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * function MyForm() {
17
+ * const metrics = useFormPerformance();
18
+ *
19
+ * console.log('Render count:', metrics.renderCount);
20
+ * console.log('Avg validation time:', metrics.averageValidationTime);
21
+ *
22
+ * return <div>...</div>;
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function useFormPerformance(): PerformanceMetrics;
27
+ /**
28
+ * Hook to track validation performance
29
+ *
30
+ * Wraps validation calls with timing metrics.
31
+ *
32
+ * @returns Object with tracked validateField and validateForm functions
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * function MyForm() {
37
+ * const {validateField, validateForm, metrics} = useValidationPerformance();
38
+ *
39
+ * const handleSubmit = () => {
40
+ * validateForm();
41
+ * console.log('Validation took:', metrics.lastValidationTime, 'ms');
42
+ * };
43
+ *
44
+ * return <button onClick={handleSubmit}>Submit</button>;
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function useValidationPerformance(): {
49
+ validateField: (name: string, value?: FormFieldValue) => string | null;
50
+ validateForm: () => Record<string, string | null>;
51
+ metrics: {
52
+ lastValidationTime: number;
53
+ totalValidations: number;
54
+ averageValidationTime: number;
55
+ };
56
+ };
57
+ //# sourceMappingURL=useFormPerformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormPerformance.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormPerformance.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAGxC,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,IAAI,kBAAkB,CAiCvD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB;0BAST,MAAM,UAAU,cAAc;;;;;;;EA2C5D"}
@@ -0,0 +1,203 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { useForm, useFormPerformance } from 'form-hook-kit';
3
+
4
+ // Detect if we're in React Native environment
5
+ /* istanbul ignore next */
6
+ const isReactNative = typeof navigator !== 'undefined' &&
7
+ navigator.product === 'ReactNative';
8
+ /**
9
+ * FormDevTools Component
10
+ *
11
+ * A cross-platform development tool for inspecting form state in real-time.
12
+ *
13
+ * **Platform Support:**
14
+ * - **Web**: Shows a visual UI panel by default (`mode="ui"`)
15
+ * - **React Native**: Logs to console by default (`mode="console"`)
16
+ * - Use with React Native Debugger, Flipper, or Metro logs
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * // Web - shows UI panel
21
+ * import {FormProvider} from 'form-hook-kit';
22
+ * import {FormDevTools} from 'form-hook-kit/devtools';
23
+ *
24
+ * function App() {
25
+ * return (
26
+ * <FormProvider schema={schema}>
27
+ * <MyForm />
28
+ * {process.env.NODE_ENV === 'development' && <FormDevTools />}
29
+ * </FormProvider>
30
+ * );
31
+ * }
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // React Native - logs to console
37
+ * import {FormProvider} from 'form-hook-kit';
38
+ * import {FormDevTools} from 'form-hook-kit/devtools';
39
+ *
40
+ * function App() {
41
+ * return (
42
+ * <FormProvider schema={schema}>
43
+ * <MyForm />
44
+ * {__DEV__ && <FormDevTools mode="console" autoLog />}
45
+ * </FormProvider>
46
+ * );
47
+ * }
48
+ * ```
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * // Force console mode (works everywhere)
53
+ * <FormDevTools mode="console" autoLog logPrefix="[MyForm]" />
54
+ * ```
55
+ */
56
+ // istanbul ignore next - default mode detection is platform-specific and untestable
57
+ function FormDevTools({ mode = isReactNative ? 'console' : 'ui', autoLog = false, logPrefix = '[FormDevTools]', position = 'bottom-right', defaultOpen = true, } = {}) {
58
+ const { values, errors } = useForm();
59
+ const metrics = useFormPerformance();
60
+ const [isOpen, setIsOpen] = useState(defaultOpen);
61
+ const [activeTab, setActiveTab] = useState('values');
62
+ const prevValuesRef = useRef(values);
63
+ const prevErrorsRef = useRef(errors);
64
+ // Console logging mode
65
+ useEffect(() => {
66
+ if (mode === 'console') {
67
+ if (autoLog) {
68
+ // Log when values change
69
+ if (prevValuesRef.current !== values) {
70
+ console.log(`${logPrefix} Values:`, values);
71
+ prevValuesRef.current = values;
72
+ }
73
+ // Log when errors change
74
+ if (prevErrorsRef.current !== errors) {
75
+ console.log(`${logPrefix} Errors:`, errors);
76
+ prevErrorsRef.current = errors;
77
+ }
78
+ }
79
+ }
80
+ }, [values, errors, mode, autoLog, logPrefix]);
81
+ // Expose global logging functions for manual inspection
82
+ useEffect(() => {
83
+ if (mode === 'console') {
84
+ const globalObj = typeof globalThis !== 'undefined' ? globalThis : /* istanbul ignore next */ (typeof window !== 'undefined' ? window : undefined);
85
+ /* istanbul ignore else */
86
+ if (globalObj) {
87
+ // Adding to global for debugging
88
+ globalObj.formDevTools = {
89
+ logValues: () => console.log(`${logPrefix} Values:`, values),
90
+ logErrors: () => console.log(`${logPrefix} Errors:`, errors),
91
+ logMetrics: () => console.log(`${logPrefix} Performance:`, metrics),
92
+ logAll: () => {
93
+ console.log(`${logPrefix} === Form State ===`);
94
+ console.log('Values:', values);
95
+ console.log('Errors:', errors);
96
+ console.log('Performance:', metrics);
97
+ },
98
+ };
99
+ }
100
+ }
101
+ }, [values, errors, metrics, mode, logPrefix]);
102
+ // If mode is 'none' or 'console', don't render UI
103
+ if (mode === 'none' || mode === 'console') {
104
+ return null;
105
+ }
106
+ // UI mode (web only)
107
+ /* istanbul ignore next */
108
+ if (isReactNative && mode === 'ui') {
109
+ console.warn(`${logPrefix} UI mode is not supported in React Native. Use mode="console" instead.`);
110
+ return null;
111
+ }
112
+ const positionStyles = {
113
+ 'top-left': { top: 10, left: 10 },
114
+ 'top-right': { top: 10, right: 10 },
115
+ 'bottom-left': { bottom: 10, left: 10 },
116
+ 'bottom-right': { bottom: 10, right: 10 },
117
+ };
118
+ const containerStyle = {
119
+ position: 'fixed',
120
+ ...positionStyles[position],
121
+ zIndex: 999999,
122
+ fontFamily: 'monospace',
123
+ fontSize: 12,
124
+ };
125
+ const panelStyle = {
126
+ backgroundColor: '#1e1e1e',
127
+ color: '#d4d4d4',
128
+ border: '1px solid #3e3e3e',
129
+ borderRadius: 4,
130
+ padding: 12,
131
+ minWidth: 300,
132
+ maxWidth: 500,
133
+ maxHeight: 400,
134
+ overflow: 'auto',
135
+ boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
136
+ };
137
+ const toggleButtonStyle = {
138
+ position: 'absolute',
139
+ top: -10,
140
+ right: -10,
141
+ backgroundColor: '#007acc',
142
+ color: 'white',
143
+ border: 'none',
144
+ borderRadius: '50%',
145
+ width: 30,
146
+ height: 30,
147
+ cursor: 'pointer',
148
+ fontSize: 16,
149
+ display: 'flex',
150
+ alignItems: 'center',
151
+ justifyContent: 'center',
152
+ };
153
+ const tabStyle = {
154
+ display: 'inline-block',
155
+ padding: '4px 8px',
156
+ marginRight: 8,
157
+ cursor: 'pointer',
158
+ borderRadius: 3,
159
+ backgroundColor: '#2d2d2d',
160
+ };
161
+ const activeTabStyle = {
162
+ ...tabStyle,
163
+ backgroundColor: '#007acc',
164
+ };
165
+ const codeStyle = {
166
+ backgroundColor: '#2d2d2d',
167
+ padding: 8,
168
+ borderRadius: 3,
169
+ overflow: 'auto',
170
+ maxHeight: 250,
171
+ };
172
+ return (React.createElement("div", { style: containerStyle },
173
+ React.createElement("button", { style: toggleButtonStyle, onClick: () => setIsOpen(!isOpen), "aria-label": "Toggle DevTools" }, "\uD83D\uDD27"),
174
+ isOpen && (React.createElement("div", { style: panelStyle },
175
+ React.createElement("div", { style: { marginBottom: 12, fontWeight: 'bold', fontSize: 14 } }, "Form DevTools"),
176
+ React.createElement("div", { style: { marginBottom: 12 } },
177
+ React.createElement("span", { style: activeTab === 'values' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('values') }, "Values"),
178
+ React.createElement("span", { style: activeTab === 'errors' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('errors') }, "Errors"),
179
+ React.createElement("span", { style: activeTab === 'performance' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('performance') }, "Performance")),
180
+ activeTab === 'values' && (React.createElement("div", null,
181
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Current Values:"),
182
+ React.createElement("pre", { style: codeStyle }, JSON.stringify(values, null, 2)))),
183
+ activeTab === 'errors' && (React.createElement("div", null,
184
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Errors:"),
185
+ React.createElement("pre", { style: codeStyle }, JSON.stringify(errors, null, 2)))),
186
+ activeTab === 'performance' && (React.createElement("div", null,
187
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Performance Metrics:"),
188
+ React.createElement("div", { style: codeStyle },
189
+ React.createElement("div", null,
190
+ "Render Count: ",
191
+ metrics.renderCount),
192
+ React.createElement("div", null,
193
+ "Last Render: ",
194
+ metrics.lastRenderTime,
195
+ "ms"),
196
+ React.createElement("div", null,
197
+ "Field Changes: ",
198
+ metrics.fieldChangeCount)),
199
+ React.createElement("div", { style: { marginTop: 12, fontSize: 11, color: '#888' } }, "Note: For validation metrics, use useValidationPerformance hook")))))));
200
+ }
201
+
202
+ export { FormDevTools };
203
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/src/devtools/FormDevTools.tsx"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var formHookKit = require('form-hook-kit');
5
+
6
+ // Detect if we're in React Native environment
7
+ /* istanbul ignore next */
8
+ const isReactNative = typeof navigator !== 'undefined' &&
9
+ navigator.product === 'ReactNative';
10
+ /**
11
+ * FormDevTools Component
12
+ *
13
+ * A cross-platform development tool for inspecting form state in real-time.
14
+ *
15
+ * **Platform Support:**
16
+ * - **Web**: Shows a visual UI panel by default (`mode="ui"`)
17
+ * - **React Native**: Logs to console by default (`mode="console"`)
18
+ * - Use with React Native Debugger, Flipper, or Metro logs
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * // Web - shows UI panel
23
+ * import {FormProvider} from 'form-hook-kit';
24
+ * import {FormDevTools} from 'form-hook-kit/devtools';
25
+ *
26
+ * function App() {
27
+ * return (
28
+ * <FormProvider schema={schema}>
29
+ * <MyForm />
30
+ * {process.env.NODE_ENV === 'development' && <FormDevTools />}
31
+ * </FormProvider>
32
+ * );
33
+ * }
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * // React Native - logs to console
39
+ * import {FormProvider} from 'form-hook-kit';
40
+ * import {FormDevTools} from 'form-hook-kit/devtools';
41
+ *
42
+ * function App() {
43
+ * return (
44
+ * <FormProvider schema={schema}>
45
+ * <MyForm />
46
+ * {__DEV__ && <FormDevTools mode="console" autoLog />}
47
+ * </FormProvider>
48
+ * );
49
+ * }
50
+ * ```
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * // Force console mode (works everywhere)
55
+ * <FormDevTools mode="console" autoLog logPrefix="[MyForm]" />
56
+ * ```
57
+ */
58
+ // istanbul ignore next - default mode detection is platform-specific and untestable
59
+ function FormDevTools({ mode = isReactNative ? 'console' : 'ui', autoLog = false, logPrefix = '[FormDevTools]', position = 'bottom-right', defaultOpen = true, } = {}) {
60
+ const { values, errors } = formHookKit.useForm();
61
+ const metrics = formHookKit.useFormPerformance();
62
+ const [isOpen, setIsOpen] = React.useState(defaultOpen);
63
+ const [activeTab, setActiveTab] = React.useState('values');
64
+ const prevValuesRef = React.useRef(values);
65
+ const prevErrorsRef = React.useRef(errors);
66
+ // Console logging mode
67
+ React.useEffect(() => {
68
+ if (mode === 'console') {
69
+ if (autoLog) {
70
+ // Log when values change
71
+ if (prevValuesRef.current !== values) {
72
+ console.log(`${logPrefix} Values:`, values);
73
+ prevValuesRef.current = values;
74
+ }
75
+ // Log when errors change
76
+ if (prevErrorsRef.current !== errors) {
77
+ console.log(`${logPrefix} Errors:`, errors);
78
+ prevErrorsRef.current = errors;
79
+ }
80
+ }
81
+ }
82
+ }, [values, errors, mode, autoLog, logPrefix]);
83
+ // Expose global logging functions for manual inspection
84
+ React.useEffect(() => {
85
+ if (mode === 'console') {
86
+ const globalObj = typeof globalThis !== 'undefined' ? globalThis : /* istanbul ignore next */ (typeof window !== 'undefined' ? window : undefined);
87
+ /* istanbul ignore else */
88
+ if (globalObj) {
89
+ // Adding to global for debugging
90
+ globalObj.formDevTools = {
91
+ logValues: () => console.log(`${logPrefix} Values:`, values),
92
+ logErrors: () => console.log(`${logPrefix} Errors:`, errors),
93
+ logMetrics: () => console.log(`${logPrefix} Performance:`, metrics),
94
+ logAll: () => {
95
+ console.log(`${logPrefix} === Form State ===`);
96
+ console.log('Values:', values);
97
+ console.log('Errors:', errors);
98
+ console.log('Performance:', metrics);
99
+ },
100
+ };
101
+ }
102
+ }
103
+ }, [values, errors, metrics, mode, logPrefix]);
104
+ // If mode is 'none' or 'console', don't render UI
105
+ if (mode === 'none' || mode === 'console') {
106
+ return null;
107
+ }
108
+ // UI mode (web only)
109
+ /* istanbul ignore next */
110
+ if (isReactNative && mode === 'ui') {
111
+ console.warn(`${logPrefix} UI mode is not supported in React Native. Use mode="console" instead.`);
112
+ return null;
113
+ }
114
+ const positionStyles = {
115
+ 'top-left': { top: 10, left: 10 },
116
+ 'top-right': { top: 10, right: 10 },
117
+ 'bottom-left': { bottom: 10, left: 10 },
118
+ 'bottom-right': { bottom: 10, right: 10 },
119
+ };
120
+ const containerStyle = {
121
+ position: 'fixed',
122
+ ...positionStyles[position],
123
+ zIndex: 999999,
124
+ fontFamily: 'monospace',
125
+ fontSize: 12,
126
+ };
127
+ const panelStyle = {
128
+ backgroundColor: '#1e1e1e',
129
+ color: '#d4d4d4',
130
+ border: '1px solid #3e3e3e',
131
+ borderRadius: 4,
132
+ padding: 12,
133
+ minWidth: 300,
134
+ maxWidth: 500,
135
+ maxHeight: 400,
136
+ overflow: 'auto',
137
+ boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
138
+ };
139
+ const toggleButtonStyle = {
140
+ position: 'absolute',
141
+ top: -10,
142
+ right: -10,
143
+ backgroundColor: '#007acc',
144
+ color: 'white',
145
+ border: 'none',
146
+ borderRadius: '50%',
147
+ width: 30,
148
+ height: 30,
149
+ cursor: 'pointer',
150
+ fontSize: 16,
151
+ display: 'flex',
152
+ alignItems: 'center',
153
+ justifyContent: 'center',
154
+ };
155
+ const tabStyle = {
156
+ display: 'inline-block',
157
+ padding: '4px 8px',
158
+ marginRight: 8,
159
+ cursor: 'pointer',
160
+ borderRadius: 3,
161
+ backgroundColor: '#2d2d2d',
162
+ };
163
+ const activeTabStyle = {
164
+ ...tabStyle,
165
+ backgroundColor: '#007acc',
166
+ };
167
+ const codeStyle = {
168
+ backgroundColor: '#2d2d2d',
169
+ padding: 8,
170
+ borderRadius: 3,
171
+ overflow: 'auto',
172
+ maxHeight: 250,
173
+ };
174
+ return (React.createElement("div", { style: containerStyle },
175
+ React.createElement("button", { style: toggleButtonStyle, onClick: () => setIsOpen(!isOpen), "aria-label": "Toggle DevTools" }, "\uD83D\uDD27"),
176
+ isOpen && (React.createElement("div", { style: panelStyle },
177
+ React.createElement("div", { style: { marginBottom: 12, fontWeight: 'bold', fontSize: 14 } }, "Form DevTools"),
178
+ React.createElement("div", { style: { marginBottom: 12 } },
179
+ React.createElement("span", { style: activeTab === 'values' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('values') }, "Values"),
180
+ React.createElement("span", { style: activeTab === 'errors' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('errors') }, "Errors"),
181
+ React.createElement("span", { style: activeTab === 'performance' ? activeTabStyle : tabStyle, onClick: () => setActiveTab('performance') }, "Performance")),
182
+ activeTab === 'values' && (React.createElement("div", null,
183
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Current Values:"),
184
+ React.createElement("pre", { style: codeStyle }, JSON.stringify(values, null, 2)))),
185
+ activeTab === 'errors' && (React.createElement("div", null,
186
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Errors:"),
187
+ React.createElement("pre", { style: codeStyle }, JSON.stringify(errors, null, 2)))),
188
+ activeTab === 'performance' && (React.createElement("div", null,
189
+ React.createElement("div", { style: { marginBottom: 8, color: '#888' } }, "Performance Metrics:"),
190
+ React.createElement("div", { style: codeStyle },
191
+ React.createElement("div", null,
192
+ "Render Count: ",
193
+ metrics.renderCount),
194
+ React.createElement("div", null,
195
+ "Last Render: ",
196
+ metrics.lastRenderTime,
197
+ "ms"),
198
+ React.createElement("div", null,
199
+ "Field Changes: ",
200
+ metrics.fieldChangeCount)),
201
+ React.createElement("div", { style: { marginTop: 12, fontSize: 11, color: '#888' } }, "Note: For validation metrics, use useValidationPerformance hook")))))));
202
+ }
203
+
204
+ exports.FormDevTools = FormDevTools;
205
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/src/devtools/FormDevTools.tsx"],"sourcesContent":[null],"names":["useForm","useFormPerformance","useState","useRef","useEffect"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "main": "./index.js",
4
+ "module": "./index.esm.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -0,0 +1,94 @@
1
+ import { AnySchema } from 'yup';
2
+ /**
3
+ * Generic form field value type
4
+ */
5
+ export type FormFieldValue = string | number | boolean | null | undefined;
6
+ /**
7
+ * Form values object
8
+ */
9
+ export type FormValues = Record<string, FormFieldValue>;
10
+ /**
11
+ * Minimal interface for form field refs
12
+ * Works with both web inputs and React Native TextInput
13
+ */
14
+ export interface FocusableElement {
15
+ focus: () => void;
16
+ }
17
+ /**
18
+ * Form field ref type (for React Native TextInput or HTML input elements)
19
+ *
20
+ * Supports both web (HTMLInputElement, HTMLTextAreaElement) and React Native (any object with focus method)
21
+ */
22
+ export type FormFieldRef = FocusableElement | null;
23
+ /**
24
+ * Form context state
25
+ */
26
+ export interface FormState {
27
+ errors: Record<string, string | null>;
28
+ values: FormValues;
29
+ }
30
+ /**
31
+ * Form context value interface
32
+ */
33
+ export interface FormContextValue {
34
+ /** Refs to form fields for focus management */
35
+ fieldRefs: React.MutableRefObject<Record<string, FormFieldRef>>;
36
+ /** Current form errors by field name */
37
+ errors: Record<string, string | null>;
38
+ /** Current form values by field name */
39
+ values: FormValues;
40
+ /** Change a single field value */
41
+ changeValue: (params: {
42
+ name: string;
43
+ value: FormFieldValue;
44
+ }) => void;
45
+ /** Change multiple field values at once */
46
+ changeValues: (values: FormValues) => void;
47
+ /** Clear error for a specific field */
48
+ clearError: (name: string) => void;
49
+ /** Set error for a specific field */
50
+ setError: (params: {
51
+ name: string;
52
+ error: string;
53
+ }) => void;
54
+ /** Validate a single field and return error if any */
55
+ validateField: (name: string, value?: FormFieldValue) => string | null;
56
+ /** Validate entire form and return errors object */
57
+ validateForm: () => Record<string, string | null>;
58
+ }
59
+ /**
60
+ * Form provider props
61
+ */
62
+ export interface FormProviderProps {
63
+ /** Form child components */
64
+ children: React.ReactNode;
65
+ /** Initial error state */
66
+ initialErrors?: Record<string, string>;
67
+ /** Initial form values */
68
+ initialValues?: FormValues;
69
+ /** Yup validation schema */
70
+ schema: AnySchema;
71
+ /**
72
+ * Debounce validation in milliseconds. Useful for performance optimization.
73
+ * @default 0 (no debounce)
74
+ */
75
+ validationDebounce?: number;
76
+ }
77
+ /**
78
+ * Form actions
79
+ */
80
+ export declare enum FormActions {
81
+ UPDATE_ERRORS = "UPDATE_ERRORS",
82
+ UPDATE_VALUES = "UPDATE_VALUES"
83
+ }
84
+ /**
85
+ * Form action types
86
+ */
87
+ export type FormAction = {
88
+ type: FormActions.UPDATE_ERRORS;
89
+ payload: Record<string, string | null>;
90
+ } | {
91
+ type: FormActions.UPDATE_VALUES;
92
+ payload: FormValues;
93
+ };
94
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,KAAK,CAAC;AAE9B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAChE,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,wCAAwC;IACxC,MAAM,EAAE,UAAU,CAAC;IACnB,kCAAkC;IAClC,WAAW,EAAE,CAAC,MAAM,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAA;KAAC,KAAK,IAAI,CAAC;IACrE,2CAA2C;IAC3C,YAAY,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,uCAAuC;IACvC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,qCAAqC;IACrC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CAAC;IAC1D,sDAAsD;IACtD,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,KAAK,MAAM,GAAG,IAAI,CAAC;IACvE,oDAAoD;IACpD,YAAY,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,0BAA0B;IAC1B,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,4BAA4B;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,oBAAY,WAAW;IACrB,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,WAAW,CAAC,aAAa,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACxC,GACD;IACE,IAAI,EAAE,WAAW,CAAC,aAAa,CAAC;IAChC,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Creates a debounced function that delays invoking func until after wait milliseconds
3
+ * have elapsed since the last time the debounced function was invoked.
4
+ */
5
+ export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
6
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../src/utils/debounce.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAYlC"}