Skip to content

Instantly share code, notes, and snippets.

@Sraleik
Last active July 20, 2022 20:20
Show Gist options
  • Save Sraleik/a8f134bfecbc045c6eea25d5b4525ed1 to your computer and use it in GitHub Desktop.
Save Sraleik/a8f134bfecbc045c6eea25d5b4525ed1 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const buttonMachine = Machine({
key: 'button',
initial: 'activated',
context: {
hasLoading: true,
hasSuccess: false,
hasFailure: false,
isFocused: false,
isMouseIn: false,
isKeyboardIn: false
},
states: {
activated: {
initial: 'basic',
states: {
basic: {
initial: 'idle',
type: 'parallel',
states: {
mouse:{
initial: 'out',
states: {
out:{
entry: assign({isMouseIn: false}),
on: {
MOUSEOVER: 'in',
}
},
in:{
initial: 'hovered',
entry: assign({isMouseIn: true}),
states: {
hovered:{
on: {
MOUSEDOWN: 'active',
}
},
active:{
on: {
MOUSEUP: {
target: 'hovered',
actions: ['emitClick']
},
}
}
},
on: {
MOUSELEAVE: 'out',
}
}
}
},
keyboard:{
initial: 'out',
states: {
out:{
entry: assign({isKeyboardIn: false}),
on: {
FOCUSIN: 'in',
}
},
in:{
initial: 'hovered',
entry: assign({isKeyboardIn: true}),
states: {
hovered:{
on: {
ENTERDOWN: 'active',
}
},
active:{
on: {
ENTERUP: {
target: 'hovered',
actions: ['emitClick']
},
ESCAPE: 'hovered'
}
}
},
on: {
FOCUSOUT: 'out',
}
}
}
},
idle: {
entry: assign({isFocused: false}),
on: {
MOUSEOVER: {
target: 'focused'
},
FOCUSIN: {
target: 'focused'
}
}
},
focused: {
initial: 'hovered',
entry: assign({isFocused: true}),
states: {
hovered: {
on: {
MOUSEDOWN: 'holdingClick',
ENTERDOWN: 'holdingEnter',
}
},
holdingClick: {
on: {
MOUSEUP: {
target: 'hovered',
actions: ['emitClick']
},
}
},
holdingEnter:{
on: {
ENTERUP: {
target: 'hovered',
actions: ['emitClick'],
},
ESCAPE: 'hovered'
}
}
},
on: {
FOCUSOUT: 'idle',
MOUSELEAVE: 'idle',
}
}
},
on:{
LOAD: {
target: 'animated',
cond: (context) => context.hasLoading
}
}
},
animated: {
initial: "loading",
states: {
loading: {
on: {
LOAD_SUCCESS: [{
target: 'success',
cond: (context) => context.hasSuccess
},
{
invoke: {
id: 'sendBack',
src: (context, event) => (callback, onReceive) => {
callback('BACK')
}
},
}
],
LOAD_FAILURE: [{
target: 'failure',
cond: (context) => context.hasFailure
},
{
target: '#button.activated.basic.focused',
cond: (context) => context.isFocused
},
{
target: '#button.activated.basic.idle',
cond: (context) => !context.isFocused
}
]
}
},
success: {
after: {
5000: [{
target: '#button.activated.basic.focused',
cond: (context) => context.isFocused
},
{
target: '#button.activated.basic.idle',
cond: (context) => !context.isFocused
}
]
},
},
failure: {
after: {
5000: [{
target: '#button.activated.basic.focused',
cond: (context) => context.isFocused
},
{
target: '#button.activated.basic.idle',
cond: (context) => !context.isFocused
}
]
},
}
},
on: {
MOUSELEAVE: {
actions: assign({isMouseIn: false}),
},
MOUSEOVER: {
actions: assign({isMouseIn: true}),
},
FOCUSOUT: {
actions: assign({isKeyboardIn: false}),
},
FOCUSIN: {
actions: assign({isKeyboardIn: true}),
},
BACK: [
{
target: ['#button.activated.basic.mouse.in', '#button.activated.basic.keyboard.in'],
cond: (context) => context.isMouseIn && context.isKeyboardIn
},
],
}
}
},
on: {
DEACTIVATE: 'deactivated',
}
},
deactivated: {
on: {
ACTIVATE: 'activated'
}
}
}
}, {
actions: {
emitClick: () => { console.log('click') }
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment