Skip to content

Instantly share code, notes, and snippets.

@alxrocha
Created October 31, 2019 14:29
Show Gist options
  • Save alxrocha/1cedb98f3acdf990f7aa234f44f37858 to your computer and use it in GitHub Desktop.
Save alxrocha/1cedb98f3acdf990f7aa234f44f37858 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const machine = Machine({
id: "menu-button",
initial: "unmounted",
context: {
button: null,
menu: null,
items: [],
search: "",
highlightIndex: -1
},
states: {
unmounted: {
on: {
UPDATE: {
target: "idle",
actions: ["bridgeView"]
}
}
},
idle: {
on: {
BUTTON_POINTER_DOWN: {
target: "clickingButton",
actions: ["resetIndex"]
},
KEYDOWN_SPACE: {
target: "selecting",
actions: ["resetIndex"]
},
KEYDOWN_ENTER: {
target: "selecting",
actions: ["resetIndex"]
},
ARROW_DOWN: {
target: "selecting",
actions: ["highlightFirst"]
},
ARROW_UP: {
target: "selecting",
actions: ["highlightLast"]
},
UPDATE: {
target: "idle",
actions: ["bridgeView"]
}
}
},
selecting: {
entry: ["disableTooltips", "focusMenu"],
exit: ["enableTooltips"],
on: {
KEYDOWN_ESCAPE: {
target: "idle",
actions: ["focusButton"]
},
KEY_ARROW_UP: {
target: "selecting",
actions: ["navigatePrev"]
},
KEY_ARROW_DOWN: {
target: "selecting",
actions: ["navigateNext"]
},
BLUR: {
target: "idle",
cond: clickedNonMenuItem
},
POINTER_ENTER_ITEM: {
target: "selecting",
actions: ["highlightItem"]
},
POINTER_LEAVE_ITEM: {
target: "selecting",
actions: ["resetIndex"]
},
ITEM_POINTER_DOWN: "clickingItem",
SELECT_ITEM_WITH_ENTER: {
target: "idle",
actions: [
"focusButton",
"selectItem"
]
},
SELECT_ITEM_WITH_SPACE: {
target: "idle",
actions: [
"focusButton",
"selectItem"
]
},
KEY_PRESS: {
target: "searching",
actions: ["concatSearch"]
},
HOME: {
target: "selecting",
actions: ["highlightFirst"]
},
END: {
target: "selecting",
actions: ["highlightLast"]
},
UPDATE: {
target: "selecting",
actions: ["bridgeView"]
}
}
},
selectingWithDrag: {
entry: [
"addDocPointerUp",
"disableTooltips"
],
exit: [
"removeDocPointerUp",
"enableTooltips"
],
on: {
POINTER_UP: [
{
target: "idle",
actions: [
"focusButton",
"selectItem"
],
cond: "hasHighlight"
},
{
target: "idle",
actions: ["focusButton"]
}
],
POINTER_ENTER_ITEM: {
target: "selectingWithDrag",
actions: ["highlightItem"]
},
POINTER_LEAVE_ITEM: {
target: "selectingWithDrag",
actions: ["resetIndex"]
},
KEYDOWN_ESCAPE: "idle"
}
},
clickingButton: {
after: {
2000: "selectingWithDrag"
},
on: {
BUTTON_POINTER_UP: 'selecting'
}
},
clickingItem: {
after: {
2000: {
target: "selectingWithDrag"
}
},
on: {
ITEM_POINTER_UP: {
target: "idle",
actions: [
"focusButton",
"selectItem"
]
}
}
},
searching: {
entry: ["setIndexFromSearch"],
after: {
2000: {
target: "selecting",
actions: ["resetSearch"]
}
},
on: {
KEY_PRESS: {
target: "searching",
actions: ["concatSearch"]
}
}
}
}
}, {
guards: {
hasHighlight: () => true
}
});
function bridgeNodesAndEvents() {}
function clickedNonMenuItem(ctx, event) {
// next line is just so it works in the xstate visualizer,
// in an app we'd always have the menu
if (!ctx.menu) return false;
return !ctx.menu.contains(event.relatedTarget);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment