@tanstack/form-core
Advanced tools
@@ -15,3 +15,2 @@ "use strict"; | ||
| this.mount = () => { | ||
| const cleanup = this.store.mount(); | ||
| if (this.options.defaultValue !== void 0 && !this.getMeta().isTouched) { | ||
@@ -55,3 +54,4 @@ this.form.setFieldValue(this.name, this.options.defaultValue, { | ||
| }); | ||
| return cleanup; | ||
| return () => { | ||
| }; | ||
| }; | ||
@@ -485,6 +485,5 @@ this.update = (opts2) => { | ||
| }; | ||
| this.store = new store.Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| this.store = store.createStore( | ||
| (prevVal) => { | ||
| this.form.store.get(); | ||
| const meta = this.form.getFieldMeta(this.name) ?? { | ||
@@ -506,3 +505,3 @@ ...metaHelper.defaultFieldMeta, | ||
| } | ||
| }); | ||
| ); | ||
| } | ||
@@ -509,0 +508,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
| import { Derived } from '@tanstack/store'; | ||
| import { ReadonlyStore } from '@tanstack/store'; | ||
| import { DeepKeys, DeepValue, UnwrapOneLevelOfArray } from './util-types.cjs'; | ||
@@ -271,3 +271,3 @@ import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs'; | ||
| */ | ||
| store: Derived<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>; | ||
| store: ReadonlyStore<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>; | ||
| /** | ||
@@ -274,0 +274,0 @@ * The current field state. |
@@ -46,4 +46,4 @@ "use strict"; | ||
| this.mount = () => { | ||
| const cleanup = this.store.mount(); | ||
| return cleanup; | ||
| return () => { | ||
| }; | ||
| }; | ||
@@ -149,20 +149,17 @@ this.validateArrayFieldsStartingFrom = async (field, index, cause) => { | ||
| } | ||
| this.store = new store.Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ currDepVals }) => { | ||
| const currFormStore = currDepVals[0]; | ||
| let values; | ||
| if (typeof this.fieldsMap === "string") { | ||
| values = utils.getBy(currFormStore.values, this.fieldsMap); | ||
| } else { | ||
| values = {}; | ||
| const fields = this.fieldsMap; | ||
| for (const key in fields) { | ||
| values[key] = utils.getBy(currFormStore.values, fields[key]); | ||
| } | ||
| this.store = store.createStore(() => { | ||
| const currFormStore = this.form.store.get(); | ||
| let values; | ||
| if (typeof this.fieldsMap === "string") { | ||
| values = utils.getBy(currFormStore.values, this.fieldsMap); | ||
| } else { | ||
| values = {}; | ||
| const fields = this.fieldsMap; | ||
| for (const key in fields) { | ||
| values[key] = utils.getBy(currFormStore.values, fields[key]); | ||
| } | ||
| return { | ||
| values | ||
| }; | ||
| } | ||
| return { | ||
| values | ||
| }; | ||
| }); | ||
@@ -169,0 +166,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FieldGroupApi.cjs","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { Derived } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: Derived<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = new Derived({\n deps: [this.form.store],\n fn: ({ currDepVals }) => {\n const currFormStore = currDepVals[0]\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n },\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n */\n mount = () => {\n const cleanup = this.store.mount()\n\n return cleanup\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["concatenatePaths","makePathArray","opts","Derived","getBy"],"mappings":"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"} | ||
| {"version":3,"file":"FieldGroupApi.cjs","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["concatenatePaths","makePathArray","opts","createStore","getBy"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| import { Derived } from '@tanstack/store'; | ||
| import { ReadonlyStore } from '@tanstack/store'; | ||
| import { Updater } from './utils.cjs'; | ||
@@ -48,3 +48,3 @@ import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs'; | ||
| getFormFieldOptions: <TOptions extends FieldOptions<any, any, any, any, any, any, any, any, any, any, any, any>>(props: TOptions) => TOptions; | ||
| store: Derived<FieldGroupState<TFieldGroupData>>; | ||
| store: ReadonlyStore<FieldGroupState<TFieldGroupData>>; | ||
| get state(): FieldGroupState<TFieldGroupData>; | ||
@@ -57,2 +57,4 @@ /** | ||
| * Mounts the field group instance to listen to value changes. | ||
| * | ||
| * TODO: Remove | ||
| */ | ||
@@ -59,0 +61,0 @@ mount: () => () => void; |
+76
-86
@@ -37,4 +37,2 @@ "use strict"; | ||
| this.mount = () => { | ||
| const cleanupFieldMetaDerived = this.fieldMetaDerived.mount(); | ||
| const cleanupStoreDerived = this.store.mount(); | ||
| const cleanupDevtoolBroadcast = this.store.subscribe(() => { | ||
@@ -77,5 +75,3 @@ utils.throttleFormState(this); | ||
| cleanupFormStateListener(); | ||
| cleanupDevtoolBroadcast(); | ||
| cleanupFieldMetaDerived(); | ||
| cleanupStoreDerived(); | ||
| cleanupDevtoolBroadcast.unsubscribe(); | ||
| EventClient.formEventClient.emit("form-unmounted", { | ||
@@ -901,9 +897,7 @@ id: this._formId | ||
| } | ||
| this.baseStore = new store.Store(baseStoreVal); | ||
| this.fieldMetaDerived = new store.Derived({ | ||
| deps: [this.baseStore], | ||
| fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| const prevBaseStore = prevDepVals?.[0]; | ||
| const currBaseStore = currDepVals[0]; | ||
| this.baseStore = store.createStore(baseStoreVal); | ||
| let prevBaseStore = void 0; | ||
| this.fieldMetaDerived = store.createStore( | ||
| (prevVal) => { | ||
| const currBaseStore = this.baseStore.get(); | ||
| let originalMetaCount = 0; | ||
@@ -955,80 +949,76 @@ const fieldMeta = {}; | ||
| } | ||
| prevBaseStore = this.baseStore.get(); | ||
| return fieldMeta; | ||
| } | ||
| }); | ||
| this.store = new store.Derived({ | ||
| deps: [this.baseStore, this.fieldMetaDerived], | ||
| fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| const prevBaseStore = prevDepVals?.[0]; | ||
| const currBaseStore = currDepVals[0]; | ||
| const currFieldMeta = currDepVals[1]; | ||
| const fieldMetaValues = Object.values(currFieldMeta).filter( | ||
| Boolean | ||
| ); | ||
| const isFieldsValidating = fieldMetaValues.some( | ||
| (field) => field.isValidating | ||
| ); | ||
| const isFieldsValid = fieldMetaValues.every((field) => field.isValid); | ||
| const isTouched = fieldMetaValues.some((field) => field.isTouched); | ||
| const isBlurred = fieldMetaValues.some((field) => field.isBlurred); | ||
| const isDefaultValue = fieldMetaValues.every( | ||
| (field) => field.isDefaultValue | ||
| ); | ||
| const shouldInvalidateOnMount = ( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| isTouched && currBaseStore.errorMap?.onMount | ||
| ); | ||
| const isDirty = fieldMetaValues.some((field) => field.isDirty); | ||
| const isPristine = !isDirty; | ||
| const hasOnMountError = Boolean( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| currBaseStore.errorMap?.onMount || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| fieldMetaValues.some((f) => f?.errorMap?.onMount) | ||
| ); | ||
| const isValidating = !!isFieldsValidating; | ||
| let errors = prevVal?.errors ?? []; | ||
| if (!prevBaseStore || currBaseStore.errorMap !== prevBaseStore.errorMap) { | ||
| errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => { | ||
| if (curr === void 0) return prev; | ||
| if (curr && utils.isGlobalFormValidationError(curr)) { | ||
| prev.push(curr.form); | ||
| return prev; | ||
| } | ||
| prev.push(curr); | ||
| ); | ||
| let prevBaseStoreForStore = void 0; | ||
| this.store = store.createStore((prevVal) => { | ||
| const currBaseStore = this.baseStore.get(); | ||
| const currFieldMeta = this.fieldMetaDerived.get(); | ||
| const fieldMetaValues = Object.values(currFieldMeta).filter( | ||
| Boolean | ||
| ); | ||
| const isFieldsValidating = fieldMetaValues.some( | ||
| (field) => field.isValidating | ||
| ); | ||
| const isFieldsValid = fieldMetaValues.every((field) => field.isValid); | ||
| const isTouched = fieldMetaValues.some((field) => field.isTouched); | ||
| const isBlurred = fieldMetaValues.some((field) => field.isBlurred); | ||
| const isDefaultValue = fieldMetaValues.every( | ||
| (field) => field.isDefaultValue | ||
| ); | ||
| const shouldInvalidateOnMount = ( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| isTouched && currBaseStore.errorMap?.onMount | ||
| ); | ||
| const isDirty = fieldMetaValues.some((field) => field.isDirty); | ||
| const isPristine = !isDirty; | ||
| const hasOnMountError = Boolean( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| currBaseStore.errorMap?.onMount || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| fieldMetaValues.some((f) => f?.errorMap?.onMount) | ||
| ); | ||
| const isValidating = !!isFieldsValidating; | ||
| let errors = prevVal?.errors ?? []; | ||
| if (!prevBaseStoreForStore || currBaseStore.errorMap !== prevBaseStoreForStore.errorMap) { | ||
| errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => { | ||
| if (curr === void 0) return prev; | ||
| if (curr && utils.isGlobalFormValidationError(curr)) { | ||
| prev.push(curr.form); | ||
| return prev; | ||
| }, []); | ||
| } | ||
| const isFormValid = errors.length === 0; | ||
| const isValid = isFieldsValid && isFormValid; | ||
| const submitInvalid = this.options.canSubmitWhenInvalid ?? false; | ||
| const canSubmit = currBaseStore.submissionAttempts === 0 && !isTouched && !hasOnMountError || !isValidating && !currBaseStore.isSubmitting && isValid || submitInvalid; | ||
| let errorMap = currBaseStore.errorMap; | ||
| if (shouldInvalidateOnMount) { | ||
| errors = errors.filter( | ||
| (err) => err !== currBaseStore.errorMap.onMount | ||
| ); | ||
| errorMap = Object.assign(errorMap, { onMount: void 0 }); | ||
| } | ||
| if (prevVal && prevBaseStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && utils.evaluate(prevBaseStore, currBaseStore)) { | ||
| return prevVal; | ||
| } | ||
| const state = { | ||
| ...currBaseStore, | ||
| errorMap, | ||
| fieldMeta: this.fieldMetaDerived.state, | ||
| errors, | ||
| isFieldsValidating, | ||
| isFieldsValid, | ||
| isFormValid, | ||
| isValid, | ||
| canSubmit, | ||
| isTouched, | ||
| isBlurred, | ||
| isPristine, | ||
| isDefaultValue, | ||
| isDirty | ||
| }; | ||
| return state; | ||
| } | ||
| prev.push(curr); | ||
| return prev; | ||
| }, []); | ||
| } | ||
| const isFormValid = errors.length === 0; | ||
| const isValid = isFieldsValid && isFormValid; | ||
| const submitInvalid = this.options.canSubmitWhenInvalid ?? false; | ||
| const canSubmit = currBaseStore.submissionAttempts === 0 && !isTouched && !hasOnMountError || !isValidating && !currBaseStore.isSubmitting && isValid || submitInvalid; | ||
| let errorMap = currBaseStore.errorMap; | ||
| if (shouldInvalidateOnMount) { | ||
| errors = errors.filter((err) => err !== currBaseStore.errorMap.onMount); | ||
| errorMap = Object.assign(errorMap, { onMount: void 0 }); | ||
| } | ||
| if (prevVal && prevBaseStoreForStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && utils.evaluate(prevBaseStoreForStore, currBaseStore)) { | ||
| return prevVal; | ||
| } | ||
| const state = { | ||
| ...currBaseStore, | ||
| errorMap, | ||
| fieldMeta: this.fieldMetaDerived.state, | ||
| errors, | ||
| isFieldsValidating, | ||
| isFieldsValid, | ||
| isFormValid, | ||
| isValid, | ||
| canSubmit, | ||
| isTouched, | ||
| isBlurred, | ||
| isPristine, | ||
| isDefaultValue, | ||
| isDirty | ||
| }; | ||
| prevBaseStoreForStore = this.baseStore.get(); | ||
| return state; | ||
| }); | ||
@@ -1035,0 +1025,0 @@ this.handleSubmit = this.handleSubmit.bind(this); |
@@ -1,2 +0,2 @@ | ||
| import { Derived, Store } from '@tanstack/store'; | ||
| import { ReadonlyStore, Store } from '@tanstack/store'; | ||
| import { ValidationLogicFn } from './ValidationLogic.cjs'; | ||
@@ -322,4 +322,4 @@ import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs'; | ||
| baseStore: Store<BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| fieldMetaDerived: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>; | ||
| store: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| fieldMetaDerived: Store<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>; | ||
| store: ReadonlyStore<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| /** | ||
@@ -326,0 +326,0 @@ * A record of field information for each field in the form. |
@@ -1,2 +0,2 @@ | ||
| import { Derived } from '@tanstack/store'; | ||
| import { ReadonlyStore } from '@tanstack/store'; | ||
| import { DeepKeys, DeepValue, UnwrapOneLevelOfArray } from './util-types.js'; | ||
@@ -271,3 +271,3 @@ import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js'; | ||
| */ | ||
| store: Derived<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>; | ||
| store: ReadonlyStore<FieldState<TParentData, TName, TData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TFormOnMount, TFormOnChange, TFormOnChangeAsync, TFormOnBlur, TFormOnBlurAsync, TFormOnSubmit, TFormOnSubmitAsync, TFormOnDynamic, TFormOnDynamicAsync>>; | ||
| /** | ||
@@ -274,0 +274,0 @@ * The current field state. |
@@ -1,2 +0,2 @@ | ||
| import { batch, Derived } from "@tanstack/store"; | ||
| import { batch, createStore } from "@tanstack/store"; | ||
| import { standardSchemaValidators, isStandardSchemaValidator } from "./standardSchemaValidator.js"; | ||
@@ -13,3 +13,2 @@ import { defaultFieldMeta } from "./metaHelper.js"; | ||
| this.mount = () => { | ||
| const cleanup = this.store.mount(); | ||
| if (this.options.defaultValue !== void 0 && !this.getMeta().isTouched) { | ||
@@ -53,3 +52,4 @@ this.form.setFieldValue(this.name, this.options.defaultValue, { | ||
| }); | ||
| return cleanup; | ||
| return () => { | ||
| }; | ||
| }; | ||
@@ -483,6 +483,5 @@ this.update = (opts2) => { | ||
| }; | ||
| this.store = new Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| this.store = createStore( | ||
| (prevVal) => { | ||
| this.form.store.get(); | ||
| const meta = this.form.getFieldMeta(this.name) ?? { | ||
@@ -504,3 +503,3 @@ ...defaultFieldMeta, | ||
| } | ||
| }); | ||
| ); | ||
| } | ||
@@ -507,0 +506,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
| import { Derived } from '@tanstack/store'; | ||
| import { ReadonlyStore } from '@tanstack/store'; | ||
| import { Updater } from './utils.js'; | ||
@@ -48,3 +48,3 @@ import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.js'; | ||
| getFormFieldOptions: <TOptions extends FieldOptions<any, any, any, any, any, any, any, any, any, any, any, any>>(props: TOptions) => TOptions; | ||
| store: Derived<FieldGroupState<TFieldGroupData>>; | ||
| store: ReadonlyStore<FieldGroupState<TFieldGroupData>>; | ||
| get state(): FieldGroupState<TFieldGroupData>; | ||
@@ -57,2 +57,4 @@ /** | ||
| * Mounts the field group instance to listen to value changes. | ||
| * | ||
| * TODO: Remove | ||
| */ | ||
@@ -59,0 +61,0 @@ mount: () => () => void; |
@@ -1,2 +0,2 @@ | ||
| import { Derived } from "@tanstack/store"; | ||
| import { createStore } from "@tanstack/store"; | ||
| import { concatenatePaths, makePathArray, getBy } from "./utils.js"; | ||
@@ -44,4 +44,4 @@ class FieldGroupApi { | ||
| this.mount = () => { | ||
| const cleanup = this.store.mount(); | ||
| return cleanup; | ||
| return () => { | ||
| }; | ||
| }; | ||
@@ -147,20 +147,17 @@ this.validateArrayFieldsStartingFrom = async (field, index, cause) => { | ||
| } | ||
| this.store = new Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ currDepVals }) => { | ||
| const currFormStore = currDepVals[0]; | ||
| let values; | ||
| if (typeof this.fieldsMap === "string") { | ||
| values = getBy(currFormStore.values, this.fieldsMap); | ||
| } else { | ||
| values = {}; | ||
| const fields = this.fieldsMap; | ||
| for (const key in fields) { | ||
| values[key] = getBy(currFormStore.values, fields[key]); | ||
| } | ||
| this.store = createStore(() => { | ||
| const currFormStore = this.form.store.get(); | ||
| let values; | ||
| if (typeof this.fieldsMap === "string") { | ||
| values = getBy(currFormStore.values, this.fieldsMap); | ||
| } else { | ||
| values = {}; | ||
| const fields = this.fieldsMap; | ||
| for (const key in fields) { | ||
| values[key] = getBy(currFormStore.values, fields[key]); | ||
| } | ||
| return { | ||
| values | ||
| }; | ||
| } | ||
| return { | ||
| values | ||
| }; | ||
| }); | ||
@@ -167,0 +164,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FieldGroupApi.js","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { Derived } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: Derived<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = new Derived({\n deps: [this.form.store],\n fn: ({ currDepVals }) => {\n const currFormStore = currDepVals[0]\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n },\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n */\n mount = () => {\n const cleanup = this.store.mount()\n\n return cleanup\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["opts"],"mappings":"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"} | ||
| {"version":3,"file":"FieldGroupApi.js","sources":["../../src/FieldGroupApi.ts"],"sourcesContent":["import { createStore } from '@tanstack/store'\nimport { concatenatePaths, getBy, makePathArray } from './utils'\nimport type { ReadonlyStore } from '@tanstack/store'\nimport type { Updater } from './utils'\nimport type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMetaBase, FieldOptions } from './FieldApi'\nimport type {\n DeepKeys,\n DeepKeysOfType,\n DeepValue,\n FieldsMap,\n} from './util-types'\nimport type {\n FieldManipulator,\n UpdateMetaOptions,\n ValidationCause,\n} from './types'\n\nexport type AnyFieldGroupApi = FieldGroupApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport interface FieldGroupState<in out TFieldGroupData> {\n /**\n * The current values of the field group\n */\n values: TFieldGroupData\n}\n\n/**\n * An object representing the options for a field group.\n */\nexport interface FieldGroupOptions<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> {\n form:\n | FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n | FieldGroupApi<\n any,\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n TSubmitMeta\n >\n /**\n * The path to the field group data.\n */\n fields: TFields\n /**\n * The expected subsetValues that the form must provide.\n */\n defaultValues?: TFieldGroupData\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n}\n\nexport class FieldGroupApi<\n in out TFormData,\n in out TFieldGroupData,\n in out TFields extends\n | DeepKeysOfType<TFormData, TFieldGroupData | null | undefined>\n | FieldsMap<TFormData, TFieldGroupData>,\n in out TOnMount extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChange extends undefined | FormValidateOrFn<TFormData>,\n in out TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n in out TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n in out TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n in out TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n in out TSubmitMeta = never,\n> implements FieldManipulator<TFieldGroupData, TSubmitMeta> {\n /**\n * The form that called this field group.\n */\n readonly form: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >\n\n readonly fieldsMap: TFields\n\n /**\n * Get the true name of the field. Not required within `Field` or `AppField`.\n * @private\n */\n getFormFieldName = <TField extends DeepKeys<TFieldGroupData>>(\n subfield: TField,\n ): DeepKeys<TFormData> => {\n if (typeof this.fieldsMap === 'string') {\n return concatenatePaths(this.fieldsMap, subfield)\n }\n\n const firstAccessor = makePathArray(subfield)[0]\n if (typeof firstAccessor !== 'string') {\n // top-level arrays cannot be mapped\n return ''\n }\n\n const restOfPath = subfield.slice(firstAccessor.length)\n const formMappedPath =\n // TFields is either a string or this. See guard above.\n (this.fieldsMap as FieldsMap<TFormData, TFieldGroupData>)[\n firstAccessor as keyof TFieldGroupData\n ]\n\n return concatenatePaths(formMappedPath, restOfPath)\n }\n\n /**\n * Get the field options with the true form DeepKeys for validators\n * @private\n */\n getFormFieldOptions = <\n TOptions extends FieldOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n >(\n props: TOptions,\n ): TOptions => {\n const newProps = { ...props }\n const validators = newProps.validators\n\n newProps.name = this.getFormFieldName(props.name)\n\n if (\n validators &&\n (validators.onChangeListenTo || validators.onBlurListenTo)\n ) {\n const newValidators = { ...validators }\n\n const remapListenTo = (listenTo: DeepKeys<any>[] | undefined) => {\n if (!listenTo) return undefined\n return listenTo.map((localFieldName) =>\n this.getFormFieldName(localFieldName),\n )\n }\n\n newValidators.onChangeListenTo = remapListenTo(\n validators.onChangeListenTo,\n )\n newValidators.onBlurListenTo = remapListenTo(validators.onBlurListenTo)\n\n newProps.validators = newValidators\n }\n\n return newProps\n }\n\n store: ReadonlyStore<FieldGroupState<TFieldGroupData>>\n\n get state() {\n return this.store.state\n }\n\n /**\n * Constructs a new `FieldGroupApi` instance with the given form options.\n */\n constructor(\n opts: FieldGroupOptions<\n TFormData,\n TFieldGroupData,\n TFields,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n if (opts.form instanceof FieldGroupApi) {\n const group = opts.form\n this.form = group.form as never\n\n // the DeepKey is already namespaced, so we need to ensure that we reference\n // the form and not the group\n if (typeof opts.fields === 'string') {\n this.fieldsMap = group.getFormFieldName(opts.fields) as TFields\n } else {\n // TypeScript has a tough time with generics being a union for some reason\n const fields = {\n ...(opts.fields as FieldsMap<TFormData, TFieldGroupData>),\n }\n for (const key in fields) {\n fields[key] = group.getFormFieldName(fields[key]) as never\n }\n this.fieldsMap = fields as never\n }\n } else {\n this.form = opts.form\n this.fieldsMap = opts.fields\n }\n\n this.store = createStore(() => {\n const currFormStore = this.form.store.get()\n let values: TFieldGroupData\n if (typeof this.fieldsMap === 'string') {\n // all values live at that name, so we can directly fetch it\n values = getBy(currFormStore.values, this.fieldsMap)\n } else {\n // we need to fetch the values from all places where they were mapped from\n values = {} as never\n const fields: Record<keyof TFieldGroupData, string> = this\n .fieldsMap as never\n for (const key in fields) {\n values[key] = getBy(currFormStore.values, fields[key])\n }\n }\n\n return {\n values,\n }\n })\n }\n\n /**\n * Mounts the field group instance to listen to value changes.\n *\n * TODO: Remove\n */\n mount = () => {\n return () => {}\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n return this.form.validateArrayFieldsStartingFrom(\n this.getFormFieldName(field),\n index,\n cause,\n )\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n return this.form.validateField(this.getFormFieldName(field), cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n // cast is required since the implementation isn't one of the two overloads\n return this.form.handleSubmit(submitMeta as any)\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n ): DeepValue<TFieldGroupData, TField> => {\n return this.form.getFieldValue(this.getFormFieldName(field)) as DeepValue<\n TFieldGroupData,\n TField\n >\n }\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.getFieldMeta(this.getFormFieldName(field))\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<AnyFieldMetaBase>,\n ) => {\n return this.form.setFieldMeta(this.getFormFieldName(field), updater)\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFieldGroupData>>(\n field: TField,\n updater: Updater<DeepValue<TFieldGroupData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.setFieldValue(\n this.getFormFieldName(field) as never,\n updater as never,\n opts,\n )\n }\n\n /**\n * Delete a field and its subfields.\n */\n deleteField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.deleteField(this.getFormFieldName(field))\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.pushFieldValue(\n this.getFormFieldName(field),\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Insert a value into an array field at the specified index.\n */\n insertFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.insertFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n value: DeepValue<TFieldGroupData, TField> extends any[]\n ? DeepValue<TFieldGroupData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.replaceFieldValue(\n this.getFormFieldName(field),\n index,\n // since unknown doesn't extend an array, it types `value` as never.\n value as never,\n opts,\n )\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <\n TField extends DeepKeysOfType<TFieldGroupData, any[]>,\n >(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.removeFieldValue(this.getFormFieldName(field), index, opts)\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.swapFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.moveFieldValues(\n this.getFormFieldName(field),\n index1,\n index2,\n opts,\n )\n }\n\n clearFieldValues = <TField extends DeepKeysOfType<TFieldGroupData, any[]>>(\n field: TField,\n opts?: UpdateMetaOptions,\n ) => {\n return this.form.clearFieldValues(this.getFormFieldName(field), opts)\n }\n\n /**\n * Resets the field value and meta to default state\n */\n resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => {\n return this.form.resetField(this.getFormFieldName(field))\n }\n\n validateAllFields = (cause: ValidationCause) =>\n this.form.validateAllFields(cause)\n}\n"],"names":["opts"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| import { Derived, Store } from '@tanstack/store'; | ||
| import { ReadonlyStore, Store } from '@tanstack/store'; | ||
| import { ValidationLogicFn } from './ValidationLogic.js'; | ||
@@ -322,4 +322,4 @@ import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js'; | ||
| baseStore: Store<BaseFormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| fieldMetaDerived: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>; | ||
| store: Derived<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| fieldMetaDerived: Store<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>['fieldMeta']>; | ||
| store: ReadonlyStore<FormState<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer>>; | ||
| /** | ||
@@ -326,0 +326,0 @@ * A record of field information for each field in the form. |
+77
-87
@@ -1,2 +0,2 @@ | ||
| import { batch, Store, Derived } from "@tanstack/store"; | ||
| import { batch, createStore } from "@tanstack/store"; | ||
| import { throttleFormState, evaluate, getSyncValidatorArray, determineFormLevelErrorSourceAndValue, getAsyncValidatorArray, getBy, functionalUpdate, setBy, deleteBy, mergeOpts, isGlobalFormValidationError, uuid, isNonEmptyArray } from "./utils.js"; | ||
@@ -35,4 +35,2 @@ import { defaultValidationLogic } from "./ValidationLogic.js"; | ||
| this.mount = () => { | ||
| const cleanupFieldMetaDerived = this.fieldMetaDerived.mount(); | ||
| const cleanupStoreDerived = this.store.mount(); | ||
| const cleanupDevtoolBroadcast = this.store.subscribe(() => { | ||
@@ -75,5 +73,3 @@ throttleFormState(this); | ||
| cleanupFormStateListener(); | ||
| cleanupDevtoolBroadcast(); | ||
| cleanupFieldMetaDerived(); | ||
| cleanupStoreDerived(); | ||
| cleanupDevtoolBroadcast.unsubscribe(); | ||
| formEventClient.emit("form-unmounted", { | ||
@@ -899,9 +895,7 @@ id: this._formId | ||
| } | ||
| this.baseStore = new Store(baseStoreVal); | ||
| this.fieldMetaDerived = new Derived({ | ||
| deps: [this.baseStore], | ||
| fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| const prevBaseStore = prevDepVals?.[0]; | ||
| const currBaseStore = currDepVals[0]; | ||
| this.baseStore = createStore(baseStoreVal); | ||
| let prevBaseStore = void 0; | ||
| this.fieldMetaDerived = createStore( | ||
| (prevVal) => { | ||
| const currBaseStore = this.baseStore.get(); | ||
| let originalMetaCount = 0; | ||
@@ -953,80 +947,76 @@ const fieldMeta = {}; | ||
| } | ||
| prevBaseStore = this.baseStore.get(); | ||
| return fieldMeta; | ||
| } | ||
| }); | ||
| this.store = new Derived({ | ||
| deps: [this.baseStore, this.fieldMetaDerived], | ||
| fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal; | ||
| const prevBaseStore = prevDepVals?.[0]; | ||
| const currBaseStore = currDepVals[0]; | ||
| const currFieldMeta = currDepVals[1]; | ||
| const fieldMetaValues = Object.values(currFieldMeta).filter( | ||
| Boolean | ||
| ); | ||
| const isFieldsValidating = fieldMetaValues.some( | ||
| (field) => field.isValidating | ||
| ); | ||
| const isFieldsValid = fieldMetaValues.every((field) => field.isValid); | ||
| const isTouched = fieldMetaValues.some((field) => field.isTouched); | ||
| const isBlurred = fieldMetaValues.some((field) => field.isBlurred); | ||
| const isDefaultValue = fieldMetaValues.every( | ||
| (field) => field.isDefaultValue | ||
| ); | ||
| const shouldInvalidateOnMount = ( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| isTouched && currBaseStore.errorMap?.onMount | ||
| ); | ||
| const isDirty = fieldMetaValues.some((field) => field.isDirty); | ||
| const isPristine = !isDirty; | ||
| const hasOnMountError = Boolean( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| currBaseStore.errorMap?.onMount || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| fieldMetaValues.some((f) => f?.errorMap?.onMount) | ||
| ); | ||
| const isValidating = !!isFieldsValidating; | ||
| let errors = prevVal?.errors ?? []; | ||
| if (!prevBaseStore || currBaseStore.errorMap !== prevBaseStore.errorMap) { | ||
| errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => { | ||
| if (curr === void 0) return prev; | ||
| if (curr && isGlobalFormValidationError(curr)) { | ||
| prev.push(curr.form); | ||
| return prev; | ||
| } | ||
| prev.push(curr); | ||
| ); | ||
| let prevBaseStoreForStore = void 0; | ||
| this.store = createStore((prevVal) => { | ||
| const currBaseStore = this.baseStore.get(); | ||
| const currFieldMeta = this.fieldMetaDerived.get(); | ||
| const fieldMetaValues = Object.values(currFieldMeta).filter( | ||
| Boolean | ||
| ); | ||
| const isFieldsValidating = fieldMetaValues.some( | ||
| (field) => field.isValidating | ||
| ); | ||
| const isFieldsValid = fieldMetaValues.every((field) => field.isValid); | ||
| const isTouched = fieldMetaValues.some((field) => field.isTouched); | ||
| const isBlurred = fieldMetaValues.some((field) => field.isBlurred); | ||
| const isDefaultValue = fieldMetaValues.every( | ||
| (field) => field.isDefaultValue | ||
| ); | ||
| const shouldInvalidateOnMount = ( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| isTouched && currBaseStore.errorMap?.onMount | ||
| ); | ||
| const isDirty = fieldMetaValues.some((field) => field.isDirty); | ||
| const isPristine = !isDirty; | ||
| const hasOnMountError = Boolean( | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| currBaseStore.errorMap?.onMount || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| fieldMetaValues.some((f) => f?.errorMap?.onMount) | ||
| ); | ||
| const isValidating = !!isFieldsValidating; | ||
| let errors = prevVal?.errors ?? []; | ||
| if (!prevBaseStoreForStore || currBaseStore.errorMap !== prevBaseStoreForStore.errorMap) { | ||
| errors = Object.values(currBaseStore.errorMap).reduce((prev, curr) => { | ||
| if (curr === void 0) return prev; | ||
| if (curr && isGlobalFormValidationError(curr)) { | ||
| prev.push(curr.form); | ||
| return prev; | ||
| }, []); | ||
| } | ||
| const isFormValid = errors.length === 0; | ||
| const isValid = isFieldsValid && isFormValid; | ||
| const submitInvalid = this.options.canSubmitWhenInvalid ?? false; | ||
| const canSubmit = currBaseStore.submissionAttempts === 0 && !isTouched && !hasOnMountError || !isValidating && !currBaseStore.isSubmitting && isValid || submitInvalid; | ||
| let errorMap = currBaseStore.errorMap; | ||
| if (shouldInvalidateOnMount) { | ||
| errors = errors.filter( | ||
| (err) => err !== currBaseStore.errorMap.onMount | ||
| ); | ||
| errorMap = Object.assign(errorMap, { onMount: void 0 }); | ||
| } | ||
| if (prevVal && prevBaseStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && evaluate(prevBaseStore, currBaseStore)) { | ||
| return prevVal; | ||
| } | ||
| const state = { | ||
| ...currBaseStore, | ||
| errorMap, | ||
| fieldMeta: this.fieldMetaDerived.state, | ||
| errors, | ||
| isFieldsValidating, | ||
| isFieldsValid, | ||
| isFormValid, | ||
| isValid, | ||
| canSubmit, | ||
| isTouched, | ||
| isBlurred, | ||
| isPristine, | ||
| isDefaultValue, | ||
| isDirty | ||
| }; | ||
| return state; | ||
| } | ||
| prev.push(curr); | ||
| return prev; | ||
| }, []); | ||
| } | ||
| const isFormValid = errors.length === 0; | ||
| const isValid = isFieldsValid && isFormValid; | ||
| const submitInvalid = this.options.canSubmitWhenInvalid ?? false; | ||
| const canSubmit = currBaseStore.submissionAttempts === 0 && !isTouched && !hasOnMountError || !isValidating && !currBaseStore.isSubmitting && isValid || submitInvalid; | ||
| let errorMap = currBaseStore.errorMap; | ||
| if (shouldInvalidateOnMount) { | ||
| errors = errors.filter((err) => err !== currBaseStore.errorMap.onMount); | ||
| errorMap = Object.assign(errorMap, { onMount: void 0 }); | ||
| } | ||
| if (prevVal && prevBaseStoreForStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && evaluate(prevBaseStoreForStore, currBaseStore)) { | ||
| return prevVal; | ||
| } | ||
| const state = { | ||
| ...currBaseStore, | ||
| errorMap, | ||
| fieldMeta: this.fieldMetaDerived.state, | ||
| errors, | ||
| isFieldsValidating, | ||
| isFieldsValid, | ||
| isFormValid, | ||
| isValid, | ||
| canSubmit, | ||
| isTouched, | ||
| isBlurred, | ||
| isPristine, | ||
| isDefaultValue, | ||
| isDirty | ||
| }; | ||
| prevBaseStoreForStore = this.baseStore.get(); | ||
| return state; | ||
| }); | ||
@@ -1033,0 +1023,0 @@ this.handleSubmit = this.handleSubmit.bind(this); |
+2
-2
| { | ||
| "name": "@tanstack/form-core", | ||
| "version": "1.28.3", | ||
| "version": "1.28.4", | ||
| "description": "Powerful, type-safe, framework agnostic forms.", | ||
@@ -42,3 +42,3 @@ "author": "tannerlinsley", | ||
| "@tanstack/pacer-lite": "^0.1.1", | ||
| "@tanstack/store": "^0.8.1" | ||
| "@tanstack/store": "^0.9.1" | ||
| }, | ||
@@ -45,0 +45,0 @@ "devDependencies": { |
+13
-12
@@ -1,2 +0,2 @@ | ||
| import { Derived, batch } from '@tanstack/store' | ||
| import { batch, createStore } from '@tanstack/store' | ||
| import { | ||
@@ -11,3 +11,2 @@ isStandardSchemaValidator, | ||
| getAsyncValidatorArray, | ||
| getBy, | ||
| getSyncValidatorArray, | ||
@@ -17,2 +16,3 @@ mergeOpts, | ||
| import { defaultValidationLogic } from './ValidationLogic' | ||
| import type { ReadonlyStore } from '@tanstack/store' | ||
| import type { DeepKeys, DeepValue, UnwrapOneLevelOfArray } from './util-types' | ||
@@ -1095,3 +1095,3 @@ import type { | ||
| */ | ||
| store!: Derived< | ||
| store!: ReadonlyStore< | ||
| FieldState< | ||
@@ -1173,6 +1173,5 @@ TParentData, | ||
| this.store = new Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ prevVal: _prevVal }) => { | ||
| const prevVal = _prevVal as | ||
| this.store = createStore( | ||
| ( | ||
| prevVal: | ||
| | FieldState< | ||
@@ -1201,3 +1200,6 @@ TParentData, | ||
| > | ||
| | undefined | ||
| | undefined, | ||
| ) => { | ||
| // Temp hack to subscribe to form.store | ||
| this.form.store.get() | ||
@@ -1250,3 +1252,3 @@ const meta = this.form.getFieldMeta(this.name) ?? { | ||
| }, | ||
| }) | ||
| ) | ||
| } | ||
@@ -1284,4 +1286,2 @@ | ||
| mount = () => { | ||
| const cleanup = this.store.mount() | ||
| if (this.options.defaultValue !== undefined && !this.getMeta().isTouched) { | ||
@@ -1332,3 +1332,4 @@ this.form.setFieldValue(this.name, this.options.defaultValue, { | ||
| return cleanup | ||
| // TODO: Remove | ||
| return () => {} | ||
| } | ||
@@ -1335,0 +1336,0 @@ |
+23
-25
@@ -1,3 +0,4 @@ | ||
| import { Derived } from '@tanstack/store' | ||
| import { createStore } from '@tanstack/store' | ||
| import { concatenatePaths, getBy, makePathArray } from './utils' | ||
| import type { ReadonlyStore } from '@tanstack/store' | ||
| import type { Updater } from './utils' | ||
@@ -228,3 +229,3 @@ import type { | ||
| store: Derived<FieldGroupState<TFieldGroupData>> | ||
| store: ReadonlyStore<FieldGroupState<TFieldGroupData>> | ||
@@ -279,24 +280,21 @@ get state() { | ||
| this.store = new Derived({ | ||
| deps: [this.form.store], | ||
| fn: ({ currDepVals }) => { | ||
| const currFormStore = currDepVals[0] | ||
| let values: TFieldGroupData | ||
| if (typeof this.fieldsMap === 'string') { | ||
| // all values live at that name, so we can directly fetch it | ||
| values = getBy(currFormStore.values, this.fieldsMap) | ||
| } else { | ||
| // we need to fetch the values from all places where they were mapped from | ||
| values = {} as never | ||
| const fields: Record<keyof TFieldGroupData, string> = this | ||
| .fieldsMap as never | ||
| for (const key in fields) { | ||
| values[key] = getBy(currFormStore.values, fields[key]) | ||
| } | ||
| this.store = createStore(() => { | ||
| const currFormStore = this.form.store.get() | ||
| let values: TFieldGroupData | ||
| if (typeof this.fieldsMap === 'string') { | ||
| // all values live at that name, so we can directly fetch it | ||
| values = getBy(currFormStore.values, this.fieldsMap) | ||
| } else { | ||
| // we need to fetch the values from all places where they were mapped from | ||
| values = {} as never | ||
| const fields: Record<keyof TFieldGroupData, string> = this | ||
| .fieldsMap as never | ||
| for (const key in fields) { | ||
| values[key] = getBy(currFormStore.values, fields[key]) | ||
| } | ||
| } | ||
| return { | ||
| values, | ||
| } | ||
| }, | ||
| return { | ||
| values, | ||
| } | ||
| }) | ||
@@ -307,7 +305,7 @@ } | ||
| * Mounts the field group instance to listen to value changes. | ||
| * | ||
| * TODO: Remove | ||
| */ | ||
| mount = () => { | ||
| const cleanup = this.store.mount() | ||
| return cleanup | ||
| return () => {} | ||
| } | ||
@@ -314,0 +312,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
1115992
-0.17%14032
-0.06%+ Added
- Removed
Updated