Skip to content

Commit 7f4debd

Browse files
committed
fix: merging of default cancel and pause props
1 parent 1993df1 commit 7f4debd

File tree

4 files changed

+34
-27
lines changed

4 files changed

+34
-27
lines changed

packages/core/src/Controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { is, each, OneOrMore, toArray, UnknownProps, noop } from 'shared'
22
import * as G from 'shared/globals'
33

44
import { Lookup, Falsy } from './types/common'
5-
import { inferTo, flush, isDefaultProp } from './helpers'
5+
import { inferTo, flush, hasDefaultProp } from './helpers'
66
import { FrameValue } from './FrameValue'
77
import { SpringPhase, CREATED, ACTIVE, IDLE } from './SpringPhase'
88
import { SpringValue, createLoopUpdate, createUpdate } from './SpringValue'
@@ -308,7 +308,7 @@ export function flushUpdate(
308308
}
309309
// Prevent `cancel: true` from ending the current `runAsync` call,
310310
// except when the default `cancel` prop is being set.
311-
else if (isDefaultProp(props, 'cancel')) {
311+
else if (hasDefaultProp(props, 'cancel')) {
312312
cancelAsync(state, props.callId)
313313
}
314314
},

packages/core/src/SpringValue.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
inferTo,
3939
flush,
4040
mergeDefaultProps,
41+
getDefaultProp,
4142
} from './helpers'
4243
import { FrameValue, isFrameValue } from './FrameValue'
4344
import {
@@ -516,22 +517,24 @@ export class SpringValue<T = any> extends FrameValue<T> {
516517

517518
/** Schedule an animation to run after an optional delay */
518519
protected _update(props: SpringUpdate<T>, isLoop?: boolean): AsyncResult<T> {
520+
type DefaultProps = typeof defaultProps
519521
const defaultProps = this._defaultProps
520-
521-
// Set the default `cancel` prop first, because it prevents other default
522-
// props in this update from being cached.
523-
if (props.default && !is.und(props.cancel)) {
524-
defaultProps.cancel = props.cancel
525-
}
526-
// The default `cancel` prop overrides all updates.
527-
else if (defaultProps.cancel) {
528-
props.cancel = true
529-
}
530-
// The default `pause` prop overrides all updates.
531-
if (defaultProps.pause) {
532-
props.pause = true
522+
const mergeDefaultProp = (key: keyof DefaultProps) => {
523+
const value = getDefaultProp(props, key)
524+
if (!is.und(value)) {
525+
defaultProps[key] = value as any
526+
}
527+
// For `cancel` and `pause`, a truthy default always wins.
528+
if (defaultProps[key]) {
529+
props[key] = defaultProps[key] as any
530+
}
533531
}
534532

533+
// These props are coerced into booleans by the `scheduleProps` function,
534+
// so they need their default values processed before then.
535+
mergeDefaultProp('cancel')
536+
mergeDefaultProp('pause')
537+
535538
// Ensure the initial value can be accessed by animated components.
536539
const range = this._prepareNode(props)
537540

@@ -596,7 +599,7 @@ export class SpringValue<T = any> extends FrameValue<T> {
596599
onDelayEnd(props, this)
597600
}
598601

599-
mergeDefaultProps(defaultProps, props)
602+
mergeDefaultProps(defaultProps, props, ['pause', 'cancel'])
600603

601604
const { to: prevTo, from: prevFrom } = anim
602605
let { to = prevTo, from = prevFrom } = range

packages/core/src/helpers.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,32 @@ export const getProps = <T, Arg = never>(
5050
(is.fun(props) ? props(i, arg) : is.arr(props) ? props[i] : { ...props })
5151

5252
/** Returns `true` if the given prop is having its default value set. */
53-
export const isDefaultProp = <T extends Lookup>(props: T, key: keyof T) =>
54-
!is.und(
55-
props.default === true ? props[key] : props.default && props.default[key]
56-
)
53+
export const hasDefaultProp = <T extends Lookup>(props: T, key: keyof T) =>
54+
!is.und(getDefaultProp(props, key))
55+
56+
/** Get the default value being set for the given `key` */
57+
export const getDefaultProp = <T extends Lookup>(props: T, key: keyof T) =>
58+
props.default === true
59+
? props[key]
60+
: props.default
61+
? props.default[key]
62+
: undefined
5763

5864
export const mergeDefaultProps = (
5965
defaultProps: Lookup,
60-
props: Lookup & { default?: boolean | Lookup }
66+
props: Lookup & { default?: boolean | Lookup },
67+
omitKeys: string[] = []
6168
) => {
6269
if (props.default === true) {
6370
each(DEFAULT_PROPS, key => {
6471
const value = props[key]
65-
if (!is.und(value)) {
72+
if (!is.und(value) && !omitKeys.includes(key)) {
6673
defaultProps[key] = value as any
6774
}
6875
})
6976
} else if (props.default) {
7077
each(props.default, (value, key) => {
71-
if (!is.und(value)) {
78+
if (!is.und(value) && !omitKeys.includes(key)) {
7279
defaultProps[key] = value as any
7380
}
7481
})

packages/core/src/runAsync.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,7 @@ export async function runAsync<T>(
7272
let result!: AnimationResult
7373

7474
const defaultProps: SpringDefaultProps<T> = {}
75-
mergeDefaultProps(defaultProps, props)
76-
77-
// The `onRest` prop is for `runAsync` to call.
78-
defaultProps.onRest = undefined
75+
mergeDefaultProps(defaultProps, props, ['onRest'])
7976

8077
const { callId, onRest } = props
8178
const throwInvalidated = () => {

0 commit comments

Comments
 (0)