Garuded Transitions, it prevents the state goes from current sate to its target state is condition is falsy.
const machine = createMachine( { initial: "idle", context: { x: 0, y: 0, dx: 0, dy: 0, px: 0, py: 0, drags: 0, }, states: { idle: { on: { mousedown:{ cond: "noMoreThanFiveTimes", actions: assignPoint, target: "dragging", }, }, }, dragging: { entry: countDrags, on: { mousemove: { actions: assignDelta, }, mouseup: { actions: [assignPosition], target: "idle", }, "keyup.escape": { target: "idle", actions: resetPosition, }, }, }, }, }, { guards: { noMoreThanFiveTimes: (context) => { return context.drags >= 5 ? false : true; }, }, } );
In the code, users cannot drag more than 5 times. So it preventing going to 'dragging' state by 'cond: "noMoreThanFiveTimes"'.
So if we cannot go 'dragging' state after five times drags... what should we do then?
We can introduce a final state "draggedOut":
const machine = createMachine( { initial: "idle", context: { x: 0, y: 0, dx: 0, dy: 0, px: 0, py: 0, drags: 0, }, states: { idle: { on: { // if use Array with cond, // for first cond which is false // then it continue to second state 'draggedOut' mousedown: [ { cond: "noMoreThanFiveTimes", actions: assignPoint, target: "dragging", }, { target: "draggedOut", }, ], }, }, draggedOut: { type: "final", }, dragging: { entry: countDrags, on: { mousemove: { actions: assignDelta, }, mouseup: { actions: [assignPosition], target: "idle", }, "keyup.escape": { target: "idle", actions: resetPosition, }, }, }, }, }, { guards: { noMoreThanFiveTimes: (context) => { return context.drags >= 5 ? false : true; }, }, } );
So in 'mousedown' event, we use 'Array' type, so it try first target 'dragging' with condition. If the condition is false, then it will try second target 'draggedOut' which is our final state.