Skip to content

Instantly share code, notes, and snippets.

@sukima
Last active May 9, 2024 23:55
Show Gist options
  • Save sukima/42abdd6e14fdf514db1b65076e4230e7 to your computer and use it in GitHub Desktop.
Save sukima/42abdd6e14fdf514db1b65076e4230e7 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
function createMachine() {
return Machine({
id: 'example-form-manager',
type: 'parallel',
context: {
canSelectNone: true,
advancedProtocol: '',
ip4Address: '',
ip6Address: ''
},
states: {
'addressFamily': {
initial: 'protocolSynced',
states: {
'protocolSynced': {
id: 'protocolSynced',
initial: 'none',
on: {
PICK_FAMILY: [
{ target: '.ip4', cond: 'isFamilyIP4' },
{ target: '.ip6', cond: 'isFamilyIP6' },
{ target: '.none', cond: 'canSelectNone' },
]
},
states: {
'ip4': {
entry: ['setFamilyPickerToIP4', 'resetIP4Address'],
exit: 'cacheIP4Address',
on: {
PICK_PROTOCOL: {
target: 'ip6',
cond: 'isProtocolICMP6'
},
PICK_MANUAL_PROTOCOL: {
target: '#manualSynced.ip6',
cond: 'isProtocolICMP6'
}
}
},
'ip6': {
entry: ['setFamilyPickerToIP6', 'resetIP6Address'],
exit: 'cacheIP6Address',
on: {
PICK_PROTOCOL: { target: 'ip4', cond: 'isProtocolICMP4' },
PICK_MANUAL_PROTOCOL: {
target: '#manualSynced.ip4',
cond: 'isProtocolICMP4'
}
}
},
'none': {
on: {
PICK_PROTOCOL: [
{ target: 'ip4', cond: 'isProtocolICMP4' },
{ target: 'ip6', cond: 'isProtocolICMP6' }
],
PICK_MANUAL_PROTOCOL: [
{ target: '#manualSynced.ip4', cond: 'isProtocolICMP4' },
{ target: '#manualSynced.ip6', cond: 'isProtocolICMP6' }
]
}
},
'hist': { type: 'history' }
}
},
'manualSynced': {
id: 'manualSynced',
states: {
'ip4': {
entry: ['setFamilyPickerToIP4', 'resetIP4Address'],
exit: 'cacheIP4Address',
on: {
PICK_PROTOCOL: [
{
target: '#protocolSynced.ip6',
cond: 'isProtocolICMP6'
},
{ target: '#protocolSynced.hist' }
],
PICK_MANUAL_PROTOCOL: [
{
target: '',
cond: 'isProtocolICMP4'
},
{
target: 'ip6',
cond: 'isProtocolICMP6'
},
{ target: '#protocolSynced.hist' }
]
}
},
'ip6': {
entry: ['setFamilyPickerToIP6', 'resetIP6Address'],
exit: 'cacheIP6Address',
on: {
PICK_PROTOCOL: [
{
target: '#protocolSynced.ip4',
cond: 'isProtocolICMP4'
},
{ target: '#protocolSynced.hist' }
],
PICK_MANUAL_PROTOCOL: [
{
target: '',
cond: 'isProtocolICMP6'
},
{
target: 'ip4',
cond: 'isProtocolICMP4'
},
{ target: '#protocolSynced.hist' }
]
}
}
}
}
}
},
'protocol': {
initial: 'any',
states: {
'icmp4': {
entry: [
'lockFamilyNone',
'setProtocolPickerToICMP4',
'assignAdvancedInputICMP4'
],
exit: [
'unlockFamilyNone',
'resetAdvancedInput'
],
on: {
PICK_FAMILY: { target: 'icmp6', cond: 'isFamilyIP6' },
}
},
'icmp6': {
entry: [
'lockFamilyNone',
'setProtocolPickerToICMP6',
'assignAdvancedInputICMP6'
],
exit: [
'unlockFamilyNone',
'resetAdvancedInput'
],
on: {
PICK_FAMILY: { target: 'icmp4', cond: 'isFamilyIP4' }
}
},
'advanced': {
exit: 'cacheAdvancedInput'
},
'other': {},
'any': {}
},
on: {
PICK_PROTOCOL: [
{ target: '.icmp4', cond: 'isProtocolICMP4' },
{ target: '.icmp6', cond: 'isProtocolICMP6' },
{ target: '.any', cond: 'isProtocolAny' },
{ target: '.advanced', cond: 'isProtocolAdvanced' },
{ target: '.other' },
]
}
}
}
}, {
actions: {
lockFamilyNone: assign({ canSelectNone: false }),
unlockFamilyNone: assign({ canSelectNone: true }),
},
guards: {
canSelectNone: ctx => ctx.canSelectNone,
isFamilyIP4: (_, { value }) => value === 'ip4',
isFamilyIP6: (_, { value }) => value === 'ip6',
isFamilyNone: (_, { value }) => value === 'none',
isProtocolICMP4: (_, { value }) => ['icmp4', '1'].includes(value),
isProtocolICMP6: (_, { value }) => ['icmp6', '58'].includes(value),
isProtocolAdvanced: (_, { value }) => value === 'advanced',
isProtocolAny: (_, { value }) => value === 'any'
}
});
}
createMachine();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment