@tanstack/solid-form 0.22.0 → 0.23.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 (41) hide show
  1. package/dist/{esm/createField.d.ts → createField.d.ts} +4 -4
  2. package/dist/createField.jsx +33 -0
  3. package/dist/createField.jsx.map +1 -0
  4. package/dist/{esm/createForm.d.ts → createForm.d.ts} +4 -4
  5. package/dist/createForm.jsx +22 -0
  6. package/dist/createForm.jsx.map +1 -0
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.js +4 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/{esm/types.d.ts → types.d.ts} +1 -2
  11. package/dist/types.js +2 -0
  12. package/dist/types.js.map +1 -0
  13. package/package.json +10 -11
  14. package/src/index.ts +1 -22
  15. package/src/tests/createField.test.tsx +9 -24
  16. package/src/tests/createForm.test.tsx +10 -25
  17. package/dist/cjs/createField.cjs +0 -33
  18. package/dist/cjs/createField.cjs.map +0 -1
  19. package/dist/cjs/createField.d.cts +0 -21
  20. package/dist/cjs/createForm.cjs +0 -27
  21. package/dist/cjs/createForm.cjs.map +0 -1
  22. package/dist/cjs/createForm.d.cts +0 -18
  23. package/dist/cjs/createFormFactory.cjs +0 -16
  24. package/dist/cjs/createFormFactory.cjs.map +0 -1
  25. package/dist/cjs/createFormFactory.d.cts +0 -9
  26. package/dist/cjs/index.cjs +0 -23
  27. package/dist/cjs/index.cjs.map +0 -1
  28. package/dist/cjs/index.d.cts +0 -7
  29. package/dist/cjs/types.d.cts +0 -5
  30. package/dist/esm/createField.js +0 -33
  31. package/dist/esm/createField.js.map +0 -1
  32. package/dist/esm/createForm.js +0 -27
  33. package/dist/esm/createForm.js.map +0 -1
  34. package/dist/esm/createFormFactory.d.ts +0 -9
  35. package/dist/esm/createFormFactory.js +0 -16
  36. package/dist/esm/createFormFactory.js.map +0 -1
  37. package/dist/esm/index.d.ts +0 -7
  38. package/dist/esm/index.js +0 -14
  39. package/dist/esm/index.js.map +0 -1
  40. package/src/createFormFactory.ts +0 -36
  41. package/src/tests/createFormFactory.test.tsx +0 -38
