@jfdevelops/react-multi-step-form 1.0.0-alpha.33 → 1.0.0-alpha.34

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/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- const require_step_schema = require('./step-schema.cjs');
2
1
  const require_use_multi_step_form_data = require('./hooks/use-multi-step-form-data.cjs');
3
2
  const require_create_context = require('./create-context.cjs');
3
+ const require_step_schema = require('./step-schema.cjs');
4
4
  const require_schema = require('./schema.cjs');
5
5
 
6
6
  exports.MultiStepFormSchema = require_schema.MultiStepFormSchema;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.cjs";
2
1
  import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.cjs";
3
2
  import { CreateHOC, MultiStepFormContextResult, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext } from "./create-context.cjs";
3
+ import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.cjs";
4
4
  import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.cjs";
5
5
  export { CreateComponentFn, CreateHOC, HelperFunctions, MultiStepFormContextResult, MultiStepFormSchema, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext, createMultiStepFormSchema, useMultiStepFormData };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.mjs";
2
1
  import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.mjs";
3
2
  import { CreateHOC, MultiStepFormContextResult, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext } from "./create-context.mjs";
3
+ import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.mjs";
4
4
  import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.mjs";
5
5
  export { CreateComponentFn, CreateHOC, HelperFunctions, MultiStepFormContextResult, MultiStepFormSchema, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext, createMultiStepFormSchema, useMultiStepFormData };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { MultiStepFormStepSchema, StepSpecificComponent } from "./step-schema.mjs";
2
1
  import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.mjs";
3
2
  import { createMultiStepFormContext } from "./create-context.mjs";
3
+ import { MultiStepFormStepSchema, StepSpecificComponent } from "./step-schema.mjs";
4
4
  import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.mjs";
5
5
 
6
6
  export { MultiStepFormSchema, MultiStepFormStepSchema, StepSpecificComponent, createMultiStepFormContext, createMultiStepFormSchema, useMultiStepFormData };
package/dist/schema.cjs CHANGED
@@ -1,6 +1,6 @@
1
+ const require_create_context = require('./create-context.cjs');
1
2
  const require_utils = require('./utils.cjs');
2
3
  const require_step_schema = require('./step-schema.cjs');
3
- const require_create_context = require('./create-context.cjs');
4
4
  let __jfdevelops_multi_step_form_core = require("@jfdevelops/multi-step-form-core");
5
5
  let __jfdevelops_multi_step_form_core__internals = require("@jfdevelops/multi-step-form-core/_internals");
6
6
 
@@ -88,7 +88,6 @@ var MultiStepFormSchema = class MultiStepFormSchema extends __jfdevelops_multi_s
88
88
  }
89
89
  withContext() {
90
90
  const context = require_create_context.createMultiStepFormContext(this);
91
- Object.assign(this, { context });
92
91
  return new MultiStepFormSchema({
93
92
  steps: this.stepSchema.original,
94
93
  form: this.formConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"schema.cjs","names":["MultiStepFormSchemaCore","#internal","DEFAULT_CASING","MultiStepFormStepSchema","MultiStepFormStepSchemaInternal","DEFAULT_STORAGE_KEY","MultiStepFormStorage","createMultiStepFormContext","createComponent"],"sources":["../src/schema.ts"],"sourcesContent":["import {\n type BaseStorageConfig,\n DEFAULT_CASING,\n DEFAULT_STORAGE_KEY,\n type Expand,\n type HelperFn,\n type HelperFnChosenSteps,\n MultiStepFormSchema as MultiStepFormSchemaCore,\n MultiStepFormStorage,\n type steps,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { type HelperFunctions, MultiStepFormStepSchema } from './step-schema';\nimport { createComponent, type CreateComponentCallback } from './utils';\nimport {\n createMultiStepFormContext,\n type MultiStepFormContextResult,\n} from './create-context';\n\n// Helper inference types for `AnyMultiStepFormSchema`\nexport namespace MultiStepFormSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > = MultiStepFormStepSchema.config<def, value> & {\n /**\n * The React context for the multi step form.\n *\n * This is a private property and is not meant to be used directly.\n * @private\n * @internal\n */\n context?: MultiStepFormContextResult<def, value>;\n };\n}\n\nexport class MultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormSchemaCore<def, value>\n implements HelperFunctions<def, value>\n{\n stepSchema: MultiStepFormStepSchema<def, value>;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n override readonly storage: MultiStepFormStorage<\n value,\n StepSchema.inferStorageKey<def>\n >;\n override readonly storageConfig: BaseStorageConfig<\n StepSchema.inferStorageKey<def>\n >;\n\n readonly context: MultiStepFormContextResult<def, value> = undefined as never;\n readonly formConfig: MultiStepFormSchemaConfig.FormConfig<def, value> =\n undefined as never;\n\n constructor(config: MultiStepFormSchema.config<def, value>) {\n const {\n nameTransformCasing = DEFAULT_CASING,\n steps,\n form,\n storage,\n context,\n } = config;\n const options = {\n steps,\n nameTransformCasing,\n storage,\n form,\n } as MultiStepFormStepSchema.config<def, value>;\n\n super(options);\n\n this.stepSchema = new MultiStepFormStepSchema(options);\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.stepSchema.original,\n getValue: () => this.stepSchema.value,\n setValue: (value) => {\n this.stepSchema.value = { ...value };\n this.storage.add(value);\n this.notify();\n },\n });\n this.storageConfig = {\n key: (storage?.key ??\n DEFAULT_STORAGE_KEY) as StepSchema.inferStorageKey<def>,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined,\n };\n this.storage = new MultiStepFormStorage({\n data: this.stepSchema.value,\n ...this.storageConfig,\n });\n if (context) {\n this.context = context;\n }\n\n if (form) {\n this.formConfig = form;\n }\n }\n\n /**\n * A helper function to add a form configuration to the {@linkcode MultiStepFormSchema}.\n *\n * By calling this function, you will have access to the create form component in all step\n * utility functions.\n *\n * @example\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: '',\n * },\n * },\n * },\n * },\n * }).withForm({\n * render(data) {\n * return (props: MyCustomProps) => {\n * return <form {...props}>{props.children}</form>;\n * };\n * },\n * });\n * ```\n * @param config The form configuration.\n * @returns A new {@linkcode MultiStepFormSchema} with the form configuration.\n */\n withForm<\n const formConfig extends MultiStepFormSchemaConfig.FormConfig<def, value>,\n >(config: formConfig) {\n const { key, store, throwWhenUndefined } = this.storageConfig;\n\n return new MultiStepFormSchema<\n Expand<def & Readonly<{ form: formConfig }>>\n >({\n steps: this.stepSchema.original,\n form: config,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key,\n store,\n throwWhenUndefined: throwWhenUndefined,\n },\n } as never);\n }\n\n withContext() {\n const context = createMultiStepFormContext(this);\n\n const t = Object.assign(this, { context });\n\n // return new instance\n return new MultiStepFormSchema<def, value>({\n steps: this.stepSchema.original,\n form: this.formConfig,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key: this.storageConfig.key,\n store: this.storageConfig.store,\n throwWhenUndefined: this.storageConfig.throwWhenUndefined,\n },\n context,\n } as never);\n }\n\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.stepSchema.value,\n });\n }\n}\n\nexport function createMultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>(options: def) {\n return new MultiStepFormSchema<def, value>(options);\n}\n"],"mappings":";;;;;;;AAwCA,IAAa,sBAAb,MAAa,4BAIHA,sDAEV;CACE;CACA,CAASC;CACT,AAAkB;CAIlB,AAAkB;CAIlB,AAAS,UAAkD;CAC3D,AAAS,aACP;CAEF,YAAY,QAAgD;EAC1D,MAAM,EACJ,sBAAsBC,kDACtB,OACA,MACA,SACA,YACE;EACJ,MAAM,UAAU;GACd;GACA;GACA;GACA;GACD;AAED,QAAM,QAAQ;AAEd,OAAK,aAAa,IAAIC,4CAAwB,QAAQ;AACtD,QAAKF,WAAY,IAAIG,6EAAgC;GACnD,eAAe,KAAK,WAAW;GAC/B,gBAAgB,KAAK,WAAW;GAChC,WAAW,UAAU;AACnB,SAAK,WAAW,QAAQ,EAAE,GAAG,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM;AACvB,SAAK,QAAQ;;GAEhB,CAAC;AACF,OAAK,gBAAgB;GACnB,KAAM,SAAS,OACbC;GACF,OAAO,SAAS;GAChB,oBAAoB,SAAS;GAC9B;AACD,OAAK,UAAU,IAAIC,uDAAqB;GACtC,MAAM,KAAK,WAAW;GACtB,GAAG,KAAK;GACT,CAAC;AACF,MAAI,QACF,MAAK,UAAU;AAGjB,MAAI,KACF,MAAK,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCtB,SAEE,QAAoB;EACpB,MAAM,EAAE,KAAK,OAAO,uBAAuB,KAAK;AAEhD,SAAO,IAAI,oBAET;GACA,OAAO,KAAK,WAAW;GACvB,MAAM;GACN,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP;IACA;IACoB;IACrB;GACF,CAAU;;CAGb,cAAc;EACZ,MAAM,UAAUC,kDAA2B,KAAK;AAEtC,SAAO,OAAO,MAAM,EAAE,SAAS,CAAC;AAG1C,SAAO,IAAI,oBAAgC;GACzC,OAAO,KAAK,WAAW;GACvB,MAAM,KAAK;GACX,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP,KAAK,KAAK,cAAc;IACxB,OAAO,KAAK,cAAc;IAC1B,oBAAoB,KAAK,cAAc;IACxC;GACD;GACD,CAAU;;CAGb,gBAOE,SACA,IACA;AACA,SAAOC,8BAAgB;GACrB;GACA,QAAQ,EAAE,gBAAgB;IACxB,OAAO,MAAKP,SAAU,yBAAyB,SAAS;IACxD,QAAQ,MAAKA,SAAU,0BAA0B,SAAS;IAC3D;GACD;GACA,OAAO,KAAK,WAAW;GACxB,CAAC;;;AAIN,SAAgB,0BAGd,SAAc;AACd,QAAO,IAAI,oBAAgC,QAAQ"}
1
+ {"version":3,"file":"schema.cjs","names":["MultiStepFormSchemaCore","#internal","DEFAULT_CASING","MultiStepFormStepSchema","MultiStepFormStepSchemaInternal","DEFAULT_STORAGE_KEY","MultiStepFormStorage","createMultiStepFormContext","createComponent"],"sources":["../src/schema.ts"],"sourcesContent":["import {\n type BaseStorageConfig,\n DEFAULT_CASING,\n DEFAULT_STORAGE_KEY,\n type Expand,\n type HelperFn,\n type HelperFnChosenSteps,\n MultiStepFormSchema as MultiStepFormSchemaCore,\n MultiStepFormStorage,\n type steps,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport {\n createMultiStepFormContext,\n type MultiStepFormContextResult,\n} from './create-context';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { type HelperFunctions, MultiStepFormStepSchema } from './step-schema';\nimport { createComponent, type CreateComponentCallback } from './utils';\n\n// Helper inference types for `AnyMultiStepFormSchema`\nexport namespace MultiStepFormSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > = MultiStepFormStepSchema.config<def, value> & {\n /**\n * The React context for the multi step form.\n *\n * This is a private property and is not meant to be used directly.\n * @private\n * @internal\n */\n context?: MultiStepFormContextResult<def, value>;\n };\n}\n\nexport class MultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormSchemaCore<def, value>\n implements HelperFunctions<def, value>\n{\n stepSchema: MultiStepFormStepSchema<def, value>;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n override readonly storage: MultiStepFormStorage<\n value,\n StepSchema.inferStorageKey<def>\n >;\n override readonly storageConfig: BaseStorageConfig<\n StepSchema.inferStorageKey<def>\n >;\n\n readonly context: MultiStepFormContextResult<def, value> = undefined as never;\n readonly formConfig: MultiStepFormSchemaConfig.FormConfig<def, value> =\n undefined as never;\n\n constructor(config: MultiStepFormSchema.config<def, value>) {\n const {\n nameTransformCasing = DEFAULT_CASING,\n steps,\n form,\n storage,\n context,\n } = config;\n const options = {\n steps,\n nameTransformCasing,\n storage,\n form,\n } as MultiStepFormStepSchema.config<def, value>;\n\n super(options);\n\n this.stepSchema = new MultiStepFormStepSchema(options);\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.stepSchema.original,\n getValue: () => this.stepSchema.value,\n setValue: (value) => {\n this.stepSchema.value = { ...value };\n this.storage.add(value);\n this.notify();\n },\n });\n this.storageConfig = {\n key: (storage?.key ??\n DEFAULT_STORAGE_KEY) as StepSchema.inferStorageKey<def>,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined,\n };\n this.storage = new MultiStepFormStorage({\n data: this.stepSchema.value,\n ...this.storageConfig,\n });\n if (context) {\n this.context = context;\n }\n\n if (form) {\n this.formConfig = form;\n }\n }\n\n /**\n * A helper function to add a form configuration to the {@linkcode MultiStepFormSchema}.\n *\n * By calling this function, you will have access to the create form component in all step\n * utility functions.\n *\n * @example\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: '',\n * },\n * },\n * },\n * },\n * }).withForm({\n * render(data) {\n * return (props: MyCustomProps) => {\n * return <form {...props}>{props.children}</form>;\n * };\n * },\n * });\n * ```\n * @param config The form configuration.\n * @returns A new {@linkcode MultiStepFormSchema} with the form configuration.\n */\n withForm<\n const formConfig extends MultiStepFormSchemaConfig.FormConfig<def, value>,\n >(config: formConfig) {\n const { key, store, throwWhenUndefined } = this.storageConfig;\n\n return new MultiStepFormSchema<\n Expand<def & Readonly<{ form: formConfig }>>\n >({\n steps: this.stepSchema.original,\n form: config,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key,\n store,\n throwWhenUndefined: throwWhenUndefined,\n },\n } as never);\n }\n\n withContext() {\n const context = createMultiStepFormContext(this);\n\n return new MultiStepFormSchema<def, value>({\n steps: this.stepSchema.original,\n form: this.formConfig,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key: this.storageConfig.key,\n store: this.storageConfig.store,\n throwWhenUndefined: this.storageConfig.throwWhenUndefined,\n },\n context,\n } as never);\n }\n\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.stepSchema.value,\n });\n }\n}\n\nexport function createMultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>(options: def) {\n return new MultiStepFormSchema<def, value>(options);\n}\n"],"mappings":";;;;;;;AAwCA,IAAa,sBAAb,MAAa,4BAIHA,sDAEV;CACE;CACA,CAASC;CACT,AAAkB;CAIlB,AAAkB;CAIlB,AAAS,UAAkD;CAC3D,AAAS,aACP;CAEF,YAAY,QAAgD;EAC1D,MAAM,EACJ,sBAAsBC,kDACtB,OACA,MACA,SACA,YACE;EACJ,MAAM,UAAU;GACd;GACA;GACA;GACA;GACD;AAED,QAAM,QAAQ;AAEd,OAAK,aAAa,IAAIC,4CAAwB,QAAQ;AACtD,QAAKF,WAAY,IAAIG,6EAAgC;GACnD,eAAe,KAAK,WAAW;GAC/B,gBAAgB,KAAK,WAAW;GAChC,WAAW,UAAU;AACnB,SAAK,WAAW,QAAQ,EAAE,GAAG,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM;AACvB,SAAK,QAAQ;;GAEhB,CAAC;AACF,OAAK,gBAAgB;GACnB,KAAM,SAAS,OACbC;GACF,OAAO,SAAS;GAChB,oBAAoB,SAAS;GAC9B;AACD,OAAK,UAAU,IAAIC,uDAAqB;GACtC,MAAM,KAAK,WAAW;GACtB,GAAG,KAAK;GACT,CAAC;AACF,MAAI,QACF,MAAK,UAAU;AAGjB,MAAI,KACF,MAAK,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCtB,SAEE,QAAoB;EACpB,MAAM,EAAE,KAAK,OAAO,uBAAuB,KAAK;AAEhD,SAAO,IAAI,oBAET;GACA,OAAO,KAAK,WAAW;GACvB,MAAM;GACN,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP;IACA;IACoB;IACrB;GACF,CAAU;;CAGb,cAAc;EACZ,MAAM,UAAUC,kDAA2B,KAAK;AAEhD,SAAO,IAAI,oBAAgC;GACzC,OAAO,KAAK,WAAW;GACvB,MAAM,KAAK;GACX,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP,KAAK,KAAK,cAAc;IACxB,OAAO,KAAK,cAAc;IAC1B,oBAAoB,KAAK,cAAc;IACxC;GACD;GACD,CAAU;;CAGb,gBAOE,SACA,IACA;AACA,SAAOC,8BAAgB;GACrB;GACA,QAAQ,EAAE,gBAAgB;IACxB,OAAO,MAAKP,SAAU,yBAAyB,SAAS;IACxD,QAAQ,MAAKA,SAAU,0BAA0B,SAAS;IAC3D;GACD;GACA,OAAO,KAAK,WAAW;GACxB,CAAC;;;AAIN,SAAgB,0BAGd,SAAc;AACd,QAAO,IAAI,oBAAgC,QAAQ"}
package/dist/schema.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CreateComponentCallback, CreatedMultiStepFormComponent } from "./utils.cjs";
2
+ import { MultiStepFormContextResult } from "./create-context.cjs";
2
3
  import { MultiStepFormSchemaConfig } from "./form-config.cjs";
3
4
  import { HelperFunctions, MultiStepFormStepSchema as MultiStepFormStepSchema$1 } from "./step-schema.cjs";
4
- import { MultiStepFormContextResult } from "./create-context.cjs";
5
5
  import * as _jfdevelops_multi_step_form_core0 from "@jfdevelops/multi-step-form-core";
6
6
  import { BaseStorageConfig, Expand, HelperFn, HelperFnChosenSteps, MultiStepFormSchema, MultiStepFormStorage, steps } from "@jfdevelops/multi-step-form-core";
7
7
  import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
package/dist/schema.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CreateComponentCallback, CreatedMultiStepFormComponent } from "./utils.mjs";
2
+ import { MultiStepFormContextResult } from "./create-context.mjs";
2
3
  import { MultiStepFormSchemaConfig } from "./form-config.mjs";
