Skip to content

Instantly share code, notes, and snippets.

@philipyoungg
Created December 15, 2019 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save philipyoungg/593cc1e1fecf3b4ee52a73d55284124e to your computer and use it in GitHub Desktop.
Save philipyoungg/593cc1e1fecf3b4ee52a73d55284124e to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// guards
const gteNewDragIndex = (c, e) => c.snapshot.index >= e.newDragIndex;
const gtNewDragIndex = (c, e) => c.snapshot.index > e.newDragIndex;
const lteNewDragIndex = (c, e) => c.snapshot.index <= e.newDragIndex;
const ltNewDragIndex = (c, e) => c.snapshot.index < e.newDragIndex;
const sameDropId = (c, e) => c.snapshot.dropId === e.destinationDropId;
const mismatchType = (c, e) => e.initialSnapshot.dropType !== c.snapshot.dropType;
const identicalToRefId = (c, e) => c.snapshot.id === e.initialSnapshot.dragId;
const isAboveActiveIndex = (c, e) =>
sameDropId(c, e) && e.initialSnapshot.dragIndex > c.snapshot.index;
const isBelowActiveIndex = (c, e) =>
sameDropId(c, e) && e.initialSnapshot.dragIndex < c.snapshot.index;
// actions
const setSnapshot = assign((c, e) => ({ snapshot: e.snapshot }));
const forwardEvent = () => {}
const droppableMachine = Machine(
{
initial: "idle",
context: {
x: 0,
y: 0,
snapshot: {},
animate: false
},
states: {
idle: {
on: {
PREPARE_DRAGGABLE: {
target: "initializing",
actions: [setSnapshot, forwardEvent]
}
}
},
initializing: {
on: {
PREPARE_DRAGGABLE: [
{
target: "dragging.disabled",
cond: "mismatchType"
},
{
target: "dragging.active",
cond: "identicalToRefId"
},
{
target: "dragging.passive_source.above_index",
cond: "isAboveActiveIndex"
},
{
target: "dragging.passive_source.below_index",
cond: "isBelowActiveIndex"
},
{
target: "dragging.passive_destination.idle"
}
]
}
},
dragging: {
on: {
START_ANIMATE: {
actions: assign({ animate: true }),
cond: (c, e) => c.snapshot.id !== e.dragId
}
},
initial: "disabled",
states: {
disabled: {
entry: "updateInitialPos",
type: "final"
},
active: {
initial: "inside_source",
entry: "updateActivePos",
on: {
UPDATE_MOUSE_POS: {
actions: "updateActivePos"
}
},
states: {
prepare: {},
inside_source: {
on: {
ENDING_DRAG: "ending.source",
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
inside_new_source: {
on: {
ENDING_DRAG: "ending.new_source",
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
outside: {
on: {
ENDING_DRAG: "ending.source",
DROPPABLE_MOUSE_ENTER: [
{
target: "inside_source",
cond: "sameDropId"
},
"inside_new_source"
]
}
},
ending: {
initial: "unknown",
entry: assign({ animate: true }),
states: {
unknown: {},
source: {
entry: assign((c, e) => {
const itemSnapshots =
e.draggableSnapshotArrByDropId[e.destinationDropId];
const newPosition = itemSnapshots[e.newDragIndex];
const { scrollingStatus } = e;
const activeIndex = e.initialSnapshot.dragIndex;
const heightOffset =
scrollingStatus === "DOWN" ||
scrollingStatus === "IDLE"
? itemSnapshots
.slice(
activeIndex + 1,
e.newDragIndex + 1
)
.reduce(
(acc, val) => acc + val.height,
0
) + itemSnapshots[activeIndex].y
: itemSnapshots[e.newDragIndex].y;
// window.scrollY +
// e.initialSnapshot.offsetY;
return { x: newPosition.x, y: heightOffset };
}),
type: "final"
},
new_source: {
entry: assign((c, e) => {
const { x, y } = e.temporaryDraggableSnapshot[
e.newDragIndex
];
return { x, y };
}),
type: "final"
}
}
}
}
},
passive_source: {
states: {
above_index: {
initial: "idle",
states: {
idle: {
entry: "updateInitialPos",
on: {
UPDATE_MOUSE_POS: {
target: "shifted",
cond: "gteNewDragIndex",
actions: "shiftPassiveSourceAboveIndex"
},
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
shifted: {
on: {
UPDATE_MOUSE_POS: {
target: "idle",
cond: "ltNewDragIndex"
},
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
outside: {
entry: "updateInitialPos",
on: {
DROPPABLE_MOUSE_ENTER: {
target: "idle",
cond: "sameDropId"
},
ENDING_DRAG: {
target: "idle",
cond: "sameDropId"
}
}
}
}
},
below_index: {
initial: "idle",
states: {
idle: {
entry: "updateInitialPos",
on: {
UPDATE_MOUSE_POS: {
target: "shifted",
cond: "lteNewDragIndex",
actions: "shiftPassiveSourceBelowIndex"
},
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
shifted: {
on: {
UPDATE_MOUSE_POS: {
target: "idle",
cond: "gtNewDragIndex"
},
DROPPABLE_MOUSE_LEAVE: "outside"
}
},
outside: {
entry: "updateInitialPosMinusActiveHeight",
on: {
DROPPABLE_MOUSE_ENTER: {
target: "idle",
cond: "sameDropId"
},
ENDING_DRAG: {
target: "idle",
cond: "sameDropId"
}
}
}
}
}
}
},
passive_destination: {
initial: "idle",
states: {
idle: {
entry: "updateInitialPos",
on: {
DROPPABLE_MOUSE_ENTER: {
actions: [
"assignTemporarySnapshot",
],
target: "condition",
cond: "sameDropId"
}
}
},
condition: {
on: {
PREPARE_DRAGGABLE: [
{
target: "below_index",
},
{
target: "above_index",
}
]
}
},
above_index: {
initial: "idle",
on: {
DROPPABLE_MOUSE_LEAVE: {
actions: "resetSnapshot",
target: "idle"
}
},
states: {
idle: {
entry: "updateInitialPos",
on: {
UPDATE_MOUSE_POS: {
target: "shifted",
cond: "gteNewDragIndex",
actions: "shiftPassiveSourceAboveIndex"
}
}
},
shifted: {
on: {
UPDATE_MOUSE_POS: {
target: "idle",
cond: "ltNewDragIndex"
}
}
}
}
},
below_index: {
initial: "idle",
on: {
DROPPABLE_MOUSE_LEAVE: {
actions: "resetSnapshot",
target: "idle"
}
},
states: {
idle: {
entry: "updateInitialPos",
on: {
UPDATE_MOUSE_POS: {
target: "shifted",
cond: "lteNewDragIndex",
actions: "shiftPassiveSourceBelowIndex"
}
}
},
shifted: {
on: {
UPDATE_MOUSE_POS: {
target: "idle",
cond: "gtNewDragIndex"
}
}
}
}
}
}
}
}
}
}
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment