@tanstack/react-form 0.13.6 → 0.14.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 (42) hide show
  1. package/dist/cjs/createFormFactory.cjs.map +1 -1
  2. package/dist/cjs/createFormFactory.d.cts +3 -3
  3. package/dist/cjs/types.d.cts +2 -2
  4. package/dist/cjs/useField.cjs +5 -28
  5. package/dist/cjs/useField.cjs.map +1 -1
  6. package/dist/cjs/useField.d.cts +4 -12
  7. package/dist/cjs/useForm.cjs +4 -6
  8. package/dist/cjs/useForm.cjs.map +1 -1
  9. package/dist/cjs/useForm.d.cts +14 -4
  10. package/dist/esm/createFormFactory.d.ts +3 -3
  11. package/dist/esm/createFormFactory.js.map +1 -1
  12. package/dist/esm/types.d.ts +2 -2
  13. package/dist/esm/useField.d.ts +4 -12
  14. package/dist/esm/useField.js +7 -30
  15. package/dist/esm/useField.js.map +1 -1
  16. package/dist/esm/useForm.d.ts +14 -4
  17. package/dist/esm/useForm.js +4 -6
  18. package/dist/esm/useForm.js.map +1 -1
  19. package/package.json +3 -3
  20. package/src/createFormFactory.ts +4 -4
  21. package/src/tests/createFormFactory.test.tsx +4 -5
  22. package/src/tests/useField.test-d.tsx +5 -5
  23. package/src/tests/useField.test.tsx +257 -32
  24. package/src/tests/useForm.test-d.tsx +1 -1
  25. package/src/tests/useForm.test.tsx +48 -25
  26. package/src/types.ts +8 -2
  27. package/src/useField.tsx +26 -68
  28. package/src/useForm.tsx +19 -14
  29. package/dist/cjs/formContext.cjs +0 -14
  30. package/dist/cjs/formContext.cjs.map +0 -1
  31. package/dist/cjs/formContext.d.cts +0 -10
  32. package/dist/cjs/useIsomorphicEffectOnce.cjs +0 -30
  33. package/dist/cjs/useIsomorphicEffectOnce.cjs.map +0 -1
  34. package/dist/cjs/useIsomorphicEffectOnce.d.cts +0 -5
  35. package/dist/esm/formContext.d.ts +0 -10
  36. package/dist/esm/formContext.js +0 -14
  37. package/dist/esm/formContext.js.map +0 -1
  38. package/dist/esm/useIsomorphicEffectOnce.d.ts +0 -5
  39. package/dist/esm/useIsomorphicEffectOnce.js +0 -30
  40. package/dist/esm/useIsomorphicEffectOnce.js.map +0 -1
  41. package/src/formContext.ts +0 -17
  42. package/src/useIsomorphicEffectOnce.ts +0 -39
@@ -1,8 +1,7 @@
1
- /// <reference lib="dom" />
2
- import '@testing-library/jest-dom'
1
+ import * as React from 'react'
2
+ import { describe, expect, it, vi } from 'vitest'
3
3
  import { render, waitFor } from '@testing-library/react'
4
4
  import userEvent from '@testing-library/user-event'
5
- import * as React from 'react'
6
5
  import { createFormFactory, useForm } from '../index'
7
6
  import { sleep } from './utils'
8
7
 
@@ -21,7 +20,7 @@ describe('useForm', () => {
21
20
  const form = formFactory.useForm()
22
21
 
23
22
  return (
24
- <form.Provider>
23
+ <>
25
24
  <form.Field
26
25
  name="firstName"
27
26
  defaultValue={''}
@@ -36,7 +35,7 @@ describe('useForm', () => {
36
35
  )
37
36
  }}
38
37
  />
39
- </form.Provider>
38
+ </>
40
39
  )
41
40
  }
42
41
 
@@ -64,14 +63,14 @@ describe('useForm', () => {
64
63
  })
65
64
 