3
4
  import { HelperFunctions, MultiStepFormStepSchema as MultiStepFormStepSchema$1 } from "./step-schema.mjs";
4
- import { MultiStepFormContextResult } from "./create-context.mjs";
5
5
  import * as _jfdevelops_multi_step_form_core0 from "@jfdevelops/multi-step-form-core";
6
6
  import { BaseStorageConfig, Expand, HelperFn, HelperFnChosenSteps, MultiStepFormSchema, MultiStepFormStorage, steps } from "@jfdevelops/multi-step-form-core";
7
7
  import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
package/dist/schema.mjs CHANGED
@@ -1,6 +1,6 @@
1
+ import { createMultiStepFormContext } from "./create-context.mjs";
1
2
  import { createComponent } from "./utils.mjs";
2
3
  import { MultiStepFormStepSchema as MultiStepFormStepSchema$1 } from "./step-schema.mjs";
3
- import { createMultiStepFormContext } from "./create-context.mjs";
4
4
  import { DEFAULT_CASING, DEFAULT_STORAGE_KEY, MultiStepFormSchema, MultiStepFormStorage } from "@jfdevelops/multi-step-form-core";
5
5
  import { MultiStepFormStepSchemaInternal } from "@jfdevelops/multi-step-form-core/_internals";
6
6
 
@@ -88,7 +88,6 @@ var MultiStepFormSchema$1 = class MultiStepFormSchema$1 extends MultiStepFormSch
88
88
  }
89
89
  withContext() {
90
90
  const context = createMultiStepFormContext(this);
91
- Object.assign(this, { context });
92
91
  return new MultiStepFormSchema$1({
93
92
  steps: this.stepSchema.original,
94
93
  form: this.formConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["MultiStepFormSchema","MultiStepFormSchemaCore","#internal","MultiStepFormStepSchema"],"sources":["../src/schema.ts"],"sourcesContent":["import {\n type BaseStorageConfig,\n DEFAULT_CASING,\n DEFAULT_STORAGE_KEY,\n type Expand,\n type HelperFn,\n type HelperFnChosenSteps,\n MultiStepFormSchema as MultiStepFormSchemaCore,\n MultiStepFormStorage,\n type steps,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { type HelperFunctions, MultiStepFormStepSchema } from './step-schema';\nimport { createComponent, type CreateComponentCallback } from './utils';\nimport {\n createMultiStepFormContext,\n type MultiStepFormContextResult,\n} from './create-context';\n\n// Helper inference types for `AnyMultiStepFormSchema`\nexport namespace MultiStepFormSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > = MultiStepFormStepSchema.config<def, value> & {\n /**\n * The React context for the multi step form.\n *\n * This is a private property and is not meant to be used directly.\n * @private\n * @internal\n */\n context?: MultiStepFormContextResult<def, value>;\n };\n}\n\nexport class MultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormSchemaCore<def, value>\n implements HelperFunctions<def, value>\n{\n stepSchema: MultiStepFormStepSchema<def, value>;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n override readonly storage: MultiStepFormStorage<\n value,\n StepSchema.inferStorageKey<def>\n >;\n override readonly storageConfig: BaseStorageConfig<\n StepSchema.inferStorageKey<def>\n >;\n\n readonly context: MultiStepFormContextResult<def, value> = undefined as never;\n readonly formConfig: MultiStepFormSchemaConfig.FormConfig<def, value> =\n undefined as never;\n\n constructor(config: MultiStepFormSchema.config<def, value>) {\n const {\n nameTransformCasing = DEFAULT_CASING,\n steps,\n form,\n storage,\n context,\n } = config;\n const options = {\n steps,\n nameTransformCasing,\n storage,\n form,\n } as MultiStepFormStepSchema.config<def, value>;\n\n super(options);\n\n this.stepSchema = new MultiStepFormStepSchema(options);\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.stepSchema.original,\n getValue: () => this.stepSchema.value,\n setValue: (value) => {\n this.stepSchema.value = { ...value };\n this.storage.add(value);\n this.notify();\n },\n });\n this.storageConfig = {\n key: (storage?.key ??\n DEFAULT_STORAGE_KEY) as StepSchema.inferStorageKey<def>,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined,\n };\n this.storage = new MultiStepFormStorage({\n data: this.stepSchema.value,\n ...this.storageConfig,\n });\n if (context) {\n this.context = context;\n }\n\n if (form) {\n this.formConfig = form;\n }\n }\n\n /**\n * A helper function to add a form configuration to the {@linkcode MultiStepFormSchema}.\n *\n * By calling this function, you will have access to the create form component in all step\n * utility functions.\n *\n * @example\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: '',\n * },\n * },\n * },\n * },\n * }).withForm({\n * render(data) {\n * return (props: MyCustomProps) => {\n * return <form {...props}>{props.children}</form>;\n * };\n * },\n * });\n * ```\n * @param config The form configuration.\n * @returns A new {@linkcode MultiStepFormSchema} with the form configuration.\n */\n withForm<\n const formConfig extends MultiStepFormSchemaConfig.FormConfig<def, value>,\n >(config: formConfig) {\n const { key, store, throwWhenUndefined } = this.storageConfig;\n\n return new MultiStepFormSchema<\n Expand<def & Readonly<{ form: formConfig }>>\n >({\n steps: this.stepSchema.original,\n form: config,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key,\n store,\n throwWhenUndefined: throwWhenUndefined,\n },\n } as never);\n }\n\n withContext() {\n const context = createMultiStepFormContext(this);\n\n const t = Object.assign(this, { context });\n\n // return new instance\n return new MultiStepFormSchema<def, value>({\n steps: this.stepSchema.original,\n form: this.formConfig,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key: this.storageConfig.key,\n store: this.storageConfig.store,\n throwWhenUndefined: this.storageConfig.throwWhenUndefined,\n },\n context,\n } as never);\n }\n\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.stepSchema.value,\n });\n }\n}\n\nexport function createMultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>(options: def) {\n return new MultiStepFormSchema<def, value>(options);\n}\n"],"mappings":";;;;;;;AAwCA,IAAaA,wBAAb,MAAaA,8BAIHC,oBAEV;CACE;CACA,CAASC;CACT,AAAkB;CAIlB,AAAkB;CAIlB,AAAS,UAAkD;CAC3D,AAAS,aACP;CAEF,YAAY,QAAgD;EAC1D,MAAM,EACJ,sBAAsB,gBACtB,gBACA,MACA,SACA,YACE;EACJ,MAAM,UAAU;GACd;GACA;GACA;GACA;GACD;AAED,QAAM,QAAQ;AAEd,OAAK,aAAa,IAAIC,0BAAwB,QAAQ;AACtD,QAAKD,WAAY,IAAI,gCAAgC;GACnD,eAAe,KAAK,WAAW;GAC/B,gBAAgB,KAAK,WAAW;GAChC,WAAW,UAAU;AACnB,SAAK,WAAW,QAAQ,EAAE,GAAG,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM;AACvB,SAAK,QAAQ;;GAEhB,CAAC;AACF,OAAK,gBAAgB;GACnB,KAAM,SAAS,OACb;GACF,OAAO,SAAS;GAChB,oBAAoB,SAAS;GAC9B;AACD,OAAK,UAAU,IAAI,qBAAqB;GACtC,MAAM,KAAK,WAAW;GACtB,GAAG,KAAK;GACT,CAAC;AACF,MAAI,QACF,MAAK,UAAU;AAGjB,MAAI,KACF,MAAK,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCtB,SAEE,QAAoB;EACpB,MAAM,EAAE,KAAK,OAAO,uBAAuB,KAAK;AAEhD,SAAO,IAAIF,sBAET;GACA,OAAO,KAAK,WAAW;GACvB,MAAM;GACN,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP;IACA;IACoB;IACrB;GACF,CAAU;;CAGb,cAAc;EACZ,MAAM,UAAU,2BAA2B,KAAK;AAEtC,SAAO,OAAO,MAAM,EAAE,SAAS,CAAC;AAG1C,SAAO,IAAIA,sBAAgC;GACzC,OAAO,KAAK,WAAW;GACvB,MAAM,KAAK;GACX,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP,KAAK,KAAK,cAAc;IACxB,OAAO,KAAK,cAAc;IAC1B,oBAAoB,KAAK,cAAc;IACxC;GACD;GACD,CAAU;;CAGb,gBAOE,SACA,IACA;AACA,SAAO,gBAAgB;GACrB;GACA,QAAQ,EAAE,gBAAgB;IACxB,OAAO,MAAKE,SAAU,yBAAyB,SAAS;IACxD,QAAQ,MAAKA,SAAU,0BAA0B,SAAS;IAC3D;GACD;GACA,OAAO,KAAK,WAAW;GACxB,CAAC;;;AAIN,SAAgB,0BAGd,SAAc;AACd,QAAO,IAAIF,sBAAgC,QAAQ"}
1
+ {"version":3,"file":"schema.mjs","names":["MultiStepFormSchema","MultiStepFormSchemaCore","#internal","MultiStepFormStepSchema"],"sources":["../src/schema.ts"],"sourcesContent":["import {\n type BaseStorageConfig,\n DEFAULT_CASING,\n DEFAULT_STORAGE_KEY,\n type Expand,\n type HelperFn,\n type HelperFnChosenSteps,\n MultiStepFormSchema as MultiStepFormSchemaCore,\n MultiStepFormStorage,\n type steps,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport {\n createMultiStepFormContext,\n type MultiStepFormContextResult,\n} from './create-context';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { type HelperFunctions, MultiStepFormStepSchema } from './step-schema';\nimport { createComponent, type CreateComponentCallback } from './utils';\n\n// Helper inference types for `AnyMultiStepFormSchema`\nexport namespace MultiStepFormSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > = MultiStepFormStepSchema.config<def, value> & {\n /**\n * The React context for the multi step form.\n *\n * This is a private property and is not meant to be used directly.\n * @private\n * @internal\n */\n context?: MultiStepFormContextResult<def, value>;\n };\n}\n\nexport class MultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormSchemaCore<def, value>\n implements HelperFunctions<def, value>\n{\n stepSchema: MultiStepFormStepSchema<def, value>;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n override readonly storage: MultiStepFormStorage<\n value,\n StepSchema.inferStorageKey<def>\n >;\n override readonly storageConfig: BaseStorageConfig<\n StepSchema.inferStorageKey<def>\n >;\n\n readonly context: MultiStepFormContextResult<def, value> = undefined as never;\n readonly formConfig: MultiStepFormSchemaConfig.FormConfig<def, value> =\n undefined as never;\n\n constructor(config: MultiStepFormSchema.config<def, value>) {\n const {\n nameTransformCasing = DEFAULT_CASING,\n steps,\n form,\n storage,\n context,\n } = config;\n const options = {\n steps,\n nameTransformCasing,\n storage,\n form,\n } as MultiStepFormStepSchema.config<def, value>;\n\n super(options);\n\n this.stepSchema = new MultiStepFormStepSchema(options);\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.stepSchema.original,\n getValue: () => this.stepSchema.value,\n setValue: (value) => {\n this.stepSchema.value = { ...value };\n this.storage.add(value);\n this.notify();\n },\n });\n this.storageConfig = {\n key: (storage?.key ??\n DEFAULT_STORAGE_KEY) as StepSchema.inferStorageKey<def>,\n store: storage?.store,\n throwWhenUndefined: storage?.throwWhenUndefined,\n };\n this.storage = new MultiStepFormStorage({\n data: this.stepSchema.value,\n ...this.storageConfig,\n });\n if (context) {\n this.context = context;\n }\n\n if (form) {\n this.formConfig = form;\n }\n }\n\n /**\n * A helper function to add a form configuration to the {@linkcode MultiStepFormSchema}.\n *\n * By calling this function, you will have access to the create form component in all step\n * utility functions.\n *\n * @example\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: '',\n * },\n * },\n * },\n * },\n * }).withForm({\n * render(data) {\n * return (props: MyCustomProps) => {\n * return <form {...props}>{props.children}</form>;\n * };\n * },\n * });\n * ```\n * @param config The form configuration.\n * @returns A new {@linkcode MultiStepFormSchema} with the form configuration.\n */\n withForm<\n const formConfig extends MultiStepFormSchemaConfig.FormConfig<def, value>,\n >(config: formConfig) {\n const { key, store, throwWhenUndefined } = this.storageConfig;\n\n return new MultiStepFormSchema<\n Expand<def & Readonly<{ form: formConfig }>>\n >({\n steps: this.stepSchema.original,\n form: config,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key,\n store,\n throwWhenUndefined: throwWhenUndefined,\n },\n } as never);\n }\n\n withContext() {\n const context = createMultiStepFormContext(this);\n\n return new MultiStepFormSchema<def, value>({\n steps: this.stepSchema.original,\n form: this.formConfig,\n nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,\n storage: {\n key: this.storageConfig.key,\n store: this.storageConfig.store,\n throwWhenUndefined: this.storageConfig.throwWhenUndefined,\n },\n context,\n } as never);\n }\n\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.stepSchema.value,\n });\n }\n}\n\nexport function createMultiStepFormSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>(options: def) {\n return new MultiStepFormSchema<def, value>(options);\n}\n"],"mappings":";;;;;;;AAwCA,IAAaA,wBAAb,MAAaA,8BAIHC,oBAEV;CACE;CACA,CAASC;CACT,AAAkB;CAIlB,AAAkB;CAIlB,AAAS,UAAkD;CAC3D,AAAS,aACP;CAEF,YAAY,QAAgD;EAC1D,MAAM,EACJ,sBAAsB,gBACtB,gBACA,MACA,SACA,YACE;EACJ,MAAM,UAAU;GACd;GACA;GACA;GACA;GACD;AAED,QAAM,QAAQ;AAEd,OAAK,aAAa,IAAIC,0BAAwB,QAAQ;AACtD,QAAKD,WAAY,IAAI,gCAAgC;GACnD,eAAe,KAAK,WAAW;GAC/B,gBAAgB,KAAK,WAAW;GAChC,WAAW,UAAU;AACnB,SAAK,WAAW,QAAQ,EAAE,GAAG,OAAO;AACpC,SAAK,QAAQ,IAAI,MAAM;AACvB,SAAK,QAAQ;;GAEhB,CAAC;AACF,OAAK,gBAAgB;GACnB,KAAM,SAAS,OACb;GACF,OAAO,SAAS;GAChB,oBAAoB,SAAS;GAC9B;AACD,OAAK,UAAU,IAAI,qBAAqB;GACtC,MAAM,KAAK,WAAW;GACtB,GAAG,KAAK;GACT,CAAC;AACF,MAAI,QACF,MAAK,UAAU;AAGjB,MAAI,KACF,MAAK,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCtB,SAEE,QAAoB;EACpB,MAAM,EAAE,KAAK,OAAO,uBAAuB,KAAK;AAEhD,SAAO,IAAIF,sBAET;GACA,OAAO,KAAK,WAAW;GACvB,MAAM;GACN,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP;IACA;IACoB;IACrB;GACF,CAAU;;CAGb,cAAc;EACZ,MAAM,UAAU,2BAA2B,KAAK;AAEhD,SAAO,IAAIA,sBAAgC;GACzC,OAAO,KAAK,WAAW;GACvB,MAAM,KAAK;GACX,qBAAqB,KAAK,WAAW;GACrC,SAAS;IACP,KAAK,KAAK,cAAc;IACxB,OAAO,KAAK,cAAc;IAC1B,oBAAoB,KAAK,cAAc;IACxC;GACD;GACD,CAAU;;CAGb,gBAOE,SACA,IACA;AACA,SAAO,gBAAgB;GACrB;GACA,QAAQ,EAAE,gBAAgB;IACxB,OAAO,MAAKE,SAAU,yBAAyB,SAAS;IACxD,QAAQ,MAAKA,SAAU,0BAA0B,SAAS;IAC3D;GACD;GACA,OAAO,KAAK,WAAW;GACxB,CAAC;;;AAIN,SAAgB,0BAGd,SAAc;AACd,QAAO,IAAIF,sBAAgC,QAAQ"}
@@ -229,17 +229,7 @@ var MultiStepFormStepSchema = class extends __jfdevelops_multi_step_form_core.Mu
229
229
  });
