OnboardingView component for Stripe Apps
Use OnboardingView to implement an onboarding flow of your Stripe App
Warning
To add the OnboardingView
component to your app:
import {OnboardingView} from '@stripe/ui-extension-sdk/ui';
The OnboardingView
component provides a standardized way to implement an onboarding view with a predefined structure:
- Left sidebar that renders a list of onboarding tasks
- Main content area that displays the content of a given onboarding step
The list of onboarding tasks is specified as an array of TaskListItemProps items. You can fully customize the content of the onboarding step itself by specifying a custom React view as a direct child of the <OnboardingView>
. This approach lets you implement a custom onboarding step based on your business needs, while the Stripe Dashboard controls the way the list of onboarding tasks renders.
OnboardingView props
Property | Type |
---|---|
| Required
React component that renders the content of the primary column. |
| Required
Whether all onboarding tasks are done |
| Required
A list of onboarding tasks. Related types: Tasks. |
| Required
Onboarding step title. |
| Optional
Onboarding step description. |
Tasks
Property | Type |
---|---|
| Required
The display title of the task. |
| Optional
An event handler for when the user clicks anywhere on the task. |
| Optional
The current status of the task. |
| Optional
A list of sub-tasks that belong to this task. Related types: SubTasks. |
SubTasks
Property | Type |
---|---|
| Required
The display title of the task. |
| Optional
An event handler for when the user clicks anywhere on the task. |
| Optional
The current status of the task. |
Basic
The following example demonstrates the basic usage of the OnboardingView
component, where a different React view is rendered for each onboarding step.
import React, {useState, useReducer, useCallback} from 'react'; import { FormFieldGroup, TextField, OnboardingView, Switch, TaskListItemProps, } from '@stripe/ui-extension-sdk/ui'; const onboardingTasks: Record<TaskName, TaskListItemProps> = { addInfo: { title: 'Add business info', status: 'in-progress', onPress: () => handlePress('addInfo'), }, connectBank: { title: 'Connect your bank', status: 'not-started', onPress: () => handlePress('connectBank'), }, review: { title: 'Review and finish', status: 'not-started', onPress: () => handlePress('review'), }, }; // These view implement the UI required by a particular onboarding step const steps: Record<TaskName, React.FunctionComponent> = { addInfo: () => ( <FormFieldGroup legend="Business Info" description="Add business info"> <TextField label="Company name" placeholder="Company name" hiddenElements={['label']} /> </FormFieldGroup> ), connectBank: () => ( <FormFieldGroup legend="Connect your bank" description="Enter the bank account to which withdrawals will be sent." > <TextField label="Bank name" placeholder="Bank name" hiddenElements={['label']} /> </FormFieldGroup> ), review: () => ( <FormFieldGroup legend="Specify settings" layout="vertical"> <Switch label="Enable automatic transfers" description="Enable automatic transfers" /> <Switch label="Enable auto-import of transactions" description="Enable auto-import of transactions" /> </FormFieldGroup> ), }; const handlePress = useCallback((taskName: TaskName) => { setTaskName(taskName); dispatch({type: 'TOGGLE_STATUS', taskName}); }, []); const [taskName, setTaskName] = useState<TaskName>('addInfo'); const [tasks, dispatch] = useReducer(taskReducer, onboardingTasks); const taskListItems = Object.values(tasks); const title = tasks[taskName].title; const description = `Please complete the onboarding step.`; const completed = taskListItems.every((item) => item.status === 'complete'); const OnboardingViewContent = steps[taskName]; return ( <OnboardingView title={title} description={description} completed={completed} tasks={taskListItems} > <OnboardingViewContent /> </OnboardingView> ); function getNextStatus( status: string, ): 'not-started' | 'in-progress' | 'complete' { switch (status) { case 'complete': return 'not-started'; case 'not-started': return 'in-progress'; case 'in-progress': return 'complete'; default: return 'not-started'; } } type TaskName = 'addInfo' | 'connectBank' | 'review'; type TaskAction = { type: 'TOGGLE_STATUS'; taskName: TaskName; }; // Reducer function to handle state updates function taskReducer( state: Record<TaskName, TaskListItemProps>, action: TaskAction, ): Record<TaskName, TaskListItemProps> { switch (action.type) { case 'TOGGLE_STATUS': return { ...state, [action.taskName]: { ...state[action.taskName], status: getNextStatus(state[action.taskName].status as string), }, }; default: return state; } }