66
65
  return (
67
- <form.Provider>
66
+ <>
68
67
  <form.Field
69
68
  name="firstName"
70
69
  children={(field) => {
71
70
  return <p>{field.state.value}</p>
72
71
  }}
73
72
  />
74
- </form.Provider>
73
+ </>
75
74
  )
76
75
  }
77
76
 
@@ -96,7 +95,7 @@ describe('useForm', () => {
96
95
  })
97
96
 
98
97
  return (
99
- <form.Provider>
98
+ <>
100
99
  <form.Field
101
100
  name="firstName"
102
101
  children={(field) => {
@@ -112,7 +111,7 @@ describe('useForm', () => {
112
111
  />
113
112
  <button onClick={form.handleSubmit}>Submit</button>
114
113
  {submittedData && <p>Submitted data: {submittedData.firstName}</p>}
115
- </form.Provider>
114
+ </>
116
115
  )
117
116
  }
118
117
 
@@ -146,9 +145,9 @@ describe('useForm', () => {
146
145
  return (
147
146
  <>
148
147
  {mountForm ? (
149
- <form.Provider>
148
+ <>
150
149
  <h1>{formMounted ? 'Form mounted' : 'Not mounted'}</h1>
151
- </form.Provider>
150
+ </>
152
151
  ) : (
153
152
  <button onClick={() => setMountForm(true)}>Mount form</button>
154
153
  )}
@@ -172,6 +171,10 @@ describe('useForm', () => {
172
171
 
173
172
  function Comp() {
174
173
  const form = formFactory.useForm({
174
+ defaultValues: {
175
+ firstName: '',
176
+ lastName: '',
177
+ },
175
178
  validators: {
176
179
  onChange() {
177
180
  return error
@@ -180,7 +183,7 @@ describe('useForm', () => {
180
183
  })
181
184
  const onChangeError = form.useStore((s) => s.errorMap.onChange)
182
185
  return (
183
- <form.Provider>
186
+ <>
184
187
  <form.Field
185
188
  name="firstName"
186
189
  children={(field) => (
@@ -194,7 +197,7 @@ describe('useForm', () => {
194
197
  )}
195
198
  />
196
199
  <p>{onChangeError}</p>
197
- </form.Provider>
200
+ </>
198
201
  )
199
202
  }
200
203
 
@@ -217,6 +220,10 @@ describe('useForm', () => {
217
220
 
218
221
  function Comp() {
219
222
  const form = formFactory.useForm({
223
+ defaultValues: {
224
+ firstName: '',
225
+ lastName: '',
226
+ },
220
227
  validators: {
221
228
  onChange: ({ value }) =>
222
229
  value.firstName === 'other' ? error : undefined,
@@ -225,7 +232,7 @@ describe('useForm', () => {
225
232
 
226
233
  const errors = form.useStore((s) => s.errors)
227
234
  return (
228
- <form.Provider>
235
+ <>
229
236
  <form.Field
230
237
  name="firstName"
231
238
  children={(field) => (
@@ -241,7 +248,7 @@ describe('useForm', () => {
241
248
  </div>
242
249
  )}
243
250
  />
244
- </form.Provider>
251
+ </>
245
252
  )
246
253
  }
247
254
 
@@ -262,6 +269,10 @@ describe('useForm', () => {
262
269
 
263
270
  function Comp() {
264
271
  const form = formFactory.useForm({
272
+ defaultValues: {
273
+ firstName: '',
274
+ lastName: '',
275
+ },
265
276
  validators: {
266
277
  onChange: ({ value }) =>
267
278
  value.firstName === 'other' ? error : undefined,
@@ -269,7 +280,7 @@ describe('useForm', () => {
269
280
  })
270
281
  const errors = form.useStore((s) => s.errorMap)
271
282
  return (
272
- <form.Provider>
283
+ <>
273
284
  <form.Field
274
285
  name="firstName"
275
286
  defaultMeta={{ isTouched: true }}
@@ -286,7 +297,7 @@ describe('useForm', () => {
286
297
  </div>
287
298
  )}
288
299
  />
289
- </form.Provider>
300
+ </>
290
301
  )
291
302
  }
292
303
 
@@ -320,7 +331,7 @@ describe('useForm', () => {
320
331
 
321
332
  const errors = form.useStore((s) => s.errorMap)
322
333
  return (
323
- <form.Provider>
334
+ <>
324
335
  <form.Field
325
336
  name="firstName"
326
337
  defaultMeta={{ isTouched: true }}
@@ -338,7 +349,7 @@ describe('useForm', () => {
338
349
  </div>
339
350
  )}
340
351
  />
341
- </form.Provider>
352
+ </>
342
353
  )
343
354
  }
344
355
  const { getByTestId, getByText, queryByText } = render(<Comp />)
@@ -362,6 +373,10 @@ describe('useForm', () => {
362
373
 
363
374
  function Comp() {
364
375
  const form = formFactory.useForm({
376
+ defaultValues: {
377
+ firstName: '',
378
+ lastName: '',
379
+ },
365
380
  validators: {
366
381
  onChangeAsync: async () => {
367
382
  await sleep(10)
@@ -371,7 +386,7 @@ describe('useForm', () => {
371
386
  })
372
387
  const errors = form.useStore((s) => s.errorMap)
373
388
  return (
374
- <form.Provider>
389
+ <>
375
390
  <form.Field
376
391
  name="firstName"
377
392
  defaultMeta={{ isTouched: true }}
@@ -388,7 +403,7 @@ describe('useForm', () => {
388
403
  </div>
389
404
  )}
390
405
  />
391
- </form.Provider>
406
+ </>
392
407
  )
393
408
  }
394
409
 
@@ -412,6 +427,10 @@ describe('useForm', () => {
412
427
 
413
428
  function Comp() {
414
429
  const form = formFactory.useForm({
430
+ defaultValues: {
431
+ firstName: '',
432
+ lastName: '',
433
+ },
415
434
  validators: {
416
435
  onChangeAsync: async () => {
417
436
  await sleep(10)
@@ -426,7 +445,7 @@ describe('useForm', () => {
426
445
  const errors = form.useStore((s) => s.errorMap)
427
446
 
428
447
  return (
429
- <form.Provider>
448
+ <>
430
449
  <form.Field
431
450
  name="firstName"
432
451
  defaultMeta={{ isTouched: true }}
@@ -444,7 +463,7 @@ describe('useForm', () => {
444
463
  </div>
445
464
  )}
446
465
  />
447
- </form.Provider>
466
+ </>
448
467
  )
449
468
  }
450
469
 
@@ -472,6 +491,10 @@ describe('useForm', () => {
472
491
 
473
492
  function Comp() {
474
493
  const form = formFactory.useForm({
494
+ defaultValues: {
495
+ firstName: '',
496
+ lastName: '',
497
+ },
475
498
  validators: {
476
499
  onChangeAsyncDebounceMs: 100,
477
500
  onChangeAsync: async () => {
@@ -484,7 +507,7 @@ describe('useForm', () => {
484
507
  const errors = form.useStore((s) => s.errors)
485
508
 
486
509
  return (
487
- <form.Provider>
510
+ <>
488
511
  <form.Field
489
512
  name="firstName"
490
513
  defaultMeta={{ isTouched: true }}
@@ -501,7 +524,7 @@ describe('useForm', () => {
501
524
  </div>
502
525
  )}
503
526
  />
504
- </form.Provider>
527
+ </>
505
528
  )
506
529
  }
507
530
 
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  DeepKeys,
3
3
  DeepValue,
4
- FieldOptions,
4
+ FieldApiOptions,
5
5
  Validator,
6
6
  } from '@tanstack/form-core'
7
7
 
@@ -15,6 +15,12 @@ export type UseFieldOptions<
15
15
  | Validator<TParentData, unknown>
16
16
  | undefined = undefined,
17
17
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
18
- > = FieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
18
+ > = FieldApiOptions<
19
+ TParentData,
20
+ TName,
21
+ TFieldValidator,
22
+ TFormValidator,
23
+ TData
24
+ > & {
19
25
  mode?: 'value' | 'array'
20
26
  }
package/src/useField.tsx CHANGED
@@ -1,9 +1,7 @@
1
- import React, { useRef, useState } from 'rehackt'
1
+ import React, { useState } from 'rehackt'
2
2
  import { useStore } from '@tanstack/react-store'
3
3
  import { FieldApi, functionalUpdate } from '@tanstack/form-core'
4
- import { formContext, useFormContext } from './formContext'
5
4
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
6
- import { useIsomorphicEffectOnce } from './useIsomorphicEffectOnce'
7
5
  import type { UseFieldOptions } from './types'
8
6
  import type {
9
7
  DeepKeys,
@@ -29,20 +27,20 @@ declare module '@tanstack/form-core' {
29
27
  }
30
28
  }
31
29
 
32
- export type UseField<TParentData> = <
30
+ export type UseField<
31
+ TParentData,
32
+ TFormValidator extends
33
+ | Validator<TParentData, unknown>
34
+ | undefined = undefined,
35
+ > = <
33
36
  TName extends DeepKeys<TParentData>,
34
37
  TFieldValidator extends
35
38
  | Validator<DeepValue<TParentData, TName>, unknown>
36
39
  | undefined = undefined,
37
- TFormValidator extends
38
- | Validator<TParentData, unknown>
39
- | undefined = undefined,
40
40
  >(
41
- opts?: { name: Narrow<TName> } & UseFieldOptions<
42
- TParentData,
43
- TName,
44
- TFieldValidator,
45
- TFormValidator
41
+ opts: Omit<
42
+ UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
43
+ 'form'
46
44
  >,
47
45
  ) => FieldApi<
48
46
  TParentData,
@@ -64,23 +62,11 @@ export function useField<
64
62
  >(
65
63
  opts: UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
66
64
  ): FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {
67
- // Get the form API either manually or from context
68
- const { formApi, parentFieldName } = useFormContext()
69
-
70
65
  const [fieldApi] = useState(() => {
71
- const name = (
72
- typeof opts.index === 'number'
73
- ? [parentFieldName, opts.index, opts.name]
74
- : [parentFieldName, opts.name]
75
- )
76
- .filter((d) => d !== undefined)
77
- .join('.')
78
-
79
66
  const api = new FieldApi({
80
67
  ...opts,
81
- form: formApi as never,
82
- // TODO: Fix typings to include `index` and `parentFieldName`, if present
83
- name: name as typeof opts.name as never,
68
+ form: opts.form,
69
+ name: opts.name,
84
70
  })
85
71
 
86
72
  api.Field = Field as never
@@ -88,12 +74,14 @@ export function useField<
88
74
  return api
89
75
  })
90
76
 
77
+ useIsomorphicLayoutEffect(fieldApi.mount, [fieldApi])
78
+
91
79
  /**
92
80
  * fieldApi.update should not have any side effects. Think of it like a `useRef`
93
81
  * that we need to keep updated every render with the most up-to-date information.
94
82
  */
95
83
  useIsomorphicLayoutEffect(() => {
96
- fieldApi.update({ ...opts, form: formApi } as never)
84
+ fieldApi.update(opts)
97
85
  })
98
86
 
99
87
  useStore(
@@ -104,19 +92,6 @@ export function useField<
104
92
  }
105
93
  : undefined,
106
94
  )
107
- const unmountFn = useRef<(() => void) | null>(null)
108
-
109
- useIsomorphicEffectOnce(() => {
110
- return () => {
111
- unmountFn.current?.()
112
- }
113
- })
114
-
115
- // We have to mount it right as soon as it renders, otherwise we get:
116
- // https://github.com/TanStack/form/issues/523
117
- if (!unmountFn.current) {
118
- unmountFn.current = fieldApi.mount()
119
- }
120
95
 
121
96
  return fieldApi as never
122
97
  }
@@ -141,19 +116,7 @@ type FieldComponentProps<
141
116
  TData
142
117
  >,
143
118
  ) => any
144
- } & (TParentData extends any[]
145
- ? {
146
- name?: TName
147
- index: number
148
- }
149
- : {
150
- name: TName
151
- index?: never
152
- }) &
153
- Omit<
154
- UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>,
155
- 'name' | 'index'
156
- >
119
+ } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>
157
120
 
158
121
  export type FieldComponent<
159
122
  TParentData,
@@ -169,12 +132,15 @@ export type FieldComponent<
169
132
  >({
170
133
  children,
171
134
  ...fieldOptions
172
- }: FieldComponentProps<
173
- TParentData,
174
- TName,
175
- TFieldValidator,
176
- TFormValidator,
177
- TData
135
+ }: Omit<
136
+ FieldComponentProps<
137
+ TParentData,
138
+ TName,
139
+ TFieldValidator,
140
+ TFormValidator,
141
+ TData
142
+ >,
143
+ 'form'
178
144
  >) => any
179
145
 
180
146
  export function Field<
@@ -196,13 +162,5 @@ export function Field<
196
162
  } & UseFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>) {
197
163
  const fieldApi = useField(fieldOptions as any)
198
164
 
199
- return (
200
- <formContext.Provider
201
- value={{
202
- formApi: fieldApi.form as never,
203
- parentFieldName: fieldApi.name,
204
- }}
205
- children={functionalUpdate(children, fieldApi as any)}
206
- />
207
- )
165
+ return <>{functionalUpdate(children, fieldApi as any)}</>
208
166
  }
package/src/useForm.tsx CHANGED
@@ -5,23 +5,31 @@ import React, {
5
5
  type ReactNode,
6
6
  useState,
7
7
  } from 'rehackt'
8
- import { Field, useField } from './useField'
9
- import { formContext } from './formContext'
8
+ import { Field, type FieldComponent, type UseField, useField } from './useField'
10
9
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
11
10
  import type { NoInfer } from '@tanstack/react-store'
12
11
  import type { FormOptions, FormState, Validator } from '@tanstack/form-core'
13
- import type { FieldComponent, UseField } from './useField'
14
12
 
15
13
  declare module '@tanstack/form-core' {
16
14
  // eslint-disable-next-line no-shadow
17
15
  interface FormApi<TFormData, TFormValidator> {
18
- Provider: (props: PropsWithChildren) => JSX.Element
19
16
  Field: FieldComponent<TFormData, TFormValidator>
20
- useField: UseField<TFormData>
17
+ useField: UseField<TFormData, TFormValidator>
21
18
  useStore: <TSelected = NoInfer<FormState<TFormData>>>(
22
19
  selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
23
20
  ) => TSelected
24
21
  Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
22
+ /**
23
+ TypeScript versions <=5.0.4 have a bug that prevents
24
+ the type of the `TSelected` generic from being inferred
25
+ from the return type of this method.
26
+
27
+ In these versions, `TSelected` will fall back to the default
28
+ type (or `unknown` if that's not defined).
29
+
30
+ @see {@link https://github.com/TanStack/form/pull/606/files#r1506715714 | This discussion on GitHub for the details}
31
+ @see {@link https://github.com/microsoft/TypeScript/issues/52786 | The bug report in `microsoft/TypeScript`}
32
+ */
25
33
  selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
26
34
  children: ((state: NoInfer<TSelected>) => ReactNode) | ReactNode
27
35
  }) => JSX.Element
@@ -35,17 +43,12 @@ export function useForm<
35
43
  opts?: FormOptions<TFormData, TFormValidator>,
36
44
  ): FormApi<TFormData, TFormValidator> {
37
45
  const [formApi] = useState(() => {
38
- // @ts-ignore
39
46
  const api = new FormApi<TFormData, TFormValidator>(opts)
40
-
41
- api.Provider = function Provider(props) {
42
- useIsomorphicLayoutEffect(api.mount, [])
43
- return (
44
- <formContext.Provider {...props} value={{ formApi: api as never }} />
45
- )
47
+ api.Field = function APIField(props) {
48
+ return <Field {...props} form={api} />
46
49
  }
47
- api.Field = Field as any
48
- api.useField = useField as any
50
+ // eslint-disable-next-line react-hooks/rules-of-hooks
51
+ api.useField = (props) => useField({ ...props, form: api })
49
52
  api.useStore = (
50
53
  // @ts-ignore
51
54
  selector,
@@ -67,6 +70,8 @@ export function useForm<
67
70
  return api
68
71
  })
69
72
 
73
+ useIsomorphicLayoutEffect(formApi.mount, [])
74
+
70
75
  formApi.useStore((state) => state.isSubmitting)
71
76
 
72
77
  /**
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const rehackt = require("rehackt");
4
- const formContext = rehackt.createContext(null);
5
- function useFormContext() {
6
- const formApi = rehackt.useContext(formContext);
7
- if (!formApi) {
8
- throw new Error(`You are trying to use the form API outside of a form!`);
9
- }
10
- return formApi;
11
- }
12
- exports.formContext = formContext;
13
- exports.useFormContext = useFormContext;
14
- //# sourceMappingURL=formContext.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"formContext.cjs","sources":["../../src/formContext.ts"],"sourcesContent":["import { createContext, useContext } from 'rehackt'\nimport type { FormApi, Validator } from '@tanstack/form-core'\n\nexport const formContext = createContext<{\n formApi: FormApi<any, Validator<any, unknown> | undefined>\n parentFieldName?: string\n} | null>(null!)\n\nexport function useFormContext() {\n const formApi = useContext(formContext)\n\n if (!formApi) {\n throw new Error(`You are trying to use the form API outside of a form!`)\n }\n\n return formApi\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAGa,MAAA,cAAcA,sBAGjB,IAAK;AAER,SAAS,iBAAiB;AACzB,QAAA,UAAUC,mBAAW,WAAW;AAEtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEO,SAAA;AACT;;;"}
@@ -1,10 +0,0 @@
1
- /// <reference types="react" />
2
- import type { FormApi, Validator } from '@tanstack/form-core';
3
- export declare const formContext: import("react").Context<{
4
- formApi: FormApi<any, Validator<any, unknown> | undefined>;
5
- parentFieldName?: string | undefined;
6
- } | null>;
7
- export declare function useFormContext(): {
8
- formApi: FormApi<any, Validator<any, unknown> | undefined>;
9
- parentFieldName?: string | undefined;
10
- };
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const rehackt = require("rehackt");
4
- const useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect.cjs");
5
- const useIsomorphicEffectOnce = (effect) => {
6
- const destroyFunc = rehackt.useRef();
7
- const effectCalled = rehackt.useRef(false);
8
- const renderAfterCalled = rehackt.useRef(false);
9
- const [val, setVal] = rehackt.useState(0);
10
- if (effectCalled.current) {
11
- renderAfterCalled.current = true;
12
- }
13
- useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
14
- if (!effectCalled.current) {
15
- destroyFunc.current = effect();
16
- effectCalled.current = true;
17
- }
18
- setVal((v) => v + 1);
19
- return () => {
20
- if (!renderAfterCalled.current) {
21
- return;
22
- }
23
- if (destroyFunc.current) {
24
- destroyFunc.current();
25
- }
26
- };
27
- }, []);
28
- };
29
- exports.useIsomorphicEffectOnce = useIsomorphicEffectOnce;
30
- //# sourceMappingURL=useIsomorphicEffectOnce.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useIsomorphicEffectOnce.cjs","sources":["../../src/useIsomorphicEffectOnce.ts"],"sourcesContent":["import { useRef, useState } from 'rehackt'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { EffectCallback } from 'rehackt'\n\n/**\n * This hook handles StrictMode and prod mode\n */\nexport const useIsomorphicEffectOnce = (effect: EffectCallback) => {\n const destroyFunc = useRef<void | (() => void)>()\n const effectCalled = useRef(false)\n const renderAfterCalled = useRef(false)\n const [val, setVal] = useState(0)\n\n if (effectCalled.current) {\n renderAfterCalled.current = true\n }\n\n useIsomorphicLayoutEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect()\n effectCalled.current = true\n }\n\n // this forces one render after the effect is run\n setVal((v) => v + 1)\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) {\n return\n }\n if (destroyFunc.current) {\n destroyFunc.current()\n }\n }\n }, [])\n}\n"],"names":["useRef","useState","useIsomorphicLayoutEffect"],"mappings":";;;;AAOa,MAAA,0BAA0B,CAAC,WAA2B;AACjE,QAAM,cAAcA,QAAAA;AACd,QAAA,eAAeA,eAAO,KAAK;AAC3B,QAAA,oBAAoBA,eAAO,KAAK;AACtC,QAAM,CAAC,KAAK,MAAM,IAAIC,iBAAS,CAAC;AAEhC,MAAI,aAAa,SAAS;AACxB,sBAAkB,UAAU;AAAA,EAC9B;AAEAC,4BAAAA,0BAA0B,MAAM;AAE1B,QAAA,CAAC,aAAa,SAAS;AACzB,kBAAY,UAAU;AACtB,mBAAa,UAAU;AAAA,IACzB;AAGO,WAAA,CAAC,MAAM,IAAI,CAAC;AAEnB,WAAO,MAAM;AAGP,UAAA,CAAC,kBAAkB,SAAS;AAC9B;AAAA,MACF;AACA,UAAI,YAAY,SAAS;AACvB,oBAAY,QAAQ;AAAA,MACtB;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAE,CAAA;AACP;;"}
@@ -1,5 +0,0 @@
1
- import type { EffectCallback } from 'rehackt';
2
- /**
3
- * This hook handles StrictMode and prod mode
4
- */
5
- export declare const useIsomorphicEffectOnce: (effect: EffectCallback) => void;
@@ -1,10 +0,0 @@
1
- /// <reference types="react" />
2
- import type { FormApi, Validator } from '@tanstack/form-core';
3
- export declare const formContext: import("react").Context<{
4
- formApi: FormApi<any, Validator<any, unknown> | undefined>;
5
- parentFieldName?: string | undefined;
6
- } | null>;
7
- export declare function useFormContext(): {
8
- formApi: FormApi<any, Validator<any, unknown> | undefined>;
9
- parentFieldName?: string | undefined;
10
- };
@@ -1,14 +0,0 @@
1
- import { createContext, useContext } from "rehackt";
2
- const formContext = createContext(null);
3
- function useFormContext() {
4
- const formApi = useContext(formContext);
5
- if (!formApi) {
6
- throw new Error(`You are trying to use the form API outside of a form!`);
7
- }
8
- return formApi;
9
- }
10
- export {
11
- formContext,
12
- useFormContext
13
- };
14
- //# sourceMappingURL=formContext.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"formContext.js","sources":["../../src/formContext.ts"],"sourcesContent":["import { createContext, useContext } from 'rehackt'\nimport type { FormApi, Validator } from '@tanstack/form-core'\n\nexport const formContext = createContext<{\n formApi: FormApi<any, Validator<any, unknown> | undefined>\n parentFieldName?: string\n} | null>(null!)\n\nexport function useFormContext() {\n const formApi = useContext(formContext)\n\n if (!formApi) {\n throw new Error(`You are trying to use the form API outside of a form!`)\n }\n\n return formApi\n}\n"],"names":[],"mappings":";AAGa,MAAA,cAAc,cAGjB,IAAK;AAER,SAAS,iBAAiB;AACzB,QAAA,UAAU,WAAW,WAAW;AAEtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEO,SAAA;AACT;"}
@@ -1,5 +0,0 @@
1
- import type { EffectCallback } from 'rehackt';
2
- /**
3
- * This hook handles StrictMode and prod mode
4
- */
5
- export declare const useIsomorphicEffectOnce: (effect: EffectCallback) => void;
@@ -1,30 +0,0 @@
1
- import { useRef, useState } from "rehackt";
2
- import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
3
- const useIsomorphicEffectOnce = (effect) => {
4
- const destroyFunc = useRef();
5
- const effectCalled = useRef(false);
6
- const renderAfterCalled = useRef(false);
7
- const [val, setVal] = useState(0);
8
- if (effectCalled.current) {
9
- renderAfterCalled.current = true;
10
- }
11
- useIsomorphicLayoutEffect(() => {
12
- if (!effectCalled.current) {
13
- destroyFunc.current = effect();
14
- effectCalled.current = true;
15
- }
16
- setVal((v) => v + 1);
17
- return () => {
18
- if (!renderAfterCalled.current) {
19
- return;
20
- }
21
- if (destroyFunc.current) {
22
- destroyFunc.current();
23
- }
24
- };
25
- }, []);
26
- };
27
- export {
28
- useIsomorphicEffectOnce
29
- };
30
- //# sourceMappingURL=useIsomorphicEffectOnce.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useIsomorphicEffectOnce.js","sources":["../../src/useIsomorphicEffectOnce.ts"],"sourcesContent":["import { useRef, useState } from 'rehackt'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\nimport type { EffectCallback } from 'rehackt'\n\n/**\n * This hook handles StrictMode and prod mode\n */\nexport const useIsomorphicEffectOnce = (effect: EffectCallback) => {\n const destroyFunc = useRef<void | (() => void)>()\n const effectCalled = useRef(false)\n const renderAfterCalled = useRef(false)\n const [val, setVal] = useState(0)\n\n if (effectCalled.current) {\n renderAfterCalled.current = true\n }\n\n useIsomorphicLayoutEffect(() => {\n // only execute the effect first time around\n if (!effectCalled.current) {\n destroyFunc.current = effect()\n effectCalled.current = true\n }\n\n // this forces one render after the effect is run\n setVal((v) => v + 1)\n\n return () => {\n // if the comp didn't render since the useEffect was called,\n // we know it's the dummy React cycle\n if (!renderAfterCalled.current) {\n return\n }\n if (destroyFunc.current) {\n destroyFunc.current()\n }\n }\n }, [])\n}\n"],"names":[],"mappings":";;AAOa,MAAA,0BAA0B,CAAC,WAA2B;AACjE,QAAM,cAAc;AACd,QAAA,eAAe,OAAO,KAAK;AAC3B,QAAA,oBAAoB,OAAO,KAAK;AACtC,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,CAAC;AAEhC,MAAI,aAAa,SAAS;AACxB,sBAAkB,UAAU;AAAA,EAC9B;AAEA,4BAA0B,MAAM;AAE1B,QAAA,CAAC,aAAa,SAAS;AACzB,kBAAY,UAAU;AACtB,mBAAa,UAAU;AAAA,IACzB;AAGO,WAAA,CAAC,MAAM,IAAI,CAAC;AAEnB,WAAO,MAAM;AAGP,UAAA,CAAC,kBAAkB,SAAS;AAC9B;AAAA,MACF;AACA,UAAI,YAAY,SAAS;AACvB,oBAAY,QAAQ;AAAA,MACtB;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAE,CAAA;AACP;"}
@@ -1,17 +0,0 @@
1
- import { createContext, useContext } from 'rehackt'
2
- import type { FormApi, Validator } from '@tanstack/form-core'
3
-
4
- export const formContext = createContext<{
5
- formApi: FormApi<any, Validator<any, unknown> | undefined>
6
- parentFieldName?: string
7
- } | null>(null!)
8
-
9
- export function useFormContext() {
10
- const formApi = useContext(formContext)
11
-
12
- if (!formApi) {
13
- throw new Error(`You are trying to use the form API outside of a form!`)
14
- }
15
-
16
- return formApi
17
- }