Skip to content

Instantly share code, notes, and snippets.

@kaze
Last active September 3, 2020 13:13
Show Gist options
  • Save kaze/85317f44e319bb486238fc8a8c25c569 to your computer and use it in GitHub Desktop.
Save kaze/85317f44e319bb486238fc8a8c25c569 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const validate = async () => null;
const should_validate = (context) => {
return (context.value &&
((context.leaving && context.validate) ||
(!context.leaving && context.validated))
)
};
const check = async (context) => {
if (should_validate(context)) {
let validated = true;
let valid = true;
let errors = null;
let result = await validate(context.value, context.validators)
if (result && result.length > 0) {
errors = result;
valid = false;
}
return { valid, validated, errors };
}
return {};
};
const update_value = assign({ value: (context, event) => event.data });
const update_validation_results = assign((context, event) => event.data);
const set_leaving = assign({ leaving: true });
const unset_leaving = assign({ leaving: false });
const validatable = {
id: 'validatable',
initial: 'checking',
states: {
checking: {
invoke: {
src: 'check',
onDone: {
actions: ['update_validation_results'],
target: 'selection',
},
},
},
selection: {
on: {
'': [
{
target: '#input.idle',
cond: 'should_leave',
},
{
target: 'invalid',
cond: 'is_invalid',
},
{
target: 'valid',
cond: 'is_valid',
},
]},
},
invalid: {
on: {
change: {
actions: ['update_value'],
target: 'checking',
},
blur: {
actions: ['set_leaving'],
target: 'checking',
},
},
},
valid: {
on: {
change: {
actions: ['update_value'],
target: 'checking',
},
blur: {
actions: ['set_leaving'],
target: 'checking',
},
},
},
},
};
const fillable = {
id: 'fillable',
initial: 'empty',
states: {
empty: {
always: {
target: 'filled',
cond: 'has_value',
},
on: {
change: {
target: 'filled',
},
},
},
filled: {
on: {
change: {
target: 'empty',
cond: 'is_empty',
},
},
...validatable,
},
// hist: {
// type: 'history',
// history: 'deep',
// target: 'empty',
// },
},
};
const input_machine = Machine(
{
id: 'input',
initial: 'idle',
context: {
value: null,
valid: true,
validate: false,
validated: false,
validators: {},
errors: null,
options: {
id: null,
name: null,
label: null,
field_type: null,
disabled: false,
required: false,
},
// utility states for the machine
leaving: false,
},
states: {
idle: {
on: {
focus: {
actions: ['unset_leaving'],
target: 'focused'
},
},
},
focused: {
...fillable,
},
},
},
{
actions: {
update_value,
update_validation_results,
set_leaving,
unset_leaving,
},
guards: {
is_empty: context => context.value === null,
has_value: context => context.value !== null,
is_valid: context => context.valid === true && context.errors === null,
is_invalid: context => context.valid === false || !context.errors !== null,
should_leave: context => contex.leaving === true,
},
services: {
check,
}
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment