@tanstack/solid-form 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
-
|
5
|
+
Signals for managing form state in Solid
|
6
6
|
|
7
7
|
<a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent">
|
8
8
|
<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack">
|
@@ -1 +1 @@
|
|
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>(\n opts: () => { name: Narrow<TName> } & Omit<\n CreateFieldOptions
|
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;;;"}
|
@@ -7,15 +7,15 @@ declare module '@tanstack/form-core' {
|
|
7
7
|
Field: FieldComponent<TParentData, TFormValidator>;
|
8
8
|
}
|
9
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>(opts: () => {
|
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
11
|
name: Narrow<TName>;
|
12
|
-
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator,
|
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>(opts: () => CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
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
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
15
|
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
16
|
-
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>;
|
16
|
+
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>;
|
17
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>(props: {
|
19
|
-
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => JSXElement;
|
20
|
-
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): import("solid-js").JSX.Element;
|
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
21
|
export {};
|
@@ -7,15 +7,15 @@ declare module '@tanstack/form-core' {
|
|
7
7
|
Field: FieldComponent<TParentData, TFormValidator>;
|
8
8
|
}
|
9
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>(opts: () => {
|
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
11
|
name: Narrow<TName>;
|
12
|
-
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator,
|
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>(opts: () => CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>;
|
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
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
15
|
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>) => JSXElement;
|
16
|
-
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>, 'form'>;
|
16
|
+
} & Omit<CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator, TData>, 'form'>;
|
17
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>(props: {
|
19
|
-
children: (fieldApi: () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator>) => JSXElement;
|
20
|
-
} & CreateFieldOptions<TParentData, TName, TFieldValidator, TFormValidator>): import("solid-js").JSX.Element;
|
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
21
|
export {};
|
@@ -1 +1 @@
|
|
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>(\n opts: () => { name: Narrow<TName> } & Omit<\n CreateFieldOptions
|
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;"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tanstack/solid-form",
|
3
|
-
"version": "0.16.
|
3
|
+
"version": "0.16.2",
|
4
4
|
"description": "Powerful, type-safe forms for Solid.",
|
5
5
|
"author": "tannerlinsley",
|
6
6
|
"license": "MIT",
|
@@ -38,7 +38,7 @@
|
|
38
38
|
},
|
39
39
|
"dependencies": {
|
40
40
|
"@tanstack/solid-store": "^0.3.1",
|
41
|
-
"@tanstack/form-core": "0.16.
|
41
|
+
"@tanstack/form-core": "0.16.2"
|
42
42
|
},
|
43
43
|
"peerDependencies": {
|
44
44
|
"solid-js": "^1.6.0"
|
@@ -49,7 +49,9 @@
|
|
49
49
|
"test:types:versions49": "node ../../node_modules/typescript49/lib/tsc.js --project tsconfig.legacy.json",
|
50
50
|
"test:types:versions50": "node ../../node_modules/typescript50/lib/tsc.js",
|
51
51
|
"test:types:versions51": "node ../../node_modules/typescript51/lib/tsc.js",
|
52
|
-
"test:types:versions52": "tsc",
|
52
|
+
"test:types:versions52": "node ../../node_modules/typescript52/lib/tsc.js",
|
53
|
+
"test:types:versions53": "node ../../node_modules/typescript53/lib/tsc.js",
|
54
|
+
"test:types:versions54": "tsc",
|
53
55
|
"test:types": "pnpm run \"/^test:types:versions.*/\"",
|
54
56
|
"test:lib": "vitest",
|
55
57
|
"test:lib:dev": "pnpm run test:lib --watch",
|
package/src/createField.tsx
CHANGED
@@ -44,18 +44,19 @@ export type CreateField<
|
|
44
44
|
TFieldValidator extends
|
45
45
|
| Validator<DeepValue<TParentData, TName>, unknown>
|
46
46
|
| undefined = undefined,
|
47
|
+
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
47
48
|
>(
|
48
49
|
opts: () => { name: Narrow<TName> } & Omit<
|
49
|
-
CreateFieldOptions<
|
50
|
+
CreateFieldOptions<
|
51
|
+
TParentData,
|
52
|
+
TName,
|
53
|
+
TFieldValidator,
|
54
|
+
TFormValidator,
|
55
|
+
TData
|
56
|
+
>,
|
50
57
|
'form'
|
51
58
|
>,
|
52
|
-
) => () => FieldApi<
|
53
|
-
TParentData,
|
54
|
-
TName,
|
55
|
-
TFieldValidator,
|
56
|
-
TFormValidator,
|
57
|
-
DeepValue<TParentData, TName>
|
58
|
-
>
|
59
|
+
) => () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>
|
59
60
|
|
60
61
|
// ugly way to trick solid into triggering updates for changes on the fieldApi
|
61
62
|
function makeFieldReactive<FieldApiT extends FieldApi<any, any, any, any>>(
|
@@ -77,14 +78,16 @@ export function createField<
|
|
77
78
|
TFormValidator extends
|
78
79
|
| Validator<TParentData, unknown>
|
79
80
|
| undefined = undefined,
|
81
|
+
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
80
82
|
>(
|
81
83
|
opts: () => CreateFieldOptions<
|
82
84
|
TParentData,
|
83
85
|
TName,
|
84
86
|
TFieldValidator,
|
85
|
-
TFormValidator
|
87
|
+
TFormValidator,
|
88
|
+
TData
|
86
89
|
>,
|
87
|
-
): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator> {
|
90
|
+
): () => FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData> {
|
88
91
|
const options = opts()
|
89
92
|
|
90
93
|
const fieldApi = new FieldApi(options)
|
@@ -125,7 +128,13 @@ type FieldComponentProps<
|
|
125
128
|
>,
|
126
129
|
) => JSXElement
|
127
130
|
} & Omit<
|
128
|
-
CreateFieldOptions<
|
131
|
+
CreateFieldOptions<
|
132
|
+
TParentData,
|
133
|
+
TName,
|
134
|
+
TFieldValidator,
|
135
|
+
TFormValidator,
|
136
|
+
TData
|
137
|
+
>,
|
129
138
|
'form'
|
130
139
|
>
|
131
140
|
|
@@ -163,6 +172,7 @@ export function Field<
|
|
163
172
|
TFormValidator extends
|
164
173
|
| Validator<TParentData, unknown>
|
165
174
|
| undefined = undefined,
|
175
|
+
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
|
166
176
|
>(
|
167
177
|
props: {
|
168
178
|
children: (
|
@@ -170,16 +180,24 @@ export function Field<
|
|
170
180
|
TParentData,
|
171
181
|
TName,
|
172
182
|
TFieldValidator,
|
173
|
-
TFormValidator
|
183
|
+
TFormValidator,
|
184
|
+
TData
|
174
185
|
>,
|
175
186
|
) => JSXElement
|
176
|
-
} & CreateFieldOptions<
|
187
|
+
} & CreateFieldOptions<
|
188
|
+
TParentData,
|
189
|
+
TName,
|
190
|
+
TFieldValidator,
|
191
|
+
TFormValidator,
|
192
|
+
TData
|
193
|
+
>,
|
177
194
|
) {
|
178
195
|
const fieldApi = createField<
|
179
196
|
TParentData,
|
180
197
|
TName,
|
181
198
|
TFieldValidator,
|
182
|
-
TFormValidator
|
199
|
+
TFormValidator,
|
200
|
+
TData
|
183
201
|
>(() => {
|
184
202
|
const { children, ...fieldOptions } = props
|
185
203
|
return fieldOptions
|
@@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest'
|
|
2
2
|
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
|
-
import { Index, Show } from 'solid-js'
|
5
|
+
import { Index, Show, createEffect } from 'solid-js'
|
6
6
|
import { createForm, createFormFactory } from '../index'
|
7
7
|
import { sleep } from './utils'
|
8
8
|
|
@@ -386,6 +386,99 @@ describe('createField', () => {
|
|
386
386
|
expect(getByText(error)).toBeInTheDocument()
|
387
387
|
})
|
388
388
|
|
389
|
+
it('should handle arrays with primitive values', async () => {
|
390
|
+
const fn = vi.fn()
|
391
|
+
|
392
|
+
function Comp() {
|
393
|
+
const form = createForm(() => ({
|
394
|
+
defaultValues: {
|
395
|
+
people: [] as Array<string>,
|
396
|
+
},
|
397
|
+
onSubmit: ({ value }) => fn(value),
|
398
|
+
}))
|
399
|
+
return (
|
400
|
+
<div>
|
401
|
+
<form
|
402
|
+
onSubmit={(e) => {
|
403
|
+
e.preventDefault()
|
404
|
+
e.stopPropagation()
|
405
|
+
void form.handleSubmit()
|
406
|
+
}}
|
407
|
+
>
|
408
|
+
<form.Field name="people">
|
409
|
+
{(field) => (
|
410
|
+
<div>
|
411
|
+
<Show when={field().state.value.length > 0}>
|
412
|
+
{/* Do not change this to For or the test will fail */}
|
413
|
+
<Index each={field().state.value}>
|
414
|
+
{(_, i) => {
|
415
|
+
return (
|
416
|
+
<form.Field name={`people[${i}]`}>
|
417
|
+
{(subField) => (
|
418
|
+
<div>
|
419
|
+
<label>
|
420
|
+
<div>Name for person {i}</div>
|
421
|
+
<input
|
422
|
+
value={subField().state.value}
|
423
|
+
onInput={(e) => {
|
424
|
+
subField().handleChange(
|
425
|
+
e.currentTarget.value,
|
426
|
+
)
|
427
|
+
}}
|
428
|
+
/>
|
429
|
+
</label>
|
430
|
+
<button
|
431
|
+
onClick={() => field().removeValue(i)}
|
432
|
+
type="button"
|
433
|
+
>
|
434
|
+
Remove person {i}
|
435
|
+
</button>
|
436
|
+
</div>
|
437
|
+
)}
|
438
|
+
</form.Field>
|
439
|
+
)
|
440
|
+
}}
|
441
|
+
</Index>
|
442
|
+
</Show>
|
443
|
+
|
444
|
+
<button onClick={() => field().pushValue('')} type="button">
|
445
|
+
Add person
|
446
|
+
</button>
|
447
|
+
</div>
|
448
|
+
)}
|
449
|
+
</form.Field>
|
450
|
+
<button type="submit">Submit</button>
|
451
|
+
</form>
|
452
|
+
</div>
|
453
|
+
)
|
454
|
+
}
|
455
|
+
|
456
|
+
const { getByText, findByLabelText, queryByText, findByText } = render(
|
457
|
+
() => <Comp />,
|
458
|
+
)
|
459
|
+
|
460
|
+
expect(queryByText('Name for person 0')).not.toBeInTheDocument()
|
461
|
+
expect(queryByText('Name for person 1')).not.toBeInTheDocument()
|
462
|
+
await user.click(getByText('Add person'))
|
463
|
+
const input = await findByLabelText('Name for person 0')
|
464
|
+
expect(input).toBeInTheDocument()
|
465
|
+
await user.type(input, 'John')
|
466
|
+
|
467
|
+
await user.click(getByText('Add person'))
|
468
|
+
const input2 = await findByLabelText('Name for person 1')
|
469
|
+
expect(input).toBeInTheDocument()
|
470
|
+
await user.type(input2, 'Jack')
|
471
|
+
|
472
|
+
expect(queryByText('Name for person 0')).toBeInTheDocument()
|
473
|
+
expect(queryByText('Name for person 1')).toBeInTheDocument()
|
474
|
+
await user.click(getByText('Remove person 1'))
|
475
|
+
expect(queryByText('Name for person 0')).toBeInTheDocument()
|
476
|
+
expect(queryByText('Name for person 1')).not.toBeInTheDocument()
|
477
|
+
|
478
|
+
await user.click(await findByText('Submit'))
|
479
|
+
expect(fn).toHaveBeenCalledWith({ people: ['John'] })
|
480
|
+
})
|
481
|
+
|
389
482
|
it('should handle arrays with subvalues', async () => {
|
390
483
|
const fn = vi.fn()
|
391
484
|
|
@@ -428,6 +521,12 @@ describe('createField', () => {
|
|
428
521
|
}}
|
429
522
|
/>
|
430
523
|
</label>
|
524
|
+
<button
|
525
|
+
onClick={() => field().removeValue(i)}
|
526
|
+
type="button"
|
527
|
+
>
|
528
|
+
Remove person {i}
|
529
|
+
</button>
|
431
530
|
</div>
|
432
531
|
)}
|
433
532
|
</form.Field>
|
@@ -456,13 +555,24 @@ describe('createField', () => {
|
|
456
555
|
)
|
457
556
|
|
458
557
|
expect(queryByText('Name for person 0')).not.toBeInTheDocument()
|
558
|
+
expect(queryByText('Name for person 1')).not.toBeInTheDocument()
|
459
559
|
await user.click(getByText('Add person'))
|
460
560
|
const input = await findByLabelText('Name for person 0')
|
461
561
|
expect(input).toBeInTheDocument()
|
462
562
|
await user.type(input, 'John')
|
563
|
+
|
564
|
+
await user.click(getByText('Add person'))
|
565
|
+
const input2 = await findByLabelText('Name for person 1')
|
566
|
+
expect(input).toBeInTheDocument()
|
567
|
+
await user.type(input2, 'Jack')
|
568
|
+
|
569
|
+
expect(queryByText('Name for person 0')).toBeInTheDocument()
|
570
|
+
expect(queryByText('Name for person 1')).toBeInTheDocument()
|
571
|
+
await user.click(getByText('Remove person 1'))
|
572
|
+
expect(queryByText('Name for person 0')).toBeInTheDocument()
|
573
|
+
expect(queryByText('Name for person 1')).not.toBeInTheDocument()
|
574
|
+
|
463
575
|
await user.click(await findByText('Submit'))
|
464
|
-
expect(fn).toHaveBeenCalledWith({
|
465
|
-
people: [{ name: 'John', age: 0 }],
|
466
|
-
})
|
576
|
+
expect(fn).toHaveBeenCalledWith({ people: [{ name: 'John', age: 0 }] })
|
467
577
|
})
|
468
578
|
})
|