230
230
  }
231
231
  createDefaultValues(targetStep) {
232
- const invariant = (0, __jfdevelops_multi_step_form_core.createInvariant)("[createDefaultValues]");
233
- invariant(targetStep in __jfdevelops_multi_step_form_core.steps, `The target step ${targetStep} is not a valid step key`);
234
- const current = this.value[targetStep];
235
- invariant(typeof current === "object" && current !== null, `The target step ${targetStep} is not an object`);
236
- invariant("fields" in current, `No "fields" were found for ${targetStep}`);
237
- let defaultValues = {};
238
- for (const [fieldName, fieldValues] of Object.entries(current.fields)) defaultValues = {
239
- ...defaultValues,
240
- [fieldName]: fieldValues.defaultValue
241
- };
242
- return defaultValues;
232
+ return __jfdevelops_multi_step_form_core.fields.getDefaultValues(this.value, targetStep);
243
233
  }
244
234
  };
245
235
 
@@ -1 +1 @@
1
- {"version":3,"file":"step-schema.cjs","names":["MultiStepFormStepSchemaBase","#internal","steps","MultiStepFormStepSchemaInternal","MultiStepFormSchemaConfig","invariant: Invariant","resolvedCtxCreator","MultiStepFormLogger","getValidatedCustomInputHooks","field","path","fields","createUseSelector","selector","createComponent"],"sources":["../src/step-schema.ts"],"sourcesContent":["import {\n createCtx,\n createInvariant,\n type Expand,\n fields,\n type HelperFn,\n type HelperFnChosenSteps,\n type HelperFnInput,\n type Invariant,\n MultiStepFormLogger,\n MultiStepFormStepSchema as MultiStepFormStepSchemaBase,\n type ResetFn,\n steps,\n type UpdateFn,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n path,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { field } from './field';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { createUseSelector, type UseSelector } from './hooks/use-selector';\nimport { selector } from './selector';\nimport {\n createComponent,\n type CreateComponent,\n type CreateComponentCallback,\n type CreatedMultiStepFormComponent,\n getValidatedCustomInputHooks,\n resolvedCtxCreator,\n} from './utils';\n\nexport type CreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = <targetStep extends steps.StepNumbers<value>, props = undefined>(\n options: HelperFn.BaseOptions<value, [targetStep]>,\n fn: CreateComponentCallback<value, [targetStep], props>\n) => CreatedMultiStepFormComponent<props>;\n\nexport namespace StepSpecificComponent {\n type instantiateFormComponentForAllSteps<\n def extends StepSchema.Config,\n value = MultiStepFormSchemaConfig.instantiateFormConfig<def>,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<value> extends MultiStepFormSchemaConfig.defaultEnabledFor\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {};\n type instantiateFormComponentForTuple<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends MultiStepFormSchemaConfig.EnabledForSteps.get<def>[number]\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n\n type instantiateFormComponentForObject<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends keyof MultiStepFormSchemaConfig.EnabledForSteps.get<def>\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n type instantiateFormComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = {\n all: instantiateFormComponentForAllSteps<def>;\n tuple: instantiateFormComponentForTuple<def, steps, chosenSteps>;\n object: instantiateFormComponentForObject<def, steps, chosenSteps>;\n };\n // The logic for getting the formCtx only works for step specific `createComponent`\n // (i.e: step1.createComponent(...)) as of now. Reason is because I can't think of a good API for integrating the form\n // ctx into the main `createComponent` since multiple steps can be chosen. In that case\n // how would the logic work for when the form component should be defined in the callback?\n // Ideas:\n // - Make the main `createComponent` return a function that accepts the current step\n export type formComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = instantiateFormComponent<\n def,\n steps,\n chosenSteps\n >[MultiStepFormSchemaConfig.EnabledForSteps.resolveType<def, steps>];\n export type updateWrappers<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n > = {\n /**\n * A useful wrapper around `update` to update the specific field.\n */\n onInputChange: UpdateFn.stepSpecific<value, targetStep>;\n /**\n * A useful wrapper for `update` to reset a specific field's value to its\n * original config value.\n * @resetFn\n */\n reset: ResetFn.stepSpecific<value, targetStep>;\n };\n type buildCurrentStep<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n > = Expand<{\n [key in targetStep]: HelperFnChosenSteps.currentStep<value, [key]>;\n }>;\n\n export type input<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n additionalCtx extends Record<string, unknown>,\n > = HelperFnInput.BaseInput<value, [targetStep], never, additionalCtx> &\n updateWrappers<value, targetStep> & {\n Field: field.component<buildCurrentStep<def, value, targetStep>>;\n /**\n * A hook for reactively selecting a value from the form context.\n * The selector function receives the contextual data for the currently rendered step, and returns any derived value.\n * `useSelector` will automatically provide the latest context data on updates, and will subscribe the caller for automatic re-renders when the underlying data changes.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @returns The derived value, which will re-render the component on change\n *\n * @example\n * const someValue = useSelector(ctx => ctx.fields.username.value);\n */\n useSelector: UseSelector<buildCurrentStep<def, value, targetStep>>;\n /**\n * A component for reactively displaying a value from the form context.\n * Unlike `useSelector`, this component only re-renders itself, not the parent component.\n * Use this when you want to display a reactive value without causing parent re-renders.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @param children - Optional render prop that receives the selected value\n *\n * @example\n * <Selector selector={(ctx) => ctx.step1.fields.firstName.defaultValue}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n */\n Selector: selector.component<buildCurrentStep<def, value, targetStep>>;\n };\n\n export type callback<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n props,\n additionalCtx extends Record<string, unknown> = {},\n > = CreateComponent<\n Expand<\n input<def, value, targetStep, additionalCtx> &\n formComponent<def, value, [targetStep]> &\n additionalCtx\n >,\n props\n >;\n export const DEFAULT_FORM_INSTANCE_ALIAS = 'form';\n export type defaultFormInstanceAlias = typeof DEFAULT_FORM_INSTANCE_ALIAS;\n export type formInstanceOptions<alias extends string, input, ret> = {\n /**\n * The name of the return value of the `render` method.\n */\n alias?: alias;\n /**\n * A function that renders/creates the form instance. This function will be called\n * at the top level of the component, ensuring hooks are called in a valid React context.\n *\n * @param input - The input object containing context and default values\n * @returns The form instance (typically from a hook like `useForm`)\n *\n * @example\n * ```tsx\n * useFormInstance: {\n * render({ defaultValues }) {\n * return useForm({\n * defaultValues,\n * });\n * },\n * }\n * ```\n *\n * **Verification**: The hook call is automatically verified:\n * - Errors are caught and reported with helpful messages\n * - In development, hook calls are logged to console.debug\n * - The hook must be called at the component top level (enforced by the framework)\n */\n render: (input: input) => ret;\n };\n\n export type options<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n formAlias extends string,\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n > = HelperFn.CtxDataSelector<value, [targetStep], additionalCtx> & {\n /**\n * If set to `true`, you'll be able to open the {@linkcode console} to view logs.\n */\n debug?: boolean;\n useFormInstance?: formInstanceOptions<\n formAlias,\n Pick<HelperFnInput.BaseInput<value, [targetStep]>, 'ctx'> & {\n /**\n * An object containing all the default values for the current step.\n */\n defaultValues: Expand<fields.getDefaultValues<value, [targetStep]>>;\n },\n formInstance\n >;\n };\n}\n\nexport interface StepSpecificCreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n> {\n /**\n * A utility function to easily create a component for the current step.\n * @param fn The callback function where the component is defined.\n */\n <props = undefined>(\n fn: StepSpecificComponent.callback<def, value, targetStep, props>\n ): CreatedMultiStepFormComponent<props>;\n /**\n * A utility function to easily create a component for the current step.\n * @param options Specific config options for creating a component for the current step.\n * @param fn The callback function where the component is defined.\n * @returns The created component.\n */\n <\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n props = undefined,\n >(\n options: StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >,\n fn: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ): CreatedMultiStepFormComponent<props>;\n}\n\nexport interface HelperFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> {\n createComponent: CreateComponentFn<def, value>;\n}\nnamespace CreateComponentImplConfig {\n export type stepSpecificConfig<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = {\n isStepSpecific: true;\n defaultId: string;\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n\n export type nonStepSpecific = {\n isStepSpecific: false;\n };\n\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = nonStepSpecific | stepSpecificConfig<def, value>;\n}\n\nexport namespace MultiStepFormStepSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = def & {\n /**\n * The form configuration.\n *\n * This is a private property and is not meant to be used directly.\n * If you want to configure the form, do so with the {@linkcode instantiateFormConfig} method.\n * @private\n * @internal\n */\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n}\n\ndeclare module '@jfdevelops/multi-step-form-core' {\n namespace steps {\n interface ExtendedStepSpecificFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n key extends steps.StepNumbers<value>,\n > {\n createComponent: StepSpecificCreateComponentFn<def, value, key>;\n }\n }\n}\n\nexport class MultiStepFormStepSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormStepSchemaBase<def, value>\n implements HelperFunctions<def, value>\n{\n value: value;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n\n constructor(config: MultiStepFormStepSchema.config<def, value>) {\n const { form, ...rest } = config;\n\n super(rest as never);\n\n this.value = steps.instantiate({ steps: this.original });\n\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.sync();\n const availableSteps = this.steps.value;\n const createFormConfig = MultiStepFormSchemaConfig.instantiateFormConfig(\n this.value,\n availableSteps\n );\n const instantiatedForm = createFormConfig(form);\n this.value = this.#internal.enrichValues(this.value, (step) => {\n const targetStep = `step${step}` as steps.StepNumbers<value>;\n\n const id = form?.id ?? targetStep;\n\n return {\n createComponent: this.createStepSpecificComponentFactory(targetStep, {\n isStepSpecific: true,\n defaultId: id,\n form: instantiatedForm as never,\n }),\n };\n });\n }\n\n private createFormComponent(\n form: Omit<MultiStepFormSchemaConfig.FormConfig<def, value>, 'alias'>,\n defaultId: string\n ) {\n const { render, enabledForSteps = 'all', id = defaultId } = form;\n\n const ctx = {\n id,\n steps: createCtx(this.value, enabledForSteps as never),\n };\n\n return (props: MultiStepFormSchemaConfig.inferFormProps<value>) => {\n const Component = render(ctx as never);\n const invariant: Invariant = createInvariant('[createFormComponent]');\n\n invariant(\n typeof Component === 'function',\n 'The \"render\" property must be a function'\n );\n\n const C = Component(props);\n\n invariant(\n typeof C === 'function',\n 'The \"render\" function must return a valid React component'\n );\n\n return C;\n };\n }\n\n private createResolvedCtx<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown>,\n >(\n options: {\n stepData: chosenStep;\n logger: MultiStepFormLogger;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const { logger, stepData, ctxData } = options;\n // Create ctx fresh each time to ensure it has the latest this.value\n const ctx = createCtx(this.value, stepData);\n\n if (ctxData) {\n const [targetStep] = stepData;\n const { [targetStep]: _, ...values } = this.value;\n const createResolvedCtx = resolvedCtxCreator(logger, values as value);\n\n return createResolvedCtx({ ctx, ctxData } as never);\n }\n\n return ctx;\n }\n\n private createStepSpecificComponentImpl<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown> = {},\n >(\n stepData: chosenStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>,\n extraConfig?: {\n logger?: MultiStepFormLogger;\n input?: (\n ctx: Expand<HelperFn.buildCtx<value, chosenStep>>\n ) => Record<string, unknown>;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const [step] = stepData;\n const invariant: Invariant = createInvariant(`[${step}:createComponent]`);\n return <props>(fn: Function) =>\n ((props: props) => {\n const ctxData = extraConfig?.ctxData;\n const logger = extraConfig?.logger ?? new MultiStepFormLogger();\n const resolvedCtx = this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n });\n const extraInput = extraConfig?.input?.(resolvedCtx as never) ?? {};\n // Call hook functions from extraInput at the top level of the component\n // This ensures hooks are called in a valid React context (before any conditionals)\n const hookResults = getValidatedCustomInputHooks(extraInput);\n const { defaultId, form } = config;\n\n invariant(\n this.steps.isValidStep(step),\n `The target step ${step} is invalid. Note, this error shouldn't appear as the target step should always be valid. If you see this error, please open an issue.`\n );\n\n const stepNumber = Number.parseInt(step.replace('step', ''));\n\n invariant(\n !Number.isNaN(stepNumber),\n `An error occurred while extracting the number`\n );\n const current = this.value[step];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The current step must be an object, was ${typeof current}`\n );\n // These checks are mostly for type safety. `current` should _always_ be in the proper format.\n // On the off chance that it's not, we have the checks here to help, but these checks are basically\n // just for type safety.\n invariant(\n 'fields' in current,\n `Unable to find the \"fields\" for the current step`\n );\n invariant(\n typeof current.fields === 'object',\n `The \"fields\" property must be an object, was ${typeof current.fields}`\n );\n\n // Memoize Field component to prevent remounting on every render\n // This ensures input focus is maintained when ctx changes\n const Field = field.create({\n propsCreator: (name) => {\n // Access current step data directly to avoid stale closure\n const currentStep = this.value[step] as typeof current;\n const currentFields = Object.keys(\n currentStep.fields as Record<string, unknown>\n );\n const invariant: Invariant = createInvariant(`[${step}:Field]`);\n\n invariant(\n typeof name === 'string',\n (formatter) =>\n `[${step}:Field]: the \"name\" prop must be a string and a valid field for ${step}. Available fields include: \"${formatter.format(\n currentFields\n )}\"`\n );\n // TODO add support for deep keys (`name`)\n\n const allAvailableFields = path\n .createDeep(currentStep.fields)\n .map((value) => (value as string).replace('.defaultValue.', '.'));\n\n invariant(\n allAvailableFields.includes(name),\n (formatter) =>\n `[${step}:Field]: the field \"${name}\" doesn't exist for the current step. Available fields include: \"${formatter.format(\n allAvailableFields\n )}\".`\n );\n\n invariant(\n 'update' in currentStep,\n `[${step}:Field]: No \"update\" function was found`\n );\n\n const defaultValue = this.getValue(step as never, name);\n const builtValuePath = fields.buildValuePath(name);\n const { label, nameTransformCasing, type } = path.pickBy(\n currentStep.fields,\n builtValuePath\n );\n\n const targetFields = `fields.${builtValuePath}`;\n\n return {\n defaultValue,\n label,\n nameTransformCasing,\n type,\n name,\n onInputChange: <\n strict extends boolean = true,\n partial extends boolean = false,\n >(\n value: unknown,\n options?: field.onInputChangeOptions<strict, partial>\n ) => {\n // Handle Updater pattern: if value is a function, call it with the current field value\n let resolvedValue;\n\n if (typeof value === 'function') {\n const defaultValue = this.getValue(step as never, name);\n\n resolvedValue = value(defaultValue);\n } else {\n resolvedValue = value;\n }\n\n this.update({\n partial: options?.partial ?? false,\n strict: options?.strict ?? true,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n targetStep: step,\n updater: resolvedValue as never,\n fields: [targetFields] as never,\n });\n },\n reset: (options?: UpdateFn.DebugOptions) =>\n this.reset({\n fields: [targetFields] as never,\n targetStep: step,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n }),\n } as never;\n },\n subscribe: this.subscribe,\n getValue: (name) => this.getValue(step as never, name as never),\n selectorCtx: this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n }) as never,\n });\n\n // Create useSelector hook for reactive value access via selector\n // This allows getting values from ctx reactively without causing re-renders\n // Pass a function that creates fresh ctx on each call to avoid stale closures\n const useSelector = createUseSelector(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n // Create Selector component that uses useSelector internally\n // This allows parts of the UI to subscribe to specific values without\n // causing the parent component to re-render\n const Selector = selector.create(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n let fnInput = {\n ctx: resolvedCtx,\n onInputChange: this.#internal.createStepUpdaterFn(step),\n reset: this.#internal.createStepResetterFn(step),\n Field,\n useSelector,\n Selector,\n ...hookResults,\n };\n\n if (form) {\n const {\n alias = MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS,\n ...rest\n } = form;\n const enabledFor = rest.enabledForSteps ?? 'all';\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n if (\n MultiStepFormSchemaConfig.isFormAvailable(\n stepData as never,\n enabledFor as never\n )\n ) {\n fnInput = {\n ...fnInput,\n [alias]: this.createFormComponent(rest, defaultId),\n };\n }\n\n return fn(fnInput, props);\n }\n\n return fn(\n {\n ...fnInput,\n [MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS]:\n MultiStepFormSchemaConfig.createDefaultForm(defaultId),\n },\n props\n );\n }) as CreatedMultiStepFormComponent<props>;\n }\n\n private createStepSpecificComponentFactory<\n targetStep extends steps.StepNumbers<value>,\n >(\n targetStep: targetStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>\n ) {\n const impl = <\n formInstance,\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n additionalCtx extends Record<string, unknown> = {},\n >(\n optionsOrFn:\n | StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >\n | StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >,\n fn?: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ) => {\n const invariant: Invariant = createInvariant(\n '[createStepSpecificComponent]'\n );\n\n const createStepSpecificComponent = () => {\n invariant(\n typeof optionsOrFn === 'function',\n 'The first argument must be a function'\n );\n\n return this.createStepSpecificComponentImpl(\n [targetStep],\n config\n )(optionsOrFn);\n };\n\n if (typeof optionsOrFn === 'object') {\n const { useFormInstance, ctxData, debug } = optionsOrFn;\n const logger = new MultiStepFormLogger({\n debug,\n prefix(prefix) {\n return `${prefix}-${targetStep}-createComponent`;\n },\n });\n\n logger.info('First argument is an object');\n\n invariant(\n typeof fn === 'function',\n 'The second argument must be a function'\n );\n\n if (useFormInstance) {\n const {\n render,\n alias = StepSpecificComponent.DEFAULT_FORM_INSTANCE_ALIAS,\n } = useFormInstance;\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n // const [step] = stepData;\n\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n input: (ctx) => {\n const defaultValues = this.createDefaultValues(\n targetStep\n ) as never;\n\n return {\n [alias]: () =>\n render({\n ctx,\n defaultValues,\n }),\n };\n },\n })(fn);\n }\n\n if (ctxData) {\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n })(fn);\n }\n\n // Empty options object. Can throw here 🤷‍♂️\n // Maybe add \"global\" - top level config - option to tune fine grained errors.\n return createStepSpecificComponent();\n }\n\n return createStepSpecificComponent();\n };\n\n return impl as StepSpecificCreateComponentFn<def, value, targetStep>;\n }\n\n /**\n * A helper function to create a component for a specific step.\n * @param options The options for creating the step specific component.\n * @param fn A callback that is used for accessing the target step's data and defining\n * any props that the component should have. This function must return a valid `JSX` element.\n * @returns The created component for the step.\n */\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.value,\n });\n }\n\n createDefaultValues<targetStep extends steps.StepNumbers<value>>(\n targetStep: targetStep\n ) {\n const invariant: Invariant = createInvariant('[createDefaultValues]');\n\n invariant(\n targetStep in steps,\n `The target step ${targetStep} is not a valid step key`\n );\n\n const current = this.value[targetStep];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The target step ${targetStep} is not an object`\n );\n invariant('fields' in current, `No \"fields\" were found for ${targetStep}`);\n\n let defaultValues = {};\n\n for (const [fieldName, fieldValues] of Object.entries(\n current.fields as Record<string, Record<string, unknown>>\n )) {\n defaultValues = {\n ...defaultValues,\n [fieldName]: fieldValues.defaultValue,\n };\n }\n\n return defaultValues as Expand<fields.getDefaultValues<value, targetStep>>;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"step-schema.cjs","names":["MultiStepFormStepSchemaBase","#internal","steps","MultiStepFormStepSchemaInternal","MultiStepFormSchemaConfig","invariant: Invariant","resolvedCtxCreator","MultiStepFormLogger","getValidatedCustomInputHooks","field","path","fields","createUseSelector","selector","createComponent"],"sources":["../src/step-schema.ts"],"sourcesContent":["import {\n createCtx,\n createInvariant,\n type Expand,\n fields,\n type HelperFn,\n type HelperFnChosenSteps,\n type HelperFnInput,\n type Invariant,\n MultiStepFormLogger,\n MultiStepFormStepSchema as MultiStepFormStepSchemaBase,\n type ResetFn,\n steps,\n type UpdateFn,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n path,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { field } from './field';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { createUseSelector, type UseSelector } from './hooks/use-selector';\nimport { selector } from './selector';\nimport {\n createComponent,\n type CreateComponent,\n type CreateComponentCallback,\n type CreatedMultiStepFormComponent,\n getValidatedCustomInputHooks,\n resolvedCtxCreator,\n} from './utils';\n\nexport type CreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = <targetStep extends steps.StepNumbers<value>, props = undefined>(\n options: HelperFn.BaseOptions<value, [targetStep]>,\n fn: CreateComponentCallback<value, [targetStep], props>\n) => CreatedMultiStepFormComponent<props>;\n\nexport namespace StepSpecificComponent {\n type instantiateFormComponentForAllSteps<\n def extends StepSchema.Config,\n value = MultiStepFormSchemaConfig.instantiateFormConfig<def>,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<value> extends MultiStepFormSchemaConfig.defaultEnabledFor\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {};\n type instantiateFormComponentForTuple<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends MultiStepFormSchemaConfig.EnabledForSteps.get<def>[number]\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n\n type instantiateFormComponentForObject<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends keyof MultiStepFormSchemaConfig.EnabledForSteps.get<def>\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n type instantiateFormComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = {\n all: instantiateFormComponentForAllSteps<def>;\n tuple: instantiateFormComponentForTuple<def, steps, chosenSteps>;\n object: instantiateFormComponentForObject<def, steps, chosenSteps>;\n };\n // The logic for getting the formCtx only works for step specific `createComponent`\n // (i.e: step1.createComponent(...)) as of now. Reason is because I can't think of a good API for integrating the form\n // ctx into the main `createComponent` since multiple steps can be chosen. In that case\n // how would the logic work for when the form component should be defined in the callback?\n // Ideas:\n // - Make the main `createComponent` return a function that accepts the current step\n export type formComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = instantiateFormComponent<\n def,\n steps,\n chosenSteps\n >[MultiStepFormSchemaConfig.EnabledForSteps.resolveType<def, steps>];\n export type updateWrappers<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n > = {\n /**\n * A useful wrapper around `update` to update the specific field.\n */\n onInputChange: UpdateFn.stepSpecific<value, targetStep>;\n /**\n * A useful wrapper for `update` to reset a specific field's value to its\n * original config value.\n * @resetFn\n */\n reset: ResetFn.stepSpecific<value, targetStep>;\n };\n type buildCurrentStep<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n > = Expand<{\n [key in targetStep]: HelperFnChosenSteps.currentStep<value, [key]>;\n }>;\n\n export type input<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n additionalCtx extends Record<string, unknown>,\n > = HelperFnInput.BaseInput<value, [targetStep], never, additionalCtx> &\n updateWrappers<value, targetStep> & {\n Field: field.component<buildCurrentStep<def, value, targetStep>>;\n /**\n * A hook for reactively selecting a value from the form context.\n * The selector function receives the contextual data for the currently rendered step, and returns any derived value.\n * `useSelector` will automatically provide the latest context data on updates, and will subscribe the caller for automatic re-renders when the underlying data changes.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @returns The derived value, which will re-render the component on change\n *\n * @example\n * const someValue = useSelector(ctx => ctx.fields.username.value);\n */\n useSelector: UseSelector<buildCurrentStep<def, value, targetStep>>;\n /**\n * A component for reactively displaying a value from the form context.\n * Unlike `useSelector`, this component only re-renders itself, not the parent component.\n * Use this when you want to display a reactive value without causing parent re-renders.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @param children - Optional render prop that receives the selected value\n *\n * @example\n * <Selector selector={(ctx) => ctx.step1.fields.firstName.defaultValue}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n */\n Selector: selector.component<buildCurrentStep<def, value, targetStep>>;\n };\n\n export type callback<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n props,\n additionalCtx extends Record<string, unknown> = {},\n > = CreateComponent<\n Expand<\n input<def, value, targetStep, additionalCtx> &\n formComponent<def, value, [targetStep]> &\n additionalCtx\n >,\n props\n >;\n export const DEFAULT_FORM_INSTANCE_ALIAS = 'form';\n export type defaultFormInstanceAlias = typeof DEFAULT_FORM_INSTANCE_ALIAS;\n export type formInstanceOptions<alias extends string, input, ret> = {\n /**\n * The name of the return value of the `render` method.\n */\n alias?: alias;\n /**\n * A function that renders/creates the form instance. This function will be called\n * at the top level of the component, ensuring hooks are called in a valid React context.\n *\n * @param input - The input object containing context and default values\n * @returns The form instance (typically from a hook like `useForm`)\n *\n * @example\n * ```tsx\n * useFormInstance: {\n * render({ defaultValues }) {\n * return useForm({\n * defaultValues,\n * });\n * },\n * }\n * ```\n *\n * **Verification**: The hook call is automatically verified:\n * - Errors are caught and reported with helpful messages\n * - In development, hook calls are logged to console.debug\n * - The hook must be called at the component top level (enforced by the framework)\n */\n render: (input: input) => ret;\n };\n\n export type options<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n formAlias extends string,\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n > = HelperFn.CtxDataSelector<value, [targetStep], additionalCtx> & {\n /**\n * If set to `true`, you'll be able to open the {@linkcode console} to view logs.\n */\n debug?: boolean;\n useFormInstance?: formInstanceOptions<\n formAlias,\n Pick<HelperFnInput.BaseInput<value, [targetStep]>, 'ctx'> & {\n /**\n * An object containing all the default values for the current step.\n */\n defaultValues: Expand<fields.getDefaultValues<value, [targetStep]>>;\n },\n formInstance\n >;\n };\n}\n\nexport interface StepSpecificCreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n> {\n /**\n * A utility function to easily create a component for the current step.\n * @param fn The callback function where the component is defined.\n */\n <props = undefined>(\n fn: StepSpecificComponent.callback<def, value, targetStep, props>\n ): CreatedMultiStepFormComponent<props>;\n /**\n * A utility function to easily create a component for the current step.\n * @param options Specific config options for creating a component for the current step.\n * @param fn The callback function where the component is defined.\n * @returns The created component.\n */\n <\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n props = undefined,\n >(\n options: StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >,\n fn: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ): CreatedMultiStepFormComponent<props>;\n}\n\nexport interface HelperFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> {\n createComponent: CreateComponentFn<def, value>;\n}\nnamespace CreateComponentImplConfig {\n export type stepSpecificConfig<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = {\n isStepSpecific: true;\n defaultId: string;\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n\n export type nonStepSpecific = {\n isStepSpecific: false;\n };\n\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = nonStepSpecific | stepSpecificConfig<def, value>;\n}\n\nexport namespace MultiStepFormStepSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = def & {\n /**\n * The form configuration.\n *\n * This is a private property and is not meant to be used directly.\n * If you want to configure the form, do so with the {@linkcode instantiateFormConfig} method.\n * @private\n * @internal\n */\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n}\n\ndeclare module '@jfdevelops/multi-step-form-core' {\n namespace steps {\n interface ExtendedStepSpecificFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n key extends steps.StepNumbers<value>,\n > {\n createComponent: StepSpecificCreateComponentFn<def, value, key>;\n }\n }\n}\n\nexport class MultiStepFormStepSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormStepSchemaBase<def, value>\n implements HelperFunctions<def, value>\n{\n value: value;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n\n constructor(config: MultiStepFormStepSchema.config<def, value>) {\n const { form, ...rest } = config;\n\n super(rest as never);\n\n this.value = steps.instantiate({ steps: this.original });\n\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.sync();\n const availableSteps = this.steps.value;\n const createFormConfig = MultiStepFormSchemaConfig.instantiateFormConfig(\n this.value,\n availableSteps\n );\n const instantiatedForm = createFormConfig(form);\n this.value = this.#internal.enrichValues(this.value, (step) => {\n const targetStep = `step${step}` as steps.StepNumbers<value>;\n\n const id = form?.id ?? targetStep;\n\n return {\n createComponent: this.createStepSpecificComponentFactory(targetStep, {\n isStepSpecific: true,\n defaultId: id,\n form: instantiatedForm as never,\n }),\n };\n });\n }\n\n private createFormComponent(\n form: Omit<MultiStepFormSchemaConfig.FormConfig<def, value>, 'alias'>,\n defaultId: string\n ) {\n const { render, enabledForSteps = 'all', id = defaultId } = form;\n\n const ctx = {\n id,\n steps: createCtx(this.value, enabledForSteps as never),\n };\n\n return (props: MultiStepFormSchemaConfig.inferFormProps<value>) => {\n const Component = render(ctx as never);\n const invariant: Invariant = createInvariant('[createFormComponent]');\n\n invariant(\n typeof Component === 'function',\n 'The \"render\" property must be a function'\n );\n\n const C = Component(props);\n\n invariant(\n typeof C === 'function',\n 'The \"render\" function must return a valid React component'\n );\n\n return C;\n };\n }\n\n private createResolvedCtx<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown>,\n >(\n options: {\n stepData: chosenStep;\n logger: MultiStepFormLogger;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const { logger, stepData, ctxData } = options;\n // Create ctx fresh each time to ensure it has the latest this.value\n const ctx = createCtx(this.value, stepData);\n\n if (ctxData) {\n const [targetStep] = stepData;\n const { [targetStep]: _, ...values } = this.value;\n const createResolvedCtx = resolvedCtxCreator(logger, values as value);\n\n return createResolvedCtx({ ctx, ctxData } as never);\n }\n\n return ctx;\n }\n\n private createStepSpecificComponentImpl<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown> = {},\n >(\n stepData: chosenStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>,\n extraConfig?: {\n logger?: MultiStepFormLogger;\n input?: (\n ctx: Expand<HelperFn.buildCtx<value, chosenStep>>\n ) => Record<string, unknown>;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const [step] = stepData;\n const invariant: Invariant = createInvariant(`[${step}:createComponent]`);\n return <props>(fn: Function) =>\n ((props: props) => {\n const ctxData = extraConfig?.ctxData;\n const logger = extraConfig?.logger ?? new MultiStepFormLogger();\n const resolvedCtx = this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n });\n const extraInput = extraConfig?.input?.(resolvedCtx as never) ?? {};\n // Call hook functions from extraInput at the top level of the component\n // This ensures hooks are called in a valid React context (before any conditionals)\n const hookResults = getValidatedCustomInputHooks(extraInput);\n const { defaultId, form } = config;\n\n invariant(\n this.steps.isValidStep(step),\n `The target step ${step} is invalid. Note, this error shouldn't appear as the target step should always be valid. If you see this error, please open an issue.`\n );\n\n const stepNumber = Number.parseInt(step.replace('step', ''));\n\n invariant(\n !Number.isNaN(stepNumber),\n `An error occurred while extracting the number`\n );\n const current = this.value[step];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The current step must be an object, was ${typeof current}`\n );\n // These checks are mostly for type safety. `current` should _always_ be in the proper format.\n // On the off chance that it's not, we have the checks here to help, but these checks are basically\n // just for type safety.\n invariant(\n 'fields' in current,\n `Unable to find the \"fields\" for the current step`\n );\n invariant(\n typeof current.fields === 'object',\n `The \"fields\" property must be an object, was ${typeof current.fields}`\n );\n\n // Memoize Field component to prevent remounting on every render\n // This ensures input focus is maintained when ctx changes\n const Field = field.create({\n propsCreator: (name) => {\n // Access current step data directly to avoid stale closure\n const currentStep = this.value[step] as typeof current;\n const currentFields = Object.keys(\n currentStep.fields as Record<string, unknown>\n );\n const invariant: Invariant = createInvariant(`[${step}:Field]`);\n\n invariant(\n typeof name === 'string',\n (formatter) =>\n `[${step}:Field]: the \"name\" prop must be a string and a valid field for ${step}. Available fields include: \"${formatter.format(\n currentFields\n )}\"`\n );\n // TODO add support for deep keys (`name`)\n\n const allAvailableFields = path\n .createDeep(currentStep.fields)\n .map((value) => (value as string).replace('.defaultValue.', '.'));\n\n invariant(\n allAvailableFields.includes(name),\n (formatter) =>\n `[${step}:Field]: the field \"${name}\" doesn't exist for the current step. Available fields include: \"${formatter.format(\n allAvailableFields\n )}\".`\n );\n\n invariant(\n 'update' in currentStep,\n `[${step}:Field]: No \"update\" function was found`\n );\n\n const defaultValue = this.getValue(step as never, name);\n const builtValuePath = fields.buildValuePath(name);\n const { label, nameTransformCasing, type } = path.pickBy(\n currentStep.fields,\n builtValuePath\n );\n\n const targetFields = `fields.${builtValuePath}`;\n\n return {\n defaultValue,\n label,\n nameTransformCasing,\n type,\n name,\n onInputChange: <\n strict extends boolean = true,\n partial extends boolean = false,\n >(\n value: unknown,\n options?: field.onInputChangeOptions<strict, partial>\n ) => {\n // Handle Updater pattern: if value is a function, call it with the current field value\n let resolvedValue;\n\n if (typeof value === 'function') {\n const defaultValue = this.getValue(step as never, name);\n\n resolvedValue = value(defaultValue);\n } else {\n resolvedValue = value;\n }\n\n this.update({\n partial: options?.partial ?? false,\n strict: options?.strict ?? true,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n targetStep: step,\n updater: resolvedValue as never,\n fields: [targetFields] as never,\n });\n },\n reset: (options?: UpdateFn.DebugOptions) =>\n this.reset({\n fields: [targetFields] as never,\n targetStep: step,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n }),\n } as never;\n },\n subscribe: this.subscribe,\n getValue: (name) => this.getValue(step as never, name as never),\n selectorCtx: this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n }) as never,\n });\n\n // Create useSelector hook for reactive value access via selector\n // This allows getting values from ctx reactively without causing re-renders\n // Pass a function that creates fresh ctx on each call to avoid stale closures\n const useSelector = createUseSelector(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n // Create Selector component that uses useSelector internally\n // This allows parts of the UI to subscribe to specific values without\n // causing the parent component to re-render\n const Selector = selector.create(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n let fnInput = {\n ctx: resolvedCtx,\n onInputChange: this.#internal.createStepUpdaterFn(step),\n reset: this.#internal.createStepResetterFn(step),\n Field,\n useSelector,\n Selector,\n ...hookResults,\n };\n\n if (form) {\n const {\n alias = MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS,\n ...rest\n } = form;\n const enabledFor = rest.enabledForSteps ?? 'all';\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n if (\n MultiStepFormSchemaConfig.isFormAvailable(\n stepData as never,\n enabledFor as never\n )\n ) {\n fnInput = {\n ...fnInput,\n [alias]: this.createFormComponent(rest, defaultId),\n };\n }\n\n return fn(fnInput, props);\n }\n\n return fn(\n {\n ...fnInput,\n [MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS]:\n MultiStepFormSchemaConfig.createDefaultForm(defaultId),\n },\n props\n );\n }) as CreatedMultiStepFormComponent<props>;\n }\n\n private createStepSpecificComponentFactory<\n targetStep extends steps.StepNumbers<value>,\n >(\n targetStep: targetStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>\n ) {\n const impl = <\n formInstance,\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n additionalCtx extends Record<string, unknown> = {},\n >(\n optionsOrFn:\n | StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >\n | StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >,\n fn?: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ) => {\n const invariant: Invariant = createInvariant(\n '[createStepSpecificComponent]'\n );\n\n const createStepSpecificComponent = () => {\n invariant(\n typeof optionsOrFn === 'function',\n 'The first argument must be a function'\n );\n\n return this.createStepSpecificComponentImpl(\n [targetStep],\n config\n )(optionsOrFn);\n };\n\n if (typeof optionsOrFn === 'object') {\n const { useFormInstance, ctxData, debug } = optionsOrFn;\n const logger = new MultiStepFormLogger({\n debug,\n prefix(prefix) {\n return `${prefix}-${targetStep}-createComponent`;\n },\n });\n\n logger.info('First argument is an object');\n\n invariant(\n typeof fn === 'function',\n 'The second argument must be a function'\n );\n\n if (useFormInstance) {\n const {\n render,\n alias = StepSpecificComponent.DEFAULT_FORM_INSTANCE_ALIAS,\n } = useFormInstance;\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n // const [step] = stepData;\n\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n input: (ctx) => {\n const defaultValues = this.createDefaultValues(\n targetStep\n ) as never;\n\n return {\n [alias]: () =>\n render({\n ctx,\n defaultValues,\n }),\n };\n },\n })(fn);\n }\n\n if (ctxData) {\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n })(fn);\n }\n\n // Empty options object. Can throw here 🤷‍♂️\n // Maybe add \"global\" - top level config - option to tune fine grained errors.\n return createStepSpecificComponent();\n }\n\n return createStepSpecificComponent();\n };\n\n return impl as StepSpecificCreateComponentFn<def, value, targetStep>;\n }\n\n /**\n * A helper function to create a component for a specific step.\n * @param options The options for creating the step specific component.\n * @param fn A callback that is used for accessing the target step's data and defining\n * any props that the component should have. This function must return a valid `JSX` element.\n * @returns The created component for the step.\n */\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.value,\n });\n }\n\n createDefaultValues<targetStep extends steps.StepNumbers<value>>(\n targetStep: targetStep\n ) {\n return fields.getDefaultValues(this.value, targetStep);\n }\n}\n"],"mappings":"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"}
@@ -160,7 +160,7 @@ declare class MultiStepFormStepSchema$1<const def extends StepSchema.Config, val
160
160
  * @returns The created component for the step.
161
161
  */
162
162
  createComponent<chosenSteps extends HelperFnChosenSteps.main<value, steps.StepNumbers<value>>, props = undefined>(options: HelperFn.BaseOptions<value, chosenSteps>, fn: CreateComponentCallback<value, chosenSteps, props>): CreatedMultiStepFormComponent<props>;
163
- createDefaultValues<targetStep extends steps.StepNumbers<value>>(targetStep: targetStep): Expand<fields.getDefaultValues<value, targetStep>>;
163
+ createDefaultValues<targetStep extends steps.StepNumbers<value>>(targetStep: targetStep): Expand<fields.getDefaultValues<value, targetStep, fields.getFieldsForStep<value, targetStep>>>;
164
164
  }
165
165
  //#endregion
166
166
  export { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema$1 as MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn };
@@ -160,7 +160,7 @@ declare class MultiStepFormStepSchema$1<const def extends StepSchema.Config, val
160
160
  * @returns The created component for the step.
161
161
  */
162
162
  createComponent<chosenSteps extends HelperFnChosenSteps.main<value, steps.StepNumbers<value>>, props = undefined>(options: HelperFn.BaseOptions<value, chosenSteps>, fn: CreateComponentCallback<value, chosenSteps, props>): CreatedMultiStepFormComponent<props>;
163
- createDefaultValues<targetStep extends steps.StepNumbers<value>>(targetStep: targetStep): Expand<fields.getDefaultValues<value, targetStep>>;
163
+ createDefaultValues<targetStep extends steps.StepNumbers<value>>(targetStep: targetStep): Expand<fields.getDefaultValues<value, targetStep, fields.getFieldsForStep<value, targetStep>>>;
164
164
  }
