Skip to content

Commit a3a330d

Browse files
committed
reanimated 3 support
1 parent 225e907 commit a3a330d

13 files changed

+298
-103
lines changed

examples/with-expo/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"react-dom": "17.0.1",
2424
"react-native": "0.64.3",
2525
"react-native-gesture-handler": "~2.1.0",
26-
"react-native-reanimated": "~2.3.1",
26+
"react-native-reanimated": "3.5.4",
2727
"react-native-svg": "13.4.0",
2828
"react-native-unimodules": "~0.15.0",
2929
"react-native-web": "0.17.1"

examples/with-next/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"raf": "^3.4.1",
1111
"react": "17.0.1",
1212
"react-dom": "17.0.1",
13-
"react-native-reanimated": "~2.3.1",
13+
"react-native-reanimated": "3.5.4",
1414
"react-native-unimodules": "~0.9.0",
1515
"react-native-web": "0.15.3"
1616
},

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,13 @@
6868
},
6969
"dependencies": {},
7070
"devDependencies": {
71-
"auto": "^10.13.3",
71+
"@babel/helper-string-parser": "^7.22.5",
7272
"@commitlint/config-conventional": "^11.0.0",
7373
"@manypkg/cli": "^0.17.0",
7474
"@types/jest": "^26.0.15",
7575
"@typescript-eslint/eslint-plugin": "^4.14.1",
7676
"@typescript-eslint/parser": "^4.14.1",
77+
"auto": "^10.13.3",
7778
"babel-jest": "^26.6.1",
7879
"codecov": "^3.8.0",
7980
"commitlint": "^11.0.0",
@@ -83,7 +84,7 @@
8384
"jest": "^26.6.1",
8485
"lerna": "^3.22.1",
8586
"prettier": "^2.2.1",
86-
"typescript": "^4.0.3"
87+
"typescript": "^5.2.0"
8788
},
8889
"author": "Fernando Rojo <frojo@sas.upenn.edu>",
8990
"auto": {

packages/moti/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
"expo-linear-gradient": "^10.0.3",
5454
"expo-module-scripts": "^2.0.0",
5555
"react-native-linear-gradient": "^2.6.2",
56-
"react-native-reanimated": "*",
57-
"typescript": "^4.0.3"
56+
"react-native-reanimated": "3.5.4",
57+
"typescript": "^5.2.0"
5858
},
5959
"react-native-builder-bob": {
6060
"source": "src",

packages/moti/src/core/use-motify.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ function animationDelay<Animate>(
106106
}
107107
}
108108

