Hook

Access and control your stepper with the useStepper hook

The useStepper hook provides methods to interact with and render your methods.

Unlike the other Stepperize packages, the Solid hook does not require a Provider component as it works as a store through createStore. So you can use it anywhere in your application and you will always have access to the stepper methods of the instance you have defined.

The hook accepts an optional configuration object with the following properties:

  • initialStep The ID of the initial step to display
  • initialMetadata The initial metadata to set for the steps

Usage

import {  } from "@stepperize/solid";
 
const {  } = (
  { : "first", : "First step" },
  { : "second", : "Second step" }
);
 
const  = () => {
  const  = ();
  // Use stepper methods here
};

Rendering Methods

when

The when method allows rendering content conditionally based on the current step. It can take an id of a step (either a string or an array of a step ID followed by booleans) and a whenFn (the function to execute if the step matches). Additionally, you can provide an optional elseFn (the function to execute if the step does not match).

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <>
      {methods.when("first", (step) => (
        <p>First step: {step.title}</p>
      ))}
      {methods.when("second", (step) => (
        <p>Second step: {step.title}</p>
      ))}
    </>
  );
};

You can define more complex conditions that not only depend on the current step's ID but also on additional boolean values. This allows for multi-condition logic where each boolean must evaluate to true for the step to match. The boolean values can represent different state conditions or external factors that affect the step's visibility or behavior.

The first element of the array is the step ID, the following elements are the boolean values.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  const condition1 = true; // or false
  const condition2 = true; // or false
 
  return (
    <>
      {methods.when(["first", condition1, condition2], (step) => (
        <p>First step: {step.title}</p>
      ))}
      {methods.when("second", (step) => (
        <p>Second step: {step.title}</p>
      ))}
    </>
  );
};

switch

The switch method allows you to render content based on the current step's ID, similar to a switch-case structure. This method provides a cleaner and more scalable way to handle different step-specific rendering logic, making it ideal for scenarios where you need to differentiate the UI depending on the current step without writing multiple when conditions.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <>
      {methods.switch({
        first: (step) => <p>First: {step.title}</p>,
        second: (step) => <p>Second: {step.title}</p>,
      })}
    </>
  );
};

match

The match method allows you to render content based on an external state, such as a value fetched from a server or any dynamic state in your application. This provides flexibility for rendering content that is tied not only to the current step in the stepper but also to any other state outside the stepper's context, such as user actions, data from an API, or global application state.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
  const state = "first"; // "Value from server or client state that matches the id of the step";
 
  return (
    <>
      {methods.match(state, {
        first: (step) => <p>First: {step.title}</p>,
        second: (step) => <p>Second: {step.title}</p>,
      })}
    </>
  );
};

match allows state-based control from client or server, useful for frameworks like Remix with server-side state management.

Before/after functions

While the API provides specific functions to move to the previous or next step, there are situations such as form validations where we want to execute actions before or after we move to the previous or next step.

That is why there are the following functions:

  • beforeNext
  • afterNext
  • beforePrev
  • afterPrev
  • beforeGoTo
  • afterGoTo

beforeNext

The beforeNext function allows you to execute a function before moving to the next step. It returns a promise that resolves to a boolean value. If the promise resolves to true, the stepper will move to the next step. If the promise resolves to false, the stepper will not move to the next step.

In case you don't need a promise, you can use the beforeNext returning a boolean value.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() => {
        methods.beforeNext(() => {
          // Your logic here
          return true; // or false
        });
      }}
    >
      Next
    </button>
  );
};

afterNext

The afterNext function allows you to execute a function after moving to the next step. It returns a promise that resolves to a void value.

In case you don't need a promise, you can use the afterNext returning a void value.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() =>
        methods.afterNext(() => {
          // Your logic here
        })
      }
    >
      Next
    </button>
  );
};

beforePrev

The beforePrev function allows you to execute a function before moving to the previous step. It returns a promise that resolves to a boolean value. If the promise resolves to true, the stepper will move to the previous step. If the promise resolves to false, the stepper will not move to the previous step.

In case you don't need a promise, you can use the beforePrev returning a boolean value.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() =>
        methods.beforePrev(() => {
          // Your logic here
          return true; // or false
        })
      }
    >
      Previous
    </button>
  );
};

afterPrev

The afterPrev function allows you to execute a function after moving to the previous step. It returns a promise that resolves to a void value.

In case you don't need a promise, you can use the afterPrev returning a void value.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() =>
        methods.afterPrev(() => {
          // Your logic here
        })
      }
    >
      Previous
    </button>
  );
};

beforeGoTo

The beforeGoTo function allows you to execute a function before moving to a specific step. It returns a promise that resolves to a boolean value. If the promise resolves to true, the stepper will move to the specific step. If the promise resolves to false, the stepper will not move to the specific step.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() =>
        methods.beforeGoTo("first", () => {
          // Your logic here
          return true; // or false
        })
      }
    >
      Go to first step
    </button>
  );
};

afterGoTo

The afterGoTo function allows you to execute a function after moving to a specific step. It returns a promise that resolves to a void value.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <button
      onClick={() =>
        methods.afterGoTo("first", () => {
          // Your logic here
        })
      }
    >
      Go to first step
    </button>
  );
};

Metadata

The metadata is a way to add custom data to a step. It is useful for adding dynamic values to a step, such as a value fetched from a server or any dynamic state in your application.

In order to add metadata to your stepper, you can add initial metadata in the useStepper hook.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper({
    initialMetadata: {
      first: {
        value: "1",
      },
    },
  });
 
  return (
    <>
      <p>First step: {methods.metadata.first?.value}</p>
    </>
  );
};

This metadata will be available in the metadata property of the useStepper hook and you can also use methods to set, get and reset the metadata.

setMetadata

Allows you to set the metadata for a step.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" },
  { id: "last", title: "Last step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  methods.setMetadata("first", {
    value: "1",
  });
 
  return (
    <>
      <p>First step: {methods.metadata.first?.value}</p>
    </>
  );
};

getMetadata

The getMetadata method allows you to get the metadata for a step.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" },
  { id: "last", title: "Last step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
  const metadata = methods.getMetadata("first");
 
  return (
    <>
      <p>First step: {metadata?.value}</p>
    </>
  );
};

resetMetadata

The resetMetadata method allows you to reset the metadata for a step. You can also pass a boolean value to keep the initial metadata defined in the useStepper hook.

import { defineStepper } from "@stepperize/solid";
 
const { useStepper } = defineStepper(
  { id: "first", title: "First step" },
  { id: "second", title: "Second step" },
  { id: "last", title: "Last step" }
);
 
const MyStepperComponent = () => {
  const methods = useStepper();
 
  return (
    <>
      <button onClick={() => methods.resetMetadata(true)}>
        Reset metadata
      </button>
    </>
  );
};

API Reference

NameTypeDescription
allStep[]Returns all steps
currentStepReturns the current step
isLastbooleanReturns true if the current step is the last step
isFirstbooleanReturns true if the current step is the first step
metadataRecord<string, Metadata>Returns the metadata for the current step
setMetadata(id: string, values: Metadata) => voidSets the metadata for a step
getMetadata(id: string) => MetadataReturns the metadata for a step
resetMetadata(keepInitialMetadata?: boolean) => voidResets the metadata. If keepInitialMetadata is true, the initial metadata defined in the useStepper hook will be kept.
beforeNext(callback: () => Promise<boolean> | boolean) => voidExecutes a function before moving to the next step
afterNext(callback: () => Promise<void> | void) => voidExecutes a function after moving to the next step
beforePrev(callback: () => Promise<boolean> | boolean) => voidExecutes a function before moving to the previous step
afterPrev(callback: () => Promise<void> | void) => voidExecutes a function after moving to the previous step
beforeGoTo(id: string, callback: () => Promise<boolean> | boolean) => voidExecutes a function before moving to a specific step
afterGoTo(id: string, callback: () => Promise<void> | void) => voidExecutes a function after moving to a specific step
next() => voidAdvances to the next step
prev() => voidReturns to the previous step
get(id: string) => StepReturns a step by its ID
goTo(id: string) => voidNavigates to a specific step by its ID
reset() => voidResets the stepper to its initial state
when(id: string, whenFn: (step: Step) => JSX.Element, elseFn?: (step: Step) => JSX.Element) => JSX.ElementExecutes a function based on the current step ID
switch(steps: { [id: string]: (step: Step) => JSX.Element }) => JSX.ElementExecutes a function based on a switch-case-like structure for steps
match(state: string, steps: { [id: string]: (step: Step) => JSX.Element }) => JSX.ElementMatches the current state with a set of possible states and executes the corresponding function
Edit on GitHub

Last updated on

On this page