An open API service indexing awesome lists of open source software.

https://github.com/toss/use-funnel

A powerful and safe step-by-step state management library at React
https://github.com/toss/use-funnel

funnel react wizard-steps

Last synced: about 1 year ago
JSON representation

A powerful and safe step-by-step state management library at React

Awesome Lists containing this project

README

          

# @use-funnel




@use-funnel



A powerful and safe step-by-step state management library


[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/toss/use-funnel/blob/main/LICENSE) [![Discord Badge](https://discord.com/api/guilds/1281071127052943361/widget.png?style=shield)](https://discord.gg/vGXbVjP2nY)

`@use-funnel` is a [React Hook](https://react.dev/reference/rules/rules-of-hooks) that helps you easily implement complex UI flows.

## Core Concepts

### Strong Type Support

By comparing the type of the current step with the next, you can ensure that only the required states are managed safely.

### State Management by History

Manage states based on history, making it easy to handle backward and forward navigation.

### Various Router Support

Supports browser history, react-router, next.js, @react-navigation/native, and more.

## Example

https://github.com/user-attachments/assets/8300d4ed-ab02-436e-a5a6-99c8d732e32f

```tsx
import { useFunnel } from '@use-funnel/browser';

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 (
history.push('SelectSchool', { jobType: 'STUDENT' }),
selectEmployee: (_, { history }) => history.push('SelectEmployee', { jobType: 'EMPLOYEE' }),
},
render({ dispatch }) {
return (
dispatch('selectSchool')}
onSelectEmployee={() => dispatch('selectEmployee')}
/>
);
},
})}
SelectSchool={({ history }) => (

history.push('EnterJoinDate', (prev) => ({
...prev,
school,
}))
}
/>
)}
SelectEmployee={({ history }) => (

history.push('EnterJoinDate', (prev) => ({
...prev,
company,
}))
}
/>
)}
EnterJoinDate={funnel.Render.overlay({
render({ history, close }) {
return (
history.push('Confirm', { joinDate })}
onClose={() => close()}
/>
);
},
})}
Confirm={({ context }) =>
context.jobType === 'STUDENT' ? (

) : (

)
}
/>
);
}

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](https://use-funnel.slash.page) for docs, guides, API and more!

[English](https://use-funnel.slash.page/en) | [한국어](https://use-funnel.slash.page/ko)

## Contributing

Read our [Contributing Guide](./CONTRIBUTING.md) to familiarize yourself with `@use-funnel` development process, how to suggest bug fixes and improvements, and the steps for building and testing your changes.




Toss

MIT © Viva Republica, Inc. See [LICENSE](./LICENSE) for details.