import React , { Dispatch , FC , createContext , useContext , useReducer , } from 'react' ; import { UnreachableCaseError , noop , omit } from '../utils' ; type PreviewState = { currentStep : number ; isPlaying : boolean ; pauseAnimation : boolean ; } ; type PreviewAction = { type : 'setStep' ; step : number ; } | ( { type : 'updatePreviewState' ; } & Partial < PreviewState > ) | { type : 'resetPreviewState' ; } ; const initialPreviewState = { currentStep : 0 , isPlaying : false , pauseAnimation : false , } ; const PreviewStateContext = createContext < PreviewState | undefined > ( undefined ) ; const PreviewDispatchContext = createContext < Dispatch < PreviewAction > | undefined > ( undefined ) ; const previewReducer = ( state , action ) => { switch ( action . type ) { case 'setStep' : return { ... state , currentStep : action . step , isPlaying : false } ; case 'updatePreviewState' : return { ... state , ... omit ( [ 'type' ] , action ) } ; case 'resetPreviewState' : return { ... initialPreviewState } ; default : const { type } = action ; throw new UnreachableCaseError ( type ) ; } } ; export const PreviewProvider = ( { children , initialState , } ) => { const [ state , dispatch ] = useReducer ( previewReducer , { ... initialPreviewState , ... initialState , } ) ; return ( < PreviewStateContext . Provider value = { state } > < PreviewDispatchContext . Provider value = { dispatch ?? noop } > { children } < /PreviewDispatchContext.Provider> < /PreviewStateContext.Provider>); } ; export const usePreviewState = ( ) => { const context = useContext ( PreviewStateContext ) ; if ( context === undefined ) { throw new Error ( 'usePreviewState must be used within a PreviewProvider' ) ; } return context ; } ; export const usePreviewDispatch = ( ) => { const context = useContext ( PreviewDispatchContext ) ; if ( context === undefined ) { throw new Error ( 'usePreviewDispatch must be used within a PreviewProvider' ) ; } return context ; } ;