rfhook 1.0.1 → 1.1.1

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
@@ -4,12 +4,13 @@ A lightweight React hook for handling form submissions with advanced form data p
4
4
 
5
5
  ## Features
6
6
 
7
- - 🚀 **Simple API** - Just one hook to handle all your form needs
8
- - 🎯 **TypeScript Support** - Fully typed with generic support
9
- - 🔧 **Nested Objects** - Parse nested form data with dot notation (`user.name`)
10
- - 📋 **Array Support** - Handle arrays with indexed notation (`items[0]`)
11
- - 📦 **Lightweight** - Zero dependencies (except React)
12
- - 🎨 **Framework Agnostic** - Works with any form structure
7
+ - :rocket: **Simple API** - Just one hook to handle all your form needs
8
+ - :dart: **TypeScript Support** - Fully typed with generic support
9
+ - :wrench: **Nested Objects** - Parse nested form data with dot notation (`user.name`)
10
+ - :clipboard: **Array Support** - Handle arrays with indexed notation (`items[0]`)
11
+ - :floppy_disk: **Automatic Prevention** - Prevents default form submission behavior by default
12
+ - :money_with_wings: **Lightweight** - Zero dependencies (except React)
13
+ - :memo: **Framework Agnostic** - Works with any form structure
13
14
 
14
15
  ## Installation
15
16
 
@@ -37,19 +38,23 @@ interface FormData {
37
38
  }
38
39
 
