Created
October 12, 2022 17:14
-
-
Save aaronmcadam/46132df7ae1c99266b5d2ad77b7bc4a9 to your computer and use it in GitHub Desktop.
Example of an XState state machine modelling a wizard process
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createModel } from 'xstate/lib/model'; | |
import { GeneralInfoFormValues } from '../create-project-screen/project-wizard/project-wizard-steps/general-info-panel'; | |
import { ArtistInfoFormValues } from '../create-project-screen/project-wizard/project-wizard-steps/artist-info-panel'; | |
import { PlaylistFormValues } from '../create-project-screen/project-wizard/project-wizard-steps/playlist-panel'; | |
import { SocialMediaLinksFormValues } from '../create-project-screen/project-wizard/project-wizard-steps/social-media-links-panel'; | |
export interface ProjectWizardContext { | |
currentStepNumber: number; | |
generalInfo: GeneralInfoFormValues; | |
artistInfo: ArtistInfoFormValues; | |
playlist: PlaylistFormValues; | |
socialMediaLinks: SocialMediaLinksFormValues; | |
} | |
export const projectWizardModel = createModel( | |
{ | |
currentStepNumber: 1, | |
generalInfo: {}, | |
artistInfo: {}, | |
playlist: {}, | |
} as ProjectWizardContext, | |
{ | |
events: { | |
ASSIGN_GENERAL_INFO: (payload: GeneralInfoFormValues) => ({ | |
payload, | |
}), | |
ASSIGN_ARTIST_INFO: (payload: ArtistInfoFormValues) => ({ | |
payload, | |
}), | |
ASSIGN_PLAYLIST: (payload: PlaylistFormValues) => ({ | |
payload, | |
}), | |
ASSIGN_SOCIAL_MEDIA_LINKS: (payload: SocialMediaLinksFormValues) => ({ | |
payload, | |
}), | |
CONTINUE: () => ({}), | |
SKIP: () => ({}), | |
BACK: () => ({}), | |
}, | |
} | |
); | |
const assignGeneralInfo = projectWizardModel.assign( | |
{ | |
generalInfo: (context, event) => { | |
return event.payload; | |
}, | |
}, | |
'ASSIGN_GENERAL_INFO' | |
); | |
const assignArtistInfo = projectWizardModel.assign( | |
{ | |
artistInfo: (context, event) => { | |
return event.payload; | |
}, | |
}, | |
'ASSIGN_ARTIST_INFO' | |
); | |
const assignPlaylist = projectWizardModel.assign( | |
{ | |
playlist: (context, event) => { | |
return event.payload; | |
}, | |
}, | |
'ASSIGN_PLAYLIST' | |
); | |
const assignSocialMediaLinks = projectWizardModel.assign( | |
{ | |
socialMediaLinks: (context, event) => { | |
return event.payload; | |
}, | |
}, | |
'ASSIGN_SOCIAL_MEDIA_LINKS' | |
); | |
const incrementStepNumber = projectWizardModel.assign( | |
{ | |
currentStepNumber: (context, event) => { | |
return context.currentStepNumber + 1; | |
}, | |
}, | |
'CONTINUE' | |
); | |
const decrementStepNumber = projectWizardModel.assign( | |
{ | |
currentStepNumber: (context, event) => { | |
return context.currentStepNumber - 1; | |
}, | |
}, | |
'BACK' | |
); | |
export const projectWizardMachine = projectWizardModel.createMachine({ | |
id: 'projectWizard', | |
initial: 'generalInfo', | |
states: { | |
generalInfo: { | |
on: { | |
ASSIGN_GENERAL_INFO: { | |
actions: [assignGeneralInfo], | |
}, | |
CONTINUE: { | |
target: 'artistInfo', | |
actions: [incrementStepNumber], | |
}, | |
}, | |
}, | |
artistInfo: { | |
on: { | |
ASSIGN_ARTIST_INFO: { | |
actions: [assignArtistInfo], | |
}, | |
CONTINUE: { | |
target: 'playlist', | |
actions: [incrementStepNumber], | |
}, | |
BACK: { | |
target: 'generalInfo', | |
actions: [decrementStepNumber], | |
}, | |
}, | |
}, | |
playlist: { | |
on: { | |
ASSIGN_PLAYLIST: { | |
actions: [assignPlaylist], | |
}, | |
CONTINUE: { | |
target: 'socialMediaLinks', | |
actions: [incrementStepNumber], | |
}, | |
BACK: { | |
target: 'artistInfo', | |
actions: [decrementStepNumber], | |
}, | |
}, | |
}, | |
socialMediaLinks: { | |
on: { | |
ASSIGN_SOCIAL_MEDIA_LINKS: { | |
actions: [assignSocialMediaLinks], | |
}, | |
CONTINUE: 'wizardCompleted', | |
SKIP: 'wizardCompleted', | |
BACK: { | |
target: 'playlist', | |
actions: [decrementStepNumber], | |
}, | |
}, | |
}, | |
wizardCompleted: { | |
type: 'final', | |
entry: ['createProject'], | |
}, | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment