diff --git a/.github/workflows/check-expo-dev-client-nightly.yml b/.github/workflows/check-expo-dev-client-nightly.yml new file mode 100644 index 000000000000..2fdbbd64a3f0 --- /dev/null +++ b/.github/workflows/check-expo-dev-client-nightly.yml @@ -0,0 +1,83 @@ +name: Check Expo dev-client nightly build +on: + pull_request: + paths: + - .github/workflows/check-expo-dev-client-nightly.yml + schedule: + - cron: '37 19 * * *' + workflow_dispatch: + +env: + SCRIPT_PATH: reanimated_repo/.github/workflows/helper/configureDevClient.js + +jobs: + build_ios: + runs-on: macos-12 + strategy: + matrix: + react-native-architecture: ['Paper', 'Fabric'] + fail-fast: false + concurrency: + group: ios-expo-dev-client-${{ matrix.react-native-architecture }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Check out reanimated repository + uses: actions/checkout@v3 + with: + path: 'reanimated_repo' + - name: Create Expo app + run: npx create-expo-app app + - name: Install expo-dev-client + working-directory: app + run: npm install expo-dev-client@next + - name: Setup configuration + run: node ${{ env.SCRIPT_PATH }} setBundleIdentifier + - name: Expo prebuild + working-directory: app + run: npx expo prebuild + - name: Install Reanimated + working-directory: app + run: npm install github:software-mansion/react-native-reanimated + - name: Set Fabric + if: ${{ matrix.react-native-architecture == 'Fabric' }} + run: node ${{ env.SCRIPT_PATH }} setupFabricIOS + - name: Install Pods + working-directory: app/ios + run: pod install + - name: Build app + working-directory: app + run: yarn react-native run-ios --simulator='iPhone 14' + + build_android: + runs-on: ubuntu-latest + strategy: + matrix: + react-native-architecture: ['Paper', 'Fabric'] + fail-fast: false + concurrency: + group: android-expo-dev-client-${{ matrix.react-native-architecture }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Check out reanimated repository + uses: actions/checkout@v3 + with: + path: 'reanimated_repo' + - name: Create Expo app + run: npx create-expo-app app + - name: Install expo-dev-client + working-directory: app + run: npm install expo-dev-client@next + - name: Setup configuration + run: node ${{ env.SCRIPT_PATH }} setBundleIdentifier + - name: Expo prebuild + working-directory: app + run: npx expo prebuild + - name: Install Reanimated + working-directory: app + run: npm install github:software-mansion/react-native-reanimated + - name: Set Fabric + if: ${{ matrix.react-native-architecture == 'Fabric' }} + run: node ${{ env.SCRIPT_PATH }} setupFabricAndroid + - name: Build app + working-directory: app/android + run: ./gradlew assembleDebug --console=plain diff --git a/.github/workflows/check-react-native-nightly.yml b/.github/workflows/check-react-native-nightly.yml new file mode 100644 index 000000000000..afd19dabe094 --- /dev/null +++ b/.github/workflows/check-react-native-nightly.yml @@ -0,0 +1,64 @@ +name: Check React Native nightly build +on: + pull_request: + paths: + - .github/workflows/check-react-native-nightly.yml + schedule: + - cron: '37 19 * * *' + workflow_dispatch: + +jobs: + build_ios: + runs-on: macos-12 + strategy: + matrix: + react-native-architecture: ['Paper', 'Fabric'] + fail-fast: false + concurrency: + group: ios-react-native-nightly-${{ matrix.react-native-architecture }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Create app + run: npx react-native init app --skip-install --version nightly + - name: Install Reanimated + working-directory: app + run: yarn add github:software-mansion/react-native-reanimated + - name: Install Paper Pods + if: ${{ matrix.react-native-architecture == 'Paper' }} + working-directory: app/ios + run: pod install + - name: Install Fabric Pods + if: ${{ matrix.react-native-architecture == 'Fabric' }} + working-directory: app/ios + run: export RCT_NEW_ARCH_ENABLED=1 && pod install + - name: Build app + working-directory: app + run: yarn react-native run-ios --simulator='iPhone 14' + + build_android: + runs-on: ubuntu-latest + strategy: + matrix: + react-native-architecture: ['Paper', 'Fabric'] + fail-fast: false + concurrency: + group: android-react-native-nightly-${{ matrix.react-native-architecture }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Set up JDK 18 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '18' + - name: Create app + run: npx react-native init app --skip-install --version nightly + - name: Install Reanimated + working-directory: app + run: yarn add github:software-mansion/react-native-reanimated + - name: Setup Fabric + if: ${{ matrix.react-native-architecture == 'Fabric' }} + working-directory: app/android + run: sed -i 's/newArchEnabled=false/newArchEnabled=true/' gradle.properties + - name: Build app + working-directory: app/android + run: ./gradlew assembleDebug --console=plain diff --git a/.github/workflows/helper/configureDevClient.js b/.github/workflows/helper/configureDevClient.js new file mode 100644 index 000000000000..ef45903c8b3e --- /dev/null +++ b/.github/workflows/helper/configureDevClient.js @@ -0,0 +1,39 @@ +fs = require('fs'); + +function patchFile(path, find, replace) { + let data = fs.readFileSync(path, 'utf8'); + data = data.replace(find, replace); + fs.writeFileSync(path, data); +} + +const command = process.argv[2]; + +if (command === 'setBundleIdentifier') { + patchFile( + 'app/app.json', + '"ios": {', + '"ios": {"bundleIdentifier":"com.swmansion.app",' + ); + + patchFile( + 'app/app.json', + '"android": {', + '"android": {"package": "com.swmansion.app",' + ); +} + +if (command === 'setupFabricIOS') { + patchFile( + 'app/ios/Podfile.properties.json', + '"expo.jsEngine"', + '"newArchEnabled":"true","expo.jsEngine"' + ); +} + +if (command === 'setupFabricAndroid') { + patchFile( + 'app/android/gradle.properties', + 'newArchEnabled=false', + 'newArchEnabled=true' + ); +} diff --git a/.husky/pre-commit b/.husky/pre-commit index 5f6ac8b5d6a5..ed1b4584fdb4 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -3,6 +3,7 @@ yarn lint-staged yarn type:check +yarn find-unused-code:js # This automatically builds Reanimated Babel plugin JavaScript files if their # TypeScript counterparts were changed. It also adds those files to the commit diff --git a/README.md b/README.md index cb842eab43f8..3b16a2087b0b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,11 @@ comes to gesture based interactions. ### Nightly CI state -[![Build nightly npm package](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-nightly-npm-package.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-nightly-npm-package.yml) [![Run nightly monorepo test](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-monorepo-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-monorepo-nightly.yml) [![Check static framework nightly build](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-static-framework-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-static-framework-nightly.yml) +[![Build nightly npm package](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-nightly-npm-package.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-nightly-npm-package.yml) +[![Run nightly monorepo test](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-monorepo-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/build-monorepo-nightly.yml) +[![Check static framework nightly build](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-static-framework-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-static-framework-nightly.yml) +[![Check React Native nightly build](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-react-native-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-react-native-nightly.yml) +[![Check Expo dev-client nightly build](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-expo-dev-client-nightly.yml/badge.svg)](https://github.com/software-mansion/react-native-reanimated/actions/workflows/check-expo-dev-client-nightly.yml) ## Installation diff --git a/ios/LayoutReanimation/REAAnimationsManager.m b/ios/LayoutReanimation/REAAnimationsManager.m index 9bd2360c4aa9..682129ca7ac7 100644 --- a/ios/LayoutReanimation/REAAnimationsManager.m +++ b/ios/LayoutReanimation/REAAnimationsManager.m @@ -77,6 +77,22 @@ - (instancetype)initWithUIManager:(RCTUIManager *)uiManager } _sharedTransitionManager = [[REASharedTransitionManager alloc] initWithAnimationsManager:self]; _reaSwizzledUIManager = [[REASwizzledUIManager alloc] initWithUIManager:uiManager withAnimationManager:self]; + + _startAnimationForTag = ^(NSNumber *tag, LayoutAnimationType type, NSDictionary *yogaValues) { + // default implementation, this block will be replaced by a setter + }; + _hasAnimationForTag = ^(NSNumber *tag, LayoutAnimationType type) { + // default implementation, this block will be replaced by a setter + return NO; + }; + _clearAnimationConfigForTag = ^(NSNumber *tag) { + // default implementation, this block will be replaced by a setter + }; +#ifdef DEBUG + _checkDuplicateSharedTag = ^(UIView *view, NSNumber *viewTag) { + // default implementation, this block will be replaced by a setter + }; +#endif } return self; } diff --git a/ios/native/REAInitializer.h b/ios/native/REAInitializer.h index 66898e8f4ef3..c6fc3264d743 100644 --- a/ios/native/REAInitializer.h +++ b/ios/native/REAInitializer.h @@ -18,6 +18,10 @@ NS_ASSUME_NONNULL_BEGIN namespace reanimated { +[[deprecated( + "REAInitializer method is no longer required, you can just remove invocation.")]] void +REAInitializer(RCTBridge *bridge); + #if REACT_NATIVE_MINOR_VERSION <= 71 [[deprecated( "REAJSIExecutorRuntimeInstaller method is no longer required, you can just remove invocation.")]] JSIExecutor:: diff --git a/ios/native/REAInitializer.mm b/ios/native/REAInitializer.mm index b2ad7d2b7adb..fa786df76119 100644 --- a/ios/native/REAInitializer.mm +++ b/ios/native/REAInitializer.mm @@ -4,6 +4,11 @@ namespace reanimated { +void REAInitializer(RCTBridge *bridge) +{ + // do nothing, just for backward compatibility +} + #if REACT_NATIVE_MINOR_VERSION <= 71 JSIExecutor::RuntimeInstaller REAJSIExecutorRuntimeInstaller( diff --git a/src/Animated.ts b/src/Animated.ts index 900b0b0d823a..2be1167c2735 100644 --- a/src/Animated.ts +++ b/src/Animated.ts @@ -1,13 +1,87 @@ -export { default as createAnimatedComponent } from './createAnimatedComponent'; -export { - addWhitelistedNativeProps, - addWhitelistedUIProps, +import type { Extrapolate as _Extrapolate } from './reanimated2/interpolateColor'; +import type { SharedValue as _SharedValue } from './reanimated2/commonTypes'; +import type { DerivedValue as _DerivedValue } from './reanimated2/hook/useDerivedValue'; +import type { + TransformStyleTypes as _TransformStyleTypes, + Adaptable as _Adaptable, + AdaptTransforms as _AdaptTransforms, + AnimatedTransform as _AnimatedTransform, + AnimateStyle as _AnimateStyle, + StylesOrDefault as _StylesOrDefault, + AnimateProps as _AnimateProps, +} from './reanimated2/helperTypes'; +import type { EasingFunction as _EasingFunction } from './reanimated2/Easing'; +import { + addWhitelistedNativeProps as _addWhitelistedNativeProps, + addWhitelistedUIProps as _addWhitelistedUIProps, } from './ConfigHelper'; +import type { AnimatedScrollViewProps as _AnimatedScrollViewProps } from './reanimated2/component/ScrollView'; +import type { FlatListPropsWithLayout as _FlatListPropsWithLayout } from './reanimated2/component/FlatList'; +export { default as createAnimatedComponent } from './createAnimatedComponent'; export { AnimatedText as Text } from './reanimated2/component/Text'; export { AnimatedView as View } from './reanimated2/component/View'; export { AnimatedScrollView as ScrollView } from './reanimated2/component/ScrollView'; export { AnimatedImage as Image } from './reanimated2/component/Image'; export { ReanimatedFlatList as FlatList } from './reanimated2/component/FlatList'; -export type { SharedValue } from './reanimated2/commonTypes'; -export type { AnimateStyle } from './reanimated2/helperTypes'; +/** + * @deprecated Please import `Extrapolate` directly from `react-native-reanimated` instead of `Animated` namespace. + */ +export type Extrapolate = typeof _Extrapolate; +/** + * @deprecated Please import `SharedValue` directly from `react-native-reanimated` instead of `Animated` namespace. + */ + +export type SharedValue = _SharedValue; +/** + * @deprecated Please import `DerivedValue` directly from `react-native-reanimated` instead of `Animated` namespace. + */ +export type DerivedValue = _DerivedValue; +/** + * @deprecated Please import `Adaptable` directly from `react-native-reanimated` instead of `Animated` namespace. + */ +export type Adaptable = _Adaptable; +/** + * @deprecated Please import `TransformStyleTypes` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type TransformStyleTypes = _TransformStyleTypes; +/** + * @deprecated Please import `AdaptTransforms` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type AdaptTransforms = _AdaptTransforms; +/** + * @deprecated Please import `AnimatedTransform` directly from `react-native-reanimated` instead of `Animated` namespace. + */ +export type AnimatedTransform = _AnimatedTransform; +/** + * @deprecated Please import `AnimateStyle` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type AnimateStyle = _AnimateStyle; +/** + * @deprecated Please import `StylesOrDefault` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type StylesOrDefault = _StylesOrDefault; +/** + * @deprecated Please import `AnimateProps` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type AnimateProps

= _AnimateProps

; +/** + * @deprecated Please import `EasingFunction` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type EasingFunction = _EasingFunction; +/** + * @deprecated Please import `addWhitelistedNativeProps` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export const addWhitelistedNativeProps = _addWhitelistedNativeProps; +/** + * @deprecated Please import `addWhitelistedUIProps` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export const addWhitelistedUIProps = _addWhitelistedUIProps; +/** + * @deprecated Please import `AnimatedScrollViewProps` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type AnimatedScrollViewProps = _AnimatedScrollViewProps; +/** + * @deprecated Please import `FlatListPropsWithLayout` directly from `react-native-reanimated` instead of `Animated` namespace. + * */ +export type FlatListPropsWithLayout = _FlatListPropsWithLayout; diff --git a/src/JSPropUpdater.ts b/src/JSPropUpdater.ts new file mode 100644 index 000000000000..387ca22b0760 --- /dev/null +++ b/src/JSPropUpdater.ts @@ -0,0 +1,65 @@ +import { + NativeEventEmitter, + NativeModules, + findNodeHandle, +} from 'react-native'; +import { nativeShouldBeMock } from './reanimated2/PlatformChecker'; +import { StyleProps } from './reanimated2'; + +interface ListenerData { + viewTag: number; + props: StyleProps; +} + +export class JSPropUpdater { + private static _tagToComponentMapping = new Map(); + private _reanimatedEventEmitter: NativeEventEmitter; + private static _reanimatedModuleMock = { + async addListener(): Promise { + // noop + }, + async removeListeners(): Promise { + // noop + }, + }; + + private static _listener(data: ListenerData) { + const component = JSPropUpdater._tagToComponentMapping.get(data.viewTag); + component && component._updateFromNative(data.props); + } + + constructor() { + let reanimatedModule: typeof JSPropUpdater._reanimatedModuleMock; + if (nativeShouldBeMock()) { + reanimatedModule = JSPropUpdater._reanimatedModuleMock; + } else { + reanimatedModule = NativeModules.ReanimatedModule; + } + this._reanimatedEventEmitter = new NativeEventEmitter(reanimatedModule); + } + + public addOnJSPropsChangeListener( + animatedComponent: React.Component + ) { + const viewTag = findNodeHandle(animatedComponent); + JSPropUpdater._tagToComponentMapping.set(viewTag, animatedComponent); + if (JSPropUpdater._tagToComponentMapping.size === 1) { + this._reanimatedEventEmitter.addListener( + 'onReanimatedPropsChange', + JSPropUpdater._listener + ); + } + } + + public removeOnJSPropsChangeListener( + animatedComponent: React.Component + ) { + const viewTag = findNodeHandle(animatedComponent); + JSPropUpdater._tagToComponentMapping.delete(viewTag); + if (JSPropUpdater._tagToComponentMapping.size === 0) { + this._reanimatedEventEmitter.removeAllListeners( + 'onReanimatedPropsChange' + ); + } + } +} diff --git a/src/createAnimatedComponent.tsx b/src/createAnimatedComponent.tsx index dc379d5706b1..09401e2c7204 100644 --- a/src/createAnimatedComponent.tsx +++ b/src/createAnimatedComponent.tsx @@ -53,6 +53,7 @@ import NativeReanimatedModule from './reanimated2/NativeReanimated'; import { isSharedValue } from './reanimated2'; import type { AnimateProps } from './reanimated2/helperTypes'; import { removeFromPropsRegistry } from './reanimated2/PropsRegistry'; +import { JSPropUpdater } from './JSPropUpdater'; function dummyListener() { // empty listener we use to assign to listener properties for which animated @@ -286,6 +287,7 @@ export default function createAnimatedComponent( _inlinePropsMapperId: number | null = null; _inlineProps: StyleProps = {}; _sharedElementTransition: SharedTransition | null = null; + _JSPropUpdater = new JSPropUpdater(); static displayName: string; constructor(props: AnimatedComponentProps) { @@ -297,6 +299,7 @@ export default function createAnimatedComponent( componentWillUnmount() { this._detachNativeEvents(); + this._JSPropUpdater.removeOnJSPropsChangeListener(this); this._detachStyles(); this._detachInlineProps(); this._sharedElementTransition?.unregisterTransition(this._viewTag); @@ -304,6 +307,7 @@ export default function createAnimatedComponent( componentDidMount() { this._attachNativeEvents(); + this._JSPropUpdater.addOnJSPropsChangeListener(this); this._attachAnimatedStyles(); this._attachInlineProps(); } diff --git a/src/reanimated2/Easing.ts b/src/reanimated2/Easing.ts index 754fa12c4fa4..cf8f9348305c 100644 --- a/src/reanimated2/Easing.ts +++ b/src/reanimated2/Easing.ts @@ -46,9 +46,19 @@ import { Bezier } from './Bezier'; * - [`out`](docs/easing.html#out) runs an easing function backwards */ -export type EasingFn = (t: number) => number; +export type EasingFunction = (t: number) => number; -export type EasingFactoryFn = { factory: () => EasingFn }; +/** + * @deprecated Please use `EasingFunction` type instead. + */ +export type EasingFn = EasingFunction; + +export type EasingFunctionFactory = { factory: () => EasingFunction }; + +/** + * @deprecated Please use `EasingFunctionFactory` type instead. + */ +export type EasingFactoryFn = EasingFunctionFactory; /** * A linear function, `f(t) = t`. Position correlates to elapsed time one to * one. @@ -99,7 +109,7 @@ function cubic(t: number): number { * n = 4: http://easings.net/#easeInQuart * n = 5: http://easings.net/#easeInQuint */ -function poly(n: number): EasingFn { +function poly(n: number): EasingFunction { 'worklet'; return (t) => { 'worklet'; @@ -147,7 +157,7 @@ function exp(t: number): number { * * http://easings.net/#easeInElastic */ -function elastic(bounciness = 1): EasingFn { +function elastic(bounciness = 1): EasingFunction { 'worklet'; const p = bounciness * Math.PI; return (t) => { @@ -232,7 +242,7 @@ function bezierFn( /** * Runs an easing function forwards. */ -function in_(easing: EasingFn): EasingFn { +function in_(easing: EasingFunction): EasingFunction { 'worklet'; return easing; } @@ -240,7 +250,7 @@ function in_(easing: EasingFn): EasingFn { /** * Runs an easing function backwards. */ -function out(easing: EasingFn): EasingFn { +function out(easing: EasingFunction): EasingFunction { 'worklet'; return (t) => { 'worklet'; @@ -253,7 +263,7 @@ function out(easing: EasingFn): EasingFn { * forwards for half of the duration, then backwards for the rest of the * duration. */ -function inOut(easing: EasingFn): EasingFn { +function inOut(easing: EasingFunction): EasingFunction { 'worklet'; return (t) => { 'worklet'; @@ -270,7 +280,7 @@ function inOut(easing: EasingFn): EasingFn { * steps in the animation, and the `roundToNextStep` parameter determines whether the animation * should start at the beginning or end of each step. */ -function steps(n = 10, roundToNextStep = true): EasingFn { +function steps(n = 10, roundToNextStep = true): EasingFunction { 'worklet'; return (t) => { 'worklet'; diff --git a/src/reanimated2/UpdateProps.ts b/src/reanimated2/UpdateProps.ts index bbd7b5721a9c..496f55ce9bce 100644 --- a/src/reanimated2/UpdateProps.ts +++ b/src/reanimated2/UpdateProps.ts @@ -1,11 +1,7 @@ import type { MutableRefObject } from 'react'; import { processColor } from './Colors'; -import type { - AnimatedStyle, - ShadowNodeWrapper, - SharedValue, - StyleProps, -} from './commonTypes'; +import type { ShadowNodeWrapper, SharedValue, StyleProps } from './commonTypes'; +import type { AnimatedStyle } from './helperTypes'; import { makeShareable } from './core'; import type { Descriptor } from './hook/commonTypes'; import { _updatePropsJS } from './js-reanimated'; @@ -35,7 +31,7 @@ export const ColorProperties = makeShareable(colorProps); let updateProps: ( viewDescriptor: SharedValue, - updates: StyleProps | AnimatedStyle, + updates: StyleProps | AnimatedStyle, maybeViewRef: ViewRefSet | undefined ) => void; @@ -63,10 +59,10 @@ if (shouldBeUseWeb()) { export const updatePropsJestWrapper = ( viewDescriptors: SharedValue, - updates: AnimatedStyle, + updates: AnimatedStyle, maybeViewRef: ViewRefSet | undefined, - animatedStyle: MutableRefObject, - adapters: ((updates: AnimatedStyle) => void)[] + animatedStyle: MutableRefObject>, + adapters: ((updates: AnimatedStyle) => void)[] ): void => { adapters.forEach((adapter) => { adapter(updates); @@ -87,12 +83,12 @@ const createUpdatePropsManager = global._IS_FABRIC // Fabric const operations: { shadowNodeWrapper: ShadowNodeWrapper; - updates: StyleProps | AnimatedStyle; + updates: StyleProps | AnimatedStyle; }[] = []; return { update( viewDescriptors: SharedValue, - updates: StyleProps | AnimatedStyle + updates: StyleProps | AnimatedStyle ) { viewDescriptors.value.forEach((viewDescriptor) => { operations.push({ @@ -117,12 +113,12 @@ const createUpdatePropsManager = global._IS_FABRIC const operations: { tag: number; name: string; - updates: StyleProps | AnimatedStyle; + updates: StyleProps | AnimatedStyle; }[] = []; return { update( viewDescriptors: SharedValue, - updates: StyleProps | AnimatedStyle + updates: StyleProps | AnimatedStyle ) { viewDescriptors.value.forEach((viewDescriptor) => { operations.push({ @@ -151,7 +147,7 @@ runOnUIImmediately(() => { export interface UpdatePropsManager { update( viewDescriptors: SharedValue, - updates: StyleProps | AnimatedStyle + updates: StyleProps | AnimatedStyle ): void; flush(): void; } diff --git a/src/reanimated2/animation/commonTypes.ts b/src/reanimated2/animation/commonTypes.ts index 4262907864b7..d2aecfc34125 100644 --- a/src/reanimated2/animation/commonTypes.ts +++ b/src/reanimated2/animation/commonTypes.ts @@ -1,5 +1,4 @@ import type { - AnimatedStyle, StyleProps, AnimatableValue, AnimationObject, @@ -7,6 +6,7 @@ import type { Timestamp, AnimationCallback, } from '../commonTypes'; +import type { AnimatedStyle } from '../helperTypes'; export interface HigherOrderAnimation { isHigherOrder?: boolean; @@ -40,11 +40,11 @@ export interface SequenceAnimation export interface StyleLayoutAnimation extends HigherOrderAnimation { current: StyleProps; - styleAnimations: AnimatedStyle; + styleAnimations: AnimatedStyle; onFrame: (animation: StyleLayoutAnimation, timestamp: Timestamp) => boolean; onStart: ( nextAnimation: StyleLayoutAnimation, - current: AnimatedStyle, + current: AnimatedStyle, timestamp: Timestamp, previousAnimation: StyleLayoutAnimation ) => void; diff --git a/src/reanimated2/animation/decay.ts b/src/reanimated2/animation/decay.ts index 1b3194b28336..a941cc4dc3fb 100644 --- a/src/reanimated2/animation/decay.ts +++ b/src/reanimated2/animation/decay.ts @@ -15,6 +15,8 @@ interface DecayConfig { velocity?: number; } +export type WithDecayConfig = DecayConfig; + interface DefaultDecayConfig { deceleration: number; velocityFactor: number; diff --git a/src/reanimated2/animation/index.ts b/src/reanimated2/animation/index.ts index b1b0ca59c635..28efdacdd3cd 100644 --- a/src/reanimated2/animation/index.ts +++ b/src/reanimated2/animation/index.ts @@ -8,10 +8,10 @@ export type { } from './commonTypes'; export { cancelAnimation, defineAnimation, initialUpdaterRun } from './util'; export { withTiming } from './timing'; -export type { TimingAnimation } from './timing'; +export type { TimingAnimation, WithTimingConfig } from './timing'; export { withSpring } from './spring'; -export type { SpringAnimation } from './springUtils'; -export { withDecay } from './decay'; +export type { SpringAnimation, WithSpringConfig } from './springUtils'; +export { withDecay, WithDecayConfig } from './decay'; export type { DecayAnimation } from './decay'; export { withDelay } from './delay'; export { withRepeat } from './repeat'; diff --git a/src/reanimated2/animation/springUtils.ts b/src/reanimated2/animation/springUtils.ts index b5ba2c1bf6aa..e6d8b663d881 100644 --- a/src/reanimated2/animation/springUtils.ts +++ b/src/reanimated2/animation/springUtils.ts @@ -21,6 +21,8 @@ export type SpringConfig = { } ); +export type WithSpringConfig = SpringConfig; + export interface SpringConfigInner { useDuration: boolean; configIsInvalid: boolean; diff --git a/src/reanimated2/animation/styleAnimation.ts b/src/reanimated2/animation/styleAnimation.ts index 48c32d4b974f..cd85fd58fb6f 100644 --- a/src/reanimated2/animation/styleAnimation.ts +++ b/src/reanimated2/animation/styleAnimation.ts @@ -4,10 +4,10 @@ import type { AnimatableValue, AnimationObject, Animation, - AnimatedStyle, NestedObject, NestedObjectValues, } from '../commonTypes'; +import type { AnimatedStyle } from '../helperTypes'; import type { StyleLayoutAnimation } from './commonTypes'; import { withTiming } from './timing'; import { ColorProperties } from '../UpdateProps'; @@ -71,7 +71,7 @@ interface NestedObjectEntry { } export function withStyleAnimation( - styleAnimations: AnimatedStyle + styleAnimations: AnimatedStyle ): StyleLayoutAnimation { 'worklet'; return defineAnimation({}, () => { @@ -143,7 +143,7 @@ export function withStyleAnimation( const onStart = ( animation: StyleLayoutAnimation, - value: AnimatedStyle, + value: AnimatedStyle, now: Timestamp, previousAnimation: StyleLayoutAnimation ): void => { diff --git a/src/reanimated2/animation/timing.ts b/src/reanimated2/animation/timing.ts index 8e00c8b67b7e..878a3baa7c9b 100644 --- a/src/reanimated2/animation/timing.ts +++ b/src/reanimated2/animation/timing.ts @@ -1,4 +1,4 @@ -import type { EasingFn, EasingFactoryFn } from '../Easing'; +import type { EasingFunction, EasingFunctionFactory } from '../Easing'; import { Easing } from '../Easing'; import { defineAnimation } from './util'; import type { @@ -10,12 +10,14 @@ import type { interface TimingConfig { duration?: number; - easing?: EasingFn | EasingFactoryFn; + easing?: EasingFunction | EasingFunctionFactory; } +export type WithTimingConfig = TimingConfig; + export interface TimingAnimation extends Animation { type: string; - easing: EasingFn; + easing: EasingFunction; startValue: AnimatableValue; startTime: Timestamp; progress: number; diff --git a/src/reanimated2/commonTypes.ts b/src/reanimated2/commonTypes.ts index 80f0ba8bbb7e..e4e546b989ea 100644 --- a/src/reanimated2/commonTypes.ts +++ b/src/reanimated2/commonTypes.ts @@ -37,31 +37,6 @@ export interface StyleProps extends ViewStyle, TextStyle { [key: string]: any; } -export interface AnimatedStyle extends Record { - [key: string]: any; - transform?: Array< - | Record<'matrix', number[] | AnimationObject> - | Partial< - Record< - | 'perspective' - | 'scale' - | 'scaleX' - | 'scaleY' - | 'translateX' - | 'translateY', - number | AnimationObject - > - > - | Partial< - Record< - 'rotate' | 'rotateX' | 'rotateY' | 'rotateZ' | 'skewX' | 'skewY', - string | AnimationObject - > - > - | Record - >; -} - export interface SharedValue { value: T; addListener: (listenerID: number, listener: (value: T) => void) => void; diff --git a/src/reanimated2/component/FlatList.tsx b/src/reanimated2/component/FlatList.tsx index d4f2eedab0ea..d923e275295c 100644 --- a/src/reanimated2/component/FlatList.tsx +++ b/src/reanimated2/component/FlatList.tsx @@ -41,6 +41,8 @@ interface ReanimatedFlatListPropsWithLayout extends FlatListProps { itemLayoutAnimation?: ILayoutAnimationBuilder; } +export type FlatListPropsWithLayout = ReanimatedFlatListPropsWithLayout; + // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. declare class ReanimatedFlatListClass extends Component< AnimateProps> diff --git a/src/reanimated2/component/ScrollView.tsx b/src/reanimated2/component/ScrollView.tsx index d9f2749946f3..482ad0c21099 100644 --- a/src/reanimated2/component/ScrollView.tsx +++ b/src/reanimated2/component/ScrollView.tsx @@ -7,7 +7,7 @@ import type { SharedValue } from '../commonTypes'; import type { AnimateProps } from '../helperTypes'; import { useAnimatedRef, useScrollViewOffset } from '../hook'; -interface AnimatedScrollViewProps extends ScrollViewProps { +export interface AnimatedScrollViewProps extends ScrollViewProps { scrollViewOffset?: SharedValue; } diff --git a/src/reanimated2/fabricUtils.ts b/src/reanimated2/fabricUtils.ts index 17331f77514a..c89b04fb3d3a 100644 --- a/src/reanimated2/fabricUtils.ts +++ b/src/reanimated2/fabricUtils.ts @@ -14,6 +14,7 @@ let findHostInstance_DEPRECATED: (ref: React.Component) => HostInstance; if (global._IS_FABRIC) { try { findHostInstance_DEPRECATED = + // eslint-disable-next-line @typescript-eslint/no-var-requires require('react-native/Libraries/Renderer/shims/ReactFabric').findHostInstance_DEPRECATED; } catch (e) { throw new Error( diff --git a/src/reanimated2/globals.d.ts b/src/reanimated2/globals.d.ts index 5c581eef7a52..f3259e4ef3e4 100644 --- a/src/reanimated2/globals.d.ts +++ b/src/reanimated2/globals.d.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable no-var */ import type { - AnimatedStyle, StyleProps, MeasuredDimensions, MapperRegistry, @@ -10,6 +9,7 @@ import type { ShadowNodeWrapper, ComplexWorkletFunction, } from './commonTypes'; +import type { AnimatedStyle } from './helperTypes'; import type { FrameCallbackRegistryUI } from './frameCallback/FrameCallbackRegistryUI'; import type { NativeReanimatedModule } from './NativeReanimated/NativeReanimated'; import type { SensorContainer } from './SensorContainer'; @@ -49,7 +49,7 @@ declare global { operations: { tag: number; name: string; - updates: StyleProps | AnimatedStyle; + updates: StyleProps | AnimatedStyle; }[] ) => void) | undefined; @@ -57,7 +57,7 @@ declare global { | (( operations: { shadowNodeWrapper: ShadowNodeWrapper; - updates: StyleProps | AnimatedStyle; + updates: StyleProps | AnimatedStyle; }[] ) => void) | undefined; diff --git a/src/reanimated2/helperTypes.ts b/src/reanimated2/helperTypes.ts index 6c3710405830..c1cbabb34943 100644 --- a/src/reanimated2/helperTypes.ts +++ b/src/reanimated2/helperTypes.ts @@ -23,21 +23,28 @@ import type { ReanimatedKeyframe } from './layoutReanimation/animationBuilder/Ke import type { SharedTransition } from './layoutReanimation/sharedTransitions'; import type { DependencyList } from './hook/commonTypes'; -type Adaptable = T | ReadonlyArray> | SharedValue; +export type Adaptable = + | T + | ReadonlyArray> + | SharedValue; -type AdaptTransforms = { +export type AdaptTransforms = { [P in keyof T]: Adaptable; }; type TransformsStyle = Pick; -type TransformStyleTypes = TransformsStyle['transform'] extends +export type TransformStyleTypes = TransformsStyle['transform'] extends | readonly (infer T)[] + | string | undefined ? T : never; -type AnimatedTransform = AdaptTransforms[]; +export type AnimatedTransform = AdaptTransforms[]; +/** + * @deprecated Please use `AnimatedStyle` type instead. + */ export type AnimateStyle = { [K in keyof S]: K extends 'transform' ? AnimatedTransform @@ -50,13 +57,15 @@ export type AnimateStyle = { : S[K] | SharedValue; }; +export type AnimatedStyle = AnimateStyle; + // provided types can either be their original types (like backgroundColor: pink) // or inline shared values/derived values type MaybeSharedValue = { [K in keyof S]: S[K] | Readonly>>; }; -type StylesOrDefault = 'style' extends keyof T +export type StylesOrDefault = 'style' extends keyof T ? MaybeSharedValue : Record; @@ -81,12 +90,12 @@ type PickStyleProps = Pick< type StyleAnimatedProps

= { [K in keyof PickStyleProps

]: StyleProp< - AnimateStyle> + AnimatedStyle> >; }; type JustStyleAnimatedProp

= { - style?: StyleProp>>; + style?: StyleProp>>; }; type NonStyleAnimatedProps

= { diff --git a/src/reanimated2/hook/index.ts b/src/reanimated2/hook/index.ts index 22ef19dafb46..9eb4f0642dca 100644 --- a/src/reanimated2/hook/index.ts +++ b/src/reanimated2/hook/index.ts @@ -8,7 +8,10 @@ export { export { useSharedValue } from './useSharedValue'; export { useReducedMotion } from './useReducedMotion'; export { useAnimatedStyle } from './useAnimatedStyle'; -export type { AnimatedStyleResult } from './useAnimatedStyle'; +export type { + AnimatedStyleResult, + AnimatedStyleProp, +} from './useAnimatedStyle'; export { useAnimatedGestureHandler } from './useAnimatedGestureHandler'; export type { GestureHandlerEvent, diff --git a/src/reanimated2/hook/useAnimatedRef.ts b/src/reanimated2/hook/useAnimatedRef.ts index e40a1252c961..7cf7972e4fcf 100644 --- a/src/reanimated2/hook/useAnimatedRef.ts +++ b/src/reanimated2/hook/useAnimatedRef.ts @@ -11,16 +11,16 @@ import { import { Platform, findNodeHandle } from 'react-native'; interface MaybeScrollableComponent extends Component { - getNativeScrollRef?: () => MaybeScrollableComponent; - getScrollableNode?: () => MaybeScrollableComponent; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getNativeScrollRef?: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getScrollableNode?: any; viewConfig?: { uiViewClassName?: string; }; } -function getComponentOrScrollable( - component: MaybeScrollableComponent -): MaybeScrollableComponent { +function getComponentOrScrollable(component: MaybeScrollableComponent) { if (global._IS_FABRIC && component.getNativeScrollRef) { return component.getNativeScrollRef(); } else if (!global._IS_FABRIC && component.getScrollableNode) { diff --git a/src/reanimated2/hook/useAnimatedStyle.ts b/src/reanimated2/hook/useAnimatedStyle.ts index f129860b2506..d3bc00327124 100644 --- a/src/reanimated2/hook/useAnimatedStyle.ts +++ b/src/reanimated2/hook/useAnimatedStyle.ts @@ -20,7 +20,6 @@ import type { AnimationObject, Timestamp, AdapterWorkletFunction, - AnimatedStyle, BasicWorkletFunction, BasicWorkletFunctionOptional, NestedObjectValues, @@ -33,26 +32,26 @@ import type { TextStyle, ViewStyle, } from 'react-native'; -import type { AnimateStyle } from '../helperTypes'; +import type { AnimatedStyle } from '../helperTypes'; export interface AnimatedStyleResult { viewDescriptors: ViewDescriptorsSet; - initial: AnimatedStyle; + initial: AnimatedStyle; viewsRef: ViewRefSet; - animatedStyle?: MutableRefObject; + animatedStyle?: MutableRefObject>; } interface AnimatedState { - last: AnimatedStyle; - animations: AnimatedStyle; + last: AnimatedStyle; + animations: AnimatedStyle; isAnimationRunning: boolean; isAnimationCancelled: boolean; } interface AnimationRef { initial: { - value: AnimatedStyle; - updater: () => AnimatedStyle; + value: AnimatedStyle; + updater: () => AnimatedStyle; }; remoteState: AnimatedState; viewDescriptors: ViewDescriptorsSet; @@ -60,9 +59,9 @@ interface AnimationRef { function prepareAnimation( frameTimestamp: number, - animatedProp: AnimatedStyle, - lastAnimation: AnimatedStyle, - lastValue: AnimatedStyle + animatedProp: AnimatedStyle, + lastAnimation: AnimatedStyle, + lastValue: AnimatedStyle ): void { 'worklet'; if (Array.isArray(animatedProp)) { @@ -119,10 +118,10 @@ function prepareAnimation( } function runAnimations( - animation: AnimatedStyle, + animation: AnimatedStyle, timestamp: Timestamp, key: number | string, - result: AnimatedStyle, + result: AnimatedStyle, animationsActive: SharedValue ): boolean { 'worklet'; @@ -181,7 +180,7 @@ function runAnimations( function styleUpdater( viewDescriptors: SharedValue, - updater: BasicWorkletFunction, + updater: BasicWorkletFunction>, state: AnimatedState, maybeViewRef: ViewRefSet | undefined, animationsActive: SharedValue @@ -217,7 +216,7 @@ function styleUpdater( return; } - const updates: AnimatedStyle = {}; + const updates: AnimatedStyle = {}; let allFinished = true; for (const propName in animations) { const finished = runAnimations( @@ -269,15 +268,15 @@ function styleUpdater( function jestStyleUpdater( viewDescriptors: SharedValue, - updater: BasicWorkletFunction, + updater: BasicWorkletFunction>, state: AnimatedState, maybeViewRef: ViewRefSet | undefined, animationsActive: SharedValue, - animatedStyle: MutableRefObject, + animatedStyle: MutableRefObject>, adapters: AdapterWorkletFunction[] = [] ): void { 'worklet'; - const animations: AnimatedStyle = state.animations ?? {}; + const animations: AnimatedStyle = state.animations ?? {}; const newValues = updater() ?? {}; const oldValues = state.last; @@ -307,7 +306,7 @@ function jestStyleUpdater( return; } - const updates: AnimatedStyle = {}; + const updates: AnimatedStyle = {}; let allFinished = true; Object.keys(animations).forEach((propName) => { const finished = runAnimations( @@ -400,8 +399,10 @@ function checkSharedValueUsage( } } -// TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. -type AnimatedStyleProp = AnimateStyle | RegisteredStyle>; +// This type is kept for backward compatibility. +export type AnimatedStyleProp = + | AnimatedStyle + | RegisteredStyle>; // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. type useAnimatedStyleType = < @@ -411,7 +412,7 @@ type useAnimatedStyleType = < deps?: DependencyList | null ) => T; -export const useAnimatedStyle = function ( +export const useAnimatedStyle = function >( // animated style cannot be an array updater: BasicWorkletFunction ? never : T>, dependencies?: DependencyList, @@ -440,9 +441,9 @@ For more, see the docs: https://docs.swmansion.com/react-native-reanimated/docs/ : []; const adaptersHash = adapters ? buildWorkletsHash(adaptersArray) : null; const animationsActive = useSharedValue(true); - const animatedStyle: MutableRefObject = useRef( - {} - ); + const animatedStyle: MutableRefObject> = useRef< + AnimatedStyle + >({}); // build dependencies if (!dependencies) { @@ -453,7 +454,7 @@ For more, see the docs: https://docs.swmansion.com/react-native-reanimated/docs/ adaptersHash && dependencies.push(adaptersHash); if (!initRef.current) { - const initialStyle: AnimatedStyle = initialUpdaterRun(updater); + const initialStyle: AnimatedStyle = initialUpdaterRun(updater); validateAnimatedStyles(initialStyle); initRef.current = { initial: { diff --git a/src/reanimated2/hook/utils.ts b/src/reanimated2/hook/utils.ts index 35dfd80eca57..d01da526554f 100644 --- a/src/reanimated2/hook/utils.ts +++ b/src/reanimated2/hook/utils.ts @@ -1,13 +1,13 @@ import type { MutableRefObject } from 'react'; import { useEffect, useRef } from 'react'; import type { - AnimatedStyle, Context, NativeEvent, NestedObjectValues, WorkletFunction, AnimationObject, } from '../commonTypes'; +import type { AnimatedStyle } from '../helperTypes'; import { makeRemote } from '../core'; import { isWeb, isJest } from '../PlatformChecker'; import WorkletEventHandler from '../WorkletEventHandler'; @@ -183,7 +183,7 @@ export function shallowEqual(a: any, b: any) { return true; } -export const validateAnimatedStyles = (styles: AnimatedStyle): void => { +export const validateAnimatedStyles = (styles: AnimatedStyle): void => { 'worklet'; if (typeof styles !== 'object') { throw new Error( diff --git a/src/reanimated2/index.ts b/src/reanimated2/index.ts index e21281485e6c..cd075ca01e06 100644 --- a/src/reanimated2/index.ts +++ b/src/reanimated2/index.ts @@ -15,4 +15,16 @@ export * from './commonTypes'; export * from './frameCallback'; export * from './pluginUtils'; export * from './jestUtils'; -export type { AnimateProps } from './helperTypes'; +export type { + Adaptable, + AdaptTransforms, + AnimateProps, + AnimatedProps, + AnimatedTransform, + TransformStyleTypes, + AnimateStyle, + AnimatedStyle, + StylesOrDefault, +} from './helperTypes'; +export type { AnimatedScrollViewProps } from './component/ScrollView'; +export type { FlatListPropsWithLayout } from './component/FlatList'; diff --git a/src/reanimated2/interpolateColor.ts b/src/reanimated2/interpolateColor.ts index 91931869edc8..5155909f3bd8 100644 --- a/src/reanimated2/interpolateColor.ts +++ b/src/reanimated2/interpolateColor.ts @@ -111,7 +111,7 @@ const interpolateColorsRGB = ( ); }; -interface InterpolateRGB { +export interface InterpolateRGB { r: number[]; g: number[]; b: number[]; @@ -141,7 +141,7 @@ const getInterpolateRGB = ( return { r, g, b, a }; }; -interface InterpolateHSV { +export interface InterpolateHSV { h: number[]; s: number[]; v: number[]; diff --git a/src/reanimated2/js-reanimated/index.ts b/src/reanimated2/js-reanimated/index.ts index a0e6d43b4d80..b223bf0ac713 100644 --- a/src/reanimated2/js-reanimated/index.ts +++ b/src/reanimated2/js-reanimated/index.ts @@ -1,5 +1,6 @@ import JSReanimated from './JSReanimated'; -import type { AnimatedStyle, StyleProps } from '../commonTypes'; +import type { StyleProps } from '../commonTypes'; +import type { AnimatedStyle } from '../helperTypes'; import { isWeb } from '../PlatformChecker'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -47,13 +48,13 @@ interface JSReanimatedComponent { } export const _updatePropsJS = ( - updates: StyleProps | AnimatedStyle, + updates: StyleProps | AnimatedStyle, viewRef: { _component?: JSReanimatedComponent } ): void => { if (viewRef._component) { const component = viewRef._component; const [rawStyles] = Object.keys(updates).reduce( - (acc: [StyleProps, AnimatedStyle], key) => { + (acc: [StyleProps, AnimatedStyle], key) => { const value = updates[key]; const index = typeof value === 'function' ? 1 : 0; acc[index][key] = value; diff --git a/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts b/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts index 62fdb857e47a..31dd48572a06 100644 --- a/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts +++ b/src/reanimated2/layoutReanimation/animationBuilder/ComplexAnimationBuilder.ts @@ -4,12 +4,12 @@ import type { BaseBuilderAnimationConfig, LayoutAnimationAndConfig, } from './commonTypes'; -import type { EasingFn } from '../../Easing'; +import type { EasingFunction } from '../../Easing'; import { BaseAnimationBuilder } from './BaseAnimationBuilder'; import type { StyleProps } from '../../commonTypes'; export class ComplexAnimationBuilder extends BaseAnimationBuilder { - easingV?: EasingFn; + easingV?: EasingFunction; rotateV?: string; type?: AnimationFunction; dampingV?: number; @@ -27,13 +27,13 @@ export class ComplexAnimationBuilder extends BaseAnimationBuilder { static easing( this: T, - easingFunction: EasingFn + easingFunction: EasingFunction ) { const instance = this.createInstance(); return instance.easing(easingFunction); } - easing(easingFunction: EasingFn): this { + easing(easingFunction: EasingFunction): this { this.easingV = easingFunction; return this; } diff --git a/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts b/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts index ed79d6ddd8d8..0131e427e6b3 100644 --- a/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts +++ b/src/reanimated2/layoutReanimation/animationBuilder/Keyframe.ts @@ -1,4 +1,4 @@ -import type { EasingFn } from '../../Easing'; +import type { EasingFunction } from '../../Easing'; import { Easing } from '../../Easing'; import { withDelay, withSequence, withTiming } from '../../animation'; import type { @@ -11,7 +11,7 @@ import type { TransformProperty, StyleProps } from '../../commonTypes'; interface KeyframePoint { duration: number; value: number | string; - easing?: EasingFn; + easing?: EasingFunction; } interface ParsedKeyframesDefinition { initialValues: StyleProps; @@ -113,7 +113,7 @@ class InnerKeyframe implements IEntryExitAnimationBuilder { key: string; value: string | number; currentKeyPoint: number; - easing?: EasingFn; + easing?: EasingFunction; }): void => { if (!(key in parsedKeyframes)) { throw Error( diff --git a/src/reanimated2/layoutReanimation/animationBuilder/commonTypes.ts b/src/reanimated2/layoutReanimation/animationBuilder/commonTypes.ts index c203a1359487..6da71bf4d1a1 100644 --- a/src/reanimated2/layoutReanimation/animationBuilder/commonTypes.ts +++ b/src/reanimated2/layoutReanimation/animationBuilder/commonTypes.ts @@ -1,8 +1,8 @@ -import type { EasingFn } from '../../Easing'; +import type { EasingFunction } from '../../Easing'; import type { StyleProps } from '../../commonTypes'; export interface KeyframeProps extends StyleProps { - easing?: EasingFn; + easing?: EasingFunction; [key: string]: any; } @@ -96,7 +96,7 @@ export interface ILayoutAnimationBuilder { export interface BaseLayoutAnimationConfig { duration?: number; - easing?: EasingFn; + easing?: EasingFunction; type?: AnimationFunction; damping?: number; dampingRatio?: number; diff --git a/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts b/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts index 18ab0e52adae..64ea6891cfa0 100644 --- a/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts +++ b/src/reanimated2/layoutReanimation/defaultTransitions/CurvedTransition.ts @@ -3,7 +3,7 @@ import type { LayoutAnimationFunction, } from '../animationBuilder/commonTypes'; import { BaseAnimationBuilder } from '../animationBuilder'; -import type { EasingFn } from '../../Easing'; +import type { EasingFunction } from '../../Easing'; import { Easing } from '../../Easing'; import { withTiming } from '../../animation'; @@ -11,10 +11,10 @@ export class CurvedTransition extends BaseAnimationBuilder implements ILayoutAnimationBuilder { - easingXV: EasingFn = Easing.in(Easing.ease); - easingYV: EasingFn = Easing.out(Easing.ease); - easingWidthV: EasingFn = Easing.in(Easing.exp); - easingHeightV: EasingFn = Easing.out(Easing.exp); + easingXV: EasingFunction = Easing.in(Easing.ease); + easingYV: EasingFunction = Easing.out(Easing.ease); + easingWidthV: EasingFunction = Easing.in(Easing.exp); + easingHeightV: EasingFunction = Easing.out(Easing.exp); static createInstance( this: T @@ -22,42 +22,42 @@ export class CurvedTransition return new CurvedTransition() as InstanceType; } - static easingX(easing: EasingFn): CurvedTransition { + static easingX(easing: EasingFunction): CurvedTransition { const instance = this.createInstance(); return instance.easingX(easing); } - easingX(easing: EasingFn): CurvedTransition { + easingX(easing: EasingFunction): CurvedTransition { this.easingXV = easing; return this; } - static easingY(easing: EasingFn): CurvedTransition { + static easingY(easing: EasingFunction): CurvedTransition { const instance = this.createInstance(); return instance.easingY(easing); } - easingY(easing: EasingFn): CurvedTransition { + easingY(easing: EasingFunction): CurvedTransition { this.easingYV = easing; return this; } - static easingWidth(easing: EasingFn): CurvedTransition { + static easingWidth(easing: EasingFunction): CurvedTransition { const instance = this.createInstance(); return instance.easingWidth(easing); } - easingWidth(easing: EasingFn): CurvedTransition { + easingWidth(easing: EasingFunction): CurvedTransition { this.easingWidthV = easing; return this; } - static easingHeight(easing: EasingFn): CurvedTransition { + static easingHeight(easing: EasingFunction): CurvedTransition { const instance = this.createInstance(); return instance.easingHeight(easing); } - easingHeight(easing: EasingFn): CurvedTransition { + easingHeight(easing: EasingFunction): CurvedTransition { this.easingHeightV = easing; return this; } diff --git a/src/reanimated2/layoutReanimation/index.ts b/src/reanimated2/layoutReanimation/index.ts index 0833600a8f87..eca1f5ff0de7 100644 --- a/src/reanimated2/layoutReanimation/index.ts +++ b/src/reanimated2/layoutReanimation/index.ts @@ -3,3 +3,4 @@ export * from './animationBuilder'; export * from './defaultAnimations'; export * from './defaultTransitions'; export * from './sharedTransitions'; +export type { KeyframeProps } from './animationBuilder/commonTypes'; diff --git a/src/reanimated2/mock.ts b/src/reanimated2/mock.ts index 22a2bdaf2590..37b838a57d39 100644 --- a/src/reanimated2/mock.ts +++ b/src/reanimated2/mock.ts @@ -1,6 +1,8 @@ /* eslint-disable node/no-callback-literal */ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck +import { SensorType } from './commonTypes'; + const NOOP = () => { // noop }; @@ -54,6 +56,31 @@ const ReanimatedV2 = { useAnimatedRef: () => ({ current: null }), useAnimatedReaction: NOOP, useAnimatedProps: IMMEDIATE_CB_INVOCATION, + SensorType: SensorType, + useAnimatedSensor: () => ({ + sensor: { + value: { + x: 0, + y: 0, + z: 0, + interfaceOrientation: 0, + qw: 0, + qx: 0, + qy: 0, + qz: 0, + yaw: 0, + pitch: 0, + roll: 0, + }, + }, + unregister: NOOP, + isAvailable: false, + config: { + interval: 0, + adjustToInterfaceOrientation: false, + iosReferenceFrame: 0, + }, + }), withTiming: (toValue, _, cb) => { cb && cb(true);