Skip to content

Commit 4de9fd0

Browse files
committed
fix: ensure stop calls do not act like cancel: true
Cancellation can lead to unintended outcomes, like a transition being reset to its previous phase.
1 parent df799a8 commit 4de9fd0

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

packages/core/src/Controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
AnimationResult,
2222
AsyncResult,
2323
} from './AnimationResult'
24-
import { runAsync, RunAsyncState, cancelAsync } from './runAsync'
24+
import { runAsync, RunAsyncState, stopAsync } from './runAsync'
2525
import { scheduleProps } from './scheduleProps'
2626
import {
2727
ControllerFlushFn,
@@ -148,8 +148,8 @@ export class Controller<State extends Lookup = Lookup>
148148
/** Stop one animation, some animations, or all animations */
149149
stop(keys?: OneOrMore<string>) {
150150
if (is.und(keys)) {
151+
stopAsync(this._state)
151152
this.each(spring => spring.stop())
152-
cancelAsync(this._state, this._lastAsyncId)
153153
} else {
154154
const springs = this.springs as Lookup<SpringValue>
155155
each(toArray(keys), key => springs[key].stop())
@@ -349,7 +349,7 @@ export async function flushUpdate(
349349
start(props, resolve) {
350350
let result: AsyncResult | undefined
351351
if (cancel) {
352-
cancelAsync(state, ctrl['_lastAsyncId'])
352+
stopAsync(state, ctrl['_lastAsyncId'])
353353
} else if (!props.cancel) {
354354
props.onRest = onRest as any
355355
result = runAsync(asyncTo!, props, state, ctrl)

packages/core/src/SpringValue.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import * as G from 'shared/globals'
2626
import { Animation } from './Animation'
2727
import { mergeConfig } from './AnimationConfig'
2828
import { scheduleProps } from './scheduleProps'
29-
import { runAsync, RunAsyncState, RunAsyncProps, cancelAsync } from './runAsync'
29+
import { runAsync, RunAsyncState, RunAsyncProps, stopAsync } from './runAsync'
3030
import {
3131
callProp,
3232
computeGoal,
@@ -401,7 +401,7 @@ export class SpringValue<T = any> extends FrameValue<T> {
401401
*/
402402
stop(cancel?: boolean) {
403403
if (!this.is(DISPOSED)) {
404-
cancelAsync(this._state, this._lastCallId)
404+
stopAsync(this._state, cancel && this._lastCallId)
405405

406406
// Ensure the `to` value equals the current value.
407407
this._focus(this.get())

packages/core/src/runAsync.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { is, each } from 'shared'
1+
import { is, each, Falsy } from 'shared'
22
import * as G from 'shared/globals'
33

44
import { PAUSED } from './SpringPhase'
@@ -26,7 +26,7 @@ export interface RunAsyncProps<T = any> extends SpringProps<T> {
2626
to?: any
2727
}
2828

29-
export interface RunAsyncState<T> {
29+
export interface RunAsyncState<T = any> {
3030
pauseQueue: Set<() => void>
3131
resumeQueue: Set<() => void>
3232
asyncId?: number
@@ -182,9 +182,10 @@ export async function runAsync<T>(
182182
})())
183183
}
184184

185-
export function cancelAsync(state: RunAsyncState<any>, callId: number) {
186-
state.cancelId = callId
185+
/** Stop the current `runAsync` call with `finished: false` (or with `cancelled: true` when `cancelId` is defined) */
186+
export function stopAsync(state: RunAsyncState, cancelId?: number | Falsy) {
187187
state.asyncId = state.asyncTo = state.promise = undefined
188+
if (cancelId) state.cancelId = cancelId
188189
}
189190

190191
/** This error is thrown to signal an interrupted async animation. */

0 commit comments

Comments
 (0)