Created
December 16, 2019 23:41
-
-
Save cevr/f2f83bbd2ba3bd2ba1d9b9153abcaaf3 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
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
// Available variables: | |
// - Machine | |
// - interpret | |
// - assign | |
// - send | |
// - sendParent | |
// - spawn | |
// - raise | |
// - actions | |
// - XState (all XState exports) | |
const FormMachineTypes = { | |
FOCUS : 'FOCUS', | |
BLUR : 'BLUR', | |
CHANGE : 'CHANGE', | |
SUBMIT : 'SUBMIT', | |
} | |
const fetchMachine = Machine( { | |
id: 'form', | |
initial: 'idle', | |
context: { | |
values: {}, | |
errors: {}, | |
refs: {}, | |
}, | |
states: { | |
idle: { | |
initial: 'noError', | |
on: { | |
[FormMachineTypes.CHANGE]: [ | |
{ | |
target: 'idle.error', | |
cond: 'hasErrors', | |
actions: ['resetError', 'setValue'], | |
}, | |
{ | |
target: 'idle.noError', | |
actions: ['resetError', 'setValue'], | |
}, | |
], | |
[FormMachineTypes.BLUR]: 'validatingField', | |
[FormMachineTypes.SUBMIT]: '#form.validating', | |
}, | |
states: { | |
noError: {}, | |
error: {}, | |
submitError: {}, | |
}, | |
}, | |
validatingField: { | |
invoke: { | |
src: 'validateField', | |
onDone: 'idle.noError', | |
onError: { | |
target: 'idle.error', | |
actions: ['setErrors', 'focusInput'], | |
}, | |
}, | |
}, | |
validating: { | |
entry: ['resetErrors'], | |
invoke: { | |
src: 'validate', | |
onDone: 'submitting', | |
onError: { | |
target: 'idle.error', | |
actions: ['setErrors', 'focusInput'], | |
}, | |
}, | |
}, | |
submitting: { | |
invoke: { | |
src: 'handleSubmit', | |
onDone: { | |
actions: 'onSubmit', | |
target: 'submitted', | |
}, | |
onError: { | |
target: 'idle.submitError', | |
actions: 'setSubmitError', | |
}, | |
}, | |
}, | |
submitted: { | |
type: 'final', | |
}, | |
}, | |
}, | |
{ | |
guards: { | |
hasErrors: context => Object.values(context.errors).some(Boolean), | |
}, | |
actions: { | |
setValue: assign((context, event) => ({ | |
values: { | |
...context.values, | |
[event.name]: event.value, | |
}, | |
})), | |
setErrors: assign({ | |
errors: (context, event) => ({ | |
...context.errors, | |
...event.data, | |
}), | |
}), | |
focusInput: (context, event) => { | |
// this will look at the first input and focus it for some pleasant UX | |
const first = Object.keys(event.data)[0]; | |
context.refs[first].current.focus() | |
}, | |
// this looks at the fetch error message | |
setSubmitError: assign({ | |
errors: (context, event) => ({ | |
...context.errors, | |
submit: event.data.message, | |
}), | |
}), | |
// when validating field, ensure no stale error passes through | |
resetError: assign({ | |
errors: (context, event) => { | |
if (!context.errors[event.name]) return context.errors; | |
return { | |
...context.errors, | |
[event.name]: undefined, | |
}; | |
}, | |
}), | |
// when validating, ensure no stale errors pass through | |
resetErrors: assign({ | |
errors: {}, | |
}), | |
}, | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment