@jfdevelops/react-multi-step-form 1.0.0-alpha.32 → 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/create-context.cjs +6 -8
- package/dist/create-context.cjs.map +1 -1
- package/dist/create-context.d.cts +19 -21
- package/dist/create-context.d.mts +19 -21
- package/dist/create-context.mjs +12 -14
- package/dist/create-context.mjs.map +1 -1
- package/dist/field.cjs.map +1 -1
- package/dist/field.d.cts +15 -15
- package/dist/field.d.mts +15 -15
- package/dist/field.mjs.map +1 -1
- package/dist/form-config.cjs +38 -6
- package/dist/form-config.cjs.map +1 -1
- package/dist/form-config.d.cts +52 -18
- package/dist/form-config.d.mts +52 -18
- package/dist/form-config.mjs +38 -6
- package/dist/form-config.mjs.map +1 -1
- package/dist/hooks/use-multi-step-form-data.cjs +4 -22
- package/dist/hooks/use-multi-step-form-data.cjs.map +1 -1
- package/dist/hooks/use-multi-step-form-data.d.cts +12 -10
- package/dist/hooks/use-multi-step-form-data.d.mts +12 -10
- package/dist/hooks/use-multi-step-form-data.mjs +5 -22
- package/dist/hooks/use-multi-step-form-data.mjs.map +1 -1
- package/dist/hooks/use-selector.cjs.map +1 -1
- package/dist/hooks/use-selector.d.cts +18 -4
- package/dist/hooks/use-selector.d.mts +18 -4
- package/dist/hooks/use-selector.mjs.map +1 -1
- package/dist/index.cjs +2 -3
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/schema.cjs +87 -10
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +66 -25
- package/dist/schema.d.mts +66 -25
- package/dist/schema.mjs +88 -11
- package/dist/schema.mjs.map +1 -1
- package/dist/selector.cjs.map +1 -1
- package/dist/selector.d.cts +8 -8
- package/dist/selector.d.mts +8 -8
- package/dist/selector.mjs.map +1 -1
- package/dist/step-schema.cjs +54 -56
- package/dist/step-schema.cjs.map +1 -1
- package/dist/step-schema.d.cts +62 -61
- package/dist/step-schema.d.mts +62 -61
- package/dist/step-schema.mjs +57 -58
- package/dist/step-schema.mjs.map +1 -1
- package/dist/utils.cjs +12 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +12 -0
- package/dist/utils.d.mts +12 -0
- package/dist/utils.mjs +13 -2
- package/dist/utils.mjs.map +1 -1
- package/package.json +2 -2
package/dist/field.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SelectorFn } from "./hooks/use-selector.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { Expand, HelperFn, Override, UpdateFn, Updater, fields } from "@jfdevelops/multi-step-form-core";
|
|
3
3
|
import * as react0 from "react";
|
|
4
4
|
import { ReactNode } from "react";
|
|
5
5
|
|
|
@@ -15,17 +15,17 @@ declare namespace field {
|
|
|
15
15
|
strict: TStrict;
|
|
16
16
|
partial: TPartial;
|
|
17
17
|
}> & UpdateFn.DebugOptions;
|
|
18
|
-
export type childrenProps<
|
|
18
|
+
export type childrenProps<steps$1 extends steps$1.instantiateSteps, field$1 extends fields.getDeepFields<steps$1, targetStep>, targetStep extends steps$1.StepNumbers<steps$1> = steps$1.StepNumbers<steps$1>, value extends fields.resolveDeepPath<steps$1, targetStep, field$1> = fields.resolveDeepPath<steps$1, targetStep, field$1>, TConfig extends fields.getConfig<steps$1, targetStep, field$1> = fields.getConfig<steps$1, targetStep, field$1>> = sharedProps<field$1> & (TConfig extends {
|
|
19
19
|
defaultValue: unknown;
|
|
20
|
-
} ? Override<TConfig, 'defaultValue',
|
|
21
|
-
defaultValue: `An unknown error occurred while getting the "defaultValue" for ${
|
|
20
|
+
} ? Override<TConfig, 'defaultValue', value> : {
|
|
21
|
+
defaultValue: `An unknown error occurred while getting the "defaultValue" for ${field$1}`;
|
|
22
22
|
}) & {
|
|
23
23
|
/**
|
|
24
24
|
* A useful wrapper around `update` to update the specific field.
|
|
25
25
|
* @param value The new value for the field.
|
|
26
26
|
* @param options The options for the update operation.
|
|
27
27
|
*/
|
|
28
|
-
onInputChange: <strict extends boolean = true, partial extends boolean = false>(value: Updater<UpdateFn.resolvedUpdaterReturnType<
|
|
28
|
+
onInputChange: <strict extends boolean = true, partial extends boolean = false>(value: Updater<UpdateFn.resolvedUpdaterReturnType<value, {
|
|
29
29
|
strict: strict;
|
|
30
30
|
partial: partial;
|
|
31
31
|
}, {}>>, options?: onInputChangeOptions<strict, partial>) => void;
|
|
@@ -35,7 +35,7 @@ declare namespace field {
|
|
|
35
35
|
*/
|
|
36
36
|
reset: (options?: UpdateFn.DebugOptions) => void;
|
|
37
37
|
};
|
|
38
|
-
export type childrenPropsWithSelected<
|
|
38
|
+
export type childrenPropsWithSelected<steps$1 extends steps$1.instantiateSteps, field$1 extends fields.getDeepFields<steps$1, steps$1.StepNumbers<steps$1>>, TSelected> = childrenProps<steps$1, field$1> & {
|
|
39
39
|
selected: {
|
|
40
40
|
/**
|
|
41
41
|
* The result of the `selectorFn`.
|
|
@@ -43,16 +43,16 @@ declare namespace field {
|
|
|
43
43
|
value: TSelected;
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
|
-
export type props<
|
|
47
|
-
selectorFn?: SelectorFn<
|
|
48
|
-
children: (props: [
|
|
46
|
+
export type props<step extends steps$1.instantiateSteps, field$1 extends fields.getDeepFields<step, steps$1.StepNumbers<step>>, selected> = sharedProps<field$1> & {
|
|
47
|
+
selectorFn?: SelectorFn<step, selected>;
|
|
48
|
+
children: (props: [selected] extends [never] ? childrenProps<step, field$1> : childrenPropsWithSelected<step, field$1, selected>) => ReactNode;
|
|
49
49
|
};
|
|
50
|
-
export type component<
|
|
51
|
-
export type createOptions<
|
|
52
|
-
propsCreator: <
|
|
50
|
+
export type component<steps$1 extends steps$1.instantiateSteps> = <field$1 extends fields.getDeepFields<steps$1, steps$1.StepNumbers<steps$1>>, selected = never>(props: props<steps$1, field$1, selected>) => ReactNode;
|
|
51
|
+
export type createOptions<step extends steps$1.instantiateSteps> = {
|
|
52
|
+
propsCreator: <field$1 extends fields.getDeepFields<step, steps$1.StepNumbers<step>>>(name: field$1) => field$1.childrenProps<step, field$1>;
|
|
53
53
|
subscribe?: (listener: () => void) => () => void;
|
|
54
|
-
getValue?: <
|
|
55
|
-
selectorCtx: Expand<
|
|
54
|
+
getValue?: <field$1 extends fields.getDeepFields<step, steps$1.StepNumbers<step>>>(name: field$1) => fields.resolveDeepPath<step, steps$1.StepNumbers<step>, field$1>;
|
|
55
|
+
selectorCtx: Expand<HelperFn.buildCtx<step, [steps$1.StepNumbers<step>]>>;
|
|
56
56
|
};
|
|
57
57
|
/**
|
|
58
58
|
* Create a field.
|
|
@@ -61,7 +61,7 @@ declare namespace field {
|
|
|
61
61
|
* @param getValue - Optional function to get the current field value reactively
|
|
62
62
|
* @returns
|
|
63
63
|
*/
|
|
64
|
-
export function create<
|
|
64
|
+
export function create<step extends steps$1.instantiateSteps>(options: createOptions<step>): react0.MemoExoticComponent<component<step>>;
|
|
65
65
|
export {};
|
|
66
66
|
}
|
|
67
67
|
//#endregion
|
package/dist/field.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.mjs","names":["Field: field.component<
|
|
1
|
+
{"version":3,"file":"field.mjs","names":["Field: field.component<step>"],"sources":["../src/field.tsx"],"sourcesContent":["import type {\n Expand,\n fields,\n HelperFn,\n Override,\n steps,\n UpdateFn,\n Updater,\n} from '@jfdevelops/multi-step-form-core';\nimport type { ReactNode } from 'react';\nimport { memo, useSyncExternalStore } from 'react';\nimport type { SelectorFn } from './hooks/use-selector';\nimport { selector } from './selector';\n\nexport namespace field {\n type sharedProps<TField extends string> = {\n /**\n * The name of the field.\n */\n name: TField;\n };\n\n export type onInputChangeOptions<\n TStrict extends boolean,\n TPartial extends boolean,\n > = UpdateFn.ModeOptions<{\n strict: TStrict;\n partial: TPartial;\n }> &\n UpdateFn.DebugOptions;\n\n export type childrenProps<\n steps extends steps.instantiateSteps,\n field extends fields.getDeepFields<steps, targetStep>,\n targetStep extends steps.StepNumbers<steps> = steps.StepNumbers<steps>,\n value extends fields.resolveDeepPath<steps, targetStep, field> =\n fields.resolveDeepPath<steps, targetStep, field>,\n TConfig extends fields.getConfig<steps, targetStep, field> =\n fields.getConfig<steps, targetStep, field>,\n > = sharedProps<field> &\n (TConfig extends { defaultValue: unknown }\n ? Override<TConfig, 'defaultValue', value>\n : {\n defaultValue: `An unknown error occurred while getting the \"defaultValue\" for ${field}`;\n }) & {\n /**\n * A useful wrapper around `update` to update the specific field.\n * @param value The new value for the field.\n * @param options The options for the update operation.\n */\n onInputChange: <\n strict extends boolean = true,\n partial extends boolean = false,\n >(\n value: Updater<\n UpdateFn.resolvedUpdaterReturnType<\n value,\n { strict: strict; partial: partial },\n {}\n >\n >,\n options?: onInputChangeOptions<strict, partial>\n ) => void;\n /**\n * Resets the field's value to the original value that was\n * defined in the config.\n */\n reset: (options?: UpdateFn.DebugOptions) => void;\n };\n\n export type childrenPropsWithSelected<\n steps extends steps.instantiateSteps,\n field extends fields.getDeepFields<steps, steps.StepNumbers<steps>>,\n TSelected,\n > = childrenProps<steps, field> & {\n selected: {\n /**\n * The result of the `selectorFn`.\n */\n value: TSelected;\n };\n };\n export type props<\n step extends steps.instantiateSteps,\n field extends fields.getDeepFields<step, steps.StepNumbers<step>>,\n selected,\n > = sharedProps<field> & {\n selectorFn?: SelectorFn<step, selected>;\n children: (\n props: [selected] extends [never]\n ? childrenProps<step, field>\n : childrenPropsWithSelected<step, field, selected>\n ) => ReactNode;\n };\n export type component<steps extends steps.instantiateSteps> = <\n field extends fields.getDeepFields<steps, steps.StepNumbers<steps>>,\n selected = never,\n >(\n props: props<steps, field, selected>\n ) => ReactNode;\n\n export type createOptions<step extends steps.instantiateSteps> = {\n propsCreator: <\n field extends fields.getDeepFields<step, steps.StepNumbers<step>>,\n >(\n name: field\n ) => field.childrenProps<step, field>;\n subscribe?: (listener: () => void) => () => void;\n getValue?: <\n field extends fields.getDeepFields<step, steps.StepNumbers<step>>,\n >(\n name: field\n ) => fields.resolveDeepPath<step, steps.StepNumbers<step>, field>;\n selectorCtx: Expand<HelperFn.buildCtx<step, [steps.StepNumbers<step>]>>;\n };\n\n /**\n * Create a field.\n * @param propsCreator\n * @param subscribe - Optional subscription function for reactivity\n * @param getValue - Optional function to get the current field value reactively\n * @returns\n */\n export function create<step extends steps.instantiateSteps>(\n options: createOptions<step>\n ) {\n const { propsCreator, subscribe, getValue, selectorCtx } = options;\n\n const Field: field.component<step> = (props) => {\n const { name, children, selectorFn } = props;\n\n // Always call the hook, but use no-op functions if subscribe/getValue aren't provided\n const subscribeFn = subscribe || (() => () => {});\n const getValueFn = getValue || (() => undefined);\n\n // Subscribe to changes to trigger rerenders\n const currentValue = useSyncExternalStore(\n subscribeFn,\n () => getValueFn(name),\n () => getValueFn(name)\n );\n\n let createdProps = propsCreator(name);\n\n // If getValue is provided, override defaultValue with the reactive value\n if (getValue) {\n createdProps = {\n ...createdProps,\n defaultValue: currentValue,\n } as never;\n }\n\n if (selectorFn) {\n const Selector = selector.create<step>(() => selectorCtx, subscribeFn);\n\n return (\n <Selector selector={selectorFn}>\n {(value) =>\n children({\n ...createdProps,\n selected: { value: value as never },\n } as never)\n }\n </Selector>\n );\n }\n\n return children(createdProps as never);\n };\n\n return memo(Field);\n }\n}\n"],"mappings":";;;;;;;CA2HS,SAAS,OACd,SACA;EACA,MAAM,EAAE,cAAc,WAAW,UAAU,gBAAgB;EAE3D,MAAMA,SAAgC,UAAU;GAC9C,MAAM,EAAE,MAAM,UAAU,eAAe;GAGvC,MAAM,cAAc,0BAA0B;GAC9C,MAAM,aAAa,mBAAmB;GAGtC,MAAM,eAAe,qBACnB,mBACM,WAAW,KAAK,QAChB,WAAW,KAAK,CACvB;GAED,IAAI,eAAe,aAAa,KAAK;AAGrC,OAAI,SACF,gBAAe;IACb,GAAG;IACH,cAAc;IACf;AAGH,OAAI,WAGF,QACE,oBAHe,SAAS,aAAmB,aAAa,YAAY;IAG1D,UAAU;eAChB,UACA,SAAS;KACP,GAAG;KACH,UAAU,EAAS,OAAgB;KACpC,CAAU;KAEJ;AAIf,UAAO,SAAS,aAAsB;;AAGxC,SAAO,KAAK,MAAM"}
|
package/dist/form-config.cjs
CHANGED
|
@@ -1,15 +1,47 @@
|
|
|
1
|
+
let __jfdevelops_multi_step_form_core = require("@jfdevelops/multi-step-form-core");
|
|
1
2
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
2
3
|
|
|
3
4
|
//#region src/form-config.tsx
|
|
4
5
|
let MultiStepFormSchemaConfig;
|
|
5
6
|
(function(_MultiStepFormSchemaConfig) {
|
|
6
|
-
_MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS = "Form";
|
|
7
|
+
const DEFAULT_FORM_ALIAS = _MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS = "Form";
|
|
8
|
+
function instantiateFormConfig(data, availableSteps) {
|
|
9
|
+
return (config) => {
|
|
10
|
+
const defaults = {
|
|
11
|
+
alias: DEFAULT_FORM_ALIAS,
|
|
12
|
+
enabledForSteps: "all",
|
|
13
|
+
props: void 0
|
|
14
|
+
};
|
|
15
|
+
if (!config) return defaults;
|
|
16
|
+
const { alias = defaults.alias, enabledForSteps = defaults.enabledForSteps, render, id } = config;
|
|
17
|
+
const invariant = (0, __jfdevelops_multi_step_form_core.createInvariant)("[instantiateFormConfig]");
|
|
18
|
+
if (id) invariant(typeof id === "string", "The id must be a string");
|
|
19
|
+
if (alias) invariant(typeof alias === "string", "The alias must be a string");
|
|
20
|
+
if (enabledForSteps) {
|
|
21
|
+
const availableStepsArray = Array.from(availableSteps);
|
|
22
|
+
invariant(__jfdevelops_multi_step_form_core.HelperFnChosenSteps.isValid(enabledForSteps, availableStepsArray), __jfdevelops_multi_step_form_core.HelperFnChosenSteps.createCatchAllMessage(availableStepsArray, "enabledFor"));
|
|
23
|
+
}
|
|
24
|
+
invariant(typeof render === "function", "The render must be a function");
|
|
25
|
+
return {
|
|
26
|
+
alias,
|
|
27
|
+
enabledForSteps,
|
|
28
|
+
[alias]: render(data)
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
_MultiStepFormSchemaConfig.instantiateFormConfig = instantiateFormConfig;
|
|
7
33
|
function isFormAvailable(target, enabledFor) {
|
|
8
|
-
if (Array.isArray(target)) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
34
|
+
if (Array.isArray(target)) return __jfdevelops_multi_step_form_core.HelperFnChosenSteps.match({
|
|
35
|
+
meta: { target },
|
|
36
|
+
default: () => false,
|
|
37
|
+
all: () => true,
|
|
38
|
+
tuple: ({ chosenSteps, meta }) => {
|
|
39
|
+
return chosenSteps.some((key) => meta.target.includes(key));
|
|
40
|
+
},
|
|
41
|
+
object: ({ chosenSteps, meta }) => {
|
|
42
|
+
return Object.keys(chosenSteps).some((key) => meta.target.includes(key));
|
|
43
|
+
}
|
|
44
|
+
})(enabledFor);
|
|
13
45
|
return false;
|
|
14
46
|
}
|
|
15
47
|
_MultiStepFormSchemaConfig.isFormAvailable = isFormAvailable;
|
package/dist/form-config.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-config.cjs","names":[],"sources":["../src/form-config.tsx"],"sourcesContent":["import type {\n Expand,\n HelperFnChosenSteps,\n StepNumbers,\n ValidStepKey,\n} from '@jfdevelops/multi-step-form-core';\nimport type { ComponentPropsWithRef, JSX } from 'react';\nimport type {\n AnyResolvedStep,\n CreatedMultiStepFormComponent,\n} from './step-schema';\n\nexport namespace MultiStepFormSchemaConfig {\n export const DEFAULT_FORM_ALIAS = 'Form';\n export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;\n export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;\n export type formEnabledFor<TResolvedStep extends AnyResolvedStep> =\n HelperFnChosenSteps<TResolvedStep, StepNumbers<TResolvedStep>>;\n type strippedResolvedSteps<T extends AnyResolvedStep> = {\n [_ in keyof T]: Expand<Omit<T[_], 'createComponent' | 'createHelperFn'>>;\n };\n export type AvailableStepForForm<\n TResolvedStep extends AnyResolvedStep,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n > = TEnabledFor extends defaultEnabledFor\n ? strippedResolvedSteps<TResolvedStep>\n : TEnabledFor extends [\n ValidStepKey<StepNumbers<TResolvedStep>>,\n ...ValidStepKey<StepNumbers<TResolvedStep>>[]\n ]\n ? TEnabledFor[number] extends keyof TResolvedStep\n ? Pick<strippedResolvedSteps<TResolvedStep>, TEnabledFor[number]>\n : never\n : keyof TEnabledFor extends keyof TResolvedStep\n ? Expand<\n Pick<\n strippedResolvedSteps<TResolvedStep>,\n Extract<keyof TResolvedStep, keyof TEnabledFor>\n >\n >\n : never;\n export type formCtx<TAlias extends string, TProps> = {\n [_ in TAlias]: CreatedMultiStepFormComponent<TProps>;\n };\n export type renderFnData<\n TResolvedStep extends AnyResolvedStep,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n > = {\n /**\n * The id for the form, either a custom one or the default one.\n */\n id: string;\n /**\n * The chosen steps that are available.\n */\n steps: Expand<AvailableStepForForm<TResolvedStep, TEnabledFor>>;\n };\n\n /**\n * The configuration options for the `form` option.\n */\n export interface FormConfig<\n TResolvedStep extends AnyResolvedStep,\n TAlias extends string,\n TFormEnabledFor extends formEnabledFor<TResolvedStep>,\n TCustomFormProps extends object\n > {\n /**\n * The `id` for the form component.\n *\n * If there is no value provided, the default id will the **current step key**.\n *\n * @default `${currentStep}`\n */\n id?: string;\n /**\n * The \"name\" of the form component.\n * @default 'Form'\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 * form: {\n * alias: 'MyCustomForm',\n * render() {\n * // return custom form component here\n * }\n * }\n * }\n * })\n *\n * const Step1 = schema.stepSchema.step1.createComponent(\n * ({ ctx, MyCustomForm }, props: { children: ReactNode }) =>\n * // Notice how the form is available with its alias\n * <MyCustomFormName>{children}</MyCustomFormName>\n * )\n * ```\n */\n alias?: TAlias;\n /**\n * If the form component should be accessible for each step when calling `createComponent`.\n *\n * If no value is given, the form will be accessible for all the steps.\n */\n enabledForSteps?: TFormEnabledFor;\n /**\n *\n * @param data The data that is available for creating the custom form.\n * @param props Props that can be used for the custom form.\n * @returns An {@see JSX.Element} that is the custom form.\n * @example\n * ### With custom props\n * ```tsx\n * type CustomProps = {\n * title: string;\n * description?: string;\n * children: ReactNode;\n * };\n *\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props: CustomProps) {\n * return (\n * <div>\n * <h1>{props.title}</h1>\n * <p>{props.description}</p>\n * <form>{props.children}</form>\n * </div>\n * );\n * }\n * }\n * }\n * })\n * ```\n * ### Without custom props\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props) {\n * // The default type for `props` will be `ComponentPropsWithRef<'form'>`\n * // return custom form component here\n * }\n * }\n * }\n * })\n * ```\n */\n render: (\n data: renderFnData<TResolvedStep, TFormEnabledFor>,\n props: TCustomFormProps\n ) => JSX.Element;\n }\n\n export interface Form<\n TResolvedStep extends AnyResolvedStep,\n TAlias extends string,\n TFormEnabledFor extends formEnabledFor<TResolvedStep>,\n TCustomFormProps extends object\n > {\n form?: FormConfig<TResolvedStep, TAlias, TFormEnabledFor, TCustomFormProps>;\n }\n\n /**\n * Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form\n * should be available.\n * @param target The target steps the form _should_ be available for.\n * @param enabledFor The steps that the form _is_ enabled for.\n * @returns A boolean representing if the form should be available.\n */\n // Note: the implementation is specific to `MultiStepFormStepSchema.createComponentForStep`\n // because the `target` will always be an `Array` in `MultiStepFormStepSchema.createComponentForStep`.\n // TODO add validation to keys\n export function isFormAvailable<\n TResolvedStep extends AnyResolvedStep,\n TTarget extends HelperFnChosenSteps<\n TResolvedStep,\n StepNumbers<TResolvedStep>\n >,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n >(target: TTarget, enabledFor: TEnabledFor) {\n if (Array.isArray(target)) {\n if (enabledFor === 'all') {\n return true;\n }\n\n if (typeof enabledFor === 'object' && !Array.isArray(enabledFor)) {\n return Object.keys(enabledFor).some((key) =>\n target.includes(key as `step${StepNumbers<TResolvedStep>}`)\n );\n }\n\n if (Array.isArray(enabledFor)) {\n return enabledFor.some((key) => target.includes(key));\n }\n }\n\n return false;\n }\n\n /**\n * Creates a form component with a default id.\n * @param id The default id for the form.\n * @returns A form component with a default {@linkcode id}.\n */\n export function createDefaultForm(id: string) {\n return (props: Omit<ComponentPropsWithRef<'form'>, 'id'>) => (\n <form id={id} {...props} />\n );\n }\n}\n"],"mappings":";;;;;iDAaoC;CA2L3B,SAAS,gBAOd,QAAiB,YAAyB;AAC1C,MAAI,MAAM,QAAQ,OAAO,EAAE;AACzB,OAAI,eAAe,MACjB,QAAO;AAGT,OAAI,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,WAAW,CAC9D,QAAO,OAAO,KAAK,WAAW,CAAC,MAAM,QACnC,OAAO,SAAS,IAA2C,CAC5D;AAGH,OAAI,MAAM,QAAQ,WAAW,CAC3B,QAAO,WAAW,MAAM,QAAQ,OAAO,SAAS,IAAI,CAAC;;AAIzD,SAAO;;;CAQF,SAAS,kBAAkB,IAAY;AAC5C,UAAQ,UACN,2CAAC;GAAS;GAAI,GAAI;IAAS"}
|
|
1
|
+
{"version":3,"file":"form-config.cjs","names":["invariant: Invariant","HelperFnChosenSteps"],"sources":["../src/form-config.tsx"],"sourcesContent":["import {\n createInvariant,\n Expand,\n HelperFnChosenSteps,\n steps,\n type Invariant,\n} from '@jfdevelops/multi-step-form-core';\nimport type { StepSchema } from '@jfdevelops/multi-step-form-core/_internals';\nimport {\n type ComponentPropsWithRef,\n type ComponentType,\n type FunctionComponent,\n} from 'react';\nimport type { CreatedMultiStepFormComponent } from './utils';\n\nexport namespace MultiStepFormSchemaConfig {\n export const DEFAULT_FORM_ALIAS = 'Form';\n export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;\n export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;\n export type formEnabledFor<value extends steps.instantiateSteps> =\n HelperFnChosenSteps.main<value, steps.StepNumbers<value>>;\n type strippedResolvedSteps<value extends steps.instantiateSteps> = {\n [_ in keyof value]: Expand<\n Omit<value[_], 'createComponent' | 'createHelperFn'>\n >;\n };\n export type inferFormAlias<def> = def extends {\n alias: infer alias extends string;\n }\n ? alias\n : defaultFormAlias;\n export type inferFormProps<def> = def extends {\n render: infer render;\n }\n ? render extends (data: any) => ComponentType<infer props>\n ? props\n : never\n : never;\n export namespace EnabledForSteps {\n export type get<def> = def extends {\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps // Case: `enabledForSteps` isn't provided (default behavior)\n : def extends { form: infer form }\n ? form extends { enabledForSteps: infer enabledForSteps }\n ? enabledForSteps // Case: `enabledForSteps` is provided in the form config\n : never\n : never;\n export type resolveType<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n value = instantiateFormConfig<def>,\n > =\n get<value> extends defaultEnabledFor\n ? 'all'\n : get<value> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? 'tuple'\n : get<value> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? 'object'\n : never;\n }\n\n export type inferFormEnabledForSteps<def> = def extends {\n // TODO decide if `enabledForSteps` validation is needed\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps\n : defaultEnabledFor;\n export type inferComponent<def> = def extends { render: infer render }\n ? render extends (data: any) => infer r\n ? r extends ComponentType<infer _>\n ? r\n : never\n : never\n : never;\n export type inferredFormComponent<def> = {\n [key in inferFormAlias<def>]: inferComponent<def>;\n };\n\n export type instantiateFormConfig<def> = [def] extends [object]\n ? def extends { form: infer form }\n ? {\n -readonly [key in keyof FormConfig.withoutRender<form>]: Expand<\n {\n alias: inferFormAlias<FormConfig.withoutRender<form>>;\n enabledForSteps: inferFormEnabledForSteps<\n FormConfig.withoutRender<form>\n >;\n } & inferredFormComponent<form>\n >;\n }[keyof FormConfig.withoutRender<form>]\n : {}\n : {};\n export type getEnabledForSteps<def> =\n instantiateFormConfig<def> extends {\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps\n : def;\n export type AvailableStepForForm<\n value extends steps.instantiateSteps,\n enabledFor extends formEnabledFor<value>,\n > = enabledFor extends defaultEnabledFor\n ? strippedResolvedSteps<value>\n : enabledFor extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >\n ? enabledFor[number] extends keyof value\n ? Pick<strippedResolvedSteps<value>, enabledFor[number]>\n : never\n : keyof enabledFor extends keyof value\n ? Expand<\n Pick<\n strippedResolvedSteps<value>,\n Extract<keyof value, keyof enabledFor>\n >\n >\n : never;\n export type formCtx<alias extends string, props> = {\n [_ in alias]: CreatedMultiStepFormComponent<props>;\n };\n export type renderFnData<\n value extends steps.instantiateSteps,\n enabledFor extends formEnabledFor<value>,\n > = {\n /**\n * The id for the form, either a custom one or the default one.\n */\n id: string;\n /**\n * The chosen steps that are available.\n */\n steps: Expand<AvailableStepForForm<value, enabledFor>>;\n };\n\n export namespace FormConfig {\n export type withoutRender<def> = Omit<def, 'render'>;\n }\n\n /**\n * The configuration options for the `form` option.\n */\n export interface FormConfig<\n def extends StepSchema.Config = StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > {\n /**\n * The `id` for the form component.\n *\n * If there is no value provided, the default id will the **current step key**.\n *\n * @default `${currentStep}`\n */\n id?: string;\n /**\n * The \"name\" of the form component.\n * @default 'Form'\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 * form: {\n * alias: 'MyCustomForm',\n * render() {\n * // return custom form component here\n * }\n * }\n * }\n * })\n *\n * const Step1 = schema.stepSchema.step1.createComponent(\n * ({ ctx, MyCustomForm }, props: { children: ReactNode }) =>\n * // Notice how the form is available with its alias\n * <MyCustomFormName>{children}</MyCustomFormName>\n * )\n * ```\n */\n alias?: string;\n /**\n * If the form component should be accessible for each step when calling `createComponent`.\n *\n * If no value is given, the form will be accessible for all the steps.\n */\n enabledForSteps?: HelperFnChosenSteps.main<value, steps.StepNumbers<value>>;\n /**\n *\n * @param data The data that is available for creating the custom form.\n * @param props Props that can be used for the custom form.\n * @returns A React component that is the custom form.\n * @example\n * ### With custom props\n * ```tsx\n * type CustomProps = {\n * title: string;\n * description?: string;\n * children: ReactNode;\n * };\n *\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props: CustomProps) {\n * return (\n * <div>\n * <h1>{props.title}</h1>\n * <p>{props.description}</p>\n * <form>{props.children}</form>\n * </div>\n * );\n * }\n * }\n * }\n * })\n * ```\n * ### Without custom props\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props) {\n * // The default type for `props` will be `ComponentPropsWithRef<'form'>`\n * // return custom form component here\n * }\n * }\n * }\n * })\n * ```\n */\n // render: (\n // data: renderFnData<value, {[key in keyof def['steps']]: {}}>,\n // props: def['formProps']\n // ) => JSX.Element;\n render: (data: value) => FunctionComponent<any>;\n }\n\n export function instantiateFormConfig<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n >(data: value, availableSteps: readonly steps.StepNumbers<value>[]) {\n return <\n const form extends FormConfig<def, value>,\n inst = instantiateFormConfig<form>,\n >(\n config: form | undefined\n ) => {\n const defaults = {\n alias: DEFAULT_FORM_ALIAS,\n enabledForSteps: 'all',\n props: undefined,\n };\n\n if (!config) {\n return defaults as inst;\n }\n\n const {\n alias = defaults.alias,\n enabledForSteps = defaults.enabledForSteps,\n render,\n id,\n } = config;\n const invariant: Invariant = createInvariant('[instantiateFormConfig]');\n\n if (id) {\n invariant(typeof id === 'string', 'The id must be a string');\n }\n\n if (alias) {\n invariant(typeof alias === 'string', 'The alias must be a string');\n }\n\n // TODO validate enabledForSteps\n if (enabledForSteps) {\n const availableStepsArray = Array.from(availableSteps);\n\n invariant(\n HelperFnChosenSteps.isValid(enabledForSteps, availableStepsArray),\n HelperFnChosenSteps.createCatchAllMessage(\n availableStepsArray,\n 'enabledFor'\n )\n );\n }\n\n invariant(typeof render === 'function', 'The render must be a function');\n\n return {\n alias,\n enabledForSteps,\n [alias]: render(data),\n } as inst;\n };\n }\n\n /**\n * Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form\n * should be available.\n * @param target The target steps the form _should_ be available for.\n * @param enabledFor The steps that the form _is_ enabled for.\n * @returns A boolean representing if the form should be available.\n */\n // Note: the implementation is specific to `MultiStepFormStepSchema.createComponentForStep`\n // because the `target` will always be an `Array` in `MultiStepFormStepSchema.createComponentForStep`.\n // TODO add validation to keys\n export function isFormAvailable<\n value extends steps.instantiateSteps,\n target extends HelperFnChosenSteps.main<value, steps.StepNumbers<value>>,\n enabledFor extends formEnabledFor<value>,\n >(target: target, enabledFor: enabledFor) {\n if (Array.isArray(target)) {\n const match = HelperFnChosenSteps.match({\n meta: {\n target,\n },\n default: () => false,\n all: () => true,\n tuple: ({ chosenSteps, meta }) => {\n return chosenSteps.some((key) => meta.target.includes(key));\n },\n object: ({ chosenSteps, meta }) => {\n return Object.keys(chosenSteps).some((key) =>\n meta.target.includes(key as steps.StepNumbers<value>)\n );\n },\n });\n\n return match(enabledFor);\n }\n\n return false;\n }\n\n /**\n * Creates a form component with a default id.\n * @param id The default id for the form.\n * @returns A form component with a default {@linkcode id}.\n */\n export function createDefaultForm(id: string) {\n return (props: Omit<ComponentPropsWithRef<'form'>, 'id'>) => (\n <form id={id} {...props} />\n );\n }\n}\n"],"mappings":";;;;;;CAgBS,MAAM,qEAAqB;CAyP3B,SAAS,sBAGd,MAAa,gBAAqD;AAClE,UAIE,WACG;GACH,MAAM,WAAW;IACf,OAAO;IACP,iBAAiB;IACjB,OAAO;IACR;AAED,OAAI,CAAC,OACH,QAAO;GAGT,MAAM,EACJ,QAAQ,SAAS,OACjB,kBAAkB,SAAS,iBAC3B,QACA,OACE;GACJ,MAAMA,mEAAuC,0BAA0B;AAEvE,OAAI,GACF,WAAU,OAAO,OAAO,UAAU,0BAA0B;AAG9D,OAAI,MACF,WAAU,OAAO,UAAU,UAAU,6BAA6B;AAIpE,OAAI,iBAAiB;IACnB,MAAM,sBAAsB,MAAM,KAAK,eAAe;AAEtD,cACEC,sDAAoB,QAAQ,iBAAiB,oBAAoB,EACjEA,sDAAoB,sBAClB,qBACA,aACD,CACF;;AAGH,aAAU,OAAO,WAAW,YAAY,gCAAgC;AAExE,UAAO;IACL;IACA;KACC,QAAQ,OAAO,KAAK;IACtB;;;;CAcE,SAAS,gBAId,QAAgB,YAAwB;AACxC,MAAI,MAAM,QAAQ,OAAO,CAiBvB,QAhBcA,sDAAoB,MAAM;GACtC,MAAM,EACJ,QACD;GACD,eAAe;GACf,WAAW;GACX,QAAQ,EAAE,aAAa,WAAW;AAChC,WAAO,YAAY,MAAM,QAAQ,KAAK,OAAO,SAAS,IAAI,CAAC;;GAE7D,SAAS,EAAE,aAAa,WAAW;AACjC,WAAO,OAAO,KAAK,YAAY,CAAC,MAAM,QACpC,KAAK,OAAO,SAAS,IAAgC,CACtD;;GAEJ,CAAC,CAEW,WAAW;AAG1B,SAAO;;;CAQF,SAAS,kBAAkB,IAAY;AAC5C,UAAQ,UACN,2CAAC;GAAS;GAAI,GAAI;IAAS"}
|
package/dist/form-config.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Expand, HelperFnChosenSteps
|
|
3
|
-
import {
|
|
1
|
+
import { CreatedMultiStepFormComponent } from "./utils.cjs";
|
|
2
|
+
import { Expand, HelperFnChosenSteps } from "@jfdevelops/multi-step-form-core";
|
|
3
|
+
import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
|
|
4
|
+
import { ComponentPropsWithRef, ComponentType, FunctionComponent } from "react";
|
|
4
5
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
6
|
|
|
6
7
|
//#region src/form-config.d.ts
|
|
@@ -8,11 +9,43 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
8
9
|
export const DEFAULT_FORM_ALIAS = "Form";
|
|
9
10
|
export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;
|
|
10
11
|
export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;
|
|
11
|
-
export type formEnabledFor<
|
|
12
|
-
type strippedResolvedSteps<
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export type formEnabledFor<value extends steps$1.instantiateSteps> = HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>;
|
|
13
|
+
type strippedResolvedSteps<value extends steps$1.instantiateSteps> = { [_ in keyof value]: Expand<Omit<value[_], 'createComponent' | 'createHelperFn'>> };
|
|
14
|
+
export type inferFormAlias<def> = def extends {
|
|
15
|
+
alias: infer alias extends string;
|
|
16
|
+
} ? alias : defaultFormAlias;
|
|
17
|
+
export type inferFormProps<def> = def extends {
|
|
18
|
+
render: infer render;
|
|
19
|
+
} ? render extends ((data: any) => ComponentType<infer props>) ? props : never : never;
|
|
20
|
+
export namespace EnabledForSteps {
|
|
21
|
+
type get<def> = def extends {
|
|
22
|
+
enabledForSteps: infer enabledForSteps;
|
|
23
|
+
} ? enabledForSteps : def extends {
|
|
24
|
+
form: infer form;
|
|
25
|
+
} ? form extends {
|
|
26
|
+
enabledForSteps: infer enabledForSteps;
|
|
27
|
+
} ? enabledForSteps : never : never;
|
|
28
|
+
type resolveType<def extends StepSchema.Config, steps$1 extends steps$1.instantiateSteps<def>, value = instantiateFormConfig<def>> = get<value> extends defaultEnabledFor ? 'all' : get<value> extends HelperFnChosenSteps.tupleNotation<steps$1.StepNumbers<steps$1>> ? 'tuple' : get<value> extends HelperFnChosenSteps.objectNotation<steps$1.StepNumbers<steps$1>> ? 'object' : never;
|
|
29
|
+
}
|
|
30
|
+
export type inferFormEnabledForSteps<def> = def extends {
|
|
31
|
+
enabledForSteps: infer enabledForSteps;
|
|
32
|
+
} ? enabledForSteps : defaultEnabledFor;
|
|
33
|
+
export type inferComponent<def> = def extends {
|
|
34
|
+
render: infer render;
|
|
35
|
+
} ? render extends ((data: any) => infer r) ? r extends ComponentType<infer _> ? r : never : never : never;
|
|
36
|
+
export type inferredFormComponent<def> = { [key in inferFormAlias<def>]: inferComponent<def> };
|
|
37
|
+
export type instantiateFormConfig<def> = [def] extends [object] ? def extends {
|
|
38
|
+
form: infer form;
|
|
39
|
+
} ? { -readonly [key in keyof FormConfig.withoutRender<form>]: Expand<{
|
|
40
|
+
alias: inferFormAlias<FormConfig.withoutRender<form>>;
|
|
41
|
+
enabledForSteps: inferFormEnabledForSteps<FormConfig.withoutRender<form>>;
|
|
42
|
+
} & inferredFormComponent<form>> }[keyof FormConfig.withoutRender<form>] : {} : {};
|
|
43
|
+
export type getEnabledForSteps<def> = instantiateFormConfig<def> extends {
|
|
44
|
+
enabledForSteps: infer enabledForSteps;
|
|
45
|
+
} ? enabledForSteps : def;
|
|
46
|
+
export type AvailableStepForForm<value extends steps$1.instantiateSteps, enabledFor extends formEnabledFor<value>> = enabledFor extends defaultEnabledFor ? strippedResolvedSteps<value> : enabledFor extends HelperFnChosenSteps.tupleNotation<steps$1.StepNumbers<value>> ? enabledFor[number] extends keyof value ? Pick<strippedResolvedSteps<value>, enabledFor[number]> : never : keyof enabledFor extends keyof value ? Expand<Pick<strippedResolvedSteps<value>, Extract<keyof value, keyof enabledFor>>> : never;
|
|
47
|
+
export type formCtx<alias extends string, props> = { [_ in alias]: CreatedMultiStepFormComponent<props> };
|
|
48
|
+
export type renderFnData<value extends steps$1.instantiateSteps, enabledFor extends formEnabledFor<value>> = {
|
|
16
49
|
/**
|
|
17
50
|
* The id for the form, either a custom one or the default one.
|
|
18
51
|
*/
|
|
@@ -20,12 +53,15 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
20
53
|
/**
|
|
21
54
|
* The chosen steps that are available.
|
|
22
55
|
*/
|
|
23
|
-
steps: Expand<AvailableStepForForm<
|
|
56
|
+
steps: Expand<AvailableStepForForm<value, enabledFor>>;
|
|
24
57
|
};
|
|
58
|
+
export namespace FormConfig {
|
|
59
|
+
type withoutRender<def> = Omit<def, 'render'>;
|
|
60
|
+
}
|
|
25
61
|
/**
|
|
26
62
|
* The configuration options for the `form` option.
|
|
27
63
|
*/
|
|
28
|
-
export interface FormConfig<
|
|
64
|
+
export interface FormConfig<def extends StepSchema.Config = StepSchema.Config, value extends steps$1.instantiateSteps<def> = steps$1.instantiateSteps<def>> {
|
|
29
65
|
/**
|
|
30
66
|
* The `id` for the form component.
|
|
31
67
|
*
|
|
@@ -65,18 +101,18 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
65
101
|
* )
|
|
66
102
|
* ```
|
|
67
103
|
*/
|
|
68
|
-
alias?:
|
|
104
|
+
alias?: string;
|
|
69
105
|
/**
|
|
70
106
|
* If the form component should be accessible for each step when calling `createComponent`.
|
|
71
107
|
*
|
|
72
108
|
* If no value is given, the form will be accessible for all the steps.
|
|
73
109
|
*/
|
|
74
|
-
enabledForSteps?:
|
|
110
|
+
enabledForSteps?: HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>;
|
|
75
111
|
/**
|
|
76
112
|
*
|
|
77
113
|
* @param data The data that is available for creating the custom form.
|
|
78
114
|
* @param props Props that can be used for the custom form.
|
|
79
|
-
* @returns
|
|
115
|
+
* @returns A React component that is the custom form.
|
|
80
116
|
* @example
|
|
81
117
|
* ### With custom props
|
|
82
118
|
* ```tsx
|
|
@@ -134,11 +170,9 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
134
170
|
* })
|
|
135
171
|
* ```
|
|
136
172
|
*/
|
|
137
|
-
render: (data:
|
|
138
|
-
}
|
|
139
|
-
export interface Form<TResolvedStep extends AnyResolvedStep$1, TAlias extends string, TFormEnabledFor extends formEnabledFor<TResolvedStep>, TCustomFormProps extends object> {
|
|
140
|
-
form?: FormConfig<TResolvedStep, TAlias, TFormEnabledFor, TCustomFormProps>;
|
|
173
|
+
render: (data: value) => FunctionComponent<any>;
|
|
141
174
|
}
|
|
175
|
+
export function instantiateFormConfig<const def extends StepSchema.Config, value extends steps$1.instantiateSteps<def>>(data: value, availableSteps: readonly steps$1.StepNumbers<value>[]): <const form extends FormConfig<def, value>, inst = instantiateFormConfig<form>>(config: form | undefined) => inst;
|
|
142
176
|
/**
|
|
143
177
|
* Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form
|
|
144
178
|
* should be available.
|
|
@@ -146,7 +180,7 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
146
180
|
* @param enabledFor The steps that the form _is_ enabled for.
|
|
147
181
|
* @returns A boolean representing if the form should be available.
|
|
148
182
|
*/
|
|
149
|
-
export function isFormAvailable<
|
|
183
|
+
export function isFormAvailable<value extends steps$1.instantiateSteps, target extends HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>, enabledFor extends formEnabledFor<value>>(target: target, enabledFor: enabledFor): boolean;
|
|
150
184
|
/**
|
|
151
185
|
* Creates a form component with a default id.
|
|
152
186
|
* @param id The default id for the form.
|
package/dist/form-config.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Expand, HelperFnChosenSteps
|
|
3
|
-
import {
|
|
1
|
+
import { CreatedMultiStepFormComponent } from "./utils.mjs";
|
|
2
|
+
import { Expand, HelperFnChosenSteps } from "@jfdevelops/multi-step-form-core";
|
|
3
|
+
import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
|
|
4
|
+
import { ComponentPropsWithRef, ComponentType, FunctionComponent } from "react";
|
|
4
5
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
6
|
|
|
6
7
|
//#region src/form-config.d.ts
|
|
@@ -8,11 +9,43 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
8
9
|
export const DEFAULT_FORM_ALIAS = "Form";
|
|
9
10
|
export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;
|
|
10
11
|
export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;
|
|
11
|
-
export type formEnabledFor<
|
|
12
|
-
type strippedResolvedSteps<
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export type formEnabledFor<value extends steps$1.instantiateSteps> = HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>;
|
|
13
|
+
type strippedResolvedSteps<value extends steps$1.instantiateSteps> = { [_ in keyof value]: Expand<Omit<value[_], 'createComponent' | 'createHelperFn'>> };
|
|
14
|
+
export type inferFormAlias<def> = def extends {
|
|
15
|
+
alias: infer alias extends string;
|
|
16
|
+
} ? alias : defaultFormAlias;
|
|
17
|
+
export type inferFormProps<def> = def extends {
|
|
18
|
+
render: infer render;
|
|
19
|
+
} ? render extends ((data: any) => ComponentType<infer props>) ? props : never : never;
|
|
20
|
+
export namespace EnabledForSteps {
|
|
21
|
+
type get<def> = def extends {
|
|
22
|
+
enabledForSteps: infer enabledForSteps;
|
|
23
|
+
} ? enabledForSteps : def extends {
|
|
24
|
+
form: infer form;
|
|
25
|
+
} ? form extends {
|
|
26
|
+
enabledForSteps: infer enabledForSteps;
|
|
27
|
+
} ? enabledForSteps : never : never;
|
|
28
|
+
type resolveType<def extends StepSchema.Config, steps$1 extends steps$1.instantiateSteps<def>, value = instantiateFormConfig<def>> = get<value> extends defaultEnabledFor ? 'all' : get<value> extends HelperFnChosenSteps.tupleNotation<steps$1.StepNumbers<steps$1>> ? 'tuple' : get<value> extends HelperFnChosenSteps.objectNotation<steps$1.StepNumbers<steps$1>> ? 'object' : never;
|
|
29
|
+
}
|
|
30
|
+
export type inferFormEnabledForSteps<def> = def extends {
|
|
31
|
+
enabledForSteps: infer enabledForSteps;
|
|
32
|
+
} ? enabledForSteps : defaultEnabledFor;
|
|
33
|
+
export type inferComponent<def> = def extends {
|
|
34
|
+
render: infer render;
|
|
35
|
+
} ? render extends ((data: any) => infer r) ? r extends ComponentType<infer _> ? r : never : never : never;
|
|
36
|
+
export type inferredFormComponent<def> = { [key in inferFormAlias<def>]: inferComponent<def> };
|
|
37
|
+
export type instantiateFormConfig<def> = [def] extends [object] ? def extends {
|
|
38
|
+
form: infer form;
|
|
39
|
+
} ? { -readonly [key in keyof FormConfig.withoutRender<form>]: Expand<{
|
|
40
|
+
alias: inferFormAlias<FormConfig.withoutRender<form>>;
|
|
41
|
+
enabledForSteps: inferFormEnabledForSteps<FormConfig.withoutRender<form>>;
|
|
42
|
+
} & inferredFormComponent<form>> }[keyof FormConfig.withoutRender<form>] : {} : {};
|
|
43
|
+
export type getEnabledForSteps<def> = instantiateFormConfig<def> extends {
|
|
44
|
+
enabledForSteps: infer enabledForSteps;
|
|
45
|
+
} ? enabledForSteps : def;
|
|
46
|
+
export type AvailableStepForForm<value extends steps$1.instantiateSteps, enabledFor extends formEnabledFor<value>> = enabledFor extends defaultEnabledFor ? strippedResolvedSteps<value> : enabledFor extends HelperFnChosenSteps.tupleNotation<steps$1.StepNumbers<value>> ? enabledFor[number] extends keyof value ? Pick<strippedResolvedSteps<value>, enabledFor[number]> : never : keyof enabledFor extends keyof value ? Expand<Pick<strippedResolvedSteps<value>, Extract<keyof value, keyof enabledFor>>> : never;
|
|
47
|
+
export type formCtx<alias extends string, props> = { [_ in alias]: CreatedMultiStepFormComponent<props> };
|
|
48
|
+
export type renderFnData<value extends steps$1.instantiateSteps, enabledFor extends formEnabledFor<value>> = {
|
|
16
49
|
/**
|
|
17
50
|
* The id for the form, either a custom one or the default one.
|
|
18
51
|
*/
|
|
@@ -20,12 +53,15 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
20
53
|
/**
|
|
21
54
|
* The chosen steps that are available.
|
|
22
55
|
*/
|
|
23
|
-
steps: Expand<AvailableStepForForm<
|
|
56
|
+
steps: Expand<AvailableStepForForm<value, enabledFor>>;
|
|
24
57
|
};
|
|
58
|
+
export namespace FormConfig {
|
|
59
|
+
type withoutRender<def> = Omit<def, 'render'>;
|
|
60
|
+
}
|
|
25
61
|
/**
|
|
26
62
|
* The configuration options for the `form` option.
|
|
27
63
|
*/
|
|
28
|
-
export interface FormConfig<
|
|
64
|
+
export interface FormConfig<def extends StepSchema.Config = StepSchema.Config, value extends steps$1.instantiateSteps<def> = steps$1.instantiateSteps<def>> {
|
|
29
65
|
/**
|
|
30
66
|
* The `id` for the form component.
|
|
31
67
|
*
|
|
@@ -65,18 +101,18 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
65
101
|
* )
|
|
66
102
|
* ```
|
|
67
103
|
*/
|
|
68
|
-
alias?:
|
|
104
|
+
alias?: string;
|
|
69
105
|
/**
|
|
70
106
|
* If the form component should be accessible for each step when calling `createComponent`.
|
|
71
107
|
*
|
|
72
108
|
* If no value is given, the form will be accessible for all the steps.
|
|
73
109
|
*/
|
|
74
|
-
enabledForSteps?:
|
|
110
|
+
enabledForSteps?: HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>;
|
|
75
111
|
/**
|
|
76
112
|
*
|
|
77
113
|
* @param data The data that is available for creating the custom form.
|
|
78
114
|
* @param props Props that can be used for the custom form.
|
|
79
|
-
* @returns
|
|
115
|
+
* @returns A React component that is the custom form.
|
|
80
116
|
* @example
|
|
81
117
|
* ### With custom props
|
|
82
118
|
* ```tsx
|
|
@@ -134,11 +170,9 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
134
170
|
* })
|
|
135
171
|
* ```
|
|
136
172
|
*/
|
|
137
|
-
render: (data:
|
|
138
|
-
}
|
|
139
|
-
export interface Form<TResolvedStep extends AnyResolvedStep$1, TAlias extends string, TFormEnabledFor extends formEnabledFor<TResolvedStep>, TCustomFormProps extends object> {
|
|
140
|
-
form?: FormConfig<TResolvedStep, TAlias, TFormEnabledFor, TCustomFormProps>;
|
|
173
|
+
render: (data: value) => FunctionComponent<any>;
|
|
141
174
|
}
|
|
175
|
+
export function instantiateFormConfig<const def extends StepSchema.Config, value extends steps$1.instantiateSteps<def>>(data: value, availableSteps: readonly steps$1.StepNumbers<value>[]): <const form extends FormConfig<def, value>, inst = instantiateFormConfig<form>>(config: form | undefined) => inst;
|
|
142
176
|
/**
|
|
143
177
|
* Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form
|
|
144
178
|
* should be available.
|
|
@@ -146,7 +180,7 @@ declare namespace MultiStepFormSchemaConfig {
|
|
|
146
180
|
* @param enabledFor The steps that the form _is_ enabled for.
|
|
147
181
|
* @returns A boolean representing if the form should be available.
|
|
148
182
|
*/
|
|
149
|
-
export function isFormAvailable<
|
|
183
|
+
export function isFormAvailable<value extends steps$1.instantiateSteps, target extends HelperFnChosenSteps.main<value, steps$1.StepNumbers<value>>, enabledFor extends formEnabledFor<value>>(target: target, enabledFor: enabledFor): boolean;
|
|
150
184
|
/**
|
|
151
185
|
* Creates a form component with a default id.
|
|
152
186
|
* @param id The default id for the form.
|
package/dist/form-config.mjs
CHANGED
|
@@ -1,15 +1,47 @@
|
|
|
1
|
+
import { HelperFnChosenSteps, createInvariant } from "@jfdevelops/multi-step-form-core";
|
|
1
2
|
import { jsx } from "react/jsx-runtime";
|
|
2
3
|
|
|
3
4
|
//#region src/form-config.tsx
|
|
4
5
|
let MultiStepFormSchemaConfig;
|
|
5
6
|
(function(_MultiStepFormSchemaConfig) {
|
|
6
|
-
_MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS = "Form";
|
|
7
|
+
const DEFAULT_FORM_ALIAS = _MultiStepFormSchemaConfig.DEFAULT_FORM_ALIAS = "Form";
|
|
8
|
+
function instantiateFormConfig(data, availableSteps) {
|
|
9
|
+
return (config) => {
|
|
10
|
+
const defaults = {
|
|
11
|
+
alias: DEFAULT_FORM_ALIAS,
|
|
12
|
+
enabledForSteps: "all",
|
|
13
|
+
props: void 0
|
|
14
|
+
};
|
|
15
|
+
if (!config) return defaults;
|
|
16
|
+
const { alias = defaults.alias, enabledForSteps = defaults.enabledForSteps, render, id } = config;
|
|
17
|
+
const invariant$1 = createInvariant("[instantiateFormConfig]");
|
|
18
|
+
if (id) invariant$1(typeof id === "string", "The id must be a string");
|
|
19
|
+
if (alias) invariant$1(typeof alias === "string", "The alias must be a string");
|
|
20
|
+
if (enabledForSteps) {
|
|
21
|
+
const availableStepsArray = Array.from(availableSteps);
|
|
22
|
+
invariant$1(HelperFnChosenSteps.isValid(enabledForSteps, availableStepsArray), HelperFnChosenSteps.createCatchAllMessage(availableStepsArray, "enabledFor"));
|
|
23
|
+
}
|
|
24
|
+
invariant$1(typeof render === "function", "The render must be a function");
|
|
25
|
+
return {
|
|
26
|
+
alias,
|
|
27
|
+
enabledForSteps,
|
|
28
|
+
[alias]: render(data)
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
_MultiStepFormSchemaConfig.instantiateFormConfig = instantiateFormConfig;
|
|
7
33
|
function isFormAvailable(target, enabledFor) {
|
|
8
|
-
if (Array.isArray(target)) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
34
|
+
if (Array.isArray(target)) return HelperFnChosenSteps.match({
|
|
35
|
+
meta: { target },
|
|
36
|
+
default: () => false,
|
|
37
|
+
all: () => true,
|
|
38
|
+
tuple: ({ chosenSteps, meta }) => {
|
|
39
|
+
return chosenSteps.some((key) => meta.target.includes(key));
|
|
40
|
+
},
|
|
41
|
+
object: ({ chosenSteps, meta }) => {
|
|
42
|
+
return Object.keys(chosenSteps).some((key) => meta.target.includes(key));
|
|
43
|
+
}
|
|
44
|
+
})(enabledFor);
|
|
13
45
|
return false;
|
|
14
46
|
}
|
|
15
47
|
_MultiStepFormSchemaConfig.isFormAvailable = isFormAvailable;
|
package/dist/form-config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-config.mjs","names":[],"sources":["../src/form-config.tsx"],"sourcesContent":["import type {\n Expand,\n HelperFnChosenSteps,\n StepNumbers,\n ValidStepKey,\n} from '@jfdevelops/multi-step-form-core';\nimport type { ComponentPropsWithRef, JSX } from 'react';\nimport type {\n AnyResolvedStep,\n CreatedMultiStepFormComponent,\n} from './step-schema';\n\nexport namespace MultiStepFormSchemaConfig {\n export const DEFAULT_FORM_ALIAS = 'Form';\n export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;\n export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;\n export type formEnabledFor<TResolvedStep extends AnyResolvedStep> =\n HelperFnChosenSteps<TResolvedStep, StepNumbers<TResolvedStep>>;\n type strippedResolvedSteps<T extends AnyResolvedStep> = {\n [_ in keyof T]: Expand<Omit<T[_], 'createComponent' | 'createHelperFn'>>;\n };\n export type AvailableStepForForm<\n TResolvedStep extends AnyResolvedStep,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n > = TEnabledFor extends defaultEnabledFor\n ? strippedResolvedSteps<TResolvedStep>\n : TEnabledFor extends [\n ValidStepKey<StepNumbers<TResolvedStep>>,\n ...ValidStepKey<StepNumbers<TResolvedStep>>[]\n ]\n ? TEnabledFor[number] extends keyof TResolvedStep\n ? Pick<strippedResolvedSteps<TResolvedStep>, TEnabledFor[number]>\n : never\n : keyof TEnabledFor extends keyof TResolvedStep\n ? Expand<\n Pick<\n strippedResolvedSteps<TResolvedStep>,\n Extract<keyof TResolvedStep, keyof TEnabledFor>\n >\n >\n : never;\n export type formCtx<TAlias extends string, TProps> = {\n [_ in TAlias]: CreatedMultiStepFormComponent<TProps>;\n };\n export type renderFnData<\n TResolvedStep extends AnyResolvedStep,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n > = {\n /**\n * The id for the form, either a custom one or the default one.\n */\n id: string;\n /**\n * The chosen steps that are available.\n */\n steps: Expand<AvailableStepForForm<TResolvedStep, TEnabledFor>>;\n };\n\n /**\n * The configuration options for the `form` option.\n */\n export interface FormConfig<\n TResolvedStep extends AnyResolvedStep,\n TAlias extends string,\n TFormEnabledFor extends formEnabledFor<TResolvedStep>,\n TCustomFormProps extends object\n > {\n /**\n * The `id` for the form component.\n *\n * If there is no value provided, the default id will the **current step key**.\n *\n * @default `${currentStep}`\n */\n id?: string;\n /**\n * The \"name\" of the form component.\n * @default 'Form'\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 * form: {\n * alias: 'MyCustomForm',\n * render() {\n * // return custom form component here\n * }\n * }\n * }\n * })\n *\n * const Step1 = schema.stepSchema.step1.createComponent(\n * ({ ctx, MyCustomForm }, props: { children: ReactNode }) =>\n * // Notice how the form is available with its alias\n * <MyCustomFormName>{children}</MyCustomFormName>\n * )\n * ```\n */\n alias?: TAlias;\n /**\n * If the form component should be accessible for each step when calling `createComponent`.\n *\n * If no value is given, the form will be accessible for all the steps.\n */\n enabledForSteps?: TFormEnabledFor;\n /**\n *\n * @param data The data that is available for creating the custom form.\n * @param props Props that can be used for the custom form.\n * @returns An {@see JSX.Element} that is the custom form.\n * @example\n * ### With custom props\n * ```tsx\n * type CustomProps = {\n * title: string;\n * description?: string;\n * children: ReactNode;\n * };\n *\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props: CustomProps) {\n * return (\n * <div>\n * <h1>{props.title}</h1>\n * <p>{props.description}</p>\n * <form>{props.children}</form>\n * </div>\n * );\n * }\n * }\n * }\n * })\n * ```\n * ### Without custom props\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props) {\n * // The default type for `props` will be `ComponentPropsWithRef<'form'>`\n * // return custom form component here\n * }\n * }\n * }\n * })\n * ```\n */\n render: (\n data: renderFnData<TResolvedStep, TFormEnabledFor>,\n props: TCustomFormProps\n ) => JSX.Element;\n }\n\n export interface Form<\n TResolvedStep extends AnyResolvedStep,\n TAlias extends string,\n TFormEnabledFor extends formEnabledFor<TResolvedStep>,\n TCustomFormProps extends object\n > {\n form?: FormConfig<TResolvedStep, TAlias, TFormEnabledFor, TCustomFormProps>;\n }\n\n /**\n * Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form\n * should be available.\n * @param target The target steps the form _should_ be available for.\n * @param enabledFor The steps that the form _is_ enabled for.\n * @returns A boolean representing if the form should be available.\n */\n // Note: the implementation is specific to `MultiStepFormStepSchema.createComponentForStep`\n // because the `target` will always be an `Array` in `MultiStepFormStepSchema.createComponentForStep`.\n // TODO add validation to keys\n export function isFormAvailable<\n TResolvedStep extends AnyResolvedStep,\n TTarget extends HelperFnChosenSteps<\n TResolvedStep,\n StepNumbers<TResolvedStep>\n >,\n TEnabledFor extends formEnabledFor<TResolvedStep>\n >(target: TTarget, enabledFor: TEnabledFor) {\n if (Array.isArray(target)) {\n if (enabledFor === 'all') {\n return true;\n }\n\n if (typeof enabledFor === 'object' && !Array.isArray(enabledFor)) {\n return Object.keys(enabledFor).some((key) =>\n target.includes(key as `step${StepNumbers<TResolvedStep>}`)\n );\n }\n\n if (Array.isArray(enabledFor)) {\n return enabledFor.some((key) => target.includes(key));\n }\n }\n\n return false;\n }\n\n /**\n * Creates a form component with a default id.\n * @param id The default id for the form.\n * @returns A form component with a default {@linkcode id}.\n */\n export function createDefaultForm(id: string) {\n return (props: Omit<ComponentPropsWithRef<'form'>, 'id'>) => (\n <form id={id} {...props} />\n );\n }\n}\n"],"mappings":";;;;;iDAaoC;CA2L3B,SAAS,gBAOd,QAAiB,YAAyB;AAC1C,MAAI,MAAM,QAAQ,OAAO,EAAE;AACzB,OAAI,eAAe,MACjB,QAAO;AAGT,OAAI,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,WAAW,CAC9D,QAAO,OAAO,KAAK,WAAW,CAAC,MAAM,QACnC,OAAO,SAAS,IAA2C,CAC5D;AAGH,OAAI,MAAM,QAAQ,WAAW,CAC3B,QAAO,WAAW,MAAM,QAAQ,OAAO,SAAS,IAAI,CAAC;;AAIzD,SAAO;;;CAQF,SAAS,kBAAkB,IAAY;AAC5C,UAAQ,UACN,oBAAC;GAAS;GAAI,GAAI;IAAS"}
|
|
1
|
+
{"version":3,"file":"form-config.mjs","names":["invariant: Invariant"],"sources":["../src/form-config.tsx"],"sourcesContent":["import {\n createInvariant,\n Expand,\n HelperFnChosenSteps,\n steps,\n type Invariant,\n} from '@jfdevelops/multi-step-form-core';\nimport type { StepSchema } from '@jfdevelops/multi-step-form-core/_internals';\nimport {\n type ComponentPropsWithRef,\n type ComponentType,\n type FunctionComponent,\n} from 'react';\nimport type { CreatedMultiStepFormComponent } from './utils';\n\nexport namespace MultiStepFormSchemaConfig {\n export const DEFAULT_FORM_ALIAS = 'Form';\n export type defaultEnabledFor = HelperFnChosenSteps.defaultStringOption;\n export type defaultFormAlias = typeof DEFAULT_FORM_ALIAS;\n export type formEnabledFor<value extends steps.instantiateSteps> =\n HelperFnChosenSteps.main<value, steps.StepNumbers<value>>;\n type strippedResolvedSteps<value extends steps.instantiateSteps> = {\n [_ in keyof value]: Expand<\n Omit<value[_], 'createComponent' | 'createHelperFn'>\n >;\n };\n export type inferFormAlias<def> = def extends {\n alias: infer alias extends string;\n }\n ? alias\n : defaultFormAlias;\n export type inferFormProps<def> = def extends {\n render: infer render;\n }\n ? render extends (data: any) => ComponentType<infer props>\n ? props\n : never\n : never;\n export namespace EnabledForSteps {\n export type get<def> = def extends {\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps // Case: `enabledForSteps` isn't provided (default behavior)\n : def extends { form: infer form }\n ? form extends { enabledForSteps: infer enabledForSteps }\n ? enabledForSteps // Case: `enabledForSteps` is provided in the form config\n : never\n : never;\n export type resolveType<\n def extends StepSchema.Config,\n steps extends steps.instantiateSteps<def>,\n value = instantiateFormConfig<def>,\n > =\n get<value> extends defaultEnabledFor\n ? 'all'\n : get<value> extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<steps>\n >\n ? 'tuple'\n : get<value> extends HelperFnChosenSteps.objectNotation<\n steps.StepNumbers<steps>\n >\n ? 'object'\n : never;\n }\n\n export type inferFormEnabledForSteps<def> = def extends {\n // TODO decide if `enabledForSteps` validation is needed\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps\n : defaultEnabledFor;\n export type inferComponent<def> = def extends { render: infer render }\n ? render extends (data: any) => infer r\n ? r extends ComponentType<infer _>\n ? r\n : never\n : never\n : never;\n export type inferredFormComponent<def> = {\n [key in inferFormAlias<def>]: inferComponent<def>;\n };\n\n export type instantiateFormConfig<def> = [def] extends [object]\n ? def extends { form: infer form }\n ? {\n -readonly [key in keyof FormConfig.withoutRender<form>]: Expand<\n {\n alias: inferFormAlias<FormConfig.withoutRender<form>>;\n enabledForSteps: inferFormEnabledForSteps<\n FormConfig.withoutRender<form>\n >;\n } & inferredFormComponent<form>\n >;\n }[keyof FormConfig.withoutRender<form>]\n : {}\n : {};\n export type getEnabledForSteps<def> =\n instantiateFormConfig<def> extends {\n enabledForSteps: infer enabledForSteps;\n }\n ? enabledForSteps\n : def;\n export type AvailableStepForForm<\n value extends steps.instantiateSteps,\n enabledFor extends formEnabledFor<value>,\n > = enabledFor extends defaultEnabledFor\n ? strippedResolvedSteps<value>\n : enabledFor extends HelperFnChosenSteps.tupleNotation<\n steps.StepNumbers<value>\n >\n ? enabledFor[number] extends keyof value\n ? Pick<strippedResolvedSteps<value>, enabledFor[number]>\n : never\n : keyof enabledFor extends keyof value\n ? Expand<\n Pick<\n strippedResolvedSteps<value>,\n Extract<keyof value, keyof enabledFor>\n >\n >\n : never;\n export type formCtx<alias extends string, props> = {\n [_ in alias]: CreatedMultiStepFormComponent<props>;\n };\n export type renderFnData<\n value extends steps.instantiateSteps,\n enabledFor extends formEnabledFor<value>,\n > = {\n /**\n * The id for the form, either a custom one or the default one.\n */\n id: string;\n /**\n * The chosen steps that are available.\n */\n steps: Expand<AvailableStepForForm<value, enabledFor>>;\n };\n\n export namespace FormConfig {\n export type withoutRender<def> = Omit<def, 'render'>;\n }\n\n /**\n * The configuration options for the `form` option.\n */\n export interface FormConfig<\n def extends StepSchema.Config = StepSchema.Config,\n value extends steps.instantiateSteps<def> = steps.instantiateSteps<def>,\n > {\n /**\n * The `id` for the form component.\n *\n * If there is no value provided, the default id will the **current step key**.\n *\n * @default `${currentStep}`\n */\n id?: string;\n /**\n * The \"name\" of the form component.\n * @default 'Form'\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 * form: {\n * alias: 'MyCustomForm',\n * render() {\n * // return custom form component here\n * }\n * }\n * }\n * })\n *\n * const Step1 = schema.stepSchema.step1.createComponent(\n * ({ ctx, MyCustomForm }, props: { children: ReactNode }) =>\n * // Notice how the form is available with its alias\n * <MyCustomFormName>{children}</MyCustomFormName>\n * )\n * ```\n */\n alias?: string;\n /**\n * If the form component should be accessible for each step when calling `createComponent`.\n *\n * If no value is given, the form will be accessible for all the steps.\n */\n enabledForSteps?: HelperFnChosenSteps.main<value, steps.StepNumbers<value>>;\n /**\n *\n * @param data The data that is available for creating the custom form.\n * @param props Props that can be used for the custom form.\n * @returns A React component that is the custom form.\n * @example\n * ### With custom props\n * ```tsx\n * type CustomProps = {\n * title: string;\n * description?: string;\n * children: ReactNode;\n * };\n *\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props: CustomProps) {\n * return (\n * <div>\n * <h1>{props.title}</h1>\n * <p>{props.description}</p>\n * <form>{props.children}</form>\n * </div>\n * );\n * }\n * }\n * }\n * })\n * ```\n * ### Without custom props\n * ```tsx\n * const schema = createMultiStepFormSchema({\n * steps: {\n * step1: {\n * title: 'Step 1',\n * fields: {\n * firstName: {\n * defaultValue: ''\n * }\n * }\n * },\n * form: {\n * alias: 'MyCustomForm',\n * render(data, props) {\n * // The default type for `props` will be `ComponentPropsWithRef<'form'>`\n * // return custom form component here\n * }\n * }\n * }\n * })\n * ```\n */\n // render: (\n // data: renderFnData<value, {[key in keyof def['steps']]: {}}>,\n // props: def['formProps']\n // ) => JSX.Element;\n render: (data: value) => FunctionComponent<any>;\n }\n\n export function instantiateFormConfig<\n const def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n >(data: value, availableSteps: readonly steps.StepNumbers<value>[]) {\n return <\n const form extends FormConfig<def, value>,\n inst = instantiateFormConfig<form>,\n >(\n config: form | undefined\n ) => {\n const defaults = {\n alias: DEFAULT_FORM_ALIAS,\n enabledForSteps: 'all',\n props: undefined,\n };\n\n if (!config) {\n return defaults as inst;\n }\n\n const {\n alias = defaults.alias,\n enabledForSteps = defaults.enabledForSteps,\n render,\n id,\n } = config;\n const invariant: Invariant = createInvariant('[instantiateFormConfig]');\n\n if (id) {\n invariant(typeof id === 'string', 'The id must be a string');\n }\n\n if (alias) {\n invariant(typeof alias === 'string', 'The alias must be a string');\n }\n\n // TODO validate enabledForSteps\n if (enabledForSteps) {\n const availableStepsArray = Array.from(availableSteps);\n\n invariant(\n HelperFnChosenSteps.isValid(enabledForSteps, availableStepsArray),\n HelperFnChosenSteps.createCatchAllMessage(\n availableStepsArray,\n 'enabledFor'\n )\n );\n }\n\n invariant(typeof render === 'function', 'The render must be a function');\n\n return {\n alias,\n enabledForSteps,\n [alias]: render(data),\n } as inst;\n };\n }\n\n /**\n * Compares {@linkcode enabledFor} to the {@linkcode target} to determine if the form\n * should be available.\n * @param target The target steps the form _should_ be available for.\n * @param enabledFor The steps that the form _is_ enabled for.\n * @returns A boolean representing if the form should be available.\n */\n // Note: the implementation is specific to `MultiStepFormStepSchema.createComponentForStep`\n // because the `target` will always be an `Array` in `MultiStepFormStepSchema.createComponentForStep`.\n // TODO add validation to keys\n export function isFormAvailable<\n value extends steps.instantiateSteps,\n target extends HelperFnChosenSteps.main<value, steps.StepNumbers<value>>,\n enabledFor extends formEnabledFor<value>,\n >(target: target, enabledFor: enabledFor) {\n if (Array.isArray(target)) {\n const match = HelperFnChosenSteps.match({\n meta: {\n target,\n },\n default: () => false,\n all: () => true,\n tuple: ({ chosenSteps, meta }) => {\n return chosenSteps.some((key) => meta.target.includes(key));\n },\n object: ({ chosenSteps, meta }) => {\n return Object.keys(chosenSteps).some((key) =>\n meta.target.includes(key as steps.StepNumbers<value>)\n );\n },\n });\n\n return match(enabledFor);\n }\n\n return false;\n }\n\n /**\n * Creates a form component with a default id.\n * @param id The default id for the form.\n * @returns A form component with a default {@linkcode id}.\n */\n export function createDefaultForm(id: string) {\n return (props: Omit<ComponentPropsWithRef<'form'>, 'id'>) => (\n <form id={id} {...props} />\n );\n }\n}\n"],"mappings":";;;;;;CAgBS,MAAM,qEAAqB;CAyP3B,SAAS,sBAGd,MAAa,gBAAqD;AAClE,UAIE,WACG;GACH,MAAM,WAAW;IACf,OAAO;IACP,iBAAiB;IACjB,OAAO;IACR;AAED,OAAI,CAAC,OACH,QAAO;GAGT,MAAM,EACJ,QAAQ,SAAS,OACjB,kBAAkB,SAAS,iBAC3B,QACA,OACE;GACJ,MAAMA,cAAuB,gBAAgB,0BAA0B;AAEvE,OAAI,GACF,aAAU,OAAO,OAAO,UAAU,0BAA0B;AAG9D,OAAI,MACF,aAAU,OAAO,UAAU,UAAU,6BAA6B;AAIpE,OAAI,iBAAiB;IACnB,MAAM,sBAAsB,MAAM,KAAK,eAAe;AAEtD,gBACE,oBAAoB,QAAQ,iBAAiB,oBAAoB,EACjE,oBAAoB,sBAClB,qBACA,aACD,CACF;;AAGH,eAAU,OAAO,WAAW,YAAY,gCAAgC;AAExE,UAAO;IACL;IACA;KACC,QAAQ,OAAO,KAAK;IACtB;;;;CAcE,SAAS,gBAId,QAAgB,YAAwB;AACxC,MAAI,MAAM,QAAQ,OAAO,CAiBvB,QAhBc,oBAAoB,MAAM;GACtC,MAAM,EACJ,QACD;GACD,eAAe;GACf,WAAW;GACX,QAAQ,EAAE,aAAa,WAAW;AAChC,WAAO,YAAY,MAAM,QAAQ,KAAK,OAAO,SAAS,IAAI,CAAC;;GAE7D,SAAS,EAAE,aAAa,WAAW;AACjC,WAAO,OAAO,KAAK,YAAY,CAAC,MAAM,QACpC,KAAK,OAAO,SAAS,IAAgC,CACtD;;GAEJ,CAAC,CAEW,WAAW;AAG1B,SAAO;;;CAQF,SAAS,kBAAkB,IAAY;AAC5C,UAAQ,UACN,oBAAC;GAAS;GAAI,GAAI;IAAS"}
|