109+
const withSpringConfigKeys: (keyof WithSpringConfig)[] = [
110+
'stiffness',
111+
'overshootClamping',
112+
'restDisplacementThreshold',
113+
'restSpeedThreshold',
114+
'velocity',
115+
'reduceMotion',
116+
'mass',
117+
'damping',
118+
'duration',
119+
'dampingRatio',
120+
]
121+
109122
function animationConfig<Animate>(
110123
styleProp: string,
111124
transition: MotiTransition<Animate> | undefined
@@ -174,16 +187,7 @@ function animationConfig<Animate>(
174187
} else if (animationType === 'spring') {
175188
animation = withSpring
176189
config = {} as WithSpringConfig
177-
const configKeys: (keyof WithSpringConfig)[] = [
178-
'damping',
179-
'mass',
180-
'overshootClamping',
181-
'restDisplacementThreshold',
182-
'restSpeedThreshold',
183-
'stiffness',
184-
'velocity',
185-
]
186-
for (const configKey of configKeys) {
190+
for (const configKey of withSpringConfigKeys) {
187191
const styleSpecificConfig = transition?.[key]?.[configKey]
188192
const transitionConfigForKey = transition?.[configKey]
189193

@@ -444,7 +448,7 @@ export function useMotify<Animate>({
444448
}
445449

446450
// need to use forEach to work with Hermes...https://github.com/nandorojo/moti/issues/214#issuecomment-1399055535
447-
Object.keys(mergedStyles).forEach((key) => {
451+
Object.keys(mergedStyles as any).forEach((key) => {
448452
let value = mergedStyles[key]
449453

450454
let inlineOnDidAnimate: InlineOnDidAnimate<any> | undefined

packages/moti/src/interactions/pressable/hoverable-context.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { createContext, useContext } from 'react'
2-
import type Animated from 'react-native-reanimated'
2+
import type { SharedValue } from 'react-native-reanimated'
33

4-
const HoveredContext = createContext<Animated.SharedValue<boolean>>({
4+
const HoveredContext = createContext({
55
value: false,
6-
})
6+
} as SharedValue<boolean>)
77

88
const useIsHovered = () => {
99
return useContext(HoveredContext)

packages/moti/src/interactions/pressable/use-moti-pressable-animated-props.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@ import { useFactory } from './use-validate-factory-or-id'
55

66
type Factory<Props> = (interaction: MotiPressableInteractionState) => Props
77

8+
type Deps = unknown[] | null | undefined
9+
810
/**
911
* Replacement for `useAnimatedProps`, which receives the interaction state as the first argument.
1012
* @param factory function that receives the interaction state and returns the props
1113
*/
1214
export function useMotiPressableAnimatedProps<Props>(
1315
id: MotiPressableInteractionIds['id'],
1416
factory: Factory<Props>,
15-
deps?: readonly any[]
17+
deps?: Deps
1618
): Partial<Props>
1719
export function useMotiPressableAnimatedProps<Props>(
1820
factory: Factory<Props>,
19-
deps?: readonly any[]
21+
deps?: Deps
2022
): Partial<Props>
21-
export function useMotiPressableAnimatedProps<Props>(
23+
export function useMotiPressableAnimatedProps<Props extends object>(
2224
factoryOrId: Factory<Props> | MotiPressableInteractionIds['id'],
23-
maybeFactoryOrDeps?: Factory<Props> | readonly any[],
24-
maybeDeps?: readonly any[]
25+
maybeFactoryOrDeps?: Factory<Props> | Deps,
26+
maybeDeps?: Deps
2527
) {
2628
const context = useMotiPressableContext()
2729

packages/moti/src/interactions/pressable/use-moti-pressable-interpolate.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { MotiPressableInteractionState } from './types'
2-
import { useDerivedValue } from 'react-native-reanimated'
3-
import type Animated from 'react-native-reanimated'
2+
import { SharedValue, useDerivedValue } from 'react-native-reanimated'
43
import { MotiPressableInteractionIds, useMotiPressableContext } from './context'
54
import { useFactory } from './use-validate-factory-or-id'
65

76
type Factory<Props> = (interaction: MotiPressableInteractionState) => Props
7+
type Deps = unknown[] | null | undefined
88

99
/**
1010
* `useInterpolateMotiPressable` lets you access the pressable state, and create a reanimated derived value from it.
@@ -74,20 +74,20 @@ type Factory<Props> = (interaction: MotiPressableInteractionState) => Props
7474
export function useInterpolateMotiPressable<Props>(
7575
id: MotiPressableInteractionIds['id'],
7676
factory: Factory<Props>,
77-
deps?: readonly any[]
78-
): Readonly<Animated.SharedValue<Props>>
77+
deps?: Deps
78+
): Readonly<SharedValue<Props>>
7979
export function useInterpolateMotiPressable<Props>(
8080
factory: Factory<Props>,
81-
deps?: readonly any[]
82-
): Readonly<Animated.SharedValue<Props>>
81+
deps?: Deps
82+
): Readonly<SharedValue<Props>>
8383
export function useInterpolateMotiPressable<Props>(
8484
factoryOrId: Factory<Props> | MotiPressableInteractionIds['id'],
85-
maybeFactoryOrDeps?: Factory<Props> | readonly any[],
86-
maybeDeps?: readonly any[]
87-
): Readonly<Animated.SharedValue<Props>> {
85+
maybeFactoryOrDeps?: Factory<Props> | Deps,
86+
maybeDeps?: Deps
87+
): Readonly<SharedValue<Props>> {
8888
const context = useMotiPressableContext()
8989

90-
const { factory, id, deps = [] } = useFactory<Factory<Props>>(
90+
const { factory, id, deps } = useFactory<Factory<Props>>(
9191
'useMotiPressableAnimatedProps',
9292
factoryOrId,
9393
maybeFactoryOrDeps,
@@ -96,5 +96,5 @@ export function useInterpolateMotiPressable<Props>(
9696

9797
return useDerivedValue<Props>(() => {
9898
return context && factory(context.containers[id].value)
99-
}, [...deps, context.containers[id]])
99+
}, [...(deps || []), context.containers[id]])
100100
}

packages/moti/src/interactions/pressable/use-moti-pressable-transition.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import type { MotiPressableInteractionState } from './types'
2-
import { useDerivedValue } from 'react-native-reanimated'
2+
import { SharedValue, useDerivedValue } from 'react-native-reanimated'
33
import type Animated from 'react-native-reanimated'
44
import { MotiPressableInteractionIds, useMotiPressableContext } from './context'
55
import { useFactory } from './use-validate-factory-or-id'
66
import type { MotiTransition } from '../../core'
77

88
type Factory<Props> = (interaction: MotiPressableInteractionState) => Props
9-
9+
type Deps = unknown[] | null | undefined
1010
/**
1111
* `useMotiPressableTransition` lets you access the pressable state, and create a custom moti transition from it.
1212
*
@@ -68,16 +68,16 @@ type Factory<Props> = (interaction: MotiPressableInteractionState) => Props
6868
export function useMotiPressableTransition(
6969
id: MotiPressableInteractionIds['id'],
7070
factory: Factory<MotiTransition>,
71-
deps?: readonly any[]
72-
): Readonly<Animated.SharedValue<MotiTransition>>
71+
deps?: Deps
72+
): Readonly<SharedValue<MotiTransition>>
7373
export function useMotiPressableTransition(
7474
factory: Factory<MotiTransition>,
75-
deps?: readonly any[]
76-
): Readonly<Animated.SharedValue<MotiTransition>>
75+
deps?: Deps
76+
): Readonly<SharedValue<MotiTransition>>
7777
export function useMotiPressableTransition(
7878
factoryOrId: Factory<MotiTransition> | MotiPressableInteractionIds['id'],
79-
maybeFactoryOrDeps?: Factory<MotiTransition> | readonly any[],
80-
maybeDeps?: readonly any[]
79+
maybeFactoryOrDeps?: Factory<MotiTransition> | Deps,
80+
maybeDeps?: Deps
8181
): Readonly<Animated.SharedValue<MotiTransition>> {
8282
const context = useMotiPressableContext()
8383

@@ -90,5 +90,5 @@ export function useMotiPressableTransition(
9090

9191
return useDerivedValue<MotiTransition>(() => {
9292
return context && factory(context.containers[id].value)
93-
}, [context.containers[id], ...deps])
93+
}, [context.containers[id], ...(deps || [])])
9494
}

packages/moti/src/interactions/pressable/use-pressable.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useMemo } from 'react'
66
import { useFactory } from './use-validate-factory-or-id'
77

88
type Id = MotiPressableInteractionIds['id']
9-
9+
type Deps = unknown[] | null | undefined
1010
/**
1111
* `useMotiPressable` lets you access the interaction state of a parent `MotiPressable` component.
1212
*
@@ -71,7 +71,7 @@ function useMotiPressable(
7171
* @worklet
7272
*/
7373
factory: MotiPressableInteractionProp,
74-
maybeDeps?: readonly any[]
74+
maybeDeps?: Deps
7575
): MotiProps['state']
7676
function useMotiPressable(
7777
/**
@@ -83,16 +83,16 @@ function useMotiPressable(
8383
* @worklet
8484
*/
8585
factory: MotiPressableInteractionProp,
86-
maybeDeps?: readonly any[]
86+
maybeDeps?: Deps
8787
): MotiProps['state']
8888
function useMotiPressable(
8989
factoryOrId: MotiPressableInteractionProp | Id,
90-
maybeFactoryOrDeps?: MotiPressableInteractionProp | readonly any[],
91-
maybeDeps?: readonly any[]
90+
maybeFactoryOrDeps?: MotiPressableInteractionProp | Deps,
91+
maybeDeps?: Deps
9292
): MotiProps['state'] {
9393
const context = useMotiPressableContext()
9494

95-
const { factory, id, deps = [] } = useFactory<MotiPressableInteractionProp>(
95+
const { factory, id, deps } = useFactory<MotiPressableInteractionProp>(
9696
'useMotiPressable',
9797
factoryOrId,
9898
maybeFactoryOrDeps,
@@ -103,7 +103,7 @@ function useMotiPressable(
103103
const interaction = context.containers[id]
104104

105105
return interaction && factory(interaction.value)
106-
}, [context, id, context.containers[id], ...deps])
106+
}, [context, id, context.containers[id], ...(deps || [])])
107107

108108
return useMemo(
109109
() => ({

packages/moti/src/interactions/pressable/use-validate-factory-or-id.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import {
66

77
type Id = MotiPressableInteractionIds['id']
88

9+
type Deps = unknown[] | null | undefined
910
type Returns<Factory> = {
1011
id: Id
1112
factory: Factory
12-
deps?: readonly any[]
13+
deps?: Deps
1314
}
1415

1516
type HookName =
@@ -20,8 +21,8 @@ type HookName =
2021
export function useFactory<Factory extends (...props: any[]) => any>(
2122
hookName: HookName,
2223
factoryOrId: Factory | MotiPressableInteractionIds['id'],
23-
maybeFactoryOrDeps?: Factory | readonly any[],
24-
maybeDeps?: readonly any[]
24+
maybeFactoryOrDeps?: Factory | Deps,
25+
maybeDeps?: Deps
2526
): Returns<Factory> {
2627
const context = useMotiPressableContext()
2728
const missingIdError = `
@@ -48,11 +49,11 @@ ${hookName}(({ pressed, hovered }) => {
4849

4950
let factory: Factory
5051
let id: Id = INTERACTION_CONTAINER_ID
51-
let deps: readonly any[] | undefined
52+
let deps: Deps
5253

5354
if (typeof factoryOrId === 'function') {
5455
factory = factoryOrId
55-
deps = maybeFactoryOrDeps as readonly any[] | undefined
56+
deps = maybeFactoryOrDeps as Deps
5657
} else if (typeof maybeFactoryOrDeps === 'function') {
5758
id = factoryOrId
5859
factory = maybeFactoryOrDeps

packages/moti/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"outDir": "./build"
66
},
77
"include": ["./src", "./src/interactions", "./src/author"],
8-
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
8+
"exclude": ["**/__mocks__/*", "**/__tests__/*", "**/*/node_modules/*"]
99
}

0 commit comments

Comments
 (0)