Skip to content

Instantly share code, notes, and snippets.

@gsong
Last active March 3, 2020 12:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gsong/eecb1402e7b7427e9a25159f644bb7d5 to your computer and use it in GitHub Desktop.
Save gsong/eecb1402e7b7427e9a25159f644bb7d5 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const form = {
initial: "editing",
states: {
editing: {
entry: "updateStatus",
on: {
CHANGE: { target: "editing", actions: ["edit"] },
RESET: { target: "editing", actions: ["reset"] },
SUBMIT: { target: "submitting", cond: "submitAllowed" },
},
},
submitting: {
invoke: {
id: "submit",
src: "submit",
onDone: ".resolved",
onError: ".rejected",
},
initial: "pending",
states: {
pending: {},
resolved: { entry: "resolveSubmit", on: { "": "#form.editing" } },
rejected: { entry: "rejectSubmit", on: { "": "#form.editing" } },
},
},
},
};
const hasChanged = context => context.previousValue !== context.value;
const isValid = (_, { value }) => /^[A-Za-z]*$/.test(value);
const formMachine = Machine(
{
id: "form",
context: {
previousValue: "",
value: "",
hasChanged: false,
isValid: true,
submitAllowed: false,
isSuccessful: undefined,
},
...form,
},
{
actions: {
edit: assign({ value: (_, { value }) => value }),
reset: assign({ value: context => context.previousValue, isValid: true }),
updateStatus: assign({
hasChanged,
isValid,
submitAllowed: (context, event) =>
hasChanged(context) && isValid(context, event),
}),
resolveSubmit: assign({
isSuccessful: true,
previousValue: context => context.value,
}),
rejectSubmit: assign({ isSuccessful: false }),
},
guards: { submitAllowed: context => context.submitAllowed },
services: {
submit: context =>
new Promise((resolve, reject) => {
setTimeout(() => {
return context.value.toLowerCase() !== "error"
? resolve()
: reject();
}, 2000);
}),
},
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment