From b16e8cb4521a45bbc558b1acbb6a8ff2b4a2196f Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Wed, 16 Sep 2026 10:46:56 -0700 Subject: [PATCH] Remove Native Animated allowlist mutation APIs (#58560) Summary: Pull Request resolved: https://github.com/react/react-native/pull/58560 Native Animated supports a fixed set of interpolation parameters, style properties, and transform properties. Remove the runtime mutation APIs and update tests and examples to rely on properties provided by the shared animated backend. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D120368517 --- .../Animated/NativeAnimatedAllowlist.js | 12 ----------- .../Animated/__tests__/Animated-itest.js | 21 +++---------------- .../AnimatedBackend-benchmark-itest.js | 5 +---- .../__tests__/AnimatedBackend-itest.js | 12 ++--------- .../AnimatedBackendSuspense-itest.js | 5 ----- .../__tests__/NativeAnimatedAllowlist-test.js | 11 ---------- .../AnimationBackend/ChessboardExample.js | 3 --- .../AnimationBackend/SwipeableListExample.js | 3 --- 8 files changed, 6 insertions(+), 66 deletions(-) diff --git a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js index 2c1fab7ac13a..9651183af915 100644 --- a/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js +++ b/packages/react-native/Libraries/Animated/NativeAnimatedAllowlist.js @@ -152,18 +152,6 @@ export default { style: SUPPORTED_STYLES, } as AnimatedPropsAllowlist; -export function allowInterpolationParam(param: string): void { - SUPPORTED_INTERPOLATION_PARAMS[param] = true; -} - -export function allowStyleProp(prop: string): void { - SUPPORTED_STYLES[prop] = true; -} - -export function allowTransformProp(prop: string): void { - SUPPORTED_TRANSFORMS[prop] = true; -} - export function isSupportedColorStyleProp(prop: string): boolean { return SUPPORTED_COLOR_STYLES.hasOwnProperty(prop); } diff --git a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js index 0b9023e2a81c..58ad5b5b64f4 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js @@ -19,7 +19,6 @@ import nullthrows from 'nullthrows'; import * as React from 'react'; import {createRef} from 'react'; import {Animated, Easing, View, useAnimatedValue} from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; // Deferred start outputs the initial value on the first animation frame and // re-anchors timing on the second. This delays animation progress by one @@ -711,8 +710,9 @@ describe('Value.extractOffset', () => { }); test('animate layout props', () => { - const viewRef = createRef(); - allowStyleProp('height'); + if (!ReactNativeFeatureFlags.useSharedAnimatedBackend()) { + return; + } let _animatedHeight; let _heightAnimation; @@ -722,7 +722,6 @@ test('animate layout props', () => { _animatedHeight = animatedHeight; return ( { root.render(); }); - const viewElement = nullthrows(viewRef.current); - Fantom.runTask(() => { _heightAnimation = Animated.timing(_animatedHeight, { toValue: 100, @@ -756,18 +753,6 @@ test('animate layout props', () => { _heightAnimation?.stop(); }); - // animation backend does not push layut updates through the direct manipulation path - // also it's changes are not currently reflected in the getFabricUpdateProps method, as - // it only captures props that are updated through UIManager::updateShadowTree - if (!ReactNativeFeatureFlags.useSharedAnimatedBackend()) { - // $FlowFixMe[incompatible-use] - expect(Fantom.unstable_getDirectManipulationProps(viewElement).height).toBe( - 100, - ); - - expect(Fantom.unstable_getFabricUpdateProps(viewElement).height).toBe(100); - } - expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual( , ); diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-benchmark-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-benchmark-itest.js index 9486a6b0aaf3..2a612a32656e 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-benchmark-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-benchmark-itest.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @fantom_flags useSharedAnimatedBackend:* + * @fantom_flags useSharedAnimatedBackend:true * @flow strict-local * @format */ @@ -15,9 +15,6 @@ import * as Fantom from '@react-native/fantom'; import * as React from 'react'; import {useEffect} from 'react'; import {Animated, View, useAnimatedValue} from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; - -allowStyleProp('height'); function MyApp() { return ( diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js index 59515ac1eaa0..15df90071365 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackend-itest.js @@ -18,12 +18,10 @@ import nullthrows from 'nullthrows'; import * as React from 'react'; import {Component, createRef, memo, useEffect, useMemo, useState} from 'react'; import {Animated, View, useAnimatedValue} from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; // marginLeft (and the other margin props) are only on the native animated -// allowlist when the shared backend is enabled. This test deliberately does NOT -// call allowStyleProp('marginLeft') — it verifies the prop is supported natively -// out of the box under useSharedAnimatedBackend. +// allowlist when the shared backend is enabled. This verifies the prop is +// supported natively out of the box under useSharedAnimatedBackend. test('animate marginLeft layout prop', () => { const viewRef = createRef(); @@ -252,7 +250,6 @@ test('animated opacity on a class composite wrapping a host', () => { test('animate layout props', () => { const viewRef = createRef(); - allowStyleProp('height'); let _animatedHeight; let _heightAnimation; @@ -309,7 +306,6 @@ test('animate layout props', () => { test('animate layout props and rerender', () => { const viewRef = createRef(); - allowStyleProp('height'); let _animatedHeight; let _heightAnimation; @@ -481,7 +477,6 @@ test('animate non-layout props and rerender', () => { test('animate layout props and rerender in many components', () => { const viewRef = createRef(); - allowStyleProp('height'); let _animatedHeight; let _heightAnimation; @@ -577,8 +572,6 @@ test('animate layout props and rerender in many components', () => { test('animate width, height and opacity at once', () => { const viewRef = createRef(); - allowStyleProp('width'); - allowStyleProp('height'); let _animatedWidth; let _animatedHeight; @@ -646,7 +639,6 @@ test('animate width, height and opacity at once', () => { test('animate width with memo and rerender (js sync test)', () => { const viewRef = createRef(); - allowStyleProp('width'); let _widthAnimation; let _setState; diff --git a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackendSuspense-itest.js b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackendSuspense-itest.js index 3cb2553d6e57..5e9410d3f353 100644 --- a/packages/react-native/Libraries/Animated/__tests__/AnimatedBackendSuspense-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/AnimatedBackendSuspense-itest.js @@ -14,7 +14,6 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; import * as Fantom from '@react-native/fantom'; import {Suspense, startTransition, use} from 'react'; import {Animated, Easing, View, useAnimatedValue} from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; // --- Shared test utilities --- @@ -103,10 +102,6 @@ function AnimatedChild({ // --- Tests --- -beforeEach(() => { - allowStyleProp('width'); -}); - test('animation state is maintained after Suspense', () => { let _animatedWidth; let _widthAnimation; diff --git a/packages/react-native/Libraries/Animated/__tests__/NativeAnimatedAllowlist-test.js b/packages/react-native/Libraries/Animated/__tests__/NativeAnimatedAllowlist-test.js index c5e56093eafc..e094cea57542 100644 --- a/packages/react-native/Libraries/Animated/__tests__/NativeAnimatedAllowlist-test.js +++ b/packages/react-native/Libraries/Animated/__tests__/NativeAnimatedAllowlist-test.js @@ -43,17 +43,6 @@ describe('NativeAnimatedAllowlist', () => { expect(isSupportedInterpolationParam('extrapolateLeft')).toBe(true); }); - it('allows new interpolation params', () => { - const { - allowInterpolationParam, - isSupportedInterpolationParam, - } = require('../NativeAnimatedAllowlist'); - - expect(isSupportedInterpolationParam('other')).toBe(false); - allowInterpolationParam('other'); - expect(isSupportedInterpolationParam('other')).toBe(true); - }); - it('checks supported transform props', () => { jest .spyOn( diff --git a/packages/rn-tester/js/examples/AnimationBackend/ChessboardExample.js b/packages/rn-tester/js/examples/AnimationBackend/ChessboardExample.js index a343729e47fe..5cf3c4ee1832 100644 --- a/packages/rn-tester/js/examples/AnimationBackend/ChessboardExample.js +++ b/packages/rn-tester/js/examples/AnimationBackend/ChessboardExample.js @@ -13,10 +13,7 @@ import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; import * as React from 'react'; import {useMemo} from 'react'; import {Animated, StyleSheet, Text, View, useAnimatedValue} from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; -allowStyleProp('width'); -allowStyleProp('height'); const colors = ['lime', 'green']; function useLoop() { diff --git a/packages/rn-tester/js/examples/AnimationBackend/SwipeableListExample.js b/packages/rn-tester/js/examples/AnimationBackend/SwipeableListExample.js index af0676bc2b7d..f7a917df67b7 100644 --- a/packages/rn-tester/js/examples/AnimationBackend/SwipeableListExample.js +++ b/packages/rn-tester/js/examples/AnimationBackend/SwipeableListExample.js @@ -24,9 +24,6 @@ import { View, useAnimatedValue, } from 'react-native'; -import {allowStyleProp} from 'react-native/Libraries/Animated/NativeAnimatedAllowlist'; - -allowStyleProp('height'); const windowDimensions = Dimensions.get('window'); const BUTTON_WIDTH = 80;