165
165
  //#endregion
166
166
  export { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema$1 as MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn };
@@ -229,17 +229,7 @@ var MultiStepFormStepSchema$1 = class extends MultiStepFormStepSchema {
229
229
  });
230
230
  }
231
231
  createDefaultValues(targetStep) {
232
- const invariant$1 = createInvariant("[createDefaultValues]");
233
- invariant$1(targetStep in steps, `The target step ${targetStep} is not a valid step key`);
234
- const current = this.value[targetStep];
235
- invariant$1(typeof current === "object" && current !== null, `The target step ${targetStep} is not an object`);
236
- invariant$1("fields" in current, `No "fields" were found for ${targetStep}`);
237
- let defaultValues = {};
238
- for (const [fieldName, fieldValues] of Object.entries(current.fields)) defaultValues = {
239
- ...defaultValues,
240
- [fieldName]: fieldValues.defaultValue
241
- };
242
- return defaultValues;
232
+ return fields.getDefaultValues(this.value, targetStep);
243
233
  }
244
234
  };
245
235
 
@@ -1 +1 @@
1
- {"version":3,"file":"step-schema.mjs","names":["MultiStepFormStepSchema","MultiStepFormStepSchemaBase","#internal","invariant: Invariant"],"sources":["../src/step-schema.ts"],"sourcesContent":["import {\n createCtx,\n createInvariant,\n type Expand,\n fields,\n type HelperFn,\n type HelperFnChosenSteps,\n type HelperFnInput,\n type Invariant,\n MultiStepFormLogger,\n MultiStepFormStepSchema as MultiStepFormStepSchemaBase,\n type ResetFn,\n steps,\n type UpdateFn,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n path,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { field } from './field';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { createUseSelector, type UseSelector } from './hooks/use-selector';\nimport { selector } from './selector';\nimport {\n createComponent,\n type CreateComponent,\n type CreateComponentCallback,\n type CreatedMultiStepFormComponent,\n getValidatedCustomInputHooks,\n resolvedCtxCreator,\n} from './utils';\n\nexport type CreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = <targetStep extends steps.StepNumbers<value>, props = undefined>(\n options: HelperFn.BaseOptions<value, [targetStep]>,\n fn: CreateComponentCallback<value, [targetStep], props>\n) => CreatedMultiStepFormComponent<props>;\n\nexport namespace StepSpecificComponent {\n type instantiateFormComponentForAllSteps<\n def extends StepSchema.Config,\n value = MultiStepFormSchemaConfig.instantiateFormConfig<def>,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<value> extends MultiStepFormSchemaConfig.defaultEnabledFor\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {};\n type instantiateFormComponentForTuple<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends MultiStepFormSchemaConfig.EnabledForSteps.get<def>[number]\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n\n type instantiateFormComponentForObject<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends keyof MultiStepFormSchemaConfig.EnabledForSteps.get<def>\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n type instantiateFormComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = {\n all: instantiateFormComponentForAllSteps<def>;\n tuple: instantiateFormComponentForTuple<def, steps, chosenSteps>;\n object: instantiateFormComponentForObject<def, steps, chosenSteps>;\n };\n // The logic for getting the formCtx only works for step specific `createComponent`\n // (i.e: step1.createComponent(...)) as of now. Reason is because I can't think of a good API for integrating the form\n // ctx into the main `createComponent` since multiple steps can be chosen. In that case\n // how would the logic work for when the form component should be defined in the callback?\n // Ideas:\n // - Make the main `createComponent` return a function that accepts the current step\n export type formComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = instantiateFormComponent<\n def,\n steps,\n chosenSteps\n >[MultiStepFormSchemaConfig.EnabledForSteps.resolveType<def, steps>];\n export type updateWrappers<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n > = {\n /**\n * A useful wrapper around `update` to update the specific field.\n */\n onInputChange: UpdateFn.stepSpecific<value, targetStep>;\n /**\n * A useful wrapper for `update` to reset a specific field's value to its\n * original config value.\n * @resetFn\n */\n reset: ResetFn.stepSpecific<value, targetStep>;\n };\n type buildCurrentStep<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n > = Expand<{\n [key in targetStep]: HelperFnChosenSteps.currentStep<value, [key]>;\n }>;\n\n export type input<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n additionalCtx extends Record<string, unknown>,\n > = HelperFnInput.BaseInput<value, [targetStep], never, additionalCtx> &\n updateWrappers<value, targetStep> & {\n Field: field.component<buildCurrentStep<def, value, targetStep>>;\n /**\n * A hook for reactively selecting a value from the form context.\n * The selector function receives the contextual data for the currently rendered step, and returns any derived value.\n * `useSelector` will automatically provide the latest context data on updates, and will subscribe the caller for automatic re-renders when the underlying data changes.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @returns The derived value, which will re-render the component on change\n *\n * @example\n * const someValue = useSelector(ctx => ctx.fields.username.value);\n */\n useSelector: UseSelector<buildCurrentStep<def, value, targetStep>>;\n /**\n * A component for reactively displaying a value from the form context.\n * Unlike `useSelector`, this component only re-renders itself, not the parent component.\n * Use this when you want to display a reactive value without causing parent re-renders.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @param children - Optional render prop that receives the selected value\n *\n * @example\n * <Selector selector={(ctx) => ctx.step1.fields.firstName.defaultValue}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n */\n Selector: selector.component<buildCurrentStep<def, value, targetStep>>;\n };\n\n export type callback<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n props,\n additionalCtx extends Record<string, unknown> = {},\n > = CreateComponent<\n Expand<\n input<def, value, targetStep, additionalCtx> &\n formComponent<def, value, [targetStep]> &\n additionalCtx\n >,\n props\n >;\n export const DEFAULT_FORM_INSTANCE_ALIAS = 'form';\n export type defaultFormInstanceAlias = typeof DEFAULT_FORM_INSTANCE_ALIAS;\n export type formInstanceOptions<alias extends string, input, ret> = {\n /**\n * The name of the return value of the `render` method.\n */\n alias?: alias;\n /**\n * A function that renders/creates the form instance. This function will be called\n * at the top level of the component, ensuring hooks are called in a valid React context.\n *\n * @param input - The input object containing context and default values\n * @returns The form instance (typically from a hook like `useForm`)\n *\n * @example\n * ```tsx\n * useFormInstance: {\n * render({ defaultValues }) {\n * return useForm({\n * defaultValues,\n * });\n * },\n * }\n * ```\n *\n * **Verification**: The hook call is automatically verified:\n * - Errors are caught and reported with helpful messages\n * - In development, hook calls are logged to console.debug\n * - The hook must be called at the component top level (enforced by the framework)\n */\n render: (input: input) => ret;\n };\n\n export type options<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n formAlias extends string,\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n > = HelperFn.CtxDataSelector<value, [targetStep], additionalCtx> & {\n /**\n * If set to `true`, you'll be able to open the {@linkcode console} to view logs.\n */\n debug?: boolean;\n useFormInstance?: formInstanceOptions<\n formAlias,\n Pick<HelperFnInput.BaseInput<value, [targetStep]>, 'ctx'> & {\n /**\n * An object containing all the default values for the current step.\n */\n defaultValues: Expand<fields.getDefaultValues<value, [targetStep]>>;\n },\n formInstance\n >;\n };\n}\n\nexport interface StepSpecificCreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n> {\n /**\n * A utility function to easily create a component for the current step.\n * @param fn The callback function where the component is defined.\n */\n <props = undefined>(\n fn: StepSpecificComponent.callback<def, value, targetStep, props>\n ): CreatedMultiStepFormComponent<props>;\n /**\n * A utility function to easily create a component for the current step.\n * @param options Specific config options for creating a component for the current step.\n * @param fn The callback function where the component is defined.\n * @returns The created component.\n */\n <\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n props = undefined,\n >(\n options: StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >,\n fn: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ): CreatedMultiStepFormComponent<props>;\n}\n\nexport interface HelperFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> {\n createComponent: CreateComponentFn<def, value>;\n}\nnamespace CreateComponentImplConfig {\n export type stepSpecificConfig<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = {\n isStepSpecific: true;\n defaultId: string;\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n\n export type nonStepSpecific = {\n isStepSpecific: false;\n };\n\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = nonStepSpecific | stepSpecificConfig<def, value>;\n}\n\nexport namespace MultiStepFormStepSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = def & {\n /**\n * The form configuration.\n *\n * This is a private property and is not meant to be used directly.\n * If you want to configure the form, do so with the {@linkcode instantiateFormConfig} method.\n * @private\n * @internal\n */\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n}\n\ndeclare module '@jfdevelops/multi-step-form-core' {\n namespace steps {\n interface ExtendedStepSpecificFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n key extends steps.StepNumbers<value>,\n > {\n createComponent: StepSpecificCreateComponentFn<def, value, key>;\n }\n }\n}\n\nexport class MultiStepFormStepSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormStepSchemaBase<def, value>\n implements HelperFunctions<def, value>\n{\n value: value;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n\n constructor(config: MultiStepFormStepSchema.config<def, value>) {\n const { form, ...rest } = config;\n\n super(rest as never);\n\n this.value = steps.instantiate({ steps: this.original });\n\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.sync();\n const availableSteps = this.steps.value;\n const createFormConfig = MultiStepFormSchemaConfig.instantiateFormConfig(\n this.value,\n availableSteps\n );\n const instantiatedForm = createFormConfig(form);\n this.value = this.#internal.enrichValues(this.value, (step) => {\n const targetStep = `step${step}` as steps.StepNumbers<value>;\n\n const id = form?.id ?? targetStep;\n\n return {\n createComponent: this.createStepSpecificComponentFactory(targetStep, {\n isStepSpecific: true,\n defaultId: id,\n form: instantiatedForm as never,\n }),\n };\n });\n }\n\n private createFormComponent(\n form: Omit<MultiStepFormSchemaConfig.FormConfig<def, value>, 'alias'>,\n defaultId: string\n ) {\n const { render, enabledForSteps = 'all', id = defaultId } = form;\n\n const ctx = {\n id,\n steps: createCtx(this.value, enabledForSteps as never),\n };\n\n return (props: MultiStepFormSchemaConfig.inferFormProps<value>) => {\n const Component = render(ctx as never);\n const invariant: Invariant = createInvariant('[createFormComponent]');\n\n invariant(\n typeof Component === 'function',\n 'The \"render\" property must be a function'\n );\n\n const C = Component(props);\n\n invariant(\n typeof C === 'function',\n 'The \"render\" function must return a valid React component'\n );\n\n return C;\n };\n }\n\n private createResolvedCtx<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown>,\n >(\n options: {\n stepData: chosenStep;\n logger: MultiStepFormLogger;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const { logger, stepData, ctxData } = options;\n // Create ctx fresh each time to ensure it has the latest this.value\n const ctx = createCtx(this.value, stepData);\n\n if (ctxData) {\n const [targetStep] = stepData;\n const { [targetStep]: _, ...values } = this.value;\n const createResolvedCtx = resolvedCtxCreator(logger, values as value);\n\n return createResolvedCtx({ ctx, ctxData } as never);\n }\n\n return ctx;\n }\n\n private createStepSpecificComponentImpl<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown> = {},\n >(\n stepData: chosenStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>,\n extraConfig?: {\n logger?: MultiStepFormLogger;\n input?: (\n ctx: Expand<HelperFn.buildCtx<value, chosenStep>>\n ) => Record<string, unknown>;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const [step] = stepData;\n const invariant: Invariant = createInvariant(`[${step}:createComponent]`);\n return <props>(fn: Function) =>\n ((props: props) => {\n const ctxData = extraConfig?.ctxData;\n const logger = extraConfig?.logger ?? new MultiStepFormLogger();\n const resolvedCtx = this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n });\n const extraInput = extraConfig?.input?.(resolvedCtx as never) ?? {};\n // Call hook functions from extraInput at the top level of the component\n // This ensures hooks are called in a valid React context (before any conditionals)\n const hookResults = getValidatedCustomInputHooks(extraInput);\n const { defaultId, form } = config;\n\n invariant(\n this.steps.isValidStep(step),\n `The target step ${step} is invalid. Note, this error shouldn't appear as the target step should always be valid. If you see this error, please open an issue.`\n );\n\n const stepNumber = Number.parseInt(step.replace('step', ''));\n\n invariant(\n !Number.isNaN(stepNumber),\n `An error occurred while extracting the number`\n );\n const current = this.value[step];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The current step must be an object, was ${typeof current}`\n );\n // These checks are mostly for type safety. `current` should _always_ be in the proper format.\n // On the off chance that it's not, we have the checks here to help, but these checks are basically\n // just for type safety.\n invariant(\n 'fields' in current,\n `Unable to find the \"fields\" for the current step`\n );\n invariant(\n typeof current.fields === 'object',\n `The \"fields\" property must be an object, was ${typeof current.fields}`\n );\n\n // Memoize Field component to prevent remounting on every render\n // This ensures input focus is maintained when ctx changes\n const Field = field.create({\n propsCreator: (name) => {\n // Access current step data directly to avoid stale closure\n const currentStep = this.value[step] as typeof current;\n const currentFields = Object.keys(\n currentStep.fields as Record<string, unknown>\n );\n const invariant: Invariant = createInvariant(`[${step}:Field]`);\n\n invariant(\n typeof name === 'string',\n (formatter) =>\n `[${step}:Field]: the \"name\" prop must be a string and a valid field for ${step}. Available fields include: \"${formatter.format(\n currentFields\n )}\"`\n );\n // TODO add support for deep keys (`name`)\n\n const allAvailableFields = path\n .createDeep(currentStep.fields)\n .map((value) => (value as string).replace('.defaultValue.', '.'));\n\n invariant(\n allAvailableFields.includes(name),\n (formatter) =>\n `[${step}:Field]: the field \"${name}\" doesn't exist for the current step. Available fields include: \"${formatter.format(\n allAvailableFields\n )}\".`\n );\n\n invariant(\n 'update' in currentStep,\n `[${step}:Field]: No \"update\" function was found`\n );\n\n const defaultValue = this.getValue(step as never, name);\n const builtValuePath = fields.buildValuePath(name);\n const { label, nameTransformCasing, type } = path.pickBy(\n currentStep.fields,\n builtValuePath\n );\n\n const targetFields = `fields.${builtValuePath}`;\n\n return {\n defaultValue,\n label,\n nameTransformCasing,\n type,\n name,\n onInputChange: <\n strict extends boolean = true,\n partial extends boolean = false,\n >(\n value: unknown,\n options?: field.onInputChangeOptions<strict, partial>\n ) => {\n // Handle Updater pattern: if value is a function, call it with the current field value\n let resolvedValue;\n\n if (typeof value === 'function') {\n const defaultValue = this.getValue(step as never, name);\n\n resolvedValue = value(defaultValue);\n } else {\n resolvedValue = value;\n }\n\n this.update({\n partial: options?.partial ?? false,\n strict: options?.strict ?? true,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n targetStep: step,\n updater: resolvedValue as never,\n fields: [targetFields] as never,\n });\n },\n reset: (options?: UpdateFn.DebugOptions) =>\n this.reset({\n fields: [targetFields] as never,\n targetStep: step,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n }),\n } as never;\n },\n subscribe: this.subscribe,\n getValue: (name) => this.getValue(step as never, name as never),\n selectorCtx: this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n }) as never,\n });\n\n // Create useSelector hook for reactive value access via selector\n // This allows getting values from ctx reactively without causing re-renders\n // Pass a function that creates fresh ctx on each call to avoid stale closures\n const useSelector = createUseSelector(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n // Create Selector component that uses useSelector internally\n // This allows parts of the UI to subscribe to specific values without\n // causing the parent component to re-render\n const Selector = selector.create(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n let fnInput = {\n ctx: resolvedCtx,\n onInputChange: this.#internal.createStepUpdaterFn(step),\n reset: this.#internal.createStepResetterFn(step),\n Field,\n useSelector,\n Selector,\n ...hookResults,\n };\n\n if (form) {\n const {\n alias = MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS,\n ...rest\n } = form;\n const enabledFor = rest.enabledForSteps ?? 'all';\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n if (\n MultiStepFormSchemaConfig.isFormAvailable(\n stepData as never,\n enabledFor as never\n )\n ) {\n fnInput = {\n ...fnInput,\n [alias]: this.createFormComponent(rest, defaultId),\n };\n }\n\n return fn(fnInput, props);\n }\n\n return fn(\n {\n ...fnInput,\n [MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS]:\n MultiStepFormSchemaConfig.createDefaultForm(defaultId),\n },\n props\n );\n }) as CreatedMultiStepFormComponent<props>;\n }\n\n private createStepSpecificComponentFactory<\n targetStep extends steps.StepNumbers<value>,\n >(\n targetStep: targetStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>\n ) {\n const impl = <\n formInstance,\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n additionalCtx extends Record<string, unknown> = {},\n >(\n optionsOrFn:\n | StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >\n | StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >,\n fn?: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ) => {\n const invariant: Invariant = createInvariant(\n '[createStepSpecificComponent]'\n );\n\n const createStepSpecificComponent = () => {\n invariant(\n typeof optionsOrFn === 'function',\n 'The first argument must be a function'\n );\n\n return this.createStepSpecificComponentImpl(\n [targetStep],\n config\n )(optionsOrFn);\n };\n\n if (typeof optionsOrFn === 'object') {\n const { useFormInstance, ctxData, debug } = optionsOrFn;\n const logger = new MultiStepFormLogger({\n debug,\n prefix(prefix) {\n return `${prefix}-${targetStep}-createComponent`;\n },\n });\n\n logger.info('First argument is an object');\n\n invariant(\n typeof fn === 'function',\n 'The second argument must be a function'\n );\n\n if (useFormInstance) {\n const {\n render,\n alias = StepSpecificComponent.DEFAULT_FORM_INSTANCE_ALIAS,\n } = useFormInstance;\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n // const [step] = stepData;\n\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n input: (ctx) => {\n const defaultValues = this.createDefaultValues(\n targetStep\n ) as never;\n\n return {\n [alias]: () =>\n render({\n ctx,\n defaultValues,\n }),\n };\n },\n })(fn);\n }\n\n if (ctxData) {\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n })(fn);\n }\n\n // Empty options object. Can throw here 🤷‍♂️\n // Maybe add \"global\" - top level config - option to tune fine grained errors.\n return createStepSpecificComponent();\n }\n\n return createStepSpecificComponent();\n };\n\n return impl as StepSpecificCreateComponentFn<def, value, targetStep>;\n }\n\n /**\n * A helper function to create a component for a specific step.\n * @param options The options for creating the step specific component.\n * @param fn A callback that is used for accessing the target step's data and defining\n * any props that the component should have. This function must return a valid `JSX` element.\n * @returns The created component for the step.\n */\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.value,\n });\n }\n\n createDefaultValues<targetStep extends steps.StepNumbers<value>>(\n targetStep: targetStep\n ) {\n const invariant: Invariant = createInvariant('[createDefaultValues]');\n\n invariant(\n targetStep in steps,\n `The target step ${targetStep} is not a valid step key`\n );\n\n const current = this.value[targetStep];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The target step ${targetStep} is not an object`\n );\n invariant('fields' in current, `No \"fields\" were found for ${targetStep}`);\n\n let defaultValues = {};\n\n for (const [fieldName, fieldValues] of Object.entries(\n current.fields as Record<string, Record<string, unknown>>\n )) {\n defaultValues = {\n ...defaultValues,\n [fieldName]: fieldValues.defaultValue,\n };\n }\n\n return defaultValues as Expand<fields.getDefaultValues<value, targetStep>>;\n }\n}\n"],"mappings":";;;;;;;;;;;sDAuL6C;;AA0J7C,IAAaA,4BAAb,cAIUC,wBAEV;CACE;CACA,CAASC;CAET,YAAY,QAAoD;EAC9D,MAAM,EAAE,MAAM,GAAG,SAAS;AAE1B,QAAM,KAAc;AAEpB,OAAK,QAAQ,MAAM,YAAY,EAAE,OAAO,KAAK,UAAU,CAAC;AAExD,QAAKA,WAAY,IAAI,gCAAgC;GACnD,eAAe,KAAK;GACpB,gBAAgB,KAAK;GACrB,WAAW,SAAS,KAAK,iBAAiB,KAAK;GAChD,CAAC;AAEF,OAAK,MAAM;EACX,MAAM,iBAAiB,KAAK,MAAM;EAKlC,MAAM,mBAJmB,0BAA0B,sBACjD,KAAK,OACL,eACD,CACyC,KAAK;AAC/C,OAAK,QAAQ,MAAKA,SAAU,aAAa,KAAK,QAAQ,SAAS;GAC7D,MAAM,aAAa,OAAO;GAE1B,MAAM,KAAK,MAAM,MAAM;AAEvB,UAAO,EACL,iBAAiB,KAAK,mCAAmC,YAAY;IACnE,gBAAgB;IAChB,WAAW;IACX,MAAM;IACP,CAAC,EACH;IACD;;CAGJ,AAAQ,oBACN,MACA,WACA;EACA,MAAM,EAAE,QAAQ,kBAAkB,OAAO,KAAK,cAAc;EAE5D,MAAM,MAAM;GACV;GACA,OAAO,UAAU,KAAK,OAAO,gBAAyB;GACvD;AAED,UAAQ,UAA2D;GACjE,MAAM,YAAY,OAAO,IAAa;GACtC,MAAMC,cAAuB,gBAAgB,wBAAwB;AAErE,eACE,OAAO,cAAc,YACrB,6CACD;GAED,MAAM,IAAI,UAAU,MAAM;AAE1B,eACE,OAAO,MAAM,YACb,8DACD;AAED,UAAO;;;CAIX,AAAQ,kBAQN,SAIA;EACA,MAAM,EAAE,QAAQ,UAAU,YAAY;EAEtC,MAAM,MAAM,UAAU,KAAK,OAAO,SAAS;AAE3C,MAAI,SAAS;GACX,MAAM,CAAC,cAAc;GACrB,MAAM,GAAG,aAAa,GAAG,GAAG,WAAW,KAAK;AAG5C,UAF0B,mBAAmB,QAAQ,OAAgB,CAE5C;IAAE;IAAK;IAAS,CAAU;;AAGrD,SAAO;;CAGT,AAAQ,gCAQN,UACA,QACA,aAMA;EACA,MAAM,CAAC,QAAQ;EACf,MAAMA,cAAuB,gBAAgB,IAAI,KAAK,mBAAmB;AACzE,UAAe,SACX,UAAiB;GACjB,MAAM,UAAU,aAAa;GAC7B,MAAM,SAAS,aAAa,UAAU,IAAI,qBAAqB;GAC/D,MAAM,cAAc,KAAK,kBAAkB;IACzC;IACA;IACA;IACD,CAAC;GAIF,MAAM,cAAc,6BAHD,aAAa,QAAQ,YAAqB,IAAI,EAAE,CAGP;GAC5D,MAAM,EAAE,WAAW,SAAS;AAE5B,eACE,KAAK,MAAM,YAAY,KAAK,EAC5B,mBAAmB,KAAK,wIACzB;GAED,MAAM,aAAa,OAAO,SAAS,KAAK,QAAQ,QAAQ,GAAG,CAAC;AAE5D,eACE,CAAC,OAAO,MAAM,WAAW,EACzB,gDACD;GACD,MAAM,UAAU,KAAK,MAAM;AAE3B,eACE,OAAO,YAAY,YAAY,YAAY,MAC3C,2CAA2C,OAAO,UACnD;AAID,eACE,YAAY,SACZ,mDACD;AACD,eACE,OAAO,QAAQ,WAAW,UAC1B,gDAAgD,OAAO,QAAQ,SAChE;GAID,MAAM,QAAQ,MAAM,OAAO;IACzB,eAAe,SAAS;KAEtB,MAAM,cAAc,KAAK,MAAM;KAC/B,MAAM,gBAAgB,OAAO,KAC3B,YAAY,OACb;KACD,MAAMA,cAAuB,gBAAgB,IAAI,KAAK,SAAS;AAE/D,iBACE,OAAO,SAAS,WACf,cACC,IAAI,KAAK,kEAAkE,KAAK,+BAA+B,UAAU,OACvH,cACD,CAAC,GACL;KAGD,MAAM,qBAAqB,KACxB,WAAW,YAAY,OAAO,CAC9B,KAAK,UAAW,MAAiB,QAAQ,kBAAkB,IAAI,CAAC;AAEnE,iBACE,mBAAmB,SAAS,KAAK,GAChC,cACC,IAAI,KAAK,sBAAsB,KAAK,mEAAmE,UAAU,OAC/G,mBACD,CAAC,IACL;AAED,iBACE,YAAY,aACZ,IAAI,KAAK,yCACV;KAED,MAAM,eAAe,KAAK,SAAS,MAAe,KAAK;KACvD,MAAM,iBAAiB,OAAO,eAAe,KAAK;KAClD,MAAM,EAAE,OAAO,qBAAqB,SAAS,KAAK,OAChD,YAAY,QACZ,eACD;KAED,MAAM,eAAe,UAAU;AAE/B,YAAO;MACL;MACA;MACA;MACA;MACA;MACA,gBAIE,OACA,YACG;OAEH,IAAI;AAEJ,WAAI,OAAO,UAAU,WAGnB,iBAAgB,MAFK,KAAK,SAAS,MAAe,KAAK,CAEpB;WAEnC,iBAAgB;AAGlB,YAAK,OAAO;QACV,SAAS,SAAS,WAAW;QAC7B,QAAQ,SAAS,UAAU;QAC3B,OAAO,SAAS;QAChB,cAAc,SAAS;QACvB,YAAY;QACZ,SAAS;QACT,QAAQ,CAAC,aAAa;QACvB,CAAC;;MAEJ,QAAQ,YACN,KAAK,MAAM;OACT,QAAQ,CAAC,aAAa;OACtB,YAAY;OACZ,OAAO,SAAS;OAChB,cAAc,SAAS;OACxB,CAAC;MACL;;IAEH,WAAW,KAAK;IAChB,WAAW,SAAS,KAAK,SAAS,MAAe,KAAc;IAC/D,aAAa,KAAK,kBAAkB;KAClC;KACA;KACA;KACD,CAAC;IACH,CAAC;GAKF,MAAM,cAAc,wBACZ,KAAK,kBAAkB;IAAE;IAAU;IAAS;IAAQ,CAAC,EAC3D,KAAK,UACN;GAKD,MAAM,WAAW,SAAS,aAClB,KAAK,kBAAkB;IAAE;IAAU;IAAS;IAAQ,CAAC,EAC3D,KAAK,UACN;GAED,IAAI,UAAU;IACZ,KAAK;IACL,eAAe,MAAKD,SAAU,oBAAoB,KAAK;IACvD,OAAO,MAAKA,SAAU,qBAAqB,KAAK;IAChD;IACA;IACA;IACA,GAAG;IACJ;AAED,OAAI,MAAM;IACR,MAAM,EACJ,QAAQ,0BAA0B,oBAClC,GAAG,SACD;IACJ,MAAM,aAAa,KAAK,mBAAmB;AAE3C,gBAAU,OAAO,UAAU,UAAU,6BAA6B;AAElE,QACE,0BAA0B,gBACxB,UACA,WACD,CAED,WAAU;KACR,GAAG;MACF,QAAQ,KAAK,oBAAoB,MAAM,UAAU;KACnD;AAGH,WAAO,GAAG,SAAS,MAAM;;AAG3B,UAAO,GACL;IACE,GAAG;KACF,0BAA0B,qBACzB,0BAA0B,kBAAkB,UAAU;IACzD,EACD,MACD;;;CAIP,AAAQ,mCAGN,YACA,QACA;EACA,MAAM,QAMJ,aAeA,OAOG;GACH,MAAMC,cAAuB,gBAC3B,gCACD;GAED,MAAM,oCAAoC;AACxC,gBACE,OAAO,gBAAgB,YACvB,wCACD;AAED,WAAO,KAAK,gCACV,CAAC,WAAW,EACZ,OACD,CAAC,YAAY;;AAGhB,OAAI,OAAO,gBAAgB,UAAU;IACnC,MAAM,EAAE,iBAAiB,SAAS,UAAU;IAC5C,MAAM,SAAS,IAAI,oBAAoB;KACrC;KACA,OAAO,QAAQ;AACb,aAAO,GAAG,OAAO,GAAG,WAAW;;KAElC,CAAC;AAEF,WAAO,KAAK,8BAA8B;AAE1C,gBACE,OAAO,OAAO,YACd,yCACD;AAED,QAAI,iBAAiB;KACnB,MAAM,EACJ,QACA,QAAQ,sBAAsB,gCAC5B;AAEJ,iBAAU,OAAO,UAAU,UAAU,6BAA6B;AAIlE,YAAO,KAAK,gCAAgC,CAAC,WAAW,EAAE,QAAQ;MAChE;MACA;MACA,QAAQ,QAAQ;OACd,MAAM,gBAAgB,KAAK,oBACzB,WACD;AAED,cAAO,GACJ,cACC,OAAO;QACL;QACA;QACD,CAAC,EACL;;MAEJ,CAAC,CAAC,GAAG;;AAGR,QAAI,QACF,QAAO,KAAK,gCAAgC,CAAC,WAAW,EAAE,QAAQ;KAChE;KACA;KACD,CAAC,CAAC,GAAG;AAKR,WAAO,6BAA6B;;AAGtC,UAAO,6BAA6B;;AAGtC,SAAO;;;;;;;;;CAUT,gBAOE,SACA,IACA;AACA,SAAO,gBAAgB;GACrB;GACA,QAAQ,EAAE,gBAAgB;IACxB,OAAO,MAAKD,SAAU,yBAAyB,SAAS;IACxD,QAAQ,MAAKA,SAAU,0BAA0B,SAAS;IAC3D;GACD;GACA,OAAO,KAAK;GACb,CAAC;;CAGJ,oBACE,YACA;EACA,MAAMC,cAAuB,gBAAgB,wBAAwB;AAErE,cACE,cAAc,OACd,mBAAmB,WAAW,0BAC/B;EAED,MAAM,UAAU,KAAK,MAAM;AAE3B,cACE,OAAO,YAAY,YAAY,YAAY,MAC3C,mBAAmB,WAAW,mBAC/B;AACD,cAAU,YAAY,SAAS,8BAA8B,aAAa;EAE1E,IAAI,gBAAgB,EAAE;AAEtB,OAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAC5C,QAAQ,OACT,CACC,iBAAgB;GACd,GAAG;IACF,YAAY,YAAY;GAC1B;AAGH,SAAO"}
1
+ {"version":3,"file":"step-schema.mjs","names":["MultiStepFormStepSchema","MultiStepFormStepSchemaBase","#internal","invariant: Invariant"],"sources":["../src/step-schema.ts"],"sourcesContent":["import {\n createCtx,\n createInvariant,\n type Expand,\n fields,\n type HelperFn,\n type HelperFnChosenSteps,\n type HelperFnInput,\n type Invariant,\n MultiStepFormLogger,\n MultiStepFormStepSchema as MultiStepFormStepSchemaBase,\n type ResetFn,\n steps,\n type UpdateFn,\n} from '@jfdevelops/multi-step-form-core';\nimport {\n MultiStepFormStepSchemaInternal,\n path,\n type StepSchema,\n} from '@jfdevelops/multi-step-form-core/_internals';\nimport { field } from './field';\nimport { MultiStepFormSchemaConfig } from './form-config';\nimport { createUseSelector, type UseSelector } from './hooks/use-selector';\nimport { selector } from './selector';\nimport {\n createComponent,\n type CreateComponent,\n type CreateComponentCallback,\n type CreatedMultiStepFormComponent,\n getValidatedCustomInputHooks,\n resolvedCtxCreator,\n} from './utils';\n\nexport type CreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = <targetStep extends steps.StepNumbers<value>, props = undefined>(\n options: HelperFn.BaseOptions<value, [targetStep]>,\n fn: CreateComponentCallback<value, [targetStep], props>\n) => CreatedMultiStepFormComponent<props>;\n\nexport namespace StepSpecificComponent {\n type instantiateFormComponentForAllSteps<\n def extends StepSchema.Config,\n value = MultiStepFormSchemaConfig.instantiateFormConfig<def>,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<value> extends MultiStepFormSchemaConfig.defaultEnabledFor\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {};\n type instantiateFormComponentForTuple<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends MultiStepFormSchemaConfig.EnabledForSteps.get<def>[number]\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n\n type instantiateFormComponentForObject<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > =\n MultiStepFormSchemaConfig.EnabledForSteps.get<def> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? chosenSteps[number] extends steps.StepNumbers<steps>\n ? chosenSteps[number] extends keyof MultiStepFormSchemaConfig.EnabledForSteps.get<def>\n ? MultiStepFormSchemaConfig.instantiateFormConfig<def>\n : {}\n : {}\n : {};\n type instantiateFormComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = {\n all: instantiateFormComponentForAllSteps<def>;\n tuple: instantiateFormComponentForTuple<def, steps, chosenSteps>;\n object: instantiateFormComponentForObject<def, steps, chosenSteps>;\n };\n // The logic for getting the formCtx only works for step specific `createComponent`\n // (i.e: step1.createComponent(...)) as of now. Reason is because I can't think of a good API for integrating the form\n // ctx into the main `createComponent` since multiple steps can be chosen. In that case\n // how would the logic work for when the form component should be defined in the callback?\n // Ideas:\n // - Make the main `createComponent` return a function that accepts the current step\n export type formComponent<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n chosenSteps extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >,\n > = instantiateFormComponent<\n def,\n steps,\n chosenSteps\n >[MultiStepFormSchemaConfig.EnabledForSteps.resolveType<def, steps>];\n export type updateWrappers<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n > = {\n /**\n * A useful wrapper around `update` to update the specific field.\n */\n onInputChange: UpdateFn.stepSpecific<value, targetStep>;\n /**\n * A useful wrapper for `update` to reset a specific field's value to its\n * original config value.\n * @resetFn\n */\n reset: ResetFn.stepSpecific<value, targetStep>;\n };\n type buildCurrentStep<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n > = Expand<{\n [key in targetStep]: HelperFnChosenSteps.currentStep<value, [key]>;\n }>;\n\n export type input<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n additionalCtx extends Record<string, unknown>,\n > = HelperFnInput.BaseInput<value, [targetStep], never, additionalCtx> &\n updateWrappers<value, targetStep> & {\n Field: field.component<buildCurrentStep<def, value, targetStep>>;\n /**\n * A hook for reactively selecting a value from the form context.\n * The selector function receives the contextual data for the currently rendered step, and returns any derived value.\n * `useSelector` will automatically provide the latest context data on updates, and will subscribe the caller for automatic re-renders when the underlying data changes.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @returns The derived value, which will re-render the component on change\n *\n * @example\n * const someValue = useSelector(ctx => ctx.fields.username.value);\n */\n useSelector: UseSelector<buildCurrentStep<def, value, targetStep>>;\n /**\n * A component for reactively displaying a value from the form context.\n * Unlike `useSelector`, this component only re-renders itself, not the parent component.\n * Use this when you want to display a reactive value without causing parent re-renders.\n *\n * @param selector - A function that receives the current step's context and returns the selected value\n * @param children - Optional render prop that receives the selected value\n *\n * @example\n * <Selector selector={(ctx) => ctx.step1.fields.firstName.defaultValue}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n */\n Selector: selector.component<buildCurrentStep<def, value, targetStep>>;\n };\n\n export type callback<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n props,\n additionalCtx extends Record<string, unknown> = {},\n > = CreateComponent<\n Expand<\n input<def, value, targetStep, additionalCtx> &\n formComponent<def, value, [targetStep]> &\n additionalCtx\n >,\n props\n >;\n export const DEFAULT_FORM_INSTANCE_ALIAS = 'form';\n export type defaultFormInstanceAlias = typeof DEFAULT_FORM_INSTANCE_ALIAS;\n export type formInstanceOptions<alias extends string, input, ret> = {\n /**\n * The name of the return value of the `render` method.\n */\n alias?: alias;\n /**\n * A function that renders/creates the form instance. This function will be called\n * at the top level of the component, ensuring hooks are called in a valid React context.\n *\n * @param input - The input object containing context and default values\n * @returns The form instance (typically from a hook like `useForm`)\n *\n * @example\n * ```tsx\n * useFormInstance: {\n * render({ defaultValues }) {\n * return useForm({\n * defaultValues,\n * });\n * },\n * }\n * ```\n *\n * **Verification**: The hook call is automatically verified:\n * - Errors are caught and reported with helpful messages\n * - In development, hook calls are logged to console.debug\n * - The hook must be called at the component top level (enforced by the framework)\n */\n render: (input: input) => ret;\n };\n\n export type options<\n value extends steps.instantiateSteps,\n targetStep extends steps.StepNumbers<value>,\n formAlias extends string,\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n > = HelperFn.CtxDataSelector<value, [targetStep], additionalCtx> & {\n /**\n * If set to `true`, you'll be able to open the {@linkcode console} to view logs.\n */\n debug?: boolean;\n useFormInstance?: formInstanceOptions<\n formAlias,\n Pick<HelperFnInput.BaseInput<value, [targetStep]>, 'ctx'> & {\n /**\n * An object containing all the default values for the current step.\n */\n defaultValues: Expand<fields.getDefaultValues<value, [targetStep]>>;\n },\n formInstance\n >;\n };\n}\n\nexport interface StepSpecificCreateComponentFn<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n targetStep extends steps.StepNumbers<value>,\n> {\n /**\n * A utility function to easily create a component for the current step.\n * @param fn The callback function where the component is defined.\n */\n <props = undefined>(\n fn: StepSpecificComponent.callback<def, value, targetStep, props>\n ): CreatedMultiStepFormComponent<props>;\n /**\n * A utility function to easily create a component for the current step.\n * @param options Specific config options for creating a component for the current step.\n * @param fn The callback function where the component is defined.\n * @returns The created component.\n */\n <\n formInstance,\n additionalCtx extends Record<string, unknown> = {},\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n props = undefined,\n >(\n options: StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >,\n fn: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ): CreatedMultiStepFormComponent<props>;\n}\n\nexport interface HelperFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> {\n createComponent: CreateComponentFn<def, value>;\n}\nnamespace CreateComponentImplConfig {\n export type stepSpecificConfig<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = {\n isStepSpecific: true;\n defaultId: string;\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n\n export type nonStepSpecific = {\n isStepSpecific: false;\n };\n\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = nonStepSpecific | stepSpecificConfig<def, value>;\n}\n\nexport namespace MultiStepFormStepSchema {\n export type config<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n > = def & {\n /**\n * The form configuration.\n *\n * This is a private property and is not meant to be used directly.\n * If you want to configure the form, do so with the {@linkcode instantiateFormConfig} method.\n * @private\n * @internal\n */\n form?: MultiStepFormSchemaConfig.FormConfig<def, value>;\n };\n}\n\ndeclare module '@jfdevelops/multi-step-form-core' {\n namespace steps {\n interface ExtendedStepSpecificFunctions<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n key extends steps.StepNumbers<value>,\n > {\n createComponent: StepSpecificCreateComponentFn<def, value, key>;\n }\n }\n}\n\nexport class MultiStepFormStepSchema<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n>\n extends MultiStepFormStepSchemaBase<def, value>\n implements HelperFunctions<def, value>\n{\n value: value;\n readonly #internal: MultiStepFormStepSchemaInternal<def, value>;\n\n constructor(config: MultiStepFormStepSchema.config<def, value>) {\n const { form, ...rest } = config;\n\n super(rest as never);\n\n this.value = steps.instantiate({ steps: this.original });\n\n this.#internal = new MultiStepFormStepSchemaInternal({\n originalValue: this.original,\n getValue: () => this.value,\n setValue: (next) => this.handlePostUpdate(next),\n });\n\n this.sync();\n const availableSteps = this.steps.value;\n const createFormConfig = MultiStepFormSchemaConfig.instantiateFormConfig(\n this.value,\n availableSteps\n );\n const instantiatedForm = createFormConfig(form);\n this.value = this.#internal.enrichValues(this.value, (step) => {\n const targetStep = `step${step}` as steps.StepNumbers<value>;\n\n const id = form?.id ?? targetStep;\n\n return {\n createComponent: this.createStepSpecificComponentFactory(targetStep, {\n isStepSpecific: true,\n defaultId: id,\n form: instantiatedForm as never,\n }),\n };\n });\n }\n\n private createFormComponent(\n form: Omit<MultiStepFormSchemaConfig.FormConfig<def, value>, 'alias'>,\n defaultId: string\n ) {\n const { render, enabledForSteps = 'all', id = defaultId } = form;\n\n const ctx = {\n id,\n steps: createCtx(this.value, enabledForSteps as never),\n };\n\n return (props: MultiStepFormSchemaConfig.inferFormProps<value>) => {\n const Component = render(ctx as never);\n const invariant: Invariant = createInvariant('[createFormComponent]');\n\n invariant(\n typeof Component === 'function',\n 'The \"render\" property must be a function'\n );\n\n const C = Component(props);\n\n invariant(\n typeof C === 'function',\n 'The \"render\" function must return a valid React component'\n );\n\n return C;\n };\n }\n\n private createResolvedCtx<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown>,\n >(\n options: {\n stepData: chosenStep;\n logger: MultiStepFormLogger;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const { logger, stepData, ctxData } = options;\n // Create ctx fresh each time to ensure it has the latest this.value\n const ctx = createCtx(this.value, stepData);\n\n if (ctxData) {\n const [targetStep] = stepData;\n const { [targetStep]: _, ...values } = this.value;\n const createResolvedCtx = resolvedCtxCreator(logger, values as value);\n\n return createResolvedCtx({ ctx, ctxData } as never);\n }\n\n return ctx;\n }\n\n private createStepSpecificComponentImpl<\n // Safe to use tuple notation here since the step specific `createComponent` will always have\n // `stepData` as a tuple\n chosenStep extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >,\n additionalCtx extends Record<string, unknown> = {},\n >(\n stepData: chosenStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>,\n extraConfig?: {\n logger?: MultiStepFormLogger;\n input?: (\n ctx: Expand<HelperFn.buildCtx<value, chosenStep>>\n ) => Record<string, unknown>;\n } & HelperFn.CtxDataSelector<value, chosenStep, additionalCtx>\n ) {\n const [step] = stepData;\n const invariant: Invariant = createInvariant(`[${step}:createComponent]`);\n return <props>(fn: Function) =>\n ((props: props) => {\n const ctxData = extraConfig?.ctxData;\n const logger = extraConfig?.logger ?? new MultiStepFormLogger();\n const resolvedCtx = this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n });\n const extraInput = extraConfig?.input?.(resolvedCtx as never) ?? {};\n // Call hook functions from extraInput at the top level of the component\n // This ensures hooks are called in a valid React context (before any conditionals)\n const hookResults = getValidatedCustomInputHooks(extraInput);\n const { defaultId, form } = config;\n\n invariant(\n this.steps.isValidStep(step),\n `The target step ${step} is invalid. Note, this error shouldn't appear as the target step should always be valid. If you see this error, please open an issue.`\n );\n\n const stepNumber = Number.parseInt(step.replace('step', ''));\n\n invariant(\n !Number.isNaN(stepNumber),\n `An error occurred while extracting the number`\n );\n const current = this.value[step];\n\n invariant(\n typeof current === 'object' && current !== null,\n `The current step must be an object, was ${typeof current}`\n );\n // These checks are mostly for type safety. `current` should _always_ be in the proper format.\n // On the off chance that it's not, we have the checks here to help, but these checks are basically\n // just for type safety.\n invariant(\n 'fields' in current,\n `Unable to find the \"fields\" for the current step`\n );\n invariant(\n typeof current.fields === 'object',\n `The \"fields\" property must be an object, was ${typeof current.fields}`\n );\n\n // Memoize Field component to prevent remounting on every render\n // This ensures input focus is maintained when ctx changes\n const Field = field.create({\n propsCreator: (name) => {\n // Access current step data directly to avoid stale closure\n const currentStep = this.value[step] as typeof current;\n const currentFields = Object.keys(\n currentStep.fields as Record<string, unknown>\n );\n const invariant: Invariant = createInvariant(`[${step}:Field]`);\n\n invariant(\n typeof name === 'string',\n (formatter) =>\n `[${step}:Field]: the \"name\" prop must be a string and a valid field for ${step}. Available fields include: \"${formatter.format(\n currentFields\n )}\"`\n );\n // TODO add support for deep keys (`name`)\n\n const allAvailableFields = path\n .createDeep(currentStep.fields)\n .map((value) => (value as string).replace('.defaultValue.', '.'));\n\n invariant(\n allAvailableFields.includes(name),\n (formatter) =>\n `[${step}:Field]: the field \"${name}\" doesn't exist for the current step. Available fields include: \"${formatter.format(\n allAvailableFields\n )}\".`\n );\n\n invariant(\n 'update' in currentStep,\n `[${step}:Field]: No \"update\" function was found`\n );\n\n const defaultValue = this.getValue(step as never, name);\n const builtValuePath = fields.buildValuePath(name);\n const { label, nameTransformCasing, type } = path.pickBy(\n currentStep.fields,\n builtValuePath\n );\n\n const targetFields = `fields.${builtValuePath}`;\n\n return {\n defaultValue,\n label,\n nameTransformCasing,\n type,\n name,\n onInputChange: <\n strict extends boolean = true,\n partial extends boolean = false,\n >(\n value: unknown,\n options?: field.onInputChangeOptions<strict, partial>\n ) => {\n // Handle Updater pattern: if value is a function, call it with the current field value\n let resolvedValue;\n\n if (typeof value === 'function') {\n const defaultValue = this.getValue(step as never, name);\n\n resolvedValue = value(defaultValue);\n } else {\n resolvedValue = value;\n }\n\n this.update({\n partial: options?.partial ?? false,\n strict: options?.strict ?? true,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n targetStep: step,\n updater: resolvedValue as never,\n fields: [targetFields] as never,\n });\n },\n reset: (options?: UpdateFn.DebugOptions) =>\n this.reset({\n fields: [targetFields] as never,\n targetStep: step,\n debug: options?.debug,\n silentErrors: options?.silentErrors,\n }),\n } as never;\n },\n subscribe: this.subscribe,\n getValue: (name) => this.getValue(step as never, name as never),\n selectorCtx: this.createResolvedCtx({\n stepData,\n ctxData,\n logger,\n }) as never,\n });\n\n // Create useSelector hook for reactive value access via selector\n // This allows getting values from ctx reactively without causing re-renders\n // Pass a function that creates fresh ctx on each call to avoid stale closures\n const useSelector = createUseSelector(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n // Create Selector component that uses useSelector internally\n // This allows parts of the UI to subscribe to specific values without\n // causing the parent component to re-render\n const Selector = selector.create(\n () => this.createResolvedCtx({ stepData, ctxData, logger }) as never,\n this.subscribe\n );\n\n let fnInput = {\n ctx: resolvedCtx,\n onInputChange: this.#internal.createStepUpdaterFn(step),\n reset: this.#internal.createStepResetterFn(step),\n Field,\n useSelector,\n Selector,\n ...hookResults,\n };\n\n if (form) {\n const {\n alias = MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS,\n ...rest\n } = form;\n const enabledFor = rest.enabledForSteps ?? 'all';\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n if (\n MultiStepFormSchemaConfig.isFormAvailable(\n stepData as never,\n enabledFor as never\n )\n ) {\n fnInput = {\n ...fnInput,\n [alias]: this.createFormComponent(rest, defaultId),\n };\n }\n\n return fn(fnInput, props);\n }\n\n return fn(\n {\n ...fnInput,\n [MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS]:\n MultiStepFormSchemaConfig.createDefaultForm(defaultId),\n },\n props\n );\n }) as CreatedMultiStepFormComponent<props>;\n }\n\n private createStepSpecificComponentFactory<\n targetStep extends steps.StepNumbers<value>,\n >(\n targetStep: targetStep,\n config: CreateComponentImplConfig.stepSpecificConfig<def, value>\n ) {\n const impl = <\n formInstance,\n formInstanceAlias extends string =\n StepSpecificComponent.defaultFormInstanceAlias,\n additionalCtx extends Record<string, unknown> = {},\n >(\n optionsOrFn:\n | StepSpecificComponent.options<\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormAlias<value>,\n formInstance,\n additionalCtx\n >\n | StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >,\n fn?: StepSpecificComponent.callback<\n def,\n value,\n targetStep,\n MultiStepFormSchemaConfig.inferFormProps<value>,\n { [_ in formInstanceAlias]: formInstance }\n >\n ) => {\n const invariant: Invariant = createInvariant(\n '[createStepSpecificComponent]'\n );\n\n const createStepSpecificComponent = () => {\n invariant(\n typeof optionsOrFn === 'function',\n 'The first argument must be a function'\n );\n\n return this.createStepSpecificComponentImpl(\n [targetStep],\n config\n )(optionsOrFn);\n };\n\n if (typeof optionsOrFn === 'object') {\n const { useFormInstance, ctxData, debug } = optionsOrFn;\n const logger = new MultiStepFormLogger({\n debug,\n prefix(prefix) {\n return `${prefix}-${targetStep}-createComponent`;\n },\n });\n\n logger.info('First argument is an object');\n\n invariant(\n typeof fn === 'function',\n 'The second argument must be a function'\n );\n\n if (useFormInstance) {\n const {\n render,\n alias = StepSpecificComponent.DEFAULT_FORM_INSTANCE_ALIAS,\n } = useFormInstance;\n\n invariant(typeof alias === 'string', 'The alias must be a string');\n\n // const [step] = stepData;\n\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n input: (ctx) => {\n const defaultValues = this.createDefaultValues(\n targetStep\n ) as never;\n\n return {\n [alias]: () =>\n render({\n ctx,\n defaultValues,\n }),\n };\n },\n })(fn);\n }\n\n if (ctxData) {\n return this.createStepSpecificComponentImpl([targetStep], config, {\n logger,\n ctxData,\n })(fn);\n }\n\n // Empty options object. Can throw here 🤷‍♂️\n // Maybe add \"global\" - top level config - option to tune fine grained errors.\n return createStepSpecificComponent();\n }\n\n return createStepSpecificComponent();\n };\n\n return impl as StepSpecificCreateComponentFn<def, value, targetStep>;\n }\n\n /**\n * A helper function to create a component for a specific step.\n * @param options The options for creating the step specific component.\n * @param fn A callback that is used for accessing the target step's data and defining\n * any props that the component should have. This function must return a valid `JSX` element.\n * @returns The created component for the step.\n */\n createComponent<\n chosenSteps extends HelperFnChosenSteps.main<\n value,\n steps.StepNumbers<value>\n >,\n props = undefined,\n >(\n options: HelperFn.BaseOptions<value, chosenSteps>,\n fn: CreateComponentCallback<value, chosenSteps, props>\n ) {\n return createComponent({\n fn,\n input: ({ stepData }) => ({\n reset: this.#internal.createHelperFnInputReset(stepData),\n update: this.#internal.createHelperFnInputUpdate(stepData),\n }),\n options,\n value: this.value,\n });\n }\n\n createDefaultValues<targetStep extends steps.StepNumbers<value>>(\n targetStep: targetStep\n ) {\n return fields.getDefaultValues(this.value, targetStep);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jfdevelops/react-multi-step-form",
3
- "version": "1.0.0-alpha.33",
3
+ "version": "1.0.0-alpha.34",
4
4
  "description": "",
5
5
  "repository": "https://github.com/jfdevelops/multi-step-form",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "use-sync-external-store": "^1.6.0",
39
- "@jfdevelops/multi-step-form-core": "1.0.0-alpha.24"
39
+ "@jfdevelops/multi-step-form-core": "1.0.0-alpha.25"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public",