Skip to content

Commit

Permalink
fix: useAnimatedProps text not working on web
Browse files Browse the repository at this point in the history
  • Loading branch information
5ZYSZ3K committed Jan 27, 2025
1 parent bfc3cfb commit 3eacc84
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
21 changes: 17 additions & 4 deletions apps/common-app/src/apps/reanimated/examples/AmountExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ import Animated, {
useDerivedValue,
useSharedValue,
withTiming,
createAnimatedPropAdapter,
} from 'react-native-reanimated';
import { Button, StyleSheet, TextInput, View } from 'react-native';
import { Button, Platform, StyleSheet, TextInput, View } from 'react-native';
import React, { useCallback } from 'react';

Animated.addWhitelistedNativeProps({ text: true });

const textAdapter = createAnimatedPropAdapter(
(props: Record<string, unknown>) => {
props._setAttributeDirectly = true;
props.value = props.text;
},
['value']
);

const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);

const DELTAS = [-100, -10, -1, 1, 10, 100];
Expand All @@ -22,9 +31,13 @@ export default function AmountExample() {
return `$${sv.value.toFixed(2)}`;
});

const animatedProps = useAnimatedProps(() => {
return { text: text.value, defaultValue: text.value };
});
const animatedProps = useAnimatedProps(
() => {
return { text: text.value, defaultValue: text.value };
},
[],
Platform.OS === 'web' ? [textAdapter] : undefined
);

const setValue = useCallback(
(delta: number) => {
Expand Down
21 changes: 17 additions & 4 deletions apps/common-app/src/apps/reanimated/examples/JSPropsExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Animated, {
useDerivedValue,
useAnimatedProps,
interpolate,
createAnimatedPropAdapter,
} from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

Expand Down Expand Up @@ -47,6 +48,14 @@ function angleToValue(angle: number, min: number, max: number) {
return interpolate(angle, [0, 360], [min, max]);
}

const textAdapter = createAnimatedPropAdapter(
(props: Record<string, unknown>) => {
props._setAttributeDirectly = true;
props.value = props.text;
},
['value']
);

type CircularSliderProps = {
size: number;
circleRadius: number;
Expand Down Expand Up @@ -109,10 +118,14 @@ function CircularSlider(props: CircularSliderProps) {
};
});

const animatedInputProps = useAnimatedProps(() => {
const text = String(currentValue.value);
return { text, defaultValue: text };
});
const animatedInputProps = useAnimatedProps(
() => {
const text = String(currentValue.value);
return { text, defaultValue: text };
},
undefined,
[textAdapter]
);

const gesture = Gesture.Pan()
.minDistance(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export const _updatePropsJS = (
const component = viewRef.getAnimatableRef
? viewRef.getAnimatableRef()
: viewRef;
const setPropDirectly = updates._setAttributeDirectly;
delete updates._setAttributeDirectly;
const [rawStyles] = Object.keys(updates).reduce(
(acc: [StyleProps, AnimatedStyle<any>], key) => {
const value = updates[key];
Expand All @@ -85,7 +87,7 @@ export const _updatePropsJS = (
) {
// React Native Web 0.19+ no longer provides setNativeProps function,
// so we need to update DOM nodes directly.
updatePropsDOM(component, rawStyles, isAnimatedProps);
updatePropsDOM(component, rawStyles, isAnimatedProps, setPropDirectly);
} else if (Object.keys(component.props).length > 0) {
Object.keys(component.props).forEach((key) => {
if (!rawStyles[key]) {
Expand Down Expand Up @@ -131,7 +133,8 @@ const setNativeProps = (
const updatePropsDOM = (
component: JSReanimatedComponent | HTMLElement,
style: StyleProps,
isAnimatedProps?: boolean
isAnimatedProps?: boolean,
setPropDirectly?: boolean
): void => {
const previousStyle = (component as JSReanimatedComponent).previousStyle
? (component as JSReanimatedComponent).previousStyle
Expand Down Expand Up @@ -159,7 +162,12 @@ const updatePropsDOM = (

for (const key in domStyle) {
if (isAnimatedProps) {
(component as HTMLElement).setAttribute(key, domStyle[key]);
if (setPropDirectly) {
// @ts-ignore We want to set a prop directly on a component without using setAttribute - to overcome React behaviour
(component as HTMLElement)[key] = domStyle[key];
} else {
(component as HTMLElement).setAttribute(key, domStyle[key]);
}
} else {
(component.style as StyleProps)[key] = domStyle[key];
}
Expand Down

0 comments on commit 3eacc84

Please sign in to comment.