39
40
  function LoginForm() {
40
- const { ref, submit } = useForm<FormData>({
41
- handleSubmit: (data) => {
41
+ const { ref, onSubmit } = useForm<FormData>({
42
+ submit: (data) => {
42
43
  console.log(data); // { email: "user@example.com", password: "secret" }
43
44
  }
44
45
  });
45
46
 
46
47
  return (
47
- <form ref={ref} onSubmit={submit}>
48
+ <form ref={ref} onSubmit={onSubmit}>
48
49
  <input name="email" type="email" />
49
50
  <input name="password" type="password" />
50
51
  <button type="submit">Login</button>
51
52
  </form>
52
53
  );
54
+ }
55
+ <button type="submit">Login</button>
56
+ </form>
57
+ );
53
58
  }
54
59
  ```
55
60
 
@@ -73,8 +78,8 @@ interface UserForm {
73
78
  }
74
79
 
75
80
  function UserForm() {
76
- const { ref, submit } = useForm<UserForm>({
77
- handleSubmit: (data) => {
81
+ const { ref, onSubmit } = useForm<UserForm>({
82
+ submit: (data) => {
78
83
  console.log(data);
79
84
  // {
80
85
  // user: {
@@ -91,7 +96,7 @@ function UserForm() {
91
96
  });
92
97
 
93
98
  return (
94
- <form ref={ref} onSubmit={submit}>
99
+ <form ref={ref} onSubmit={onSubmit}>
95
100
  <input name="user.profile.name" placeholder="Name" />
96
101
  <input name="user.profile.age" type="number" placeholder="Age" />
97
102
  <select name="user.preferences.theme">
@@ -117,8 +122,8 @@ interface TodoForm {
117
122
  }
118
123
 
119
124
  function TodoForm() {
120
- const { ref, submit } = useForm<TodoForm>({
121
- handleSubmit: (data) => {
125
+ const { ref, onSubmit } = useForm<TodoForm>({
126
+ submit: (data) => {
122
127
  console.log(data);
123
128
  // {
124
129
  // todos: [
@@ -130,7 +135,7 @@ function TodoForm() {
130
135
  });
131
136
 
132
137
  return (
133
- <form ref={ref} onSubmit={submit}>
138
+ <form ref={ref} onSubmit={onSubmit}>
134
139
  <input name="todos[0].title" placeholder="First todo" />
135
140
  <input name="todos[0].completed" type="checkbox" />
136
141
 
@@ -149,12 +154,59 @@ function TodoForm() {
149
154
 
150
155
  #### Parameters
151
156
 
152
- - `options.handleSubmit: (data: T) => void` - Callback function called when form is submitted
157
+ - `options.submit: (data: T) => void` - Callback function called when form is submitted with parsed form data
153
158
 
154
159
  #### Returns
155
160
 
156
- - `ref: RefObject<HTMLFormElement>` - React ref to attach to your form element
157
- - `submit: (event: React.FormEvent) => void` - Submit handler to attach to form's `onSubmit`
161
+ - `ref: React.RefObject<HTMLFormElement>` - React ref to attach to your form element
162
+ - `onSubmit: (event: React.FormEvent<HTMLFormElement>) => void` - Form submission handler that prevents default behavior and calls submit with parsed data
163
+ - `reset: () => void` - Resets the form to its initial state
164
+ - `getFormData: () => T | null` - Gets current form data without triggering submission (returns null if form ref is not available)
165
+ - `setValue: (name: string, value: string) => void` - Sets the value of a specific form field by name
166
+
167
+ ### Additional Usage Examples
168
+
169
+ #### Using Form Utilities
170
+
171
+ ```tsx
172
+ function MyForm() {
173
+ const form = useForm<FormData>({
174
+ submit: (data) => console.log('Submitted:', data)
175
+ });
176
+
177
+ const handleReset = () => {
178
+ form.reset(); // Reset form to initial state
179
+ };
180
+
181
+ const handlePreview = () => {
182
+ const currentData = form.getFormData();
183
+ if (currentData) {
184
+ console.log('Current form data:', currentData);
185
+ }
186
+ };
187
+
188
+ const handlePrefill = () => {
189
+ form.setValue('email', 'user@example.com');
190
+ form.setValue('name', 'John Doe');
191
+ };
192
+
193
+ return (
194
+ <>
195
+ <form ref={form.ref} onSubmit={form.onSubmit}>
196
+ <input name="name" placeholder="Name" />
197
+ <input name="email" type="email" placeholder="Email" />
198
+ <button type="submit">Submit</button>
199
+ </form>
200
+
201
+ <div>
202
+ <button onClick={handleReset}>Reset Form</button>
203
+ <button onClick={handlePreview}>Preview Data</button>
204
+ <button onClick={handlePrefill}>Prefill Form</button>
205
+ </div>
206
+ </>
207
+ );
208
+ }
209
+ ```
158
210
 
159
211
  ### Form Data Parsing Rules
160
212
 
@@ -182,8 +234,8 @@ interface ContactData {
182
234
  }
183
235
 
184
236
  function ContactForm() {
185
- const { ref, submit } = useForm<ContactData>({
186
- handleSubmit: async (data) => {
237
+ const { ref, onSubmit } = useForm<ContactData>({
238
+ submit: async (data) => {
187
239
  try {
188
240
  const response = await fetch('/api/contact', {
189
241
  method: 'POST',
@@ -201,7 +253,7 @@ function ContactForm() {
201
253
  });
202
254
 
203
255
  return (
204
- <form ref={ref} onSubmit={submit}>
256
+ <form ref={ref} onSubmit={onSubmit}>
205
257
  <input name="name" placeholder="Your Name" required />
206
258
  <input name="email" type="email" placeholder="Your Email" required />
207
259
  <textarea name="message" placeholder="Your Message" required />
package/dist/index.cjs CHANGED
@@ -49,17 +49,70 @@ function parseFormData(formData) {
49
49
  return result;
50
50
  }
51
51
 
52
- function useForm({ handleSubmit }) {
52
+ /**
53
+ * A React hook for handling form state and submission
54
+ *
55
+ * @template T - The expected shape of the parsed form data
56
+ * @param options - Configuration options for the form
57
+ * @returns Object containing form ref, handlers, and utility functions
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * interface LoginData {
62
+ * email: string;
63
+ * password: string;
64
+ * }
65
+ *
66
+ * const form = useForm<LoginData>({
67
+ * submit: (data) => console.log(data.email, data.password)
68
+ * });
69
+ *
70
+ * return (
71
+ * <form ref={form.ref} onSubmit={form.onSubmit}>
72
+ * <input name="email" type="email" />
73
+ * <input name="password" type="password" />
74
+ * <button type="submit">Login</button>
75
+ * </form>
76
+ * );
77
+ * ```
78
+ */
79
+ function useForm({ submit }) {
53
80
  const ref = react.useRef(null);
54
- const submit = (event) => {
81
+ const onSubmit = (event) => {
55
82
  event.preventDefault();
56
83
  if (!ref.current)
57
84
  return;
58
85
  const formData = new FormData(ref.current);
59
86
  const data = parseFormData(formData);
60
- handleSubmit(data);
87
+ submit(data);
88
+ };
89
+ const reset = () => {
90
+ if (!ref.current)
91
+ return;
92
+ ref.current.reset();
93
+ };
94
+ const getFormData = () => {
95
+ if (!ref.current)
96
+ return null;
97
+ const formData = new FormData(ref.current);
98
+ const data = parseFormData(formData);
99
+ return data;
100
+ };
101
+ const setValue = (name, value) => {
102
+ if (!ref.current)
103
+ return;
104
+ const element = ref.current.elements.namedItem(name);
105
+ if (element && 'value' in element) {
106
+ element.value = value;
107
+ }
108
+ };
109
+ return {
110
+ ref,
111
+ onSubmit,
112
+ reset,
113
+ getFormData,
114
+ setValue
61
115
  };
62
- return { ref, submit };
63
116
  }
64
117
 
65
118
  exports.useForm = useForm;
package/dist/index.js CHANGED
@@ -47,17 +47,70 @@ function parseFormData(formData) {
47
47
  return result;
48
48
  }
49
49
 
50
- function useForm({ handleSubmit }) {
50
+ /**
51
+ * A React hook for handling form state and submission
52
+ *
53
+ * @template T - The expected shape of the parsed form data
54
+ * @param options - Configuration options for the form
55
+ * @returns Object containing form ref, handlers, and utility functions
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * interface LoginData {
60
+ * email: string;
61
+ * password: string;
62
+ * }
63
+ *
64
+ * const form = useForm<LoginData>({
65
+ * submit: (data) => console.log(data.email, data.password)
66
+ * });
67
+ *
68
+ * return (
69
+ * <form ref={form.ref} onSubmit={form.onSubmit}>
70
+ * <input name="email" type="email" />
71
+ * <input name="password" type="password" />
72
+ * <button type="submit">Login</button>
73
+ * </form>
74
+ * );
75
+ * ```
76
+ */
77
+ function useForm({ submit }) {
51
78
  const ref = useRef(null);
52
- const submit = (event) => {
79
+ const onSubmit = (event) => {
53
80
  event.preventDefault();
54
81
  if (!ref.current)
55
82
  return;
56
83
  const formData = new FormData(ref.current);
57
84
  const data = parseFormData(formData);
58
- handleSubmit(data);
85
+ submit(data);
86
+ };
87
+ const reset = () => {
88
+ if (!ref.current)
89
+ return;
90
+ ref.current.reset();
91
+ };
92
+ const getFormData = () => {
93
+ if (!ref.current)
94
+ return null;
95
+ const formData = new FormData(ref.current);
96
+ const data = parseFormData(formData);
97
+ return data;
98
+ };
99
+ const setValue = (name, value) => {
100
+ if (!ref.current)
101
+ return;
102
+ const element = ref.current.elements.namedItem(name);
103
+ if (element && 'value' in element) {
104
+ element.value = value;
105
+ }
106
+ };
107
+ return {
108
+ ref,
109
+ onSubmit,
110
+ reset,
111
+ getFormData,
112
+ setValue
59
113
  };
60
- return { ref, submit };
61
114
  }
62
115
 
63
116
  export { useForm };
@@ -1,8 +1,51 @@
1
- interface UseForm<T> {
2
- handleSubmit: (data: T) => void;
1
+ /**
2
+ * Configuration options for the useForm hook
3
+ */
4
+ interface UseFormOptions<T> {
5
+ /** Callback function called when form is submitted with parsed form data */
6
+ submit: (data: T) => void;
3
7
  }
4
- export declare function useForm<T = object>({ handleSubmit }: UseForm<T>): {
5
- ref: import("react").RefObject<HTMLFormElement | null>;
6
- submit: (event: React.FormEvent) => void;
7
- };
8
+ /**
9
+ * Return type of the useForm hook
10
+ */
11
+ interface UseFormReturn<T> {
12
+ /** React ref to be attached to the form element */
13
+ ref: React.RefObject<HTMLFormElement | null>;
14
+ /** Form submission handler - prevents default and calls submit with parsed data */
15
+ onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
16
+ /** Resets the form to its initial state */
17
+ reset: () => void;
18
+ /** Gets current form data without triggering submission */
19
+ getFormData: () => T | null;
20
+ /** Sets the value of a specific form field by name */
21
+ setValue: (name: string, value: string) => void;
22
+ }
23
+ /**
24
+ * A React hook for handling form state and submission
25
+ *
26
+ * @template T - The expected shape of the parsed form data
27
+ * @param options - Configuration options for the form
28
+ * @returns Object containing form ref, handlers, and utility functions
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * interface LoginData {
33
+ * email: string;
34
+ * password: string;
35
+ * }
36
+ *
37
+ * const form = useForm<LoginData>({
38
+ * submit: (data) => console.log(data.email, data.password)
39
+ * });
40
+ *
41
+ * return (
42
+ * <form ref={form.ref} onSubmit={form.onSubmit}>
43
+ * <input name="email" type="email" />
44
+ * <input name="password" type="password" />
45
+ * <button type="submit">Login</button>
46
+ * </form>
47
+ * );
48
+ * ```
49
+ */
50
+ export declare function useForm<T = Record<string, unknown>>({ submit }: UseFormOptions<T>): UseFormReturn<T>;
8
51
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rfhook",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -2,24 +2,110 @@ import { useRef } from 'react';
2
2
 
3
3
  import { parseFormData } from './utils/parseFormData';
4
4
 
5
- interface UseForm<T> {
6
- handleSubmit: (data: T) => void;
5
+ /**
6
+ * Configuration options for the useForm hook
7
+ */
8
+ interface UseFormOptions<T> {
9
+ /** Callback function called when form is submitted with parsed form data */
10
+ submit: (data: T) => void;
7
11
  }
8
12
 
9
- export function useForm<T = object>({ handleSubmit }: UseForm<T>) {
13
+ /**
14
+ * Form element types that can have their values set programmatically
15
+ */
16
+ type FormElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
17
+
18
+ /**
19
+ * Return type of the useForm hook
20
+ */
21
+ interface UseFormReturn<T> {
22
+ /** React ref to be attached to the form element */
23
+ ref: React.RefObject<HTMLFormElement | null>;
24
+ /** Form submission handler - prevents default and calls submit with parsed data */
25
+ onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
26
+ /** Resets the form to its initial state */
27
+ reset: () => void;
28
+ /** Gets current form data without triggering submission */
29
+ getFormData: () => T | null;
30
+ /** Sets the value of a specific form field by name */
31
+ setValue: (name: string, value: string) => void;
32
+ }
33
+
34
+ /**
35
+ * A React hook for handling form state and submission
36
+ *
37
+ * @template T - The expected shape of the parsed form data
38
+ * @param options - Configuration options for the form
39
+ * @returns Object containing form ref, handlers, and utility functions
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * interface LoginData {
44
+ * email: string;
45
+ * password: string;
46
+ * }
47
+ *
48
+ * const form = useForm<LoginData>({
49
+ * submit: (data) => console.log(data.email, data.password)
50
+ * });
51
+ *
52
+ * return (
53
+ * <form ref={form.ref} onSubmit={form.onSubmit}>
54
+ * <input name="email" type="email" />
55
+ * <input name="password" type="password" />
56
+ * <button type="submit">Login</button>
57
+ * </form>
58
+ * );
59
+ * ```
60
+ */
61
+ export function useForm<T = Record<string, unknown>>(
62
+ { submit }: UseFormOptions<T>
63
+ ): UseFormReturn<T> {
10
64
  const ref = useRef<HTMLFormElement>(null);
11
65
 
12
- const submit = (event: React.FormEvent) => {
66
+ const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
13
67
  event.preventDefault();
14
68
 
15
- if (!ref.current) return
69
+ if (!ref.current) return;
16
70
 
17
71
  const formData = new FormData(ref.current);
18
72
 
19
- const data: object = parseFormData(formData);
73
+ const data = parseFormData(formData) as T;
74
+
75
+ submit(data);
76
+ }
77
+
78
+ const reset = () => {
79
+ if (!ref.current) return;
80
+
81
+ ref.current.reset();
82
+ };
83
+
84
+ const getFormData = (): T | null => {
85
+ if (!ref.current) return null;
86
+
87
+ const formData = new FormData(ref.current);
88
+
89
+ const data = parseFormData(formData) as T;
90
+
91
+ return data;
92
+ };
93
+
94
+ const setValue = (name: string, value: string) => {
95
+ if (!ref.current) return;
96
+
97
+ const element = ref.current.elements.namedItem(name) as FormElement | null;
20
98
 
21
- handleSubmit(data as T);
99
+ if (element && 'value' in element) {
100
+ element.value = value;
22
101
  }
102
+ };
23
103
 
24
- return { ref, submit };
104
+ return {
105
+ ref,
106
+ onSubmit,
107
+ reset,
108
+ getFormData,
109
+ setValue
110
+ };
25
111
  }