Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@stepperize/core

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@stepperize/core - npm Package Compare versions

Comparing version
1.2.7
to
2.0.0
+220
-86
dist/index.d.ts

@@ -1,81 +0,67 @@

type Step = {
id: string;
} & Record<string, any>;
type Step<Id extends string = string, Data extends object = {}> = {
id: Id;
} & Data;
type Metadata = Record<string, any> | null;
type Stepper<Steps extends Step[] = Step[]> = {
/** Returns all steps. */
/** Step status for UI: active (current), success (past), inactive (future) */
type StepStatus = "active" | "inactive" | "success";
type StepperState<Steps extends Step[] = Step[]> = {
/**
* The steps of the stepper.
* @returns The steps of the stepper.
*/
all: Steps;
/** Returns the current step. */
current: Steps[number];
/** Returns true if the current step is the last step. */
isLast: boolean;
/** Returns true if the current step is the first step. */
isFirst: boolean;
/** Advances to the next step. */
next: () => void;
/** Returns to the previous step. */
prev: () => void;
/** Returns a step by its ID. */
get: <Id extends Get.Id<Steps>>(id: Id) => Get.StepById<Steps, Id>;
/** Navigates to a specific step by its ID. */
goTo: (id: Get.Id<Steps>) => void;
/** Resets the stepper to its initial state. */
reset: () => void;
/** Executes a function before navigating to the next step. */
beforeNext: (callback: () => Promise<boolean> | boolean) => Promise<void> | void;
/** Executes a function after navigating to the next step. */
afterNext: (callback: () => Promise<void> | void) => Promise<void> | void;
/** Executes a function before navigating to the previous step. */
beforePrev: (callback: () => Promise<boolean> | boolean) => Promise<void> | void;
/** Executes a function after navigating to the previous step. */
afterPrev: (callback: () => Promise<void> | void) => Promise<void> | void;
/** Executes a function before navigating to a specific step. */
beforeGoTo: (id: Get.Id<Steps>, callback: () => Promise<boolean> | boolean) => Promise<void> | void;
/** Executes a function after navigating to a specific step. */
afterGoTo: (id: Get.Id<Steps>, callback: () => Promise<void> | void) => Promise<void> | void;
/**
* Executes a function based on the current step ID.
* @param id - The ID of the step to check.
* @param whenFn - Function to execute if the current step matches the ID.
* @param elseFn - Optional function to execute if the current step does not match the ID.
* @returns The result of whenFn or elseFn.
* The current step of the stepper.
* @returns The current step of the stepper.
*/
when: <Id extends Get.Id<Steps>, R1, R2>(id: Id | [Id, ...boolean[]], whenFn: (step: Get.StepById<Steps, Id>) => R1, elseFn?: (step: Get.StepSansId<Steps, Id>) => R2) => R1 | R2;
current: {
data: Steps[number];
index: number;
status: StepStatus;
metadata: {
get: <M extends Metadata>() => M;
set: <M extends Metadata>(values: M) => void;
reset: (keepInitialMetadata?: boolean) => void;
};
};
/**
* Executes a function based on a switch-case-like structure for steps.
* @param when - An object mapping step IDs to functions.
* @returns The result of the function corresponding to the current step ID.
* Returns true if the current step is the last step.
* @returns True if the current step is the last step.
*/
switch: <R>(when: Get.Switch<Steps, R>) => R;
isLast: boolean;
/**
* Matches the current state with a set of possible states and executes the corresponding function.
* @param state - The current state ID.
* @param matches - An object mapping state IDs to functions.
* @returns The result of the matched function or null if no match is found.
* Returns true if the current step is the first step.
* @returns True if the current step is the first step.
*/
match: <State extends Get.Id<Steps>, R>(state: State, matches: Get.Switch<Steps, R>) => R | null;
isFirst: boolean;
/**
* Retrieves the metadata for the current step.
* @returns The metadata for the current step.
* Returns true if the stepper is transitioning.
* @returns True if the stepper is transitioning.
*/
metadata: Record<Get.Id<Steps>, Metadata>;
isTransitioning: boolean;
};
type StepperNavigation<Steps extends Step[] = Step[]> = {
/**
* Sets the metadata for a step.
* @param id - The ID of the step to set the metadata for.
* @param values - The values to set for the metadata.
* Advances to the next step.
* @returns The next step.
*/
setMetadata: <M extends Metadata>(id: Get.Id<Steps>, values: M) => void;
next: () => void | Promise<void>;
/**
* Get the metadata for a step.
* @param id - The ID of the step to get the metadata for.
* @returns The metadata for the step.
* Returns to the previous step.
* @returns The previous step.
*/
getMetadata: <M extends Metadata>(id: Get.Id<Steps>) => M;
prev: () => void | Promise<void>;
/**
* Resets the metadata to the initial state.
* @param keepInitialMetadata - If true, the initial metadata defined in the useStepper hook will be kept.
* Navigates to a specific step by its ID.
* @param id - The ID of the step to navigate to.
* @returns The step to navigate to.
*/
resetMetadata: (keepInitialMetadata?: boolean) => void;
goTo: (id: Get.Id<Steps>) => void | Promise<void>;
/**
* Resets the stepper to its initial state.
* @returns The initial state of the stepper.
*/
reset: () => void;
};
type Utils<Steps extends Step[] = Step[]> = {
type StepperLookup<Steps extends Step[] = Step[]> = {
/**

@@ -136,2 +122,151 @@ * Retrieves all steps.

};
type StepperFlow<Steps extends Step[] = Step[]> = {
/**
* Executes a function based on the current step ID.
* @param id - The ID of the step to check.
* @param whenFn - Function to execute if the current step matches the ID.
* @param elseFn - Optional function to execute if the current step does not match the ID.
* @returns The result of whenFn or elseFn.
*/
when: <Id extends Get.Id<Steps>, R1, R2>(id: Id | [Id, ...boolean[]], whenFn: (step: Get.StepById<Steps, Id>) => R1, elseFn?: (step: Get.StepSansId<Steps, Id>) => R2) => R1 | R2;
/**
* Executes a function based on a switch-case-like structure for steps.
* @param when - An object mapping step IDs to functions.
* @returns The result of the function corresponding to the current step ID.
*/
switch: <R>(when: Get.Switch<Steps, R>) => R;
/**
* Matches the current state with a set of possible states and executes the corresponding function.
* @param state - The current state ID.
* @param matches - An object mapping state IDs to functions.
* @returns The result of the matched function or null if no match is found.
*/
match: <State extends Get.Id<Steps>, R>(state: State, matches: Get.Switch<Steps, R>) => R | null;
/**
* Returns whether the current step has the given ID. Use for conditionals (e.g. `stepper.flow.is("payment")`).
*
* @param id - Step ID to check (e.g. `"shipping"`, `"payment"`).
* @returns `true` if the current step's id equals `id`, otherwise `false`.
*
* @example
* ```ts
* if (stepper.flow.is("payment")) {
* return <PaymentForm />;
* }
* // or in JSX
* {stepper.flow.is("confirmation") && <Summary />}
* ```
*/
is: <Id extends Get.Id<Steps>>(id: Id) => boolean;
};
type StepperMetadata<Steps extends Step[] = Step[]> = {
/**
* The metadata values for each step.
* @returns The metadata values for each step.
*/
values: Record<Get.Id<Steps>, Metadata>;
/**
* Sets the metadata values for a step.
* @param id - The ID of the step to set the metadata values for.
* @param values - The values to set for the metadata.
*/
set: <M extends Metadata>(id: Get.Id<Steps>, values: M) => void;
/**
* Gets the metadata values for a step.
* @param id - The ID of the step to get the metadata values for.
* @returns The metadata values for the step.
*/
get: <M extends Metadata>(id: Get.Id<Steps>) => M;
/**
* Resets the metadata values to the initial state.
* @param keepInitialMetadata - If true, the initial metadata values defined in the useStepper hook will be kept.
*/
reset: (keepInitialMetadata?: boolean) => void;
};
type StepperLifecycle<Steps extends Step[] = Step[]> = {
/**
* Called before a transition occurs.
* @param cb - The callback to call before the transition occurs.
*/
onBeforeTransition: (cb: (ctx: TransitionContext<Steps>) => void | Promise<void | false>) => void;
/**
* Called after a transition occurs.
*/
onAfterTransition: (cb: (ctx: TransitionContext<Steps>) => void | Promise<void>) => void;
};
type TransitionContext<Steps extends Step[] = Step[]> = {
/**
* The step being transitioned from.
*/
from: Steps[number];
/**
* The step being transitioned to.
*/
to: Steps[number];
/**
* The metadata for the transition.
*/
metadata: Record<Get.Id<Steps>, Metadata>;
/**
* The statuses for the transition.
*/
statuses: Record<Get.Id<Steps>, StepStatus>;
/**
* The direction of the transition.
*/
direction: "next" | "prev" | "goTo";
/**
* The index of the step being transitioned from.
*/
fromIndex: number;
/**
* The index of the step being transitioned to.
*/
toIndex: number;
};
/**
* Full stepper API returned by `useStepper` / `defineStepper`. Gives you state, navigation, lookup helpers, flow branching, and step-scoped metadata.
*
* @example
* ```ts
* const stepper = useStepper({ steps: [{ id: "a" }, { id: "b" }] });
* stepper.state.current.data; // current step
* stepper.navigation.next(); // go next
* stepper.lookup.get("b"); // get step by id
* stepper.flow.when("a", () => "on A", () => "else"); // branch by step
* stepper.metadata.set("a", { count: 1 }); // step metadata
* ```
*/
type Stepper<Steps extends Step[] = Step[]> = {
/**
* Read-only state: current step data, index, status (active/inactive/success), and metadata get/set for the active step.
* @example `stepper.state.current.data` — current step; `stepper.state.current.metadata.get()` — current step metadata
*/
state: StepperState<Steps>;
/**
* Imperative navigation: `next()`, `prev()`, `goTo(id)`, `reset()`.
* @example `stepper.navigation.next()` — advance; `stepper.navigation.goTo("confirm")` — jump to step by id
*/
navigation: StepperNavigation<Steps>;
/**
* Step lookup: `getAll()`, `get(id)`, `getIndex(id)`, `getByIndex(i)`, `getFirst` / `getLast` / `getNext` / `getPrev` / `getNeighbors(id)`.
* @example `stepper.lookup.get("summary")` — get step by id; `stepper.lookup.getNext(stepper.state.current.data.id)` — next step
*/
lookup: StepperLookup<Steps>;
/**
* Branch by step id: `when(id, whenFn, elseFn?)`, `switch(when)`, `match(state, matches)`.
* @example `stepper.flow.when("payment", () => <Payment />)` — render by step; `stepper.flow.switch({ payment: () => 1, done: () => 2 })` — switch by id
*/
flow: StepperFlow<Steps>;
/**
* Step-scoped metadata: `values`, `set(id, values)`, `get(id)`, `reset()`.
* @example `stepper.metadata.set("form", { draft: true })` — persist data per step; `stepper.metadata.get("form")` — read it
*/
metadata: StepperMetadata<Steps>;
/**
* Lifecycle hooks: `onBeforeTransition()`, `onAfterTransition()`.
* @example `stepper.lifecycle.onBeforeTransition(() => { console.log("before transition") });` — before transition; `stepper.lifecycle.onAfterTransition(() => { console.log("after transition") });` — after transition
*/
lifecycle: StepperLifecycle<Steps>;
};
declare namespace Get {

@@ -153,2 +288,4 @@ /** Returns a union of possible IDs from the given Steps. */

}
/** Alias for StepperLookup (return type of generateStepperUtils). */
type Utils<Steps extends Step[] = Step[]> = StepperLookup<Steps>;

@@ -165,9 +302,21 @@ /**

getByIndex: <Index extends number>(index: Index) => Steps[Index];
getFirst(): Step;
getLast(): Step;
getNext<Id extends Get.Id<Steps>>(id: Id): Step;
getPrev<Id extends Get.Id<Steps>>(id: Id): Step;
getFirst(): {
id: string;
};
getLast(): {
id: string;
};
getNext<Id extends Get.Id<Steps>>(id: Id): {
id: string;
};
getPrev<Id extends Get.Id<Steps>>(id: Id): {
id: string;
};
getNeighbors<Id extends Get.Id<Steps>>(id: Id): {
prev: Step | null;
next: Step | null;
prev: {
id: string;
} | null;
next: {
id: string;
} | null;
};

@@ -196,19 +345,4 @@ };

*/
declare function generateCommonStepperUseFns<const Steps extends Step[]>(steps: Steps, currentStep: Steps[number], stepIndex: number): Pick<Stepper<Steps>, "switch" | "when" | "match">;
declare function generateCommonStepperUseFns<const Steps extends Step[]>(steps: Steps, currentStep: Steps[number], stepIndex: number): StepperFlow<Steps>;
/**
* This function is used to execute a callback before or after a transition.
* @param stepper - The stepper to execute the transition for.
* @param direction - The direction to execute the transition for.
* @param callback - The callback to execute the transition for.
* @param before - Whether the callback is before the transition.
* @param targetId - The target ID to execute the transition for.
*/
declare const executeTransition: <Steps extends Step[]>({ stepper, direction, callback, before, targetId, }: {
stepper: Stepper<Steps>;
direction: "next" | "prev" | "goTo";
callback: (() => Promise<boolean> | boolean) | (() => Promise<void> | void);
before: boolean;
targetId?: Get.Id<Steps>;
}) => Promise<void>;
/**
* Update the step index.

@@ -221,2 +355,2 @@ * @param steps - The steps to update the step index for.

export { Get, type Metadata, type Step, type Stepper, type Utils, executeTransition, generateCommonStepperUseFns, generateStepperUtils, getInitialMetadata, getInitialStepIndex, updateStepIndex };
export { Get, type Metadata, type Step, type StepStatus, type Stepper, type StepperFlow, type StepperLookup, type StepperMetadata, type StepperNavigation, type StepperState, type Utils, generateCommonStepperUseFns, generateStepperUtils, getInitialMetadata, getInitialStepIndex, updateStepIndex };

@@ -1,1 +0,1 @@

function e(...e){return{getAll:()=>e,get:n=>e.find(e=>e.id===n),getIndex:n=>e.findIndex(e=>e.id===n),getByIndex:n=>e[n],getFirst:()=>e[0],getLast:()=>e[e.length-1],getNext:n=>e[e.findIndex(e=>e.id===n)+1],getPrev:n=>e[e.findIndex(e=>e.id===n)-1],getNeighbors(n){const t=e.findIndex(e=>e.id===n);return{prev:t>0?e[t-1]:null,next:t<e.length-1?e[t+1]:null}}}}function n(e,n){return Math.max(e.findIndex(e=>e.id===n),0)}function t(e,n){return e.reduce((e,t)=>(e[t.id]=n?.[t.id]??null,e),{})}function r(e,n,t){return{switch(e){const t=e[n.id];return t?.(n)},when(n,r,i){const d=e[t];return(Array.isArray(n)?d.id===n[0]&&n.slice(1).every(Boolean):d.id===n)?r?.(d):i?.(d)},match(n,t){const r=e.find(e=>e.id===n);if(!r)return null;const i=t[n];return i?.(r)??null}}}async function i(e,n){const t=await e();return!n||!1!==t}var d=async({stepper:e,direction:n,callback:t,before:r,targetId:d})=>{(!r||await i(t,!0))&&("next"===n?e.next():"prev"===n?e.prev():"goTo"===n&&d&&e.goTo(d),r||await i(t,!1))},o=(e,n,t)=>{n<0&&s({steps:e,newIndex:n,direction:"next",reason:"it is the first step"}),n>=e.length&&s({steps:e,newIndex:n,direction:"prev",reason:"it is the last step"}),t(n)},s=({steps:e,newIndex:n,direction:t,reason:r})=>{const i=e[n]?.id??`index ${n}`;throw new Error(`Cannot navigate ${t} from step "${i}": ${r}`)};export{d as executeTransition,r as generateCommonStepperUseFns,e as generateStepperUtils,t as getInitialMetadata,n as getInitialStepIndex,o as updateStepIndex};
function e(...e){return{getAll:()=>e,get:n=>e.find(e=>e.id===n),getIndex:n=>e.findIndex(e=>e.id===n),getByIndex:n=>e[n],getFirst:()=>e[0],getLast:()=>e[e.length-1],getNext:n=>e[e.findIndex(e=>e.id===n)+1],getPrev:n=>e[e.findIndex(e=>e.id===n)-1],getNeighbors(n){const t=e.findIndex(e=>e.id===n);return{prev:t>0?e[t-1]:null,next:t<e.length-1?e[t+1]:null}}}}function n(e,n){return Math.max(e.findIndex(e=>e.id===n),0)}function t(e,n){return e.reduce((e,t)=>(e[t.id]=n?.[t.id]??null,e),{})}function i(e,n,t){return{switch(e){const t=e[n.id];return t?.(n)},when(n,i,r){const d=e[t];return(Array.isArray(n)?d.id===n[0]&&n.slice(1).every(Boolean):d.id===n)?i?.(d):r?.(d)},match(n,t){const i=e.find(e=>e.id===n);if(!i)return null;const r=t[n];return r?.(i)??null},is:e=>n.id===e}}var r=(e,n,t)=>{n<0&&d({steps:e,newIndex:n,direction:"next",reason:"it is the first step"}),n>=e.length&&d({steps:e,newIndex:n,direction:"prev",reason:"it is the last step"}),t(n)},d=({steps:e,newIndex:n,direction:t,reason:i})=>{const r=e[n]?.id??`index ${n}`;throw new Error(`Cannot navigate ${t} from step "${r}": ${i}`)};export{i as generateCommonStepperUseFns,e as generateStepperUtils,t as getInitialMetadata,n as getInitialStepIndex,r as updateStepIndex};
{
"name": "@stepperize/core",
"version": "1.2.7",
"version": "2.0.0",
"private": false,

@@ -31,9 +31,9 @@ "publishConfig": {

"devDependencies": {
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"jsdom": "^27.0.0",
"tsup": "^8.5.0",
"terser": "^5.44.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"jsdom": "^27.4.0",
"tsup": "^8.5.1",
"terser": "^5.46.0",
"typescript": "^5.9.3",
"vitest": "^4.0.17"
},

@@ -40,0 +40,0 @@ "scripts": {