Skip to content

Commit b4f9aa1

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
fix sticky header with tappable element (#44046)
Summary: X-link: facebook/react-fbsource-import#5 Pull Request resolved: #44046 changelog: [internal] `passthroughAnimatedPropExplicitValues` from sticky header were removed in D46703731 with assumption that native animations trigger on complete callback and it can be used as a synchronisation point for Fabric. On complete callback is triggered for native animations do trigger on complete callback with one exception: when the native animation is driven by scroll view's content offset. As a result, synchronisation between React and Fabric doesn't happen and Pressability stops working if there is a pressable element in the sticky header. Reviewed By: rubennorte Differential Revision: D56005408 fbshipit-source-id: daead3a566e157593aa3f1b3ae3553ec1094b6da
1 parent aacde17 commit b4f9aa1

3 files changed

Lines changed: 48 additions & 13 deletions

File tree

packages/react-native/Libraries/Animated/createAnimatedComponent.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@
88
* @format
99
*/
1010

11+
import View from '../Components/View/View';
1112
import useMergeRefs from '../Utilities/useMergeRefs';
1213
import useAnimatedProps from './useAnimatedProps';
1314
import * as React from 'react';
1415

1516
// $FlowFixMe[deprecated-type]
16-
export type AnimatedProps<Props: {...}> = $ObjMap<Props, () => any>;
17+
export type AnimatedProps<Props: {...}> = $ObjMap<
18+
Props &
19+
$ReadOnly<{
20+
passthroughAnimatedPropExplicitValues?: React.ElementConfig<typeof View>,
21+
}>,
22+
() => any,
23+
>;
1724

1825
export type AnimatedComponentType<
1926
Props: {...},
@@ -36,9 +43,19 @@ export default function createAnimatedComponent<TProps: {...}, TInstance>(
3643
// transformed and Pressable, onPress will not work after transform
3744
// without these passthrough values.
3845
// $FlowFixMe[prop-missing]
39-
const {style} = reducedProps;
46+
const {passthroughAnimatedPropExplicitValues, style} = reducedProps;
47+
const {style: passthroughStyle, ...passthroughProps} =
48+
passthroughAnimatedPropExplicitValues ?? {};
49+
const mergedStyle = {...style, ...passthroughStyle};
4050

41-
return <Component {...reducedProps} style={style} ref={ref} />;
51+
return (
52+
<Component
53+
{...reducedProps}
54+
{...passthroughProps}
55+
style={mergedStyle}
56+
ref={ref}
57+
/>
58+
);
4259
},
4360
);
4461

packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,16 @@ const ScrollViewStickyHeaderWithForwardedRef: React.AbstractComponent<
267267

268268
const child = React.Children.only<$FlowFixMe>(props.children);
269269

270+
const passthroughAnimatedPropExplicitValues =
271+
isFabric && translateY != null
272+
? {
273+
style: {transform: [{translateY: translateY}]},
274+
}
275+
: null;
276+
270277
return (
278+
/* $FlowFixMe[prop-missing] passthroughAnimatedPropExplicitValues isn't properly
279+
included in the Animated.View flow type. */
271280
<Animated.View
272281
collapsable={false}
273282
nativeID={props.nativeID}
@@ -277,7 +286,10 @@ const ScrollViewStickyHeaderWithForwardedRef: React.AbstractComponent<
277286
child.props.style,
278287
styles.header,
279288
{transform: [{translateY: animatedTranslateY}]},
280-
]}>
289+
]}
290+
passthroughAnimatedPropExplicitValues={
291+
passthroughAnimatedPropExplicitValues
292+
}>
281293
{React.cloneElement(child, {
282294
style: styles.fill, // We transfer the child style to the wrapper.
283295
onLayout: undefined, // we call this manually through our this._onLayout

packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,13 @@ exports[`public API should not change unintentionally Libraries/Animated/compone
810810
`;
811811

812812
exports[`public API should not change unintentionally Libraries/Animated/createAnimatedComponent.js 1`] = `
813-
"export type AnimatedProps<Props: { ... }> = $ObjMap<Props, () => any>;
813+
"export type AnimatedProps<Props: { ... }> = $ObjMap<
814+
Props &
815+
$ReadOnly<{
816+
passthroughAnimatedPropExplicitValues?: React.ElementConfig<typeof View>,
817+
}>,
818+
() => any,
819+
>;
814820
export type AnimatedComponentType<
815821
Props: { ... },
816822
+Instance = mixed,
@@ -8399,6 +8405,14 @@ exports[`public API should not change unintentionally Libraries/Utilities/DebugE
83998405
"
84008406
`;
84018407

8408+
exports[`public API should not change unintentionally Libraries/Utilities/DevLoadingView.js 1`] = `
8409+
"declare module.exports: {
8410+
showMessage(message: string, type: \\"load\\" | \\"refresh\\"): void,
8411+
hide(): void,
8412+
};
8413+
"
8414+
`;
8415+
84028416
exports[`public API should not change unintentionally Libraries/Utilities/DevSettings.js 1`] = `
84038417
"declare let DevSettings: {
84048418
addMenuItem(title: string, handler: () => mixed): void,
@@ -8516,14 +8530,6 @@ export interface IPerformanceLogger {
85168530
"
85178531
`;
85188532

8519-
exports[`public API should not change unintentionally Libraries/Utilities/DevLoadingView.js 1`] = `
8520-
"declare module.exports: {
8521-
showMessage(message: string, type: \\"load\\" | \\"refresh\\"): void,
8522-
hide(): void,
8523-
};
8524-
"
8525-
`;
8526-
85278533
exports[`public API should not change unintentionally Libraries/Utilities/NativeAppearance.js 1`] = `
85288534
"export type * from \\"../../src/private/specs/modules/NativeAppearance\\";
85298535
declare export default typeof NativeAppearance;

0 commit comments

Comments
 (0)