@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
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
let use_sync_external_store_shim_with_selector = require("use-sync-external-store/shim/with-selector");
|
|
1
|
+
const require_use_selector = require('./use-selector.cjs');
|
|
3
2
|
|
|
4
3
|
//#region src/hooks/use-multi-step-form-data.ts
|
|
5
|
-
function
|
|
6
|
-
(
|
|
7
|
-
const { as, isValidStepNumber } = schema.stepSchema.steps;
|
|
8
|
-
const formattedStepNumbersList = new Intl.ListFormat("en", {
|
|
9
|
-
type: "disjunction",
|
|
10
|
-
style: "long"
|
|
11
|
-
}).format(as("array.string.untyped"));
|
|
12
|
-
(0, __jfdevelops_multi_step_form_core.invariant)(__jfdevelops_multi_step_form_core.VALIDATED_STEP_REGEX.test(targetStep), `The target step must match the following format: "step{number}". Available steps are ${formattedStepNumbersList}`);
|
|
13
|
-
const stepNumber = Number.parseInt(targetStep.replace("step", ""));
|
|
14
|
-
(0, __jfdevelops_multi_step_form_core.invariant)(isValidStepNumber(stepNumber), `The step number "${stepNumber}" is not a valid step number. Valid step numbers include ${formattedStepNumbersList}`, TypeError);
|
|
15
|
-
return stepNumber;
|
|
4
|
+
function noopSubscribe() {
|
|
5
|
+
return () => {};
|
|
16
6
|
}
|
|
17
7
|
function createMultiStepFormDataHook(schema) {
|
|
18
8
|
function useMultiStepFormData$1(optionsOrSelector) {
|
|
19
|
-
return
|
|
20
|
-
if (typeof optionsOrSelector === "object") {
|
|
21
|
-
const stepNumber = throwIfInvalidStepNumber(snapshot, optionsOrSelector.targetStep);
|
|
22
|
-
return snapshot.stepSchema.get({ step: stepNumber }).data;
|
|
23
|
-
}
|
|
24
|
-
if (typeof optionsOrSelector === "function") return optionsOrSelector(snapshot);
|
|
25
|
-
return snapshot;
|
|
26
|
-
});
|
|
9
|
+
return require_use_selector.createUseSelector(optionsOrSelector ? () => optionsOrSelector : noopSubscribe, schema.subscribe);
|
|
27
10
|
}
|
|
28
11
|
return useMultiStepFormData$1;
|
|
29
12
|
}
|
|
@@ -36,6 +19,5 @@ function useMultiStepFormData(schema, optionsOrSelector) {
|
|
|
36
19
|
|
|
37
20
|
//#endregion
|
|
38
21
|
exports.createMultiStepFormDataHook = createMultiStepFormDataHook;
|
|
39
|
-
exports.throwIfInvalidStepNumber = throwIfInvalidStepNumber;
|
|
40
22
|
exports.useMultiStepFormData = useMultiStepFormData;
|
|
41
23
|
//# sourceMappingURL=use-multi-step-form-data.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-multi-step-form-data.cjs","names":["
|
|
1
|
+
{"version":3,"file":"use-multi-step-form-data.cjs","names":["useMultiStepFormData","createUseSelector"],"sources":["../../src/hooks/use-multi-step-form-data.ts"],"sourcesContent":["import type { MultiStepFormSchema } from '@/schema';\nimport { steps } from '@jfdevelops/multi-step-form-core';\nimport type { StepSchema } from '@jfdevelops/multi-step-form-core/_internals';\nimport { createUseSelector } from './use-selector';\n\nexport type UseMultiStepFormDataOptions<targetStep extends string> = {\n targetStep: targetStep;\n};\nexport type UseMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = {\n /**\n * Returns the entire {@linkcode MultiStepFormSchema instance}.\n */\n (): MultiStepFormSchema<def, value>;\n /**\n * Returns the data for the target step.\n * @param stepNumber The step number to return.\n * @throws {TypeError} If `options.stepNumber` is invalid.\n */\n <targetStep extends steps.StepNumbers<value>>(\n options: UseMultiStepFormDataOptions<targetStep>\n ): steps.getCurrent<value, targetStep>;\n /**\n * Returns the specified data from the {@linkcode MultiStepFormSchema} instance via the callback's return.\n */\n <data>(selector: (schema: MultiStepFormSchema<def, value>) => data): data;\n};\n\nfunction noopSubscribe() {\n return () => {};\n}\n\nexport function createMultiStepFormDataHook<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(schema: MultiStepFormSchema<def, value>): UseMultiStepFormData<def, value> {\n function useMultiStepFormData(\n optionsOrSelector?:\n | UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n | ((data: MultiStepFormSchema<def, value>) => unknown)\n ) {\n return createUseSelector(\n optionsOrSelector ? () => optionsOrSelector : noopSubscribe,\n schema.subscribe\n );\n }\n\n return useMultiStepFormData as any;\n}\n\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(schema: MultiStepFormSchema<def, value>): MultiStepFormSchema<def, value>;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(\n schema: MultiStepFormSchema<def, value>,\n options: UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n): steps.getCurrent<value, steps.StepNumbers<value>>;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n data,\n>(\n schema: MultiStepFormSchema<def, value>,\n selector: (schema: MultiStepFormSchema<def, value>) => data\n): data;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(\n schema: MultiStepFormSchema<def, value>,\n optionsOrSelector?:\n | UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n | ((data: MultiStepFormSchema<def, value>) => unknown)\n) {\n const hook = createMultiStepFormDataHook(schema);\n\n if (typeof optionsOrSelector === 'object') {\n return hook(optionsOrSelector);\n }\n\n if (typeof optionsOrSelector === 'function') {\n return hook(optionsOrSelector);\n }\n\n return hook();\n}\n\nexport { useMultiStepFormData };\n"],"mappings":";;;AA8BA,SAAS,gBAAgB;AACvB,cAAa;;AAGf,SAAgB,4BAGd,QAA2E;CAC3E,SAASA,uBACP,mBAGA;AACA,SAAOC,uCACL,0BAA0B,oBAAoB,eAC9C,OAAO,UACR;;AAGH,QAAOD;;AAsBT,SAAS,qBAIP,QACA,mBAGA;CACA,MAAM,OAAO,4BAA4B,OAAO;AAEhD,KAAI,OAAO,sBAAsB,SAC/B,QAAO,KAAK,kBAAkB;AAGhC,KAAI,OAAO,sBAAsB,WAC/B,QAAO,KAAK,kBAAkB;AAGhC,QAAO,MAAM"}
|
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MultiStepFormSchema as MultiStepFormSchema$1 } from "../schema.cjs";
|
|
2
|
+
import { steps } from "@jfdevelops/multi-step-form-core";
|
|
3
|
+
import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
|
|
2
4
|
|
|
3
5
|
//#region src/hooks/use-multi-step-form-data.d.ts
|
|
4
|
-
type UseMultiStepFormDataOptions<
|
|
5
|
-
targetStep:
|
|
6
|
+
type UseMultiStepFormDataOptions<targetStep extends string> = {
|
|
7
|
+
targetStep: targetStep;
|
|
6
8
|
};
|
|
7
|
-
type UseMultiStepFormData<
|
|
9
|
+
type UseMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>> = {
|
|
8
10
|
/**
|
|
9
11
|
* Returns the entire {@linkcode MultiStepFormSchema instance}.
|
|
10
12
|
*/
|
|
11
|
-
():
|
|
13
|
+
(): MultiStepFormSchema$1<def, value>;
|
|
12
14
|
/**
|
|
13
15
|
* Returns the data for the target step.
|
|
14
16
|
* @param stepNumber The step number to return.
|
|
15
17
|
* @throws {TypeError} If `options.stepNumber` is invalid.
|
|
16
18
|
*/
|
|
17
|
-
<targetStep extends
|
|
19
|
+
<targetStep extends steps.StepNumbers<value>>(options: UseMultiStepFormDataOptions<targetStep>): steps.getCurrent<value, targetStep>;
|
|
18
20
|
/**
|
|
19
21
|
* Returns the specified data from the {@linkcode MultiStepFormSchema} instance via the callback's return.
|
|
20
22
|
*/
|
|
21
|
-
<data>(selector: (schema:
|
|
23
|
+
<data>(selector: (schema: MultiStepFormSchema$1<def, value>) => data): data;
|
|
22
24
|
};
|
|
23
|
-
declare function useMultiStepFormData<
|
|
24
|
-
declare function useMultiStepFormData<
|
|
25
|
-
declare function useMultiStepFormData<
|
|
25
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>>(schema: MultiStepFormSchema$1<def, value>): MultiStepFormSchema$1<def, value>;
|
|
26
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>>(schema: MultiStepFormSchema$1<def, value>, options: UseMultiStepFormDataOptions<steps.StepNumbers<value>>): steps.getCurrent<value, steps.StepNumbers<value>>;
|
|
27
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>, data>(schema: MultiStepFormSchema$1<def, value>, selector: (schema: MultiStepFormSchema$1<def, value>) => data): data;
|
|
26
28
|
//#endregion
|
|
27
29
|
export { UseMultiStepFormData, useMultiStepFormData };
|
|
28
30
|
//# sourceMappingURL=use-multi-step-form-data.d.cts.map
|
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MultiStepFormSchema as MultiStepFormSchema$1 } from "../schema.mjs";
|
|
2
|
+
import { steps } from "@jfdevelops/multi-step-form-core";
|
|
3
|
+
import { StepSchema } from "@jfdevelops/multi-step-form-core/_internals";
|
|
2
4
|
|
|
3
5
|
//#region src/hooks/use-multi-step-form-data.d.ts
|
|
4
|
-
type UseMultiStepFormDataOptions<
|
|
5
|
-
targetStep:
|
|
6
|
+
type UseMultiStepFormDataOptions<targetStep extends string> = {
|
|
7
|
+
targetStep: targetStep;
|
|
6
8
|
};
|
|
7
|
-
type UseMultiStepFormData<
|
|
9
|
+
type UseMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>> = {
|
|
8
10
|
/**
|
|
9
11
|
* Returns the entire {@linkcode MultiStepFormSchema instance}.
|
|
10
12
|
*/
|
|
11
|
-
():
|
|
13
|
+
(): MultiStepFormSchema$1<def, value>;
|
|
12
14
|
/**
|
|
13
15
|
* Returns the data for the target step.
|
|
14
16
|
* @param stepNumber The step number to return.
|
|
15
17
|
* @throws {TypeError} If `options.stepNumber` is invalid.
|
|
16
18
|
*/
|
|
17
|
-
<targetStep extends
|
|
19
|
+
<targetStep extends steps.StepNumbers<value>>(options: UseMultiStepFormDataOptions<targetStep>): steps.getCurrent<value, targetStep>;
|
|
18
20
|
/**
|
|
19
21
|
* Returns the specified data from the {@linkcode MultiStepFormSchema} instance via the callback's return.
|
|
20
22
|
*/
|
|
21
|
-
<data>(selector: (schema:
|
|
23
|
+
<data>(selector: (schema: MultiStepFormSchema$1<def, value>) => data): data;
|
|
22
24
|
};
|
|
23
|
-
declare function useMultiStepFormData<
|
|
24
|
-
declare function useMultiStepFormData<
|
|
25
|
-
declare function useMultiStepFormData<
|
|
25
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>>(schema: MultiStepFormSchema$1<def, value>): MultiStepFormSchema$1<def, value>;
|
|
26
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>>(schema: MultiStepFormSchema$1<def, value>, options: UseMultiStepFormDataOptions<steps.StepNumbers<value>>): steps.getCurrent<value, steps.StepNumbers<value>>;
|
|
27
|
+
declare function useMultiStepFormData<def extends StepSchema.Config, value extends steps.instantiateSteps<def>, data>(schema: MultiStepFormSchema$1<def, value>, selector: (schema: MultiStepFormSchema$1<def, value>) => data): data;
|
|
26
28
|
//#endregion
|
|
27
29
|
export { UseMultiStepFormData, useMultiStepFormData };
|
|
28
30
|
//# sourceMappingURL=use-multi-step-form-data.d.mts.map
|
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector";
|
|
1
|
+
import { createUseSelector } from "./use-selector.mjs";
|
|
3
2
|
|
|
4
3
|
//#region src/hooks/use-multi-step-form-data.ts
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
const { as, isValidStepNumber } = schema.stepSchema.steps;
|
|
8
|
-
const formattedStepNumbersList = new Intl.ListFormat("en", {
|
|
9
|
-
type: "disjunction",
|
|
10
|
-
style: "long"
|
|
11
|
-
}).format(as("array.string.untyped"));
|
|
12
|
-
invariant(VALIDATED_STEP_REGEX.test(targetStep), `The target step must match the following format: "step{number}". Available steps are ${formattedStepNumbersList}`);
|
|
13
|
-
const stepNumber = Number.parseInt(targetStep.replace("step", ""));
|
|
14
|
-
invariant(isValidStepNumber(stepNumber), `The step number "${stepNumber}" is not a valid step number. Valid step numbers include ${formattedStepNumbersList}`, TypeError);
|
|
15
|
-
return stepNumber;
|
|
4
|
+
function noopSubscribe() {
|
|
5
|
+
return () => {};
|
|
16
6
|
}
|
|
17
7
|
function createMultiStepFormDataHook(schema) {
|
|
18
8
|
function useMultiStepFormData$1(optionsOrSelector) {
|
|
19
|
-
return
|
|
20
|
-
if (typeof optionsOrSelector === "object") {
|
|
21
|
-
const stepNumber = throwIfInvalidStepNumber(snapshot, optionsOrSelector.targetStep);
|
|
22
|
-
return snapshot.stepSchema.get({ step: stepNumber }).data;
|
|
23
|
-
}
|
|
24
|
-
if (typeof optionsOrSelector === "function") return optionsOrSelector(snapshot);
|
|
25
|
-
return snapshot;
|
|
26
|
-
});
|
|
9
|
+
return createUseSelector(optionsOrSelector ? () => optionsOrSelector : noopSubscribe, schema.subscribe);
|
|
27
10
|
}
|
|
28
11
|
return useMultiStepFormData$1;
|
|
29
12
|
}
|
|
@@ -35,5 +18,5 @@ function useMultiStepFormData(schema, optionsOrSelector) {
|
|
|
35
18
|
}
|
|
36
19
|
|
|
37
20
|
//#endregion
|
|
38
|
-
export { createMultiStepFormDataHook,
|
|
21
|
+
export { createMultiStepFormDataHook, useMultiStepFormData };
|
|
39
22
|
//# sourceMappingURL=use-multi-step-form-data.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-multi-step-form-data.mjs","names":["useMultiStepFormData"],"sources":["../../src/hooks/use-multi-step-form-data.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"use-multi-step-form-data.mjs","names":["useMultiStepFormData"],"sources":["../../src/hooks/use-multi-step-form-data.ts"],"sourcesContent":["import type { MultiStepFormSchema } from '@/schema';\nimport { steps } from '@jfdevelops/multi-step-form-core';\nimport type { StepSchema } from '@jfdevelops/multi-step-form-core/_internals';\nimport { createUseSelector } from './use-selector';\n\nexport type UseMultiStepFormDataOptions<targetStep extends string> = {\n targetStep: targetStep;\n};\nexport type UseMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n> = {\n /**\n * Returns the entire {@linkcode MultiStepFormSchema instance}.\n */\n (): MultiStepFormSchema<def, value>;\n /**\n * Returns the data for the target step.\n * @param stepNumber The step number to return.\n * @throws {TypeError} If `options.stepNumber` is invalid.\n */\n <targetStep extends steps.StepNumbers<value>>(\n options: UseMultiStepFormDataOptions<targetStep>\n ): steps.getCurrent<value, targetStep>;\n /**\n * Returns the specified data from the {@linkcode MultiStepFormSchema} instance via the callback's return.\n */\n <data>(selector: (schema: MultiStepFormSchema<def, value>) => data): data;\n};\n\nfunction noopSubscribe() {\n return () => {};\n}\n\nexport function createMultiStepFormDataHook<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(schema: MultiStepFormSchema<def, value>): UseMultiStepFormData<def, value> {\n function useMultiStepFormData(\n optionsOrSelector?:\n | UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n | ((data: MultiStepFormSchema<def, value>) => unknown)\n ) {\n return createUseSelector(\n optionsOrSelector ? () => optionsOrSelector : noopSubscribe,\n schema.subscribe\n );\n }\n\n return useMultiStepFormData as any;\n}\n\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(schema: MultiStepFormSchema<def, value>): MultiStepFormSchema<def, value>;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(\n schema: MultiStepFormSchema<def, value>,\n options: UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n): steps.getCurrent<value, steps.StepNumbers<value>>;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n data,\n>(\n schema: MultiStepFormSchema<def, value>,\n selector: (schema: MultiStepFormSchema<def, value>) => data\n): data;\nfunction useMultiStepFormData<\n def extends StepSchema.Config,\n value extends steps.instantiateSteps<def>,\n>(\n schema: MultiStepFormSchema<def, value>,\n optionsOrSelector?:\n | UseMultiStepFormDataOptions<steps.StepNumbers<value>>\n | ((data: MultiStepFormSchema<def, value>) => unknown)\n) {\n const hook = createMultiStepFormDataHook(schema);\n\n if (typeof optionsOrSelector === 'object') {\n return hook(optionsOrSelector);\n }\n\n if (typeof optionsOrSelector === 'function') {\n return hook(optionsOrSelector);\n }\n\n return hook();\n}\n\nexport { useMultiStepFormData };\n"],"mappings":";;;AA8BA,SAAS,gBAAgB;AACvB,cAAa;;AAGf,SAAgB,4BAGd,QAA2E;CAC3E,SAASA,uBACP,mBAGA;AACA,SAAO,kBACL,0BAA0B,oBAAoB,eAC9C,OAAO,UACR;;AAGH,QAAOA;;AAsBT,SAAS,qBAIP,QACA,mBAGA;CACA,MAAM,OAAO,4BAA4B,OAAO;AAEhD,KAAI,OAAO,sBAAsB,SAC/B,QAAO,KAAK,kBAAkB;AAGhC,KAAI,OAAO,sBAAsB,WAC/B,QAAO,KAAK,kBAAkB;AAGhC,QAAO,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-selector.cjs","names":["hasChanged: boolean"],"sources":["../../src/hooks/use-selector.ts"],"sourcesContent":["import type {\n AnyResolvedStep,\n CurrentStepHelperFnCtx,\n Expand,\n MultiStepFormLogger,\n MultiStepFormLoggerOptions,\n} from '@jfdevelops/multi-step-form-core';\nimport { useRef, useSyncExternalStore } from 'react';\n\n/**\n * Deep equality check that compares values regardless of property order.\n * Handles objects, arrays, primitives, and null/undefined.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or both are the same primitive value\n if (a === b) {\n return true;\n }\n\n // Handle null/undefined\n if (a == null || b == null) {\n return a === b;\n }\n\n // Type mismatch\n if (typeof a !== typeof b) {\n return false;\n }\n\n // Both are primitives (but not equal due to first check)\n if (typeof a !== 'object') {\n return false;\n }\n\n // Both are arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n return true;\n }\n\n // One is array, other is not\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n // Both are objects (not arrays)\n const keysA = Object.keys(a as Record<string, unknown>);\n const keysB = Object.keys(b as Record<string, unknown>);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n // Check if all keys in A exist in B with equal values\n for (const key of keysA) {\n if (!keysB.includes(key)) {\n return false;\n }\n if (\n !deepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key]\n )\n ) {\n return false;\n }\n }\n\n return true;\n}\n\ntype PrefixOptions = {\n /**\n * The action to perform on the prefix.\n *\n * @default 'prepend'\n */\n action?: 'prepend' | 'append';\n /**\n * The value to add to the prefix.\n */\n value: string | ((prefix: string) => string);\n /**\n * The delimiter to use between the original prefix and the added prefix.\n * @default '-'\n * @example\n * ```tsx\n * <Selector debug={{ prefix: { action: 'prepend', value: 'MySelector', delimiter: '|' } }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n */\n delimiter?: string;\n};\n\n/**\n * Debug options for customizing logging behavior in the Selector component.\n * All options are optional - you can provide any combination of these functions\n * to customize how debug information is logged.\n */\nexport type DebugOptions<TSelected> = {\n /**\n * The prefix to use for the logger.\n *\n * If a string or function is provided, it will replace the default prefix.\n * If you need to prepend or append to the default prefix, you can provide {@linkcode PrefixOptions}.\n * @default 'MultiStepFormSchema-Selector'\n *\n * @example\n * ```tsx\n * <Selector debug={{ prefix: 'MySelector' }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n *\n */\n prefix?: MultiStepFormLoggerOptions['prefix'] | PrefixOptions;\n /**\n * Called when the Selector component renders with the selected value.\n * This is called on every render of the Selector component, regardless of\n * whether the selected value has changed.\n *\n * @param selected - The current selected value from the selector function\n */\n onRender?: (selected: TSelected) => string;\n\n /**\n * Called when the Selector component renders its children.\n * This is only called when the Selector has a children render prop.\n */\n onChildrenRender?: () => string;\n\n /**\n * Called when the initial value is set for the first time.\n * This is called once when the selector first evaluates and caches its value.\n *\n * @param value - The initial selected value\n */\n onInitialValue?: (value: TSelected) => string;\n\n /**\n * Called when the selected value changes from one value to another.\n * This is called whenever the selector detects that the value has changed\n * (using Object.is() for primitives or deep comparison for objects/arrays).\n *\n * @param oldValue - The previous selected value\n * @param newValue - The new selected value\n */\n onValueChanged?: (oldValue: TSelected, newValue: TSelected) => string;\n\n /**\n * Called when the selected value is checked but hasn't changed.\n * This is called when the selector evaluates but determines that the value\n * is the same as the previously cached value.\n *\n * @param value - The current selected value (unchanged from previous check)\n */\n onValueUnchanged?: (value: TSelected) => string;\n};\n\nexport type UseSelector<TCurrentStep extends AnyResolvedStep> = ReturnType<\n typeof createUseSelector<TCurrentStep>\n>;\nexport type SelectorFn<TCurrentStep extends AnyResolvedStep, TSelected> = (\n ctx: Expand<CurrentStepHelperFnCtx<TCurrentStep>>\n) => TSelected;\n\nexport function createUseSelector<TCurrentStep extends AnyResolvedStep>(\n createCtx: () => Expand<CurrentStepHelperFnCtx<TCurrentStep>>,\n subscribe: (listener: () => void) => () => void\n) {\n return <selected>(\n selectorFn: SelectorFn<TCurrentStep, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ) => {\n const snapshotCacheRef = useRef<{ value: selected } | null>(null);\n const selectorRef = useRef(selectorFn);\n\n // Update the selector ref on every render to ensure we always use the latest selector\n selectorRef.current = selectorFn;\n\n const getSnapshot = () => {\n const currentCtx = createCtx();\n const newValue = selectorRef.current(currentCtx);\n\n // Cache the result to ensure stable reference\n if (snapshotCacheRef.current === null) {\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onInitialValue?.(newValue) ??\n `Initial value: ${JSON.stringify(newValue)}`\n );\n\n return newValue;\n }\n\n // Check if the value actually changed\n // For primitive values, use Object.is() for fast comparison\n // For complex values, use deep comparison\n const isPrimitive =\n newValue === null ||\n (typeof newValue !== 'object' && typeof newValue !== 'function');\n\n let hasChanged: boolean;\n\n if (isPrimitive) {\n // Use Object.is() for primitives (faster and more reliable)\n hasChanged = !Object.is(snapshotCacheRef.current.value, newValue);\n } else {\n // For objects/arrays, we need to do a deep comparison\n // First check reference equality (fast path)\n const oldValue = snapshotCacheRef.current.value;\n if (oldValue === newValue) {\n hasChanged = false;\n } else {\n // Deep comparison using a proper deep equality function\n // This correctly handles property order differences\n hasChanged = !deepEqual(oldValue, newValue);\n }\n }\n\n if (hasChanged) {\n const oldValue = snapshotCacheRef.current.value;\n\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onValueChanged?.(oldValue, newValue) ??\n `Value changed: ${JSON.stringify(oldValue)} -> ${JSON.stringify(\n newValue\n )}`\n );\n // Return the new value so useSyncExternalStore can detect the change via Object.is()\n return newValue;\n }\n\n // Return the cached value to maintain stable reference when value hasn't changed\n logger?.info(\n debugOptions?.onValueUnchanged?.(newValue) ??\n `Value unchanged: ${JSON.stringify(newValue)}`\n );\n\n return snapshotCacheRef.current.value;\n };\n\n return useSyncExternalStore(\n subscribe,\n () => getSnapshot(),\n () => getSnapshot()\n );\n };\n}\n"],"mappings":";;;;;;;AAaA,SAAS,UAAU,GAAY,GAAqB;AAElD,KAAI,MAAM,EACR,QAAO;AAIT,KAAI,KAAK,QAAQ,KAAK,KACpB,QAAO,MAAM;AAIf,KAAI,OAAO,MAAM,OAAO,EACtB,QAAO;AAIT,KAAI,OAAO,MAAM,SACf,QAAO;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,EAAE;AACxC,MAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,OAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CACxB,QAAO;AAGX,SAAO;;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CACtC,QAAO;CAIT,MAAM,QAAQ,OAAO,KAAK,EAA6B;CACvD,MAAM,QAAQ,OAAO,KAAK,EAA6B;AAEvD,KAAI,MAAM,WAAW,MAAM,OACzB,QAAO;AAIT,MAAK,MAAM,OAAO,OAAO;AACvB,MAAI,CAAC,MAAM,SAAS,IAAI,CACtB,QAAO;AAET,MACE,CAAC,UACE,EAA8B,MAC9B,EAA8B,KAChC,CAED,QAAO;;AAIX,QAAO;;AAmGT,SAAgB,kBACd,WACA,WACA;AACA,SACE,YACA,QACA,iBACG;EACH,MAAM,qCAAsD,KAAK;EACjE,MAAM,gCAAqB,WAAW;AAGtC,cAAY,UAAU;EAEtB,MAAM,oBAAoB;GACxB,MAAM,aAAa,WAAW;GAC9B,MAAM,WAAW,YAAY,QAAQ,WAAW;AAGhD,OAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,SAAS,IACtC,kBAAkB,KAAK,UAAU,SAAS,GAC7C;AAED,WAAO;;GAMT,MAAM,cACJ,aAAa,QACZ,OAAO,aAAa,YAAY,OAAO,aAAa;GAEvD,IAAIA;AAEJ,OAAI,YAEF,cAAa,CAAC,OAAO,GAAG,iBAAiB,QAAQ,OAAO,SAAS;QAC5D;IAGL,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,QAAI,aAAa,SACf,cAAa;QAIb,cAAa,CAAC,UAAU,UAAU,SAAS;;AAI/C,OAAI,YAAY;IACd,MAAM,WAAW,iBAAiB,QAAQ;AAE1C,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,UAAU,SAAS,IAChD,kBAAkB,KAAK,UAAU,SAAS,CAAC,MAAM,KAAK,UACpD,SACD,GACJ;AAED,WAAO;;AAIT,WAAQ,KACN,cAAc,mBAAmB,SAAS,IACxC,oBAAoB,KAAK,UAAU,SAAS,GAC/C;AAED,UAAO,iBAAiB,QAAQ;;AAGlC,yCACE,iBACM,aAAa,QACb,aAAa,CACpB"}
|
|
1
|
+
{"version":3,"file":"use-selector.cjs","names":["hasChanged: boolean"],"sources":["../../src/hooks/use-selector.ts"],"sourcesContent":["import type {\n steps,\n Expand,\n MultiStepFormLogger,\n MultiStepFormLoggerOptions,\n HelperFn,\n} from '@jfdevelops/multi-step-form-core';\nimport { useRef, useSyncExternalStore } from 'react';\n\n/**\n * Deep equality check that compares values regardless of property order.\n * Handles objects, arrays, primitives, and null/undefined.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or both are the same primitive value\n if (a === b) {\n return true;\n }\n\n // Handle null/undefined\n if (a == null || b == null) {\n return a === b;\n }\n\n // Type mismatch\n if (typeof a !== typeof b) {\n return false;\n }\n\n // Both are primitives (but not equal due to first check)\n if (typeof a !== 'object') {\n return false;\n }\n\n // Both are arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n return true;\n }\n\n // One is array, other is not\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n // Both are objects (not arrays)\n const keysA = Object.keys(a as Record<string, unknown>);\n const keysB = Object.keys(b as Record<string, unknown>);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n // Check if all keys in A exist in B with equal values\n for (const key of keysA) {\n if (!keysB.includes(key)) {\n return false;\n }\n if (\n !deepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key]\n )\n ) {\n return false;\n }\n }\n\n return true;\n}\n\ntype PrefixOptions = {\n /**\n * The action to perform on the prefix.\n *\n * @default 'prepend'\n */\n action?: 'prepend' | 'append';\n /**\n * The value to add to the prefix.\n */\n value: string | ((prefix: string) => string);\n /**\n * The delimiter to use between the original prefix and the added prefix.\n * @default '-'\n * @example\n * ```tsx\n * <Selector debug={{ prefix: { action: 'prepend', value: 'MySelector', delimiter: '|' } }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n */\n delimiter?: string;\n};\n\n/**\n * Debug options for customizing logging behavior in the Selector component.\n * All options are optional - you can provide any combination of these functions\n * to customize how debug information is logged.\n */\nexport type DebugOptions<TSelected> = {\n /**\n * The prefix to use for the logger.\n *\n * If a string or function is provided, it will replace the default prefix.\n * If you need to prepend or append to the default prefix, you can provide {@linkcode PrefixOptions}.\n * @default 'MultiStepFormSchema-Selector'\n *\n * @example\n * ```tsx\n * <Selector debug={{ prefix: 'MySelector' }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n *\n */\n prefix?: MultiStepFormLoggerOptions['prefix'] | PrefixOptions;\n /**\n * Called when the Selector component renders with the selected value.\n * This is called on every render of the Selector component, regardless of\n * whether the selected value has changed.\n *\n * @param selected - The current selected value from the selector function\n */\n onRender?: (selected: TSelected) => string;\n\n /**\n * Called when the Selector component renders its children.\n * This is only called when the Selector has a children render prop.\n */\n onChildrenRender?: () => string;\n\n /**\n * Called when the initial value is set for the first time.\n * This is called once when the selector first evaluates and caches its value.\n *\n * @param value - The initial selected value\n */\n onInitialValue?: (value: TSelected) => string;\n\n /**\n * Called when the selected value changes from one value to another.\n * This is called whenever the selector detects that the value has changed\n * (using Object.is() for primitives or deep comparison for objects/arrays).\n *\n * @param oldValue - The previous selected value\n * @param newValue - The new selected value\n */\n onValueChanged?: (oldValue: TSelected, newValue: TSelected) => string;\n\n /**\n * Called when the selected value is checked but hasn't changed.\n * This is called when the selector evaluates but determines that the value\n * is the same as the previously cached value.\n *\n * @param value - The current selected value (unchanged from previous check)\n */\n onValueUnchanged?: (value: TSelected) => string;\n};\n\nexport type UseSelectorOptions<\n steps extends steps.instantiateSteps,\n selected,\n> = {\n selectorFn: SelectorFn<steps, selected>;\n logger?: MultiStepFormLogger;\n debugOptions?: DebugOptions<selected>;\n};\nexport type UseSelector<steps extends steps.instantiateSteps> = {\n /**\n * @deprecated Use the {@link UseSelectorOptions} instead. Will be removed in the future.\n */\n <selected>(\n selectorFn: SelectorFn<steps, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ): selected;\n /**\n * @param options - The options for the useSelector hook.\n * @returns The selected value.\n */\n <selected>(options: UseSelectorOptions<steps, selected>): selected;\n};\nexport type SelectorFn<steps extends steps.instantiateSteps, selected> = (\n ctx: Expand<HelperFn.buildCtx<steps, [steps.StepNumbers<steps>]>>\n) => selected;\n\nexport function createUseSelector<steps extends steps.instantiateSteps>(\n createCtx: () => Expand<HelperFn.buildCtx<steps, [steps.StepNumbers<steps>]>>,\n subscribe: (listener: () => void) => () => void\n) {\n return <selected>(\n selectorFn: SelectorFn<steps, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ) => {\n const snapshotCacheRef = useRef<{ value: selected } | null>(null);\n const selectorRef = useRef(selectorFn);\n\n // Update the selector ref on every render to ensure we always use the latest selector\n selectorRef.current = selectorFn;\n\n const getSnapshot = () => {\n const currentCtx = createCtx();\n const newValue = selectorRef.current(currentCtx);\n\n // Cache the result to ensure stable reference\n if (snapshotCacheRef.current === null) {\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onInitialValue?.(newValue) ??\n `Initial value: ${JSON.stringify(newValue)}`\n );\n\n return newValue;\n }\n\n // Check if the value actually changed\n // For primitive values, use Object.is() for fast comparison\n // For complex values, use deep comparison\n const isPrimitive =\n newValue === null ||\n (typeof newValue !== 'object' && typeof newValue !== 'function');\n\n let hasChanged: boolean;\n\n if (isPrimitive) {\n // Use Object.is() for primitives (faster and more reliable)\n hasChanged = !Object.is(snapshotCacheRef.current.value, newValue);\n } else {\n // For objects/arrays, we need to do a deep comparison\n // First check reference equality (fast path)\n const oldValue = snapshotCacheRef.current.value;\n if (oldValue === newValue) {\n hasChanged = false;\n } else {\n // Deep comparison using a proper deep equality function\n // This correctly handles property order differences\n hasChanged = !deepEqual(oldValue, newValue);\n }\n }\n\n if (hasChanged) {\n const oldValue = snapshotCacheRef.current.value;\n\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onValueChanged?.(oldValue, newValue) ??\n `Value changed: ${JSON.stringify(oldValue)} -> ${JSON.stringify(\n newValue\n )}`\n );\n // Return the new value so useSyncExternalStore can detect the change via Object.is()\n return newValue;\n }\n\n // Return the cached value to maintain stable reference when value hasn't changed\n logger?.info(\n debugOptions?.onValueUnchanged?.(newValue) ??\n `Value unchanged: ${JSON.stringify(newValue)}`\n );\n\n return snapshotCacheRef.current.value;\n };\n\n return useSyncExternalStore(\n subscribe,\n () => getSnapshot(),\n () => getSnapshot()\n );\n };\n}\n"],"mappings":";;;;;;;AAaA,SAAS,UAAU,GAAY,GAAqB;AAElD,KAAI,MAAM,EACR,QAAO;AAIT,KAAI,KAAK,QAAQ,KAAK,KACpB,QAAO,MAAM;AAIf,KAAI,OAAO,MAAM,OAAO,EACtB,QAAO;AAIT,KAAI,OAAO,MAAM,SACf,QAAO;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,EAAE;AACxC,MAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,OAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CACxB,QAAO;AAGX,SAAO;;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CACtC,QAAO;CAIT,MAAM,QAAQ,OAAO,KAAK,EAA6B;CACvD,MAAM,QAAQ,OAAO,KAAK,EAA6B;AAEvD,KAAI,MAAM,WAAW,MAAM,OACzB,QAAO;AAIT,MAAK,MAAM,OAAO,OAAO;AACvB,MAAI,CAAC,MAAM,SAAS,IAAI,CACtB,QAAO;AAET,MACE,CAAC,UACE,EAA8B,MAC9B,EAA8B,KAChC,CAED,QAAO;;AAIX,QAAO;;AAuHT,SAAgB,kBACd,WACA,WACA;AACA,SACE,YACA,QACA,iBACG;EACH,MAAM,qCAAsD,KAAK;EACjE,MAAM,gCAAqB,WAAW;AAGtC,cAAY,UAAU;EAEtB,MAAM,oBAAoB;GACxB,MAAM,aAAa,WAAW;GAC9B,MAAM,WAAW,YAAY,QAAQ,WAAW;AAGhD,OAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,SAAS,IACtC,kBAAkB,KAAK,UAAU,SAAS,GAC7C;AAED,WAAO;;GAMT,MAAM,cACJ,aAAa,QACZ,OAAO,aAAa,YAAY,OAAO,aAAa;GAEvD,IAAIA;AAEJ,OAAI,YAEF,cAAa,CAAC,OAAO,GAAG,iBAAiB,QAAQ,OAAO,SAAS;QAC5D;IAGL,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,QAAI,aAAa,SACf,cAAa;QAIb,cAAa,CAAC,UAAU,UAAU,SAAS;;AAI/C,OAAI,YAAY;IACd,MAAM,WAAW,iBAAiB,QAAQ;AAE1C,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,UAAU,SAAS,IAChD,kBAAkB,KAAK,UAAU,SAAS,CAAC,MAAM,KAAK,UACpD,SACD,GACJ;AAED,WAAO;;AAIT,WAAQ,KACN,cAAc,mBAAmB,SAAS,IACxC,oBAAoB,KAAK,UAAU,SAAS,GAC/C;AAED,UAAO,iBAAiB,QAAQ;;AAGlC,yCACE,iBACM,aAAa,QACb,aAAa,CACpB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Expand, HelperFn, MultiStepFormLogger, MultiStepFormLoggerOptions } from "@jfdevelops/multi-step-form-core";
|
|
2
2
|
|
|
3
3
|
//#region src/hooks/use-selector.d.ts
|
|
4
4
|
type PrefixOptions = {
|
|
@@ -84,9 +84,23 @@ type DebugOptions<TSelected> = {
|
|
|
84
84
|
*/
|
|
85
85
|
onValueUnchanged?: (value: TSelected) => string;
|
|
86
86
|
};
|
|
87
|
-
type
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
type UseSelectorOptions<steps$1 extends steps$1.instantiateSteps, selected> = {
|
|
88
|
+
selectorFn: SelectorFn<steps$1, selected>;
|
|
89
|
+
logger?: MultiStepFormLogger;
|
|
90
|
+
debugOptions?: DebugOptions<selected>;
|
|
91
|
+
};
|
|
92
|
+
type UseSelector<steps$1 extends steps$1.instantiateSteps> = {
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated Use the {@link UseSelectorOptions} instead. Will be removed in the future.
|
|
95
|
+
*/
|
|
96
|
+
<selected>(selectorFn: SelectorFn<steps$1, selected>, logger?: MultiStepFormLogger, debugOptions?: DebugOptions<selected>): selected;
|
|
97
|
+
/**
|
|
98
|
+
* @param options - The options for the useSelector hook.
|
|
99
|
+
* @returns The selected value.
|
|
100
|
+
*/
|
|
101
|
+
<selected>(options: UseSelectorOptions<steps$1, selected>): selected;
|
|
102
|
+
};
|
|
103
|
+
type SelectorFn<steps$1 extends steps$1.instantiateSteps, selected> = (ctx: Expand<HelperFn.buildCtx<steps$1, [steps$1.StepNumbers<steps$1>]>>) => selected;
|
|
90
104
|
//#endregion
|
|
91
105
|
export { DebugOptions, SelectorFn, UseSelector };
|
|
92
106
|
//# sourceMappingURL=use-selector.d.cts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Expand, HelperFn, MultiStepFormLogger, MultiStepFormLoggerOptions } from "@jfdevelops/multi-step-form-core";
|
|
2
2
|
|
|
3
3
|
//#region src/hooks/use-selector.d.ts
|
|
4
4
|
type PrefixOptions = {
|
|
@@ -84,9 +84,23 @@ type DebugOptions<TSelected> = {
|
|
|
84
84
|
*/
|
|
85
85
|
onValueUnchanged?: (value: TSelected) => string;
|
|
86
86
|
};
|
|
87
|
-
type
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
type UseSelectorOptions<steps$1 extends steps$1.instantiateSteps, selected> = {
|
|
88
|
+
selectorFn: SelectorFn<steps$1, selected>;
|
|
89
|
+
logger?: MultiStepFormLogger;
|
|
90
|
+
debugOptions?: DebugOptions<selected>;
|
|
91
|
+
};
|
|
92
|
+
type UseSelector<steps$1 extends steps$1.instantiateSteps> = {
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated Use the {@link UseSelectorOptions} instead. Will be removed in the future.
|
|
95
|
+
*/
|
|
96
|
+
<selected>(selectorFn: SelectorFn<steps$1, selected>, logger?: MultiStepFormLogger, debugOptions?: DebugOptions<selected>): selected;
|
|
97
|
+
/**
|
|
98
|
+
* @param options - The options for the useSelector hook.
|
|
99
|
+
* @returns The selected value.
|
|
100
|
+
*/
|
|
101
|
+
<selected>(options: UseSelectorOptions<steps$1, selected>): selected;
|
|
102
|
+
};
|
|
103
|
+
type SelectorFn<steps$1 extends steps$1.instantiateSteps, selected> = (ctx: Expand<HelperFn.buildCtx<steps$1, [steps$1.StepNumbers<steps$1>]>>) => selected;
|
|
90
104
|
//#endregion
|
|
91
105
|
export { DebugOptions, SelectorFn, UseSelector };
|
|
92
106
|
//# sourceMappingURL=use-selector.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-selector.mjs","names":["hasChanged: boolean"],"sources":["../../src/hooks/use-selector.ts"],"sourcesContent":["import type {\n AnyResolvedStep,\n CurrentStepHelperFnCtx,\n Expand,\n MultiStepFormLogger,\n MultiStepFormLoggerOptions,\n} from '@jfdevelops/multi-step-form-core';\nimport { useRef, useSyncExternalStore } from 'react';\n\n/**\n * Deep equality check that compares values regardless of property order.\n * Handles objects, arrays, primitives, and null/undefined.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or both are the same primitive value\n if (a === b) {\n return true;\n }\n\n // Handle null/undefined\n if (a == null || b == null) {\n return a === b;\n }\n\n // Type mismatch\n if (typeof a !== typeof b) {\n return false;\n }\n\n // Both are primitives (but not equal due to first check)\n if (typeof a !== 'object') {\n return false;\n }\n\n // Both are arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n return true;\n }\n\n // One is array, other is not\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n // Both are objects (not arrays)\n const keysA = Object.keys(a as Record<string, unknown>);\n const keysB = Object.keys(b as Record<string, unknown>);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n // Check if all keys in A exist in B with equal values\n for (const key of keysA) {\n if (!keysB.includes(key)) {\n return false;\n }\n if (\n !deepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key]\n )\n ) {\n return false;\n }\n }\n\n return true;\n}\n\ntype PrefixOptions = {\n /**\n * The action to perform on the prefix.\n *\n * @default 'prepend'\n */\n action?: 'prepend' | 'append';\n /**\n * The value to add to the prefix.\n */\n value: string | ((prefix: string) => string);\n /**\n * The delimiter to use between the original prefix and the added prefix.\n * @default '-'\n * @example\n * ```tsx\n * <Selector debug={{ prefix: { action: 'prepend', value: 'MySelector', delimiter: '|' } }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n */\n delimiter?: string;\n};\n\n/**\n * Debug options for customizing logging behavior in the Selector component.\n * All options are optional - you can provide any combination of these functions\n * to customize how debug information is logged.\n */\nexport type DebugOptions<TSelected> = {\n /**\n * The prefix to use for the logger.\n *\n * If a string or function is provided, it will replace the default prefix.\n * If you need to prepend or append to the default prefix, you can provide {@linkcode PrefixOptions}.\n * @default 'MultiStepFormSchema-Selector'\n *\n * @example\n * ```tsx\n * <Selector debug={{ prefix: 'MySelector' }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n *\n */\n prefix?: MultiStepFormLoggerOptions['prefix'] | PrefixOptions;\n /**\n * Called when the Selector component renders with the selected value.\n * This is called on every render of the Selector component, regardless of\n * whether the selected value has changed.\n *\n * @param selected - The current selected value from the selector function\n */\n onRender?: (selected: TSelected) => string;\n\n /**\n * Called when the Selector component renders its children.\n * This is only called when the Selector has a children render prop.\n */\n onChildrenRender?: () => string;\n\n /**\n * Called when the initial value is set for the first time.\n * This is called once when the selector first evaluates and caches its value.\n *\n * @param value - The initial selected value\n */\n onInitialValue?: (value: TSelected) => string;\n\n /**\n * Called when the selected value changes from one value to another.\n * This is called whenever the selector detects that the value has changed\n * (using Object.is() for primitives or deep comparison for objects/arrays).\n *\n * @param oldValue - The previous selected value\n * @param newValue - The new selected value\n */\n onValueChanged?: (oldValue: TSelected, newValue: TSelected) => string;\n\n /**\n * Called when the selected value is checked but hasn't changed.\n * This is called when the selector evaluates but determines that the value\n * is the same as the previously cached value.\n *\n * @param value - The current selected value (unchanged from previous check)\n */\n onValueUnchanged?: (value: TSelected) => string;\n};\n\nexport type UseSelector<TCurrentStep extends AnyResolvedStep> = ReturnType<\n typeof createUseSelector<TCurrentStep>\n>;\nexport type SelectorFn<TCurrentStep extends AnyResolvedStep, TSelected> = (\n ctx: Expand<CurrentStepHelperFnCtx<TCurrentStep>>\n) => TSelected;\n\nexport function createUseSelector<TCurrentStep extends AnyResolvedStep>(\n createCtx: () => Expand<CurrentStepHelperFnCtx<TCurrentStep>>,\n subscribe: (listener: () => void) => () => void\n) {\n return <selected>(\n selectorFn: SelectorFn<TCurrentStep, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ) => {\n const snapshotCacheRef = useRef<{ value: selected } | null>(null);\n const selectorRef = useRef(selectorFn);\n\n // Update the selector ref on every render to ensure we always use the latest selector\n selectorRef.current = selectorFn;\n\n const getSnapshot = () => {\n const currentCtx = createCtx();\n const newValue = selectorRef.current(currentCtx);\n\n // Cache the result to ensure stable reference\n if (snapshotCacheRef.current === null) {\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onInitialValue?.(newValue) ??\n `Initial value: ${JSON.stringify(newValue)}`\n );\n\n return newValue;\n }\n\n // Check if the value actually changed\n // For primitive values, use Object.is() for fast comparison\n // For complex values, use deep comparison\n const isPrimitive =\n newValue === null ||\n (typeof newValue !== 'object' && typeof newValue !== 'function');\n\n let hasChanged: boolean;\n\n if (isPrimitive) {\n // Use Object.is() for primitives (faster and more reliable)\n hasChanged = !Object.is(snapshotCacheRef.current.value, newValue);\n } else {\n // For objects/arrays, we need to do a deep comparison\n // First check reference equality (fast path)\n const oldValue = snapshotCacheRef.current.value;\n if (oldValue === newValue) {\n hasChanged = false;\n } else {\n // Deep comparison using a proper deep equality function\n // This correctly handles property order differences\n hasChanged = !deepEqual(oldValue, newValue);\n }\n }\n\n if (hasChanged) {\n const oldValue = snapshotCacheRef.current.value;\n\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onValueChanged?.(oldValue, newValue) ??\n `Value changed: ${JSON.stringify(oldValue)} -> ${JSON.stringify(\n newValue\n )}`\n );\n // Return the new value so useSyncExternalStore can detect the change via Object.is()\n return newValue;\n }\n\n // Return the cached value to maintain stable reference when value hasn't changed\n logger?.info(\n debugOptions?.onValueUnchanged?.(newValue) ??\n `Value unchanged: ${JSON.stringify(newValue)}`\n );\n\n return snapshotCacheRef.current.value;\n };\n\n return useSyncExternalStore(\n subscribe,\n () => getSnapshot(),\n () => getSnapshot()\n );\n };\n}\n"],"mappings":";;;;;;;AAaA,SAAS,UAAU,GAAY,GAAqB;AAElD,KAAI,MAAM,EACR,QAAO;AAIT,KAAI,KAAK,QAAQ,KAAK,KACpB,QAAO,MAAM;AAIf,KAAI,OAAO,MAAM,OAAO,EACtB,QAAO;AAIT,KAAI,OAAO,MAAM,SACf,QAAO;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,EAAE;AACxC,MAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,OAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CACxB,QAAO;AAGX,SAAO;;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CACtC,QAAO;CAIT,MAAM,QAAQ,OAAO,KAAK,EAA6B;CACvD,MAAM,QAAQ,OAAO,KAAK,EAA6B;AAEvD,KAAI,MAAM,WAAW,MAAM,OACzB,QAAO;AAIT,MAAK,MAAM,OAAO,OAAO;AACvB,MAAI,CAAC,MAAM,SAAS,IAAI,CACtB,QAAO;AAET,MACE,CAAC,UACE,EAA8B,MAC9B,EAA8B,KAChC,CAED,QAAO;;AAIX,QAAO;;AAmGT,SAAgB,kBACd,WACA,WACA;AACA,SACE,YACA,QACA,iBACG;EACH,MAAM,mBAAmB,OAAmC,KAAK;EACjE,MAAM,cAAc,OAAO,WAAW;AAGtC,cAAY,UAAU;EAEtB,MAAM,oBAAoB;GACxB,MAAM,aAAa,WAAW;GAC9B,MAAM,WAAW,YAAY,QAAQ,WAAW;AAGhD,OAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,SAAS,IACtC,kBAAkB,KAAK,UAAU,SAAS,GAC7C;AAED,WAAO;;GAMT,MAAM,cACJ,aAAa,QACZ,OAAO,aAAa,YAAY,OAAO,aAAa;GAEvD,IAAIA;AAEJ,OAAI,YAEF,cAAa,CAAC,OAAO,GAAG,iBAAiB,QAAQ,OAAO,SAAS;QAC5D;IAGL,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,QAAI,aAAa,SACf,cAAa;QAIb,cAAa,CAAC,UAAU,UAAU,SAAS;;AAI/C,OAAI,YAAY;IACd,MAAM,WAAW,iBAAiB,QAAQ;AAE1C,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,UAAU,SAAS,IAChD,kBAAkB,KAAK,UAAU,SAAS,CAAC,MAAM,KAAK,UACpD,SACD,GACJ;AAED,WAAO;;AAIT,WAAQ,KACN,cAAc,mBAAmB,SAAS,IACxC,oBAAoB,KAAK,UAAU,SAAS,GAC/C;AAED,UAAO,iBAAiB,QAAQ;;AAGlC,SAAO,qBACL,iBACM,aAAa,QACb,aAAa,CACpB"}
|
|
1
|
+
{"version":3,"file":"use-selector.mjs","names":["hasChanged: boolean"],"sources":["../../src/hooks/use-selector.ts"],"sourcesContent":["import type {\n steps,\n Expand,\n MultiStepFormLogger,\n MultiStepFormLoggerOptions,\n HelperFn,\n} from '@jfdevelops/multi-step-form-core';\nimport { useRef, useSyncExternalStore } from 'react';\n\n/**\n * Deep equality check that compares values regardless of property order.\n * Handles objects, arrays, primitives, and null/undefined.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n // Same reference or both are the same primitive value\n if (a === b) {\n return true;\n }\n\n // Handle null/undefined\n if (a == null || b == null) {\n return a === b;\n }\n\n // Type mismatch\n if (typeof a !== typeof b) {\n return false;\n }\n\n // Both are primitives (but not equal due to first check)\n if (typeof a !== 'object') {\n return false;\n }\n\n // Both are arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) {\n return false;\n }\n }\n return true;\n }\n\n // One is array, other is not\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n // Both are objects (not arrays)\n const keysA = Object.keys(a as Record<string, unknown>);\n const keysB = Object.keys(b as Record<string, unknown>);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n // Check if all keys in A exist in B with equal values\n for (const key of keysA) {\n if (!keysB.includes(key)) {\n return false;\n }\n if (\n !deepEqual(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key]\n )\n ) {\n return false;\n }\n }\n\n return true;\n}\n\ntype PrefixOptions = {\n /**\n * The action to perform on the prefix.\n *\n * @default 'prepend'\n */\n action?: 'prepend' | 'append';\n /**\n * The value to add to the prefix.\n */\n value: string | ((prefix: string) => string);\n /**\n * The delimiter to use between the original prefix and the added prefix.\n * @default '-'\n * @example\n * ```tsx\n * <Selector debug={{ prefix: { action: 'prepend', value: 'MySelector', delimiter: '|' } }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n */\n delimiter?: string;\n};\n\n/**\n * Debug options for customizing logging behavior in the Selector component.\n * All options are optional - you can provide any combination of these functions\n * to customize how debug information is logged.\n */\nexport type DebugOptions<TSelected> = {\n /**\n * The prefix to use for the logger.\n *\n * If a string or function is provided, it will replace the default prefix.\n * If you need to prepend or append to the default prefix, you can provide {@linkcode PrefixOptions}.\n * @default 'MultiStepFormSchema-Selector'\n *\n * @example\n * ```tsx\n * <Selector debug={{ prefix: 'MySelector' }}>\n * {(value) => <p>First name: {value}</p>}\n * </Selector>\n * ```\n *\n */\n prefix?: MultiStepFormLoggerOptions['prefix'] | PrefixOptions;\n /**\n * Called when the Selector component renders with the selected value.\n * This is called on every render of the Selector component, regardless of\n * whether the selected value has changed.\n *\n * @param selected - The current selected value from the selector function\n */\n onRender?: (selected: TSelected) => string;\n\n /**\n * Called when the Selector component renders its children.\n * This is only called when the Selector has a children render prop.\n */\n onChildrenRender?: () => string;\n\n /**\n * Called when the initial value is set for the first time.\n * This is called once when the selector first evaluates and caches its value.\n *\n * @param value - The initial selected value\n */\n onInitialValue?: (value: TSelected) => string;\n\n /**\n * Called when the selected value changes from one value to another.\n * This is called whenever the selector detects that the value has changed\n * (using Object.is() for primitives or deep comparison for objects/arrays).\n *\n * @param oldValue - The previous selected value\n * @param newValue - The new selected value\n */\n onValueChanged?: (oldValue: TSelected, newValue: TSelected) => string;\n\n /**\n * Called when the selected value is checked but hasn't changed.\n * This is called when the selector evaluates but determines that the value\n * is the same as the previously cached value.\n *\n * @param value - The current selected value (unchanged from previous check)\n */\n onValueUnchanged?: (value: TSelected) => string;\n};\n\nexport type UseSelectorOptions<\n steps extends steps.instantiateSteps,\n selected,\n> = {\n selectorFn: SelectorFn<steps, selected>;\n logger?: MultiStepFormLogger;\n debugOptions?: DebugOptions<selected>;\n};\nexport type UseSelector<steps extends steps.instantiateSteps> = {\n /**\n * @deprecated Use the {@link UseSelectorOptions} instead. Will be removed in the future.\n */\n <selected>(\n selectorFn: SelectorFn<steps, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ): selected;\n /**\n * @param options - The options for the useSelector hook.\n * @returns The selected value.\n */\n <selected>(options: UseSelectorOptions<steps, selected>): selected;\n};\nexport type SelectorFn<steps extends steps.instantiateSteps, selected> = (\n ctx: Expand<HelperFn.buildCtx<steps, [steps.StepNumbers<steps>]>>\n) => selected;\n\nexport function createUseSelector<steps extends steps.instantiateSteps>(\n createCtx: () => Expand<HelperFn.buildCtx<steps, [steps.StepNumbers<steps>]>>,\n subscribe: (listener: () => void) => () => void\n) {\n return <selected>(\n selectorFn: SelectorFn<steps, selected>,\n logger?: MultiStepFormLogger,\n debugOptions?: DebugOptions<selected>\n ) => {\n const snapshotCacheRef = useRef<{ value: selected } | null>(null);\n const selectorRef = useRef(selectorFn);\n\n // Update the selector ref on every render to ensure we always use the latest selector\n selectorRef.current = selectorFn;\n\n const getSnapshot = () => {\n const currentCtx = createCtx();\n const newValue = selectorRef.current(currentCtx);\n\n // Cache the result to ensure stable reference\n if (snapshotCacheRef.current === null) {\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onInitialValue?.(newValue) ??\n `Initial value: ${JSON.stringify(newValue)}`\n );\n\n return newValue;\n }\n\n // Check if the value actually changed\n // For primitive values, use Object.is() for fast comparison\n // For complex values, use deep comparison\n const isPrimitive =\n newValue === null ||\n (typeof newValue !== 'object' && typeof newValue !== 'function');\n\n let hasChanged: boolean;\n\n if (isPrimitive) {\n // Use Object.is() for primitives (faster and more reliable)\n hasChanged = !Object.is(snapshotCacheRef.current.value, newValue);\n } else {\n // For objects/arrays, we need to do a deep comparison\n // First check reference equality (fast path)\n const oldValue = snapshotCacheRef.current.value;\n if (oldValue === newValue) {\n hasChanged = false;\n } else {\n // Deep comparison using a proper deep equality function\n // This correctly handles property order differences\n hasChanged = !deepEqual(oldValue, newValue);\n }\n }\n\n if (hasChanged) {\n const oldValue = snapshotCacheRef.current.value;\n\n snapshotCacheRef.current = { value: newValue };\n\n logger?.info(\n debugOptions?.onValueChanged?.(oldValue, newValue) ??\n `Value changed: ${JSON.stringify(oldValue)} -> ${JSON.stringify(\n newValue\n )}`\n );\n // Return the new value so useSyncExternalStore can detect the change via Object.is()\n return newValue;\n }\n\n // Return the cached value to maintain stable reference when value hasn't changed\n logger?.info(\n debugOptions?.onValueUnchanged?.(newValue) ??\n `Value unchanged: ${JSON.stringify(newValue)}`\n );\n\n return snapshotCacheRef.current.value;\n };\n\n return useSyncExternalStore(\n subscribe,\n () => getSnapshot(),\n () => getSnapshot()\n );\n };\n}\n"],"mappings":";;;;;;;AAaA,SAAS,UAAU,GAAY,GAAqB;AAElD,KAAI,MAAM,EACR,QAAO;AAIT,KAAI,KAAK,QAAQ,KAAK,KACpB,QAAO,MAAM;AAIf,KAAI,OAAO,MAAM,OAAO,EACtB,QAAO;AAIT,KAAI,OAAO,MAAM,SACf,QAAO;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,EAAE;AACxC,MAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,OAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,CACxB,QAAO;AAGX,SAAO;;AAIT,KAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,CACtC,QAAO;CAIT,MAAM,QAAQ,OAAO,KAAK,EAA6B;CACvD,MAAM,QAAQ,OAAO,KAAK,EAA6B;AAEvD,KAAI,MAAM,WAAW,MAAM,OACzB,QAAO;AAIT,MAAK,MAAM,OAAO,OAAO;AACvB,MAAI,CAAC,MAAM,SAAS,IAAI,CACtB,QAAO;AAET,MACE,CAAC,UACE,EAA8B,MAC9B,EAA8B,KAChC,CAED,QAAO;;AAIX,QAAO;;AAuHT,SAAgB,kBACd,WACA,WACA;AACA,SACE,YACA,QACA,iBACG;EACH,MAAM,mBAAmB,OAAmC,KAAK;EACjE,MAAM,cAAc,OAAO,WAAW;AAGtC,cAAY,UAAU;EAEtB,MAAM,oBAAoB;GACxB,MAAM,aAAa,WAAW;GAC9B,MAAM,WAAW,YAAY,QAAQ,WAAW;AAGhD,OAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,SAAS,IACtC,kBAAkB,KAAK,UAAU,SAAS,GAC7C;AAED,WAAO;;GAMT,MAAM,cACJ,aAAa,QACZ,OAAO,aAAa,YAAY,OAAO,aAAa;GAEvD,IAAIA;AAEJ,OAAI,YAEF,cAAa,CAAC,OAAO,GAAG,iBAAiB,QAAQ,OAAO,SAAS;QAC5D;IAGL,MAAM,WAAW,iBAAiB,QAAQ;AAC1C,QAAI,aAAa,SACf,cAAa;QAIb,cAAa,CAAC,UAAU,UAAU,SAAS;;AAI/C,OAAI,YAAY;IACd,MAAM,WAAW,iBAAiB,QAAQ;AAE1C,qBAAiB,UAAU,EAAE,OAAO,UAAU;AAE9C,YAAQ,KACN,cAAc,iBAAiB,UAAU,SAAS,IAChD,kBAAkB,KAAK,UAAU,SAAS,CAAC,MAAM,KAAK,UACpD,SACD,GACJ;AAED,WAAO;;AAIT,WAAQ,KACN,cAAc,mBAAmB,SAAS,IACxC,oBAAoB,KAAK,UAAU,SAAS,GAC/C;AAED,UAAO,iBAAiB,QAAQ;;AAGlC,SAAO,qBACL,iBACM,aAAa,QACb,aAAa,CACpB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const require_step_schema = require('./step-schema.cjs');
|
|
2
|
-
const require_schema = require('./schema.cjs');
|
|
3
1
|
const require_use_multi_step_form_data = require('./hooks/use-multi-step-form-data.cjs');
|
|
4
2
|
const require_create_context = require('./create-context.cjs');
|
|
3
|
+
const require_step_schema = require('./step-schema.cjs');
|
|
4
|
+
const require_schema = require('./schema.cjs');
|
|
5
5
|
|
|
6
6
|
exports.MultiStepFormSchema = require_schema.MultiStepFormSchema;
|
|
7
7
|
exports.MultiStepFormStepSchema = require_step_schema.MultiStepFormStepSchema;
|
|
@@ -11,7 +11,6 @@ Object.defineProperty(exports, 'StepSpecificComponent', {
|
|
|
11
11
|
return require_step_schema.StepSpecificComponent;
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
exports.createDefaultValues = require_step_schema.createDefaultValues;
|
|
15
14
|
exports.createMultiStepFormContext = require_create_context.createMultiStepFormContext;
|
|
16
15
|
exports.createMultiStepFormSchema = require_schema.createMultiStepFormSchema;
|
|
17
16
|
exports.useMultiStepFormData = require_use_multi_step_form_data.useMultiStepFormData;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnyResolvedStep, CreateComponent, CreateComponentCallback, CreateComponentFn, CreateFunction, CreateStepSpecificComponentCallback, CreatedMultiStepFormComponent, ExtractedDefaultValues, HelperFunctions, MultiStepFormSchemaStepConfig, MultiStepFormStepSchema, ResolvedStep, StepSpecificComponent, StepSpecificCreateComponentFn, createDefaultValues } from "./step-schema.cjs";
|
|
2
|
-
import { AnyMultiStepFormSchema, MultiStepFormSchema, MultiStepFormSchemaOptions, createMultiStepFormSchema } from "./schema.cjs";
|
|
3
1
|
import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.cjs";
|
|
4
2
|
import { CreateHOC, MultiStepFormContextResult, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext } from "./create-context.cjs";
|
|
5
|
-
|
|
3
|
+
import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.cjs";
|
|
4
|
+
import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.cjs";
|
|
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 { AnyResolvedStep, CreateComponent, CreateComponentCallback, CreateComponentFn, CreateFunction, CreateStepSpecificComponentCallback, CreatedMultiStepFormComponent, ExtractedDefaultValues, HelperFunctions, MultiStepFormSchemaStepConfig, MultiStepFormStepSchema, ResolvedStep, StepSpecificComponent, StepSpecificCreateComponentFn, createDefaultValues } from "./step-schema.mjs";
|
|
2
|
-
import { AnyMultiStepFormSchema, MultiStepFormSchema, MultiStepFormSchemaOptions, createMultiStepFormSchema } from "./schema.mjs";
|
|
3
1
|
import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.mjs";
|
|
4
2
|
import { CreateHOC, MultiStepFormContextResult, UseCurrentStepBaseResult, UseCurrentStepErrorResult, UseCurrentStepOptions, UseCurrentStepResult, UseCurrentStepSuccessResult, UseProgressBaseOptions, UseProgressOptions, UseProgressResult, createMultiStepFormContext } from "./create-context.mjs";
|
|
5
|
-
|
|
3
|
+
import { CreateComponentFn, HelperFunctions, MultiStepFormStepSchema, StepSpecificComponent, StepSpecificCreateComponentFn } from "./step-schema.mjs";
|
|
4
|
+
import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.mjs";
|
|
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, createDefaultValues } from "./step-schema.mjs";
|
|
2
|
-
import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.mjs";
|
|
3
1
|
import { useMultiStepFormData } from "./hooks/use-multi-step-form-data.mjs";
|
|
4
2
|
import { createMultiStepFormContext } from "./create-context.mjs";
|
|
3
|
+
import { MultiStepFormStepSchema, StepSpecificComponent } from "./step-schema.mjs";
|
|
4
|
+
import { MultiStepFormSchema, createMultiStepFormSchema } from "./schema.mjs";
|
|
5
5
|
|
|
6
|
-
export { MultiStepFormSchema, MultiStepFormStepSchema, StepSpecificComponent,
|
|
6
|
+
export { MultiStepFormSchema, MultiStepFormStepSchema, StepSpecificComponent, createMultiStepFormContext, createMultiStepFormSchema, useMultiStepFormData };
|
package/dist/schema.cjs
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
const require_create_context = require('./create-context.cjs');
|
|
2
|
+
const require_utils = require('./utils.cjs');
|
|
1
3
|
const require_step_schema = require('./step-schema.cjs');
|
|
2
4
|
let __jfdevelops_multi_step_form_core = require("@jfdevelops/multi-step-form-core");
|
|
3
5
|
let __jfdevelops_multi_step_form_core__internals = require("@jfdevelops/multi-step-form-core/_internals");
|
|
4
6
|
|
|
5
7
|
//#region src/schema.ts
|
|
6
|
-
var MultiStepFormSchema = class extends __jfdevelops_multi_step_form_core.MultiStepFormSchema {
|
|
8
|
+
var MultiStepFormSchema = class MultiStepFormSchema extends __jfdevelops_multi_step_form_core.MultiStepFormSchema {
|
|
7
9
|
stepSchema;
|
|
8
10
|
#internal;
|
|
11
|
+
storage;
|
|
12
|
+
storageConfig;
|
|
13
|
+
context = void 0;
|
|
14
|
+
formConfig = void 0;
|
|
9
15
|
constructor(config) {
|
|
10
|
-
const { nameTransformCasing = __jfdevelops_multi_step_form_core.DEFAULT_CASING, storage,
|
|
16
|
+
const { nameTransformCasing = __jfdevelops_multi_step_form_core.DEFAULT_CASING, steps, form, storage, context } = config;
|
|
11
17
|
const options = {
|
|
18
|
+
steps,
|
|
12
19
|
nameTransformCasing,
|
|
13
20
|
storage,
|
|
14
|
-
|
|
21
|
+
form
|
|
15
22
|
};
|
|
16
23
|
super(options);
|
|
17
24
|
this.stepSchema = new require_step_schema.MultiStepFormStepSchema(options);
|
|
@@ -24,15 +31,85 @@ var MultiStepFormSchema = class extends __jfdevelops_multi_step_form_core.MultiS
|
|
|
24
31
|
this.notify();
|
|
25
32
|
}
|
|
26
33
|
});
|
|
34
|
+
this.storageConfig = {
|
|
35
|
+
key: storage?.key ?? __jfdevelops_multi_step_form_core.DEFAULT_STORAGE_KEY,
|
|
36
|
+
store: storage?.store,
|
|
37
|
+
throwWhenUndefined: storage?.throwWhenUndefined
|
|
38
|
+
};
|
|
39
|
+
this.storage = new __jfdevelops_multi_step_form_core.MultiStepFormStorage({
|
|
40
|
+
data: this.stepSchema.value,
|
|
41
|
+
...this.storageConfig
|
|
42
|
+
});
|
|
43
|
+
if (context) this.context = context;
|
|
44
|
+
if (form) this.formConfig = form;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A helper function to add a form configuration to the {@linkcode MultiStepFormSchema}.
|
|
48
|
+
*
|
|
49
|
+
* By calling this function, you will have access to the create form component in all step
|
|
50
|
+
* utility functions.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* const schema = createMultiStepFormSchema({
|
|
55
|
+
* steps: {
|
|
56
|
+
* step1: {
|
|
57
|
+
* title: 'Step 1',
|
|
58
|
+
* fields: {
|
|
59
|
+
* firstName: {
|
|
60
|
+
* defaultValue: '',
|
|
61
|
+
* },
|
|
62
|
+
* },
|
|
63
|
+
* },
|
|
64
|
+
* },
|
|
65
|
+
* }).withForm({
|
|
66
|
+
* render(data) {
|
|
67
|
+
* return (props: MyCustomProps) => {
|
|
68
|
+
* return <form {...props}>{props.children}</form>;
|
|
69
|
+
* };
|
|
70
|
+
* },
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
* @param config The form configuration.
|
|
74
|
+
* @returns A new {@linkcode MultiStepFormSchema} with the form configuration.
|
|
75
|
+
*/
|
|
76
|
+
withForm(config) {
|
|
77
|
+
const { key, store, throwWhenUndefined } = this.storageConfig;
|
|
78
|
+
return new MultiStepFormSchema({
|
|
79
|
+
steps: this.stepSchema.original,
|
|
80
|
+
form: config,
|
|
81
|
+
nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,
|
|
82
|
+
storage: {
|
|
83
|
+
key,
|
|
84
|
+
store,
|
|
85
|
+
throwWhenUndefined
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
withContext() {
|
|
90
|
+
const context = require_create_context.createMultiStepFormContext(this);
|
|
91
|
+
return new MultiStepFormSchema({
|
|
92
|
+
steps: this.stepSchema.original,
|
|
93
|
+
form: this.formConfig,
|
|
94
|
+
nameTransformCasing: this.stepSchema.defaultNameTransformationCasing,
|
|
95
|
+
storage: {
|
|
96
|
+
key: this.storageConfig.key,
|
|
97
|
+
store: this.storageConfig.store,
|
|
98
|
+
throwWhenUndefined: this.storageConfig.throwWhenUndefined
|
|
99
|
+
},
|
|
100
|
+
context
|
|
101
|
+
});
|
|
27
102
|
}
|
|
28
103
|
createComponent(options, fn) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
104
|
+
return require_utils.createComponent({
|
|
105
|
+
fn,
|
|
106
|
+
input: ({ stepData }) => ({
|
|
107
|
+
reset: this.#internal.createHelperFnInputReset(stepData),
|
|
108
|
+
update: this.#internal.createHelperFnInputUpdate(stepData)
|
|
109
|
+
}),
|
|
110
|
+
options,
|
|
111
|
+
value: this.stepSchema.value
|
|
112
|
+
});
|
|
36
113
|
}
|
|
37
114
|
};
|
|
38
115
|
function createMultiStepFormSchema(options) {
|