@use-funnel
is a React Hook that helps you easily implement complex UI flows.
By comparing the type of the current step with the next, you can ensure that only the required states are managed safely.
Manage states based on history, making it easy to handle backward and forward navigation.
Supports browser history, react-router-dom, next.js, @react-navigation/native, and more.
use-funnel-example.mp4
import { useFunnel } from '@use-funnel/react-router-dom';
export function App() {
const funnel = useFunnel<{
SelectJob: { jobType?: 'STUDENT' | 'EMPLOYEE' };
SelectSchool: { jobType: 'STUDENT'; school?: string };
SelectEmployee: { jobType: 'EMPLOYEE'; company?: string };
EnterJoinDate: { jobType: 'STUDENT'; school: string } | { jobType: 'EMPLOYEE'; company: string };
Confirm: ({ jobType: 'STUDENT'; school: string } | { jobType: 'EMPLOYEE'; company: string }) & { joinDate: string };
}>({
id: 'hello-world',
initial: {
step: 'SelectJob',
context: {},
},
});
return (
<funnel.Render
SelectJob={funnel.Render.with({
events: {
selectSchool: (_, { history }) => history.push('SelectSchool', { jobType: 'STUDENT' }),
selectEmployee: (_, { history }) => history.push('SelectEmployee', { jobType: 'EMPLOYEE' }),
},
render({ dispatch }) {
return (
<SelectJob
onSelectSchool={() => dispatch('selectSchool')}
onSelectEmployee={() => dispatch('selectEmployee')}
/>
);
},
})}
SelectSchool={({ history }) => (
<SelectSchool
onNext={(school) =>
history.push('EnterJoinDate', (prev) => ({
...prev,
school
}))
}
/>
)}
SelectEmployee={({ history }) => (
<SelectEmployee
onNext={(company) =>
history.push('EnterJoinDate', (prev) => ({
...prev,
company,
}))
}
/>
)}
EnterJoinDate={funnel.Render.overlay({
render({ history, close }) {
return (
<EnterJoinDateBottomSheet
onNext={(joinDate) => history.push('Confirm', { joinDate })}
onClose={() => close()}
/>
);
},
})}
Confirm={({ context }) =>
context.jobType === 'STUDENT' ? (
<ConfirmStudent school={context.school} joinDate={context.joinDate} />
) : (
<ConfirmEmployee company={context.company} joinDate={context.joinDate} />
)
}
/>
);
}
declare function SelectJob(props: { onSelectSchool(): void; onSelectEmployee(): void }): JSX.Element;
declare function SelectSchool(props: { onNext(school: string): void }): JSX.Element;
declare function SelectEmployee(props: { onNext(company: string): void }): JSX.Element;
declare function EnterJoinDateBottomSheet(props: { onNext(joinDate: string): void; onClose(): void }): JSX.Element;
declare function ConfirmStudent(props: { school: string; joinDate: string }): JSX.Element;
declare function ConfirmEmployee(props: { company: string; joinDate: string }): JSX.Element;
Visit use-funnel.slash.page for docs, guides, API and more!
Read our Contributing Guide to familiarize yourself with @use-funnel
development process, how to suggest bug fixes and improvements, and the steps for building and testing your changes.
MIT © Viva Republica, Inc. See LICENSE for details.