Last active
September 3, 2020 13:21
-
-
Save kaze/86b601bcc01bc03c6d4c75f322b561c8 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
const validate = async () => null; | |
// validation helpers ------------------------------------------------------ // | |
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 {}; | |
}; | |
// machine actions --------------------------------------------------- // | |
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 }); | |
// machine parts ----------------------------------------------------- // | |
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.hist' | |
}, | |
}, | |
}, | |
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 => context.leaving === true, | |
}, | |
services: { | |
check, | |
} | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment