View Docs
Using Overlay

Using Overlay

Overlay example

The overlay is used to display UI such as modals, bottom sheets, and similar components. while maintaining the previous step as shown in the image on the right.

In the following example, when moving from the "School Input" step to the "Start Date Input" step, an overlay is used. When the <StartDateInputBottomSheet /> component is rendered, the UI of the previous step <SchoolInput /> is remains visible.

<funnel.Render
  SchoolInput={({ history }) => (
    <SchoolInput
      onNext={(school) => history.push('StartDateInput', { school })}
    />
  )}
  StartDateInput={funnel.Render.overlay({
    render({ history, close }) {
      return (
        <StartDateInputBottomSheet
          onNext={(startDate) => history.push('NextStep', { startDate })}
          onClose={() => close()}
        />
      );
    }
  })}
/>
⚠️

Note: If the overlay is closed by an interaction other than the router's back button, you need to explicitly execute close() in the render() argument. Executing close() will navigate to the previous step through the history.

Example

import { useFunnel } from "@use-funnel/react-router-dom";
import { OverlayProvider } from "overlay-kit";

import { SchoolInput } from "./SchoolInput";
import { StartDateInputBottomSheet } from "./StartDateInputBottomSheet";

export const Example = () => {
  const funnel = useFunnel<{
    SchoolInput: { school?: string };
    StartDateInput: { school: string; startDate?: string };
    NextStep: { school: string; startDate: string };
  }>({
    id: "overlay-example",
    initial: {
      step: "SchoolInput",
      context: {},
    },
  });

  return (
    <OverlayProvider>
      <funnel.Render
        SchoolInput={({ history }) => (
          <SchoolInput
            onNext={(school) => history.push('StartDateInput', { school })}
          />
        )}
        StartDateInput={funnel.Render.overlay({
          render({ history, close }) {
            return (
              <StartDateInputBottomSheet
                onNext={(startDate) => history.push('NextStep', { startDate })}
                onClose={() => close()}
              />
            );
          }
        })}
      />
    </OverlayProvider>
  );
};
💡

Note: The overlay-kit library is used in the example above. You can use any overlay library you prefer.

Overlay with event example

To define an overlay along with transition events, use the events property.

In the following example, the "Email Input" step uses transition events and an overlay together. Define the "Email Input Complete" and "Email Input Fail" events, and trigger the transition to the next step for each event.

<funnel.Render
  EmailInput={funnel.Render.overlay({
    events: {
      EmailInputComplete: (email: string, { history }) => history.push('PasswordInput', { email }),
      EmailInputFail: (error: Error, { history }) => history.push('ErrorPage', { error: error.message })
    },
    render({ context, dispatch }) {
      return (
        <EmailInput
          email={context.email}
          onNext={(email) => dispatch('EmailInputComplete', email)}
          onError={(error) => dispatch('EmailInputFail', error)}
        />
      );
    }
  })}
/>
⚠️

You cannot use history in the rendering function when defining events. Instead, you should trigger the events defined in the events object using dispatch().