@@ -1,7 +1,7 @@
1
- import { FieldApi, DeepKeys, DeepValue, Narrow, Validator } from '@tanstack/form-core';
2
- import { JSXElement } from 'solid-js';
3
- import { CreateFieldOptions } from './types.js';
4
-
1
+ import { FieldApi } from '@tanstack/form-core';
2
+ import type { DeepKeys, DeepValue, Narrow, Validator } from '@tanstack/form-core';
3
+ import type { JSXElement } from 'solid-js';
4
+ import type { CreateFieldOptions } from './types';
5
5
  declare module '@tanstack/form-core' {
6
6
  interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
7
7
  Field: FieldComponent<TParentData, TFormValidator>;
@@ -0,0 +1,33 @@
1
+ import { FieldApi } from '@tanstack/form-core';
2
+ import { createComponent, createComputed, createMemo, createSignal, onCleanup, onMount, } from 'solid-js';
3
+ // ugly way to trick solid into triggering updates for changes on the fieldApi
4
+ function makeFieldReactive(fieldApi) {
5
+ const [flag, setFlag] = createSignal(false);
6
+ const fieldApiMemo = createMemo(() => [flag(), fieldApi]);
7
+ const unsubscribeStore = fieldApi.store.subscribe(() => setFlag((f) => !f));
8
+ onCleanup(unsubscribeStore);
9
+ return () => fieldApiMemo()[1];
10
+ }
11
+ export function createField(opts) {
12
+ const options = opts();
13
+ const fieldApi = new FieldApi(options);
14
+ fieldApi.Field = Field;
15
+ /**
16
+ * fieldApi.update should not have any side effects. Think of it like a `useRef`
17
+ * that we need to keep updated every render with the most up-to-date information.
18
+ *
19
+ * createComputed to make sure this effect runs before render effects
20
+ */
21
+ createComputed(() => fieldApi.update(opts()));
22
+ // Instantiates field meta and removes it when unrendered
23
+ onMount(() => onCleanup(fieldApi.mount()));
24
+ return makeFieldReactive(fieldApi);
25
+ }
26
+ export function Field(props) {
27
+ const fieldApi = createField(() => {
28
+ const { children, ...fieldOptions } = props;
29
+ return fieldOptions;
30
+ });
31
+ return <>{createComponent(() => props.children(fieldApi), {})}</>;
32
+ }
33
+ //# sourceMappingURL=createField.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createField.jsx","sourceRoot":"","sources":["../src/createField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EACL,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,EACZ,SAAS,EACT,OAAO,GACR,MAAM,UAAU,CAAA;AAoDjB,8EAA8E;AAC9E,SAAS,iBAAiB,CACxB,QAAmB;IAEnB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAU,CAAC,CAAA;IAClE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3E,SAAS,CAAC,gBAAgB,CAAC,CAAA;IAC3B,OAAO,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,WAAW,CAWzB,IAMC;IAED,MAAM,OAAO,GAAG,IAAI,EAAE,CAAA;IAEtB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAA;IACtC,QAAQ,CAAC,KAAK,GAAG,KAAc,CAAA;IAE/B;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAE7C,yDAAyD;IACzD,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAE1C,OAAO,iBAAiB,CAAC,QAAQ,CAAU,CAAA;AAC7C,CAAC;AA0DD,MAAM,UAAU,KAAK,CAWnB,KAgBC;IAED,MAAM,QAAQ,GAAG,WAAW,CAM1B,GAAG,EAAE;QACL,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,CAAA;QAC3C,OAAO,YAAY,CAAA;IACrB,CAAC,CAAC,CAAA;IAEF,OAAO,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAA;AACnE,CAAC"}
@@ -1,7 +1,7 @@
1
- import { FormApi, FormOptions, FormState, Validator } from '@tanstack/form-core';
2
- import { JSXElement } from 'solid-js';
3
- import { CreateField, FieldComponent } from './createField.js';
4
-
1
+ import { FormApi } from '@tanstack/form-core';
2
+ import { type JSXElement } from 'solid-js';
3
+ import { type CreateField, type FieldComponent } from './createField';
4
+ import type { FormOptions, FormState, Validator } from '@tanstack/form-core';
5
5
  type NoInfer<T> = [T][T extends any ? 0 : never];
6
6
  declare module '@tanstack/form-core' {
7
7
  interface FormApi<TFormData, TFormValidator> {
@@ -0,0 +1,22 @@
1
+ import { FormApi, functionalUpdate } from '@tanstack/form-core';
2
+ import { createComputed, onMount } from 'solid-js';
3
+ import { useStore } from '@tanstack/solid-store';
4
+ import { Field, createField, } from './createField';
5
+ export function createForm(opts) {
6
+ const options = opts?.();
7
+ const formApi = new FormApi(options);
8
+ formApi.Field = (props) => <Field {...props} form={formApi}/>;
9
+ formApi.createField = (props) => createField(() => {
10
+ return { ...props(), form: formApi };
11
+ });
12
+ formApi.useStore = (selector) => useStore(formApi.store, selector);
13
+ formApi.Subscribe = (props) => functionalUpdate(props.children, useStore(formApi.store, props.selector));
14
+ onMount(formApi.mount);
15
+ /**
16
+ * formApi.update should not have any side effects. Think of it like a `useRef`
17
+ * that we need to keep updated every render with the most up-to-date information.
18
+ */
19
+ createComputed(() => formApi.update(opts?.()));
20
+ return formApi;
21
+ }
22
+ //# sourceMappingURL=createForm.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createForm.jsx","sourceRoot":"","sources":["../src/createForm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAmB,cAAc,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAEL,KAAK,EAEL,WAAW,GACZ,MAAM,eAAe,CAAA;AAoBtB,MAAM,UAAU,UAAU,CAMxB,IAAqD;IAErD,MAAM,OAAO,GAAG,IAAI,EAAE,EAAE,CAAA;IACxB,MAAM,OAAO,GAAG,IAAI,OAAO,CAA8B,OAAO,CAAC,CAAA;IAEjE,OAAO,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAG,CAAA;IAC9D,OAAO,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,EAAE,CAC9B,WAAW,CAAC,GAAG,EAAE;QACf,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACtC,CAAC,CAAC,CAAA;IACJ,OAAO,CAAC,QAAQ,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAClE,OAAO,CAAC,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE,CAC5B,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE3E,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAEtB;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IAE9C,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from '@tanstack/form-core';
2
+ export { createForm } from './createForm';
3
+ export type { CreateField, FieldComponent } from './createField';
4
+ export { createField, Field } from './createField';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from '@tanstack/form-core';
2
+ export { createForm } from './createForm';
3
+ export { createField, Field } from './createField';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA"}
@@ -1,5 +1,4 @@
1
- import { DeepKeys, DeepValue, FieldApiOptions, Validator } from '@tanstack/form-core';
2
-
1
+ import type { DeepKeys, DeepValue, FieldApiOptions, Validator } from '@tanstack/form-core';
3
2
  export type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldApiOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
4
3
  mode?: 'value' | 'array';
5
4
  };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-form",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Powerful, type-safe forms for Solid.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -16,18 +16,17 @@
16
16
  "src"
17
17
  ],
18
18
  "type": "module",
19
- "types": "dist/esm/index.d.ts",
20
- "main": "dist/cjs/index.cjs",
21
- "module": "dist/esm/index.js",
19
+ "types": "dist/index.d.ts",
20
+ "module": "dist/index.js",
22
21
  "exports": {
23
22
  ".": {
24
- "import": {
25
- "types": "./dist/esm/index.d.ts",
26
- "default": "./dist/esm/index.js"
23
+ "solid": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
27
26
  },
28
- "require": {
29
- "types": "./dist/cjs/index.d.cts",
30
- "default": "./dist/cjs/index.cjs"
27
+ "import": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
31
30
  }
32
31
  },
33
32
  "./package.json": "./package.json"
@@ -39,7 +38,7 @@
39
38
  },
40
39
  "dependencies": {
41
40
  "@tanstack/solid-store": "^0.4.1",
42
- "@tanstack/form-core": "0.22.0"
41
+ "@tanstack/form-core": "0.23.0"
43
42
  },
44
43
  "peerDependencies": {
45
44
  "solid-js": "^1.6.0"
package/src/index.ts CHANGED
@@ -1,27 +1,6 @@
1
- export type {
2
- DeepKeys,
3
- DeepValue,
4
- FieldApiOptions,
5
- FieldInfo,
6
- FieldMeta,
7
- FieldOptions,
8
- FieldState,
9
- FormOptions,
10
- FormState,
11
- RequiredByKey,
12
- Updater,
13
- UpdaterFn,
14
- ValidationCause,
15
- ValidationError,
16
- ValidationMeta,
17
- } from '@tanstack/form-core'
18
-
19
- export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core'
1
+ export * from '@tanstack/form-core'
20
2
 
21
3
  export { createForm } from './createForm'
22
4
 
23
5
  export type { CreateField, FieldComponent } from './createField'
24
6
  export { createField, Field } from './createField'
25
-
26
- export type { FormFactory } from './createFormFactory'
27
- export { createFormFactory } from './createFormFactory'
@@ -3,7 +3,7 @@ import { render, waitFor } from '@solidjs/testing-library'
3
3
  import userEvent from '@testing-library/user-event'
4
4
  import '@testing-library/jest-dom/vitest'
5
5
  import { Index, Show, createEffect } from 'solid-js'
6
- import { createForm, createFormFactory } from '../index'
6
+ import { createForm } from '../index'
7
7
  import { sleep } from './utils'
8
8
 
9
9
  const user = userEvent.setup()
@@ -15,10 +15,8 @@ describe('createField', () => {
15
15
  lastName: string
16
16
  }
17
17
 
18
- const formFactory = createFormFactory<Person>()
19
-
20
18
  function Comp() {
21
- const form = formFactory.createForm()
19
+ const form = createForm<Person>()
22
20
 
23
21
  return (
24
22
  <>
@@ -51,10 +49,8 @@ describe('createField', () => {
51
49
  lastName: string
52
50
  }
53
51
 
54
- const formFactory = createFormFactory<Person>()
55
-
56
52
  function Comp() {
57
- const form = formFactory.createForm(() => ({
53
+ const form = createForm<Person>(() => ({
58
54
  defaultValues: {
59
55
  firstName: 'FirstName',
60
56
  lastName: 'LastName',
@@ -93,10 +89,8 @@ describe('createField', () => {
93
89
  }
94
90
  const error = 'Please enter a different value'
95
91
 
96
- const formFactory = createFormFactory<Person>()
97
-
98
92
  function Comp() {
99
- const form = formFactory.createForm()
93
+ const form = createForm<Person>()
100
94
 
101
95
  return (
102
96
  <>
@@ -136,10 +130,8 @@ describe('createField', () => {
136
130
  }
137
131
  const error = 'Please enter a different value'
138
132
 
139
- const formFactory = createFormFactory<Person>()
140
-
141
133
  function Comp() {
142
- const form = formFactory.createForm()
134
+ const form = createForm<Person>()
143
135
 
144
136
  return (
145
137
  <>
@@ -184,10 +176,8 @@ describe('createField', () => {
184
176
  const onChangeError = 'Please enter a different value (onChangeError)'
185
177
  const onBlurError = 'Please enter a different value (onBlurError)'
186
178
 
187
- const formFactory = createFormFactory<Person>()
188
-
189
179
  function Comp() {
190
- const form = formFactory.createForm()
180
+ const form = createForm<Person>()
191
181
 
192
182
  return (
193
183
  <>
@@ -235,10 +225,8 @@ describe('createField', () => {
235
225
  }
236
226
  const error = 'Please enter a different value'
237
227
 
238
- const formFactory = createFormFactory<Person>()
239
-
240
228
  function Comp() {
241
- const form = formFactory.createForm()
229
+ const form = createForm<Person>()
242
230
 
243
231
  return (
244
232
  <>
@@ -284,10 +272,8 @@ describe('createField', () => {
284
272
  const onChangeError = 'Please enter a different value (onChangeError)'
285
273
  const onBlurError = 'Please enter a different value (onBlurError)'
286
274
 
287
- const formFactory = createFormFactory<Person>()
288
-
289
275
  function Comp() {
290
- const form = formFactory.createForm()
276
+ const form = createForm<Person>()
291
277
 
292
278
  return (
293
279
  <>
@@ -342,10 +328,9 @@ describe('createField', () => {
342
328
  }
343
329
  const mockFn = vi.fn()
344
330
  const error = 'Please enter a different value'
345
- const formFactory = createFormFactory<Person>()
346
331
 
347
332
  function Comp() {
348
- const form = formFactory.createForm()
333
+ const form = createForm<Person>()
349
334
 
350
335
  return (
351
336
  <>
@@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest'
2
2
  import { render, screen, waitFor } from '@solidjs/testing-library'
3
3
  import userEvent from '@testing-library/user-event'
4
4
  import { Show, createSignal, onCleanup } from 'solid-js'
5
- import { createForm, createFormFactory } from '../index'
5
+ import { createForm } from '../index'
6
6
  import { sleep } from './utils'
7
7
  import type { ValidationErrorMap } from '@tanstack/form-core'
8
8
 
@@ -15,10 +15,8 @@ describe('createForm', () => {
15
15
  lastName: string
16
16
  }
17
17
 
18
- const formFactory = createFormFactory<Person>()
19
-
20
18
  function Comp() {
21
- const form = formFactory.createForm()
19
+ const form = createForm<Person>()
22
20
  return (
23
21
  <>
24
22
  <form.Field
@@ -50,14 +48,12 @@ describe('createForm', () => {
50
48
  lastName: string
51
49
  }
52
50
 
53
- const formFactory = createFormFactory<Person>()
54
-
55
51
  function Comp() {
56
- const form = formFactory.createForm(() => ({
52
+ const form = createForm(() => ({
57
53
  defaultValues: {
58
54
  firstName: 'FirstName',
59
55
  lastName: 'LastName',
60
- },
56
+ } as Person,
61
57
  }))
62
58
 
63
59
  return (
@@ -159,10 +155,8 @@ describe('createForm', () => {
159
155
  }
160
156
  const error = 'Please enter a different value'
161
157
 
162
- const formFactory = createFormFactory<Person>()
163
-
164
158
  function Comp() {
165
- const form = formFactory.createForm(() => ({
159
+ const form = createForm<Person>(() => ({
166
160
  validators: {
167
161
  onChange: ({ value }) =>
168
162
  value.firstName.includes('other') ? error : undefined,
@@ -205,10 +199,8 @@ describe('createForm', () => {
205
199
  }
206
200
  const error = 'Please enter a different value'
207
201
 
208
- const formFactory = createFormFactory<Person>()
209
-
210
202
  function Comp() {
211
- const form = formFactory.createForm(() => ({
203
+ const form = createForm<Person>(() => ({
212
204
  validators: {
213
205
  onChange: ({ value }) =>
214
206
  value.firstName.includes('other') ? error : undefined,
@@ -257,10 +249,8 @@ describe('createForm', () => {
257
249
  const onChangeError = 'Please enter a different value (onChangeError)'
258
250
  const onBlurError = 'Please enter a different value (onBlurError)'
259
251
 
260
- const formFactory = createFormFactory<Person>()
261
-
262
252
  function Comp() {
263
- const form = formFactory.createForm(() => ({
253
+ const form = createForm<Person>(() => ({
264
254
  validators: {
265
255
  onChange: ({ value }) =>
266
256
  value.firstName.includes('other') ? onChangeError : undefined,
@@ -312,10 +302,8 @@ describe('createForm', () => {
312
302
  }
313
303
  const error = 'Please enter a different value'
314
304
 
315
- const formFactory = createFormFactory<Person>()
316
-
317
305
  function Comp() {
318
- const form = formFactory.createForm(() => ({
306
+ const form = createForm<Person>(() => ({
319
307
  validators: {
320
308
  onChangeAsync: async () => {
321
309
  await sleep(10)
@@ -365,10 +353,8 @@ describe('createForm', () => {
365
353
  const onChangeError = 'Please enter a different value (onChangeError)'
366
354
  const onBlurError = 'Please enter a different value (onBlurError)'
367
355
 
368
- const formFactory = createFormFactory<Person>()
369
-
370
356
  function Comp() {
371
- const form = formFactory.createForm(() => ({
357
+ const form = createForm<Person>(() => ({
372
358
  validators: {
373
359
  async onChangeAsync() {
374
360
  await sleep(10)
@@ -427,10 +413,9 @@ describe('createForm', () => {
427
413
  }
428
414
  const mockFn = vi.fn()
429
415
  const error = 'Please enter a different value'
430
- const formFactory = createFormFactory<Person>()
431
416
 
432
417
  function Comp() {
433
- const form = formFactory.createForm(() => ({
418
+ const form = createForm<Person>(() => ({
434
419
  validators: {
435
420
  onChangeAsyncDebounceMs: 100,
436
421
  onChangeAsync: async () => {
@@ -1,33 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const web = require("solid-js/web");
4
- const formCore = require("@tanstack/form-core");
5
- const solidJs = require("solid-js");
6
- function makeFieldReactive(fieldApi) {
7
- const [flag, setFlag] = solidJs.createSignal(false);
8
- const fieldApiMemo = solidJs.createMemo(() => [flag(), fieldApi]);
9
- const unsubscribeStore = fieldApi.store.subscribe(() => setFlag((f) => !f));
10
- solidJs.onCleanup(unsubscribeStore);
11
- return () => fieldApiMemo()[1];
12
- }
13
- function createField(opts) {
14
- const options = opts();
15
- const fieldApi = new formCore.FieldApi(options);
16
- fieldApi.Field = Field;
17
- solidJs.createComputed(() => fieldApi.update(opts()));
18
- solidJs.onMount(() => solidJs.onCleanup(fieldApi.mount()));
19
- return makeFieldReactive(fieldApi);
20
- }
21
- function Field(props) {
22
- const fieldApi = createField(() => {
23
- const {
24
- children,
25
- ...fieldOptions
26
- } = props;
27
- return fieldOptions;
28
- });
29
- return web.memo(() => solidJs.createComponent(() => props.children(fieldApi), {}));
30
- }
31
- exports.Field = Field;
32
- exports.createField = createField;
33
- //# sourceMappingURL=createField.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createField.cjs","sources":["../../src/createField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport {\n createComponent,\n createComputed,\n createMemo,\n createSignal,\n onCleanup,\n onMount,\n} from 'solid-js'\n\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\nimport type { JSXElement } from 'solid-js'\nimport type { CreateFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type CreateField<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: () => { name: Narrow<TName> } & Omit<\n CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n >,\n) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n// ugly way to trick solid into triggering updates for changes on the fieldApi\nfunction makeFieldReactive<FieldApiT extends FieldApi<any, any, any, any>>(\n fieldApi: FieldApiT,\n): () => FieldApiT {\n const [flag, setFlag] = createSignal(false)\n const fieldApiMemo = createMemo(() => [flag(), fieldApi] as const)\n const unsubscribeStore = fieldApi.store.subscribe(() => setFlag((f) => !f))\n onCleanup(unsubscribeStore)\n return () => fieldApiMemo()[1]\n}\n\nexport function createField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: () => CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {\n const options = opts()\n\n const fieldApi = new FieldApi(options)\n fieldApi.Field = Field as never\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n *\n * createComputed to make sure this effect runs before render effects\n */\n createComputed(() => fieldApi.update(opts()))\n\n // Instantiates field meta and removes it when unrendered\n onMount(() => onCleanup(fieldApi.mount()))\n\n return makeFieldReactive(fieldApi) as never\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: () => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => JSXElement\n} & Omit<\n CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>\n\nexport type FieldComponent<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>) => JSXElement\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n props: {\n children: (\n fieldApi: () => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => JSXElement\n } & CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n) {\n const fieldApi = createField<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >(() => {\n const { children, ...fieldOptions } = props\n return fieldOptions\n })\n\n return <>{createComponent(() => props.children(fieldApi), {})}</>\n}\n"],"names":["makeFieldReactive","fieldApi","flag","setFlag","createSignal","fieldApiMemo","createMemo","unsubscribeStore","store","subscribe","f","onCleanup","createField","opts","options","FieldApi","Field","createComputed","update","onMount","mount","props","children","fieldOptions","_$memo","createComponent"],"mappings":";;;;;AA6DA,SAASA,kBACPC,UACiB;AACjB,QAAM,CAACC,MAAMC,OAAO,IAAIC,qBAAa,KAAK;AAC1C,QAAMC,eAAeC,QAAAA,WAAW,MAAM,CAACJ,KAAK,GAAGD,QAAQ,CAAW;AAC5DM,QAAAA,mBAAmBN,SAASO,MAAMC,UAAU,MAAMN,QAASO,CAAAA,MAAM,CAACA,CAAC,CAAC;AAC1EC,UAAAA,UAAUJ,gBAAgB;AACnB,SAAA,MAAMF,eAAe,CAAC;AAC/B;AAEO,SAASO,YAWdC,MAO4E;AAC5E,QAAMC,UAAUD;AAEVZ,QAAAA,WAAW,IAAIc,kBAASD,OAAO;AACrCb,WAASe,QAAQA;AAQjBC,UAAAA,eAAe,MAAMhB,SAASiB,OAAOL,KAAAA,CAAM,CAAC;AAG5CM,UAAAA,QAAQ,MAAMR,QAAAA,UAAUV,SAASmB,MAAAA,CAAO,CAAC;AAEzC,SAAOpB,kBAAkBC,QAAQ;AACnC;AA0DO,SAASe,MAWdK,OAiBA;AACMpB,QAAAA,WAAWW,YAMf,MAAM;AACA,UAAA;AAAA,MAAEU;AAAAA,MAAU,GAAGC;AAAAA,IAAiBF,IAAAA;AAC/BE,WAAAA;AAAAA,EAAAA,CACR;AAEDC,SAAAA,IAAAA,KAAA,MAAUC,QAAAA,gBAAgB,MAAMJ,MAAMC,SAASrB,QAAQ,GAAG,CAAE,CAAA,CAAC;AAC/D;;;"}
@@ -1,21 +0,0 @@
1
- import { FieldApi, DeepKeys, DeepValue, Narrow, Validator } from '@tanstack/form-core';
2
- import { JSXElement } from 'solid-js';
3
- import { CreateFieldOptions } from './types.cjs';
4
-
5
- declare module '@tanstack/form-core' {
6
- interface FieldApi<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> {
7
- Field: FieldComponent<TParentData, TFormValidator>;
8
- }
9
- }
10
- export type CreateField<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>(opts: () => {
11
- name: Narrow<TName>;
12
- } & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
13
- export declare function createField<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>(opts: () => CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
14
- type FieldComponentProps<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = {
15
- children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
16
- } & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>;
17
- export type FieldComponent<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined> = <TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>({ children, ...fieldOptions }: Omit<FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>) => JSXElement;
18
- export declare function Field<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>>(props: {
19
- children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
20
- } & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>): import("solid-js").JSX.Element;
21
- export {};
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const web = require("solid-js/web");
4
- const formCore = require("@tanstack/form-core");
5
- const solidJs = require("solid-js");
6
- const solidStore = require("@tanstack/solid-store");
7
- const createField = require("./createField.cjs");
8
- function createForm(opts) {
9
- const options = opts == null ? void 0 : opts();
10
- const formApi = new formCore.FormApi(options);
11
- formApi.Field = (props) => web.createComponent(createField.Field, web.mergeProps(props, {
12
- form: formApi
13
- }));
14
- formApi.createField = (props) => createField.createField(() => {
15
- return {
16
- ...props(),
17
- form: formApi
18
- };
19
- });
20
- formApi.useStore = (selector) => solidStore.useStore(formApi.store, selector);
21
- formApi.Subscribe = (props) => formCore.functionalUpdate(props.children, solidStore.useStore(formApi.store, props.selector));
22
- solidJs.onMount(formApi.mount);
23
- solidJs.createComputed(() => formApi.update(opts == null ? void 0 : opts()));
24
- return formApi;
25
- }
26
- exports.createForm = createForm;
27
- //# sourceMappingURL=createForm.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createForm.cjs","sources":["../../src/createForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { type JSXElement, createComputed, onMount } from 'solid-js'\nimport { useStore } from '@tanstack/solid-store'\nimport {\n type CreateField,\n Field,\n type FieldComponent,\n createField,\n} from './createField'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ntype NoInfer<T> = [T][T extends any ? 0 : never]\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n createField: CreateField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => () => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement\n }) => JSXElement\n }\n}\n\nexport function createForm<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts?: () => FormOptions<TParentData, TFormValidator>,\n): FormApi<TParentData, TFormValidator> {\n const options = opts?.()\n const formApi = new FormApi<TParentData, TFormValidator>(options)\n\n formApi.Field = (props) => <Field {...props} form={formApi} />\n formApi.createField = (props) =>\n createField(() => {\n return { ...props(), form: formApi }\n })\n formApi.useStore = (selector) => useStore(formApi.store, selector)\n formApi.Subscribe = (props) =>\n functionalUpdate(props.children, useStore(formApi.store, props.selector))\n\n onMount(formApi.mount)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n createComputed(() => formApi.update(opts?.()))\n\n return formApi\n}\n"],"names":["createForm","opts","options","formApi","FormApi","Field","props","_$createComponent","_$mergeProps","form","createField","useStore","selector","store","Subscribe","functionalUpdate","children","onMount","mount","createComputed","update"],"mappings":";;;;;;;AA4BO,SAASA,WAMdC,MACsC;AACtC,QAAMC,UAAUD;AACVE,QAAAA,UAAU,IAAIC,iBAAqCF,OAAO;AAEhEC,UAAQE,QAASC,CAAAA,UAAKC,IAAMF,gBAAAA,YAAAA,OAAKG,eAAKF,OAAK;AAAA,IAAEG,MAAMN;AAAAA,EAAW,CAAA,CAAA;AACtDO,UAAAA,cAAeJ,CACrBI,UAAAA,YAAAA,YAAY,MAAM;AACT,WAAA;AAAA,MAAE,GAAGJ,MAAM;AAAA,MAAGG,MAAMN;AAAAA,IAAAA;AAAAA,EAAQ,CACpC;AACHA,UAAQQ,WAAYC,CAAAA,aAAaD,WAASR,SAAAA,QAAQU,OAAOD,QAAQ;AACzDE,UAAAA,YAAaR,CACnBS,UAAAA,SAAAA,iBAAiBT,MAAMU,UAAUL,oBAASR,QAAQU,OAAOP,MAAMM,QAAQ,CAAC;AAE1EK,kBAAQd,QAAQe,KAAK;AAMrBC,UAAAA,eAAe,MAAMhB,QAAQiB,OAAOnB,8BAAQ,CAAC;AAEtCE,SAAAA;AACT;;"}
@@ -1,18 +0,0 @@
1
- import { FormApi, FormOptions, FormState, Validator } from '@tanstack/form-core';
2
- import { JSXElement } from 'solid-js';
3
- import { CreateField, FieldComponent } from './createField.cjs';
4
-
5
- type NoInfer<T> = [T][T extends any ? 0 : never];
6
- declare module '@tanstack/form-core' {
7
- interface FormApi<TFormData, TFormValidator> {
8
- Field: FieldComponent<TFormData, TFormValidator>;
9
- createField: CreateField<TFormData, TFormValidator>;
10
- useStore: <TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected) => () => TSelected;
11
- Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
12
- selector?: (state: NoInfer<FormState<TFormData>>) => TSelected;
13
- children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement;
14
- }) => JSXElement;
15
- }
16
- }
17
- export declare function createForm<TParentData, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined>(opts?: () => FormOptions<TParentData, TFormValidator>): FormApi<TParentData, TFormValidator>;
18
- export {};
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const solidJs = require("solid-js");
4
- const createField = require("./createField.cjs");
5
- const createForm = require("./createForm.cjs");
6
- function createFormFactory(defaultOpts) {
7
- return {
8
- createForm: (opts) => createForm.createForm(
9
- () => solidJs.mergeProps((defaultOpts == null ? void 0 : defaultOpts()) ?? {}, (opts == null ? void 0 : opts()) ?? {})
10
- ),
11
- createField: createField.createField,
12
- Field: createField.Field
13
- };
14
- }
15
- exports.createFormFactory = createFormFactory;
16
- //# sourceMappingURL=createFormFactory.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createFormFactory.cjs","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { mergeProps } from 'solid-js'\nimport {\n type CreateField,\n Field,\n type FieldComponent,\n createField,\n} from './createField'\nimport { createForm } from './createForm'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n createForm: (\n opts?: () => FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n createField: typeof createField\n Field: typeof Field\n}\n\nexport function createFormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: () => FormOptions<TFormData, TFormValidator>,\n): FormFactory<TFormData, TFormValidator> {\n return {\n createForm: (opts) =>\n createForm<TFormData, TFormValidator>(() =>\n mergeProps(defaultOpts?.() ?? {}, opts?.() ?? {}),\n ),\n createField,\n Field: Field,\n }\n}\n"],"names":["createForm","mergeProps","createField","Field"],"mappings":";;;;;AAqBO,SAAS,kBAId,aACwC;AACjC,SAAA;AAAA,IACL,YAAY,CAAC,SACXA,WAAA;AAAA,MAAsC,MACpCC,QAAAA,YAAW,iDAAmB,CAAI,IAAA,mCAAY,CAAA,CAAE;AAAA,IAClD;AAAA,IAAA,aACFC,YAAA;AAAA,IAAA,OACAC,YAAA;AAAA,EAAA;AAEJ;;"}
@@ -1,9 +0,0 @@
1
- import { Field, createField } from './createField.cjs';
2
- import { FormApi, FormOptions, Validator } from '@tanstack/form-core';
3
-
4
- export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
5
- createForm: (opts?: () => FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
6
- createField: typeof createField;
7
- Field: typeof Field;
8
- };
9
- export declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: () => FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const formCore = require("@tanstack/form-core");
4
- const createForm = require("./createForm.cjs");
5
- const createField = require("./createField.cjs");
6
- const createFormFactory = require("./createFormFactory.cjs");
7
- Object.defineProperty(exports, "FieldApi", {
8
- enumerable: true,
9
- get: () => formCore.FieldApi
10
- });
11
- Object.defineProperty(exports, "FormApi", {
12
- enumerable: true,
13
- get: () => formCore.FormApi
14
- });
15
- Object.defineProperty(exports, "functionalUpdate", {
16
- enumerable: true,
17
- get: () => formCore.functionalUpdate
18
- });
19
- exports.createForm = createForm.createForm;
20
- exports.Field = createField.Field;
21
- exports.createField = createField.createField;
22
- exports.createFormFactory = createFormFactory.createFormFactory;
23
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +0,0 @@
1
- export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
2
- export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core';
3
- export { createForm } from './createForm.cjs';
4
- export type { CreateField, FieldComponent } from './createField.cjs';
5
- export { createField, Field } from './createField.cjs';
6
- export type { FormFactory } from './createFormFactory.cjs';
7
- export { createFormFactory } from './createFormFactory.cjs';
@@ -1,5 +0,0 @@
1
- import { DeepKeys, DeepValue, FieldApiOptions, Validator } from '@tanstack/form-core';
2
-
3
- export type CreateFieldOptions<TParentData, TName extends DeepKeys<TParentData>, TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined, TFormValidator extends Validator<TParentData, unknown> | undefined = undefined, TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>> = FieldApiOptions<TParentData, TName, TFieldValidator, TFormValidator, TData> & {
4
- mode?: 'value' | 'array';
5
- };
@@ -1,33 +0,0 @@
1
- import { memo } from "solid-js/web";
2
- import { FieldApi } from "@tanstack/form-core";
3
- import { createComputed, onMount, onCleanup, createComponent, createSignal, createMemo } from "solid-js";
4
- function makeFieldReactive(fieldApi) {
5
- const [flag, setFlag] = createSignal(false);
6
- const fieldApiMemo = createMemo(() => [flag(), fieldApi]);
7
- const unsubscribeStore = fieldApi.store.subscribe(() => setFlag((f) => !f));
8
- onCleanup(unsubscribeStore);
9
- return () => fieldApiMemo()[1];
10
- }
11
- function createField(opts) {
12
- const options = opts();
13
- const fieldApi = new FieldApi(options);
14
- fieldApi.Field = Field;
15
- createComputed(() => fieldApi.update(opts()));
16
- onMount(() => onCleanup(fieldApi.mount()));
17
- return makeFieldReactive(fieldApi);
18
- }
19
- function Field(props) {
20
- const fieldApi = createField(() => {
21
- const {
22
- children,
23
- ...fieldOptions
24
- } = props;
25
- return fieldOptions;
26
- });
27
- return memo(() => createComponent(() => props.children(fieldApi), {}));
28
- }
29
- export {
30
- Field,
31
- createField
32
- };
33
- //# sourceMappingURL=createField.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createField.js","sources":["../../src/createField.tsx"],"sourcesContent":["import { FieldApi } from '@tanstack/form-core'\nimport {\n createComponent,\n createComputed,\n createMemo,\n createSignal,\n onCleanup,\n onMount,\n} from 'solid-js'\n\nimport type {\n DeepKeys,\n DeepValue,\n Narrow,\n Validator,\n} from '@tanstack/form-core'\nimport type { JSXElement } from 'solid-js'\nimport type { CreateFieldOptions } from './types'\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n > {\n Field: FieldComponent<TParentData, TFormValidator>\n }\n}\n\nexport type CreateField<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: () => { name: Narrow<TName> } & Omit<\n CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n >,\n) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n\n// ugly way to trick solid into triggering updates for changes on the fieldApi\nfunction makeFieldReactive<FieldApiT extends FieldApi<any, any, any, any>>(\n fieldApi: FieldApiT,\n): () => FieldApiT {\n const [flag, setFlag] = createSignal(false)\n const fieldApiMemo = createMemo(() => [flag(), fieldApi] as const)\n const unsubscribeStore = fieldApi.store.subscribe(() => setFlag((f) => !f))\n onCleanup(unsubscribeStore)\n return () => fieldApiMemo()[1]\n}\n\nexport function createField<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n opts: () => CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {\n const options = opts()\n\n const fieldApi = new FieldApi(options)\n fieldApi.Field = Field as never\n\n /**\n * fieldApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n *\n * createComputed to make sure this effect runs before render effects\n */\n createComputed(() => fieldApi.update(opts()))\n\n // Instantiates field meta and removes it when unrendered\n onMount(() => onCleanup(fieldApi.mount()))\n\n return makeFieldReactive(fieldApi) as never\n}\n\ntype FieldComponentProps<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = {\n children: (\n fieldApi: () => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => JSXElement\n} & Omit<\n CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>\n\nexport type FieldComponent<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n> = <\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>({\n children,\n ...fieldOptions\n}: Omit<\n FieldComponentProps<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n 'form'\n>) => JSXElement\n\nexport function Field<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n>(\n props: {\n children: (\n fieldApi: () => FieldApi<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => JSXElement\n } & CreateFieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n) {\n const fieldApi = createField<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >(() => {\n const { children, ...fieldOptions } = props\n return fieldOptions\n })\n\n return <>{createComponent(() => props.children(fieldApi), {})}</>\n}\n"],"names":["makeFieldReactive","fieldApi","flag","setFlag","createSignal","fieldApiMemo","createMemo","unsubscribeStore","store","subscribe","f","onCleanup","createField","opts","options","FieldApi","Field","createComputed","update","onMount","mount","props","children","fieldOptions","_$memo","createComponent"],"mappings":";;;AA6DA,SAASA,kBACPC,UACiB;AACjB,QAAM,CAACC,MAAMC,OAAO,IAAIC,aAAa,KAAK;AAC1C,QAAMC,eAAeC,WAAW,MAAM,CAACJ,KAAK,GAAGD,QAAQ,CAAW;AAC5DM,QAAAA,mBAAmBN,SAASO,MAAMC,UAAU,MAAMN,QAASO,CAAAA,MAAM,CAACA,CAAC,CAAC;AAC1EC,YAAUJ,gBAAgB;AACnB,SAAA,MAAMF,eAAe,CAAC;AAC/B;AAEO,SAASO,YAWdC,MAO4E;AAC5E,QAAMC,UAAUD;AAEVZ,QAAAA,WAAW,IAAIc,SAASD,OAAO;AACrCb,WAASe,QAAQA;AAQjBC,iBAAe,MAAMhB,SAASiB,OAAOL,KAAAA,CAAM,CAAC;AAG5CM,UAAQ,MAAMR,UAAUV,SAASmB,MAAAA,CAAO,CAAC;AAEzC,SAAOpB,kBAAkBC,QAAQ;AACnC;AA0DO,SAASe,MAWdK,OAiBA;AACMpB,QAAAA,WAAWW,YAMf,MAAM;AACA,UAAA;AAAA,MAAEU;AAAAA,MAAU,GAAGC;AAAAA,IAAiBF,IAAAA;AAC/BE,WAAAA;AAAAA,EAAAA,CACR;AAEDC,SAAAA,KAAA,MAAUC,gBAAgB,MAAMJ,MAAMC,SAASrB,QAAQ,GAAG,CAAE,CAAA,CAAC;AAC/D;"}
@@ -1,27 +0,0 @@
1
- import { createComponent, mergeProps } from "solid-js/web";
2
- import { FormApi, functionalUpdate } from "@tanstack/form-core";
3
- import { onMount, createComputed } from "solid-js";
4
- import { useStore } from "@tanstack/solid-store";
5
- import { Field, createField } from "./createField.js";
6
- function createForm(opts) {
7
- const options = opts == null ? void 0 : opts();
8
- const formApi = new FormApi(options);
9
- formApi.Field = (props) => createComponent(Field, mergeProps(props, {
10
- form: formApi
11
- }));
12
- formApi.createField = (props) => createField(() => {
13
- return {
14
- ...props(),
15
- form: formApi
16
- };
17
- });
18
- formApi.useStore = (selector) => useStore(formApi.store, selector);
19
- formApi.Subscribe = (props) => functionalUpdate(props.children, useStore(formApi.store, props.selector));
20
- onMount(formApi.mount);
21
- createComputed(() => formApi.update(opts == null ? void 0 : opts()));
22
- return formApi;
23
- }
24
- export {
25
- createForm
26
- };
27
- //# sourceMappingURL=createForm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createForm.js","sources":["../../src/createForm.tsx"],"sourcesContent":["import { FormApi, functionalUpdate } from '@tanstack/form-core'\nimport { type JSXElement, createComputed, onMount } from 'solid-js'\nimport { useStore } from '@tanstack/solid-store'\nimport {\n type CreateField,\n Field,\n type FieldComponent,\n createField,\n} from './createField'\nimport type { FormOptions, FormState, Validator } from '@tanstack/form-core'\n\ntype NoInfer<T> = [T][T extends any ? 0 : never]\n\ndeclare module '@tanstack/form-core' {\n // eslint-disable-next-line no-shadow\n interface FormApi<TFormData, TFormValidator> {\n Field: FieldComponent<TFormData, TFormValidator>\n createField: CreateField<TFormData, TFormValidator>\n useStore: <TSelected = NoInfer<FormState<TFormData>>>(\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,\n ) => () => TSelected\n Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {\n selector?: (state: NoInfer<FormState<TFormData>>) => TSelected\n children: ((state: () => NoInfer<TSelected>) => JSXElement) | JSXElement\n }) => JSXElement\n }\n}\n\nexport function createForm<\n TParentData,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n>(\n opts?: () => FormOptions<TParentData, TFormValidator>,\n): FormApi<TParentData, TFormValidator> {\n const options = opts?.()\n const formApi = new FormApi<TParentData, TFormValidator>(options)\n\n formApi.Field = (props) => <Field {...props} form={formApi} />\n formApi.createField = (props) =>\n createField(() => {\n return { ...props(), form: formApi }\n })\n formApi.useStore = (selector) => useStore(formApi.store, selector)\n formApi.Subscribe = (props) =>\n functionalUpdate(props.children, useStore(formApi.store, props.selector))\n\n onMount(formApi.mount)\n\n /**\n * formApi.update should not have any side effects. Think of it like a `useRef`\n * that we need to keep updated every render with the most up-to-date information.\n */\n createComputed(() => formApi.update(opts?.()))\n\n return formApi\n}\n"],"names":["createForm","opts","options","formApi","FormApi","Field","props","_$createComponent","_$mergeProps","form","createField","useStore","selector","store","Subscribe","functionalUpdate","children","onMount","mount","createComputed","update"],"mappings":";;;;;AA4BO,SAASA,WAMdC,MACsC;AACtC,QAAMC,UAAUD;AACVE,QAAAA,UAAU,IAAIC,QAAqCF,OAAO;AAEhEC,UAAQE,QAASC,CAAAA,UAAKC,gBAAMF,OAAKG,WAAKF,OAAK;AAAA,IAAEG,MAAMN;AAAAA,EAAW,CAAA,CAAA;AACtDO,UAAAA,cAAeJ,CACrBI,UAAAA,YAAY,MAAM;AACT,WAAA;AAAA,MAAE,GAAGJ,MAAM;AAAA,MAAGG,MAAMN;AAAAA,IAAAA;AAAAA,EAAQ,CACpC;AACHA,UAAQQ,WAAYC,CAAAA,aAAaD,SAASR,QAAQU,OAAOD,QAAQ;AACzDE,UAAAA,YAAaR,CACnBS,UAAAA,iBAAiBT,MAAMU,UAAUL,SAASR,QAAQU,OAAOP,MAAMM,QAAQ,CAAC;AAE1EK,UAAQd,QAAQe,KAAK;AAMrBC,iBAAe,MAAMhB,QAAQiB,OAAOnB,8BAAQ,CAAC;AAEtCE,SAAAA;AACT;"}
@@ -1,9 +0,0 @@
1
- import { Field, createField } from './createField.js';
2
- import { FormApi, FormOptions, Validator } from '@tanstack/form-core';
3
-
4
- export type FormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined> = {
5
- createForm: (opts?: () => FormOptions<TFormData, TFormValidator>) => FormApi<TFormData, TFormValidator>;
6
- createField: typeof createField;
7
- Field: typeof Field;
8
- };
9
- export declare function createFormFactory<TFormData, TFormValidator extends Validator<TFormData, unknown> | undefined = undefined>(defaultOpts?: () => FormOptions<TFormData, TFormValidator>): FormFactory<TFormData, TFormValidator>;
@@ -1,16 +0,0 @@
1
- import { mergeProps } from "solid-js";
2
- import { createField, Field } from "./createField.js";
3
- import { createForm } from "./createForm.js";
4
- function createFormFactory(defaultOpts) {
5
- return {
6
- createForm: (opts) => createForm(
7
- () => mergeProps((defaultOpts == null ? void 0 : defaultOpts()) ?? {}, (opts == null ? void 0 : opts()) ?? {})
8
- ),
9
- createField,
10
- Field
11
- };
12
- }
13
- export {
14
- createFormFactory
15
- };
16
- //# sourceMappingURL=createFormFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createFormFactory.js","sources":["../../src/createFormFactory.ts"],"sourcesContent":["import { mergeProps } from 'solid-js'\nimport {\n type CreateField,\n Field,\n type FieldComponent,\n createField,\n} from './createField'\nimport { createForm } from './createForm'\nimport type { FormApi, FormOptions, Validator } from '@tanstack/form-core'\n\nexport type FormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n createForm: (\n opts?: () => FormOptions<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n createField: typeof createField\n Field: typeof Field\n}\n\nexport function createFormFactory<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n>(\n defaultOpts?: () => FormOptions<TFormData, TFormValidator>,\n): FormFactory<TFormData, TFormValidator> {\n return {\n createForm: (opts) =>\n createForm<TFormData, TFormValidator>(() =>\n mergeProps(defaultOpts?.() ?? {}, opts?.() ?? {}),\n ),\n createField,\n Field: Field,\n }\n}\n"],"names":[],"mappings":";;;AAqBO,SAAS,kBAId,aACwC;AACjC,SAAA;AAAA,IACL,YAAY,CAAC,SACX;AAAA,MAAsC,MACpC,YAAW,iDAAmB,CAAI,IAAA,mCAAY,CAAA,CAAE;AAAA,IAClD;AAAA,IACF;AAAA,IACA;AAAA,EAAA;AAEJ;"}
@@ -1,7 +0,0 @@
1
- export type { DeepKeys, DeepValue, FieldApiOptions, FieldInfo, FieldMeta, FieldOptions, FieldState, FormOptions, FormState, RequiredByKey, Updater, UpdaterFn, ValidationCause, ValidationError, ValidationMeta, } from '@tanstack/form-core';
2
- export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core';
3
- export { createForm } from './createForm.js';
4
- export type { CreateField, FieldComponent } from './createField.js';
5
- export { createField, Field } from './createField.js';
6
- export type { FormFactory } from './createFormFactory.js';
7
- export { createFormFactory } from './createFormFactory.js';
package/dist/esm/index.js DELETED
@@ -1,14 +0,0 @@
1
- import { FieldApi, FormApi, functionalUpdate } from "@tanstack/form-core";
2
- import { createForm } from "./createForm.js";
3
- import { Field, createField } from "./createField.js";
4
- import { createFormFactory } from "./createFormFactory.js";
5
- export {
6
- Field,
7
- FieldApi,
8
- FormApi,
9
- createField,
10
- createForm,
11
- createFormFactory,
12
- functionalUpdate
13
- };
14
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,36 +0,0 @@
1
- import { mergeProps } from 'solid-js'
2
- import {
3
- type CreateField,
4
- Field,
5
- type FieldComponent,
6
- createField,
7
- } from './createField'
8
- import { createForm } from './createForm'
9
- import type { FormApi, FormOptions, Validator } from '@tanstack/form-core'
10
-
11
- export type FormFactory<
12
- TFormData,
13
- TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
14
- > = {
15
- createForm: (
16
- opts?: () => FormOptions<TFormData, TFormValidator>,
17
- ) => FormApi<TFormData, TFormValidator>
18
- createField: typeof createField
19
- Field: typeof Field
20
- }
21
-
22
- export function createFormFactory<
23
- TFormData,
24
- TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,
25
- >(
26
- defaultOpts?: () => FormOptions<TFormData, TFormValidator>,
27
- ): FormFactory<TFormData, TFormValidator> {
28
- return {
29
- createForm: (opts) =>
30
- createForm<TFormData, TFormValidator>(() =>
31
- mergeProps(defaultOpts?.() ?? {}, opts?.() ?? {}),
32
- ),
33
- createField,
34
- Field: Field,
35
- }
36
- }
@@ -1,38 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { render } from '@solidjs/testing-library'
3
- import { createFormFactory } from '../index'
4
-
5
- describe('createFormFactory', () => {
6
- it('should allow default values to be set', async () => {
7
- type Person = {
8
- firstName: string
9
- lastName: string
10
- }
11
-
12
- const formFactory = createFormFactory<Person>(() => ({
13
- defaultValues: {
14
- firstName: 'FirstName',
15
- lastName: 'LastName',
16
- },
17
- }))
18
-
19
- function Comp() {
20
- const form = formFactory.createForm()
21
-
22
- return (
23
- <>
24
- <form.Field
25
- name="firstName"
26
- children={(field) => {
27
- return <p>{field().state.value}</p>
28
- }}
29
- />
30
- </>
31
- )
32
- }
33
-
34
- const { findByText, queryByText } = render(() => <Comp />)
35
- expect(await findByText('FirstName')).toBeInTheDocument()
36
- expect(queryByText('LastName')).not.toBeInTheDocument()
37
- })
38
- })