@office-iss/react-native-win32 0.0.0-canary.264 → 0.0.0-canary.265
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.flowconfig +1 -1
- package/CHANGELOG.json +14981 -14942
- package/CHANGELOG.md +31 -19
- package/Libraries/Animated/AnimatedImplementation.js +2 -2
- package/Libraries/Animated/NativeAnimatedAllowlist.js +20 -9
- package/Libraries/Animated/animations/Animation.js +1 -4
- package/Libraries/Animated/createAnimatedComponent.js +13 -0
- package/Libraries/Animated/nodes/AnimatedNode.js +39 -45
- package/Libraries/Animated/nodes/AnimatedObject.js +13 -3
- package/Libraries/Animated/nodes/AnimatedProps.js +81 -37
- package/Libraries/Animated/nodes/AnimatedStyle.js +104 -39
- package/Libraries/Animated/nodes/AnimatedTransform.js +55 -22
- package/Libraries/Animated/nodes/AnimatedWithChildren.js +1 -3
- package/Libraries/Animated/useAnimatedProps.js +38 -20
- package/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +3 -1
- package/Libraries/Components/ScrollView/ScrollView.js +12 -9
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +3 -0
- package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
- package/Libraries/Components/TextInput/TextInput.d.ts +19 -0
- package/Libraries/Components/TextInput/TextInput.flow.js +17 -1
- package/Libraries/Components/TextInput/TextInput.js +17 -1
- package/Libraries/Components/TextInput/TextInput.win32.js +17 -1
- package/Libraries/Components/Touchable/TouchableBounce.js +1 -1
- package/Libraries/Components/Touchable/TouchableHighlight.js +2 -2
- package/Libraries/Components/Touchable/TouchableOpacity.js +1 -1
- package/Libraries/Components/View/ReactNativeStyleAttributes.js +6 -2
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Image/AssetSourceResolver.js +12 -1
- package/Libraries/Modal/Modal.d.ts +7 -0
- package/Libraries/Modal/Modal.js +9 -1
- package/Libraries/NativeComponent/BaseViewConfig.android.js +7 -2
- package/Libraries/NativeComponent/BaseViewConfig.ios.js +11 -2
- package/Libraries/NativeComponent/BaseViewConfig.win32.js +1 -1
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -1
- package/Libraries/ReactNative/AppRegistry.js +2 -6
- package/Libraries/ReactNative/getNativeComponentAttributes.js +4 -0
- package/Libraries/Renderer/shims/ReactNativeTypes.js +3 -3
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +5 -6
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +102 -5
- package/Libraries/StyleSheet/StyleSheetTypes.js +9 -5
- package/Libraries/StyleSheet/processBoxShadow.js +5 -7
- package/Libraries/StyleSheet/processFilter.js +4 -4
- package/Libraries/Text/TextNativeComponent.js +0 -1
- package/Libraries/Utilities/HMRClient.js +5 -5
- package/overrides.json +6 -6
- package/package.json +18 -16
- package/src/private/animated/NativeAnimatedHelper.js +12 -8
- package/src/private/animated/NativeAnimatedHelper.win32.js +12 -8
- package/src/private/animated/useAnimatedPropsMemo.js +349 -0
- package/src/private/components/HScrollViewNativeComponents.js +9 -8
- package/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +13 -9
- package/src/private/components/VScrollViewNativeComponents.js +9 -8
- package/src/private/featureflags/ReactNativeFeatureFlags.js +50 -22
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +8 -2
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +7 -4
- package/src/private/webapis/dom/geometry/DOMRect.js +2 -2
- package/src/private/webapis/dom/geometry/DOMRectReadOnly.js +2 -2
- package/types/experimental.d.ts +0 -105
- package/types/modules/Codegen.d.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
# Change Log - @office-iss/react-native-win32
|
|
2
|
-
|
|
3
|
-
<!-- This log was last generated on
|
|
4
|
-
|
|
5
|
-
<!-- Start content -->
|
|
6
|
-
|
|
7
|
-
## 0.0.0-canary.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Changes
|
|
12
|
-
|
|
13
|
-
- RN
|
|
14
|
-
- Bump @rnw-scripts/eslint-config to v1.2.
|
|
15
|
-
- Bump @rnw-scripts/jest-out-of-tree-snapshot-resolver to v1.1.
|
|
16
|
-
- Bump @rnw-scripts/just-task to v2.3.
|
|
17
|
-
- Bump react-native-platform-override to v1.9.
|
|
18
|
-
|
|
1
|
+
# Change Log - @office-iss/react-native-win32
|
|
2
|
+
|
|
3
|
+
<!-- This log was last generated on Mon, 07 Oct 2024 19:54:26 GMT and should not be manually modified. -->
|
|
4
|
+
|
|
5
|
+
<!-- Start content -->
|
|
6
|
+
|
|
7
|
+
## 0.0.0-canary.265
|
|
8
|
+
|
|
9
|
+
Mon, 07 Oct 2024 19:54:26 GMT
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
- integrate RN nightly 0.77.0-nightly-20240921-1747f57c6 (tatianakapos@microsoft.com)
|
|
14
|
+
- Bump @rnw-scripts/eslint-config to v1.2.29
|
|
15
|
+
- Bump @rnw-scripts/jest-out-of-tree-snapshot-resolver to v1.1.33
|
|
16
|
+
- Bump @rnw-scripts/just-task to v2.3.46
|
|
17
|
+
- Bump react-native-platform-override to v1.9.48
|
|
18
|
+
|
|
19
|
+
## 0.0.0-canary.263
|
|
20
|
+
|
|
21
|
+
Thu, 26 Sep 2024 17:38:26 GMT
|
|
22
|
+
|
|
23
|
+
### Changes
|
|
24
|
+
|
|
25
|
+
- RN Integration 9/9 (1422161+marlenecota@users.noreply.github.com)
|
|
26
|
+
- Bump @rnw-scripts/eslint-config to v1.2.27
|
|
27
|
+
- Bump @rnw-scripts/jest-out-of-tree-snapshot-resolver to v1.1.31
|
|
28
|
+
- Bump @rnw-scripts/just-task to v2.3.44
|
|
29
|
+
- Bump react-native-platform-override to v1.9.46
|
|
30
|
+
|
|
19
31
|
## 0.0.0-canary.262
|
|
20
32
|
|
|
21
33
|
Sat, 07 Sep 2024 05:14:10 GMT
|
|
@@ -5679,4 +5691,4 @@ Mon, 01 May 2017 19:28:16 GMT
|
|
|
5679
5691
|
|
|
5680
5692
|
### Patches
|
|
5681
5693
|
|
|
5682
|
-
- Move @office-iss/react-native to 0.40.1 to fix build
|
|
5694
|
+
- Move @office-iss/react-native to 0.40.1 to fix build
|
|
@@ -373,7 +373,7 @@ const parallel = function (
|
|
|
373
373
|
const stopTogether = !(config && config.stopTogether === false);
|
|
374
374
|
|
|
375
375
|
const result = {
|
|
376
|
-
start: function (callback?: ?EndCallback) {
|
|
376
|
+
start: function (callback?: ?EndCallback, isLooping?: boolean) {
|
|
377
377
|
if (doneCount === animations.length) {
|
|
378
378
|
callback && callback({finished: true});
|
|
379
379
|
return;
|
|
@@ -397,7 +397,7 @@ const parallel = function (
|
|
|
397
397
|
if (!animation) {
|
|
398
398
|
cb({finished: true});
|
|
399
399
|
} else {
|
|
400
|
-
animation.start(cb);
|
|
400
|
+
animation.start(cb, isLooping);
|
|
401
401
|
}
|
|
402
402
|
});
|
|
403
403
|
},
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {AnimatedPropsAllowlist} from './nodes/AnimatedProps';
|
|
12
|
+
|
|
11
13
|
import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -16,7 +18,7 @@ import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNa
|
|
|
16
18
|
* In general native animated implementation should support any numeric or color property that
|
|
17
19
|
* doesn't need to be updated through the shadow view hierarchy (all non-layout properties).
|
|
18
20
|
*/
|
|
19
|
-
const SUPPORTED_COLOR_STYLES: {[string]:
|
|
21
|
+
const SUPPORTED_COLOR_STYLES: {[string]: true} = {
|
|
20
22
|
backgroundColor: true,
|
|
21
23
|
borderBottomColor: true,
|
|
22
24
|
borderColor: true,
|
|
@@ -29,7 +31,7 @@ const SUPPORTED_COLOR_STYLES: {[string]: boolean} = {
|
|
|
29
31
|
tintColor: true,
|
|
30
32
|
};
|
|
31
33
|
|
|
32
|
-
const SUPPORTED_STYLES: {[string]:
|
|
34
|
+
const SUPPORTED_STYLES: {[string]: true} = {
|
|
33
35
|
...SUPPORTED_COLOR_STYLES,
|
|
34
36
|
borderBottomEndRadius: true,
|
|
35
37
|
borderBottomLeftRadius: true,
|
|
@@ -58,7 +60,7 @@ const SUPPORTED_STYLES: {[string]: boolean} = {
|
|
|
58
60
|
translateY: true,
|
|
59
61
|
};
|
|
60
62
|
|
|
61
|
-
const SUPPORTED_TRANSFORMS: {[string]:
|
|
63
|
+
const SUPPORTED_TRANSFORMS: {[string]: true} = {
|
|
62
64
|
translateX: true,
|
|
63
65
|
translateY: true,
|
|
64
66
|
scale: true,
|
|
@@ -71,10 +73,12 @@ const SUPPORTED_TRANSFORMS: {[string]: boolean} = {
|
|
|
71
73
|
perspective: true,
|
|
72
74
|
skewX: true,
|
|
73
75
|
skewY: true,
|
|
74
|
-
|
|
76
|
+
...(ReactNativeFeatureFlags.shouldUseAnimatedObjectForTransform()
|
|
77
|
+
? {matrix: true}
|
|
78
|
+
: {}),
|
|
75
79
|
};
|
|
76
80
|
|
|
77
|
-
const SUPPORTED_INTERPOLATION_PARAMS: {[string]:
|
|
81
|
+
const SUPPORTED_INTERPOLATION_PARAMS: {[string]: true} = {
|
|
78
82
|
inputRange: true,
|
|
79
83
|
outputRange: true,
|
|
80
84
|
extrapolate: true,
|
|
@@ -82,6 +86,13 @@ const SUPPORTED_INTERPOLATION_PARAMS: {[string]: boolean} = {
|
|
|
82
86
|
extrapolateLeft: true,
|
|
83
87
|
};
|
|
84
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Default allowlist for component props that support native animated values.
|
|
91
|
+
*/
|
|
92
|
+
export default {
|
|
93
|
+
style: SUPPORTED_STYLES,
|
|
94
|
+
} as AnimatedPropsAllowlist;
|
|
95
|
+
|
|
85
96
|
export function allowInterpolationParam(param: string): void {
|
|
86
97
|
SUPPORTED_INTERPOLATION_PARAMS[param] = true;
|
|
87
98
|
}
|
|
@@ -95,17 +106,17 @@ export function allowTransformProp(prop: string): void {
|
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
export function isSupportedColorStyleProp(prop: string): boolean {
|
|
98
|
-
return SUPPORTED_COLOR_STYLES
|
|
109
|
+
return Object.hasOwn(SUPPORTED_COLOR_STYLES, prop);
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
export function isSupportedInterpolationParam(param: string): boolean {
|
|
102
|
-
return SUPPORTED_INTERPOLATION_PARAMS
|
|
113
|
+
return Object.hasOwn(SUPPORTED_INTERPOLATION_PARAMS, param);
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
export function isSupportedStyleProp(prop: string): boolean {
|
|
106
|
-
return SUPPORTED_STYLES
|
|
117
|
+
return Object.hasOwn(SUPPORTED_STYLES, prop);
|
|
107
118
|
}
|
|
108
119
|
|
|
109
120
|
export function isSupportedTransformProp(prop: string): boolean {
|
|
110
|
-
return SUPPORTED_TRANSFORMS
|
|
121
|
+
return Object.hasOwn(SUPPORTED_TRANSFORMS, prop);
|
|
111
122
|
}
|
|
@@ -110,10 +110,7 @@ export default class Animation {
|
|
|
110
110
|
if (value != null) {
|
|
111
111
|
animatedValue.__onAnimatedValueUpdateReceived(value);
|
|
112
112
|
|
|
113
|
-
if (
|
|
114
|
-
ReactNativeFeatureFlags.shouldSkipStateUpdatesForLoopingAnimations() &&
|
|
115
|
-
this.__isLooping
|
|
116
|
-
) {
|
|
113
|
+
if (this.__isLooping) {
|
|
117
114
|
return;
|
|
118
115
|
}
|
|
119
116
|
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {AnimatedPropsAllowlist} from './nodes/AnimatedProps';
|
|
12
|
+
|
|
11
13
|
import composeStyles from '../../src/private/styles/composeStyles';
|
|
12
14
|
import View from '../Components/View/View';
|
|
13
15
|
import useMergeRefs from '../Utilities/useMergeRefs';
|
|
@@ -32,12 +34,23 @@ export type AnimatedComponentType<
|
|
|
32
34
|
|
|
33
35
|
export default function createAnimatedComponent<TProps: {...}, TInstance>(
|
|
34
36
|
Component: React.AbstractComponent<TProps, TInstance>,
|
|
37
|
+
): AnimatedComponentType<TProps, TInstance> {
|
|
38
|
+
return unstable_createAnimatedComponentWithAllowlist(Component, null);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function unstable_createAnimatedComponentWithAllowlist<
|
|
42
|
+
TProps: {...},
|
|
43
|
+
TInstance,
|
|
44
|
+
>(
|
|
45
|
+
Component: React.AbstractComponent<TProps, TInstance>,
|
|
46
|
+
allowlist: ?AnimatedPropsAllowlist,
|
|
35
47
|
): AnimatedComponentType<TProps, TInstance> {
|
|
36
48
|
const AnimatedComponent = React.forwardRef<AnimatedProps<TProps>, TInstance>(
|
|
37
49
|
(props, forwardedRef) => {
|
|
38
50
|
const [reducedProps, callbackRef] = useAnimatedProps<TProps, TInstance>(
|
|
39
51
|
// $FlowFixMe[incompatible-call]
|
|
40
52
|
props,
|
|
53
|
+
allowlist,
|
|
41
54
|
);
|
|
42
55
|
const ref = useMergeRefs<TInstance>(callbackRef, forwardedRef);
|
|
43
56
|
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
11
|
import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
|
|
14
12
|
import type {PlatformConfig} from '../AnimatedPlatformConfig';
|
|
15
13
|
|
|
@@ -29,12 +27,11 @@ let _assertNativeAnimatedModule: ?() => void = () => {
|
|
|
29
27
|
_assertNativeAnimatedModule = null;
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
// Note(vjeux): this would be better as an interface but flow doesn't
|
|
33
|
-
// support them yet
|
|
34
30
|
export default class AnimatedNode {
|
|
35
31
|
#listeners: Map<string, ValueListenerCallback> = new Map();
|
|
32
|
+
#updateSubscription: ?EventSubscription = null;
|
|
33
|
+
|
|
36
34
|
_platformConfig: ?PlatformConfig = undefined;
|
|
37
|
-
__nativeAnimatedValueListener: ?EventSubscription = null;
|
|
38
35
|
__attach(): void {}
|
|
39
36
|
__detach(): void {
|
|
40
37
|
this.removeAllListeners();
|
|
@@ -56,16 +53,17 @@ export default class AnimatedNode {
|
|
|
56
53
|
/* Methods and props used by native Animated impl */
|
|
57
54
|
__isNative: boolean = false;
|
|
58
55
|
__nativeTag: ?number = undefined;
|
|
59
|
-
__shouldUpdateListenersForNewNativeTag: boolean = false;
|
|
60
56
|
|
|
61
57
|
__makeNative(platformConfig: ?PlatformConfig): void {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
// Subclasses are expected to set `__isNative` to true before this.
|
|
59
|
+
invariant(
|
|
60
|
+
this.__isNative,
|
|
61
|
+
'This node cannot be made a "native" animated node',
|
|
62
|
+
);
|
|
65
63
|
|
|
66
64
|
this._platformConfig = platformConfig;
|
|
67
65
|
if (this.#listeners.size > 0) {
|
|
68
|
-
this
|
|
66
|
+
this.#ensureUpdateSubscriptionExists();
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
69
|
|
|
@@ -80,7 +78,7 @@ export default class AnimatedNode {
|
|
|
80
78
|
const id = String(_uniqueId++);
|
|
81
79
|
this.#listeners.set(id, callback);
|
|
82
80
|
if (this.__isNative) {
|
|
83
|
-
this
|
|
81
|
+
this.#ensureUpdateSubscriptionExists();
|
|
84
82
|
}
|
|
85
83
|
return id;
|
|
86
84
|
}
|
|
@@ -94,7 +92,7 @@ export default class AnimatedNode {
|
|
|
94
92
|
removeListener(id: string): void {
|
|
95
93
|
this.#listeners.delete(id);
|
|
96
94
|
if (this.__isNative && this.#listeners.size === 0) {
|
|
97
|
-
this
|
|
95
|
+
this.#updateSubscription?.remove();
|
|
98
96
|
}
|
|
99
97
|
}
|
|
100
98
|
|
|
@@ -106,7 +104,7 @@ export default class AnimatedNode {
|
|
|
106
104
|
removeAllListeners(): void {
|
|
107
105
|
this.#listeners.clear();
|
|
108
106
|
if (this.__isNative) {
|
|
109
|
-
this
|
|
107
|
+
this.#updateSubscription?.remove();
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
110
|
|
|
@@ -114,33 +112,36 @@ export default class AnimatedNode {
|
|
|
114
112
|
return this.#listeners.size > 0;
|
|
115
113
|
}
|
|
116
114
|
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
this.__nativeAnimatedValueListener &&
|
|
120
|
-
!this.__shouldUpdateListenersForNewNativeTag
|
|
121
|
-
) {
|
|
115
|
+
#ensureUpdateSubscriptionExists(): void {
|
|
116
|
+
if (this.#updateSubscription != null) {
|
|
122
117
|
return;
|
|
123
118
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this._stopListeningForNativeValueUpdates();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
startListeningToAnimatedNodeValue(this.__getNativeTag());
|
|
131
|
-
this.__nativeAnimatedValueListener =
|
|
119
|
+
const nativeTag = this.__getNativeTag();
|
|
120
|
+
startListeningToAnimatedNodeValue(nativeTag);
|
|
121
|
+
const subscription: EventSubscription =
|
|
132
122
|
NativeAnimatedHelper.nativeEventEmitter.addListener(
|
|
133
123
|
'onAnimatedValueUpdate',
|
|
134
124
|
data => {
|
|
135
|
-
if (data.tag
|
|
136
|
-
|
|
125
|
+
if (data.tag === nativeTag) {
|
|
126
|
+
this.__onAnimatedValueUpdateReceived(data.value);
|
|
137
127
|
}
|
|
138
|
-
this.__onAnimatedValueUpdateReceived(data.value);
|
|
139
128
|
},
|
|
140
129
|
);
|
|
130
|
+
|
|
131
|
+
this.#updateSubscription = {
|
|
132
|
+
remove: () => {
|
|
133
|
+
// Only this function assigns to `this.#updateSubscription`.
|
|
134
|
+
if (this.#updateSubscription == null) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.#updateSubscription = null;
|
|
138
|
+
subscription.remove();
|
|
139
|
+
stopListeningToAnimatedNodeValue(nativeTag);
|
|
140
|
+
},
|
|
141
|
+
};
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
__onAnimatedValueUpdateReceived(value: number) {
|
|
144
|
+
__onAnimatedValueUpdateReceived(value: number): void {
|
|
144
145
|
this.__callListeners(value);
|
|
145
146
|
}
|
|
146
147
|
|
|
@@ -151,16 +152,6 @@ export default class AnimatedNode {
|
|
|
151
152
|
});
|
|
152
153
|
}
|
|
153
154
|
|
|
154
|
-
_stopListeningForNativeValueUpdates() {
|
|
155
|
-
if (!this.__nativeAnimatedValueListener) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
this.__nativeAnimatedValueListener.remove();
|
|
160
|
-
this.__nativeAnimatedValueListener = null;
|
|
161
|
-
stopListeningToAnimatedNodeValue(this.__getNativeTag());
|
|
162
|
-
}
|
|
163
|
-
|
|
164
155
|
__getNativeTag(): number {
|
|
165
156
|
let nativeTag = this.__nativeTag;
|
|
166
157
|
if (nativeTag == null) {
|
|
@@ -181,7 +172,6 @@ export default class AnimatedNode {
|
|
|
181
172
|
config.platformConfig = this._platformConfig;
|
|
182
173
|
}
|
|
183
174
|
NativeAnimatedHelper.API.createAnimatedNode(nativeTag, config);
|
|
184
|
-
this.__shouldUpdateListenersForNewNativeTag = true;
|
|
185
175
|
}
|
|
186
176
|
return nativeTag;
|
|
187
177
|
}
|
|
@@ -192,10 +182,6 @@ export default class AnimatedNode {
|
|
|
192
182
|
);
|
|
193
183
|
}
|
|
194
184
|
|
|
195
|
-
toJSON(): any {
|
|
196
|
-
return this.__getValue();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
185
|
__getPlatformConfig(): ?PlatformConfig {
|
|
200
186
|
return this._platformConfig;
|
|
201
187
|
}
|
|
@@ -203,4 +189,12 @@ export default class AnimatedNode {
|
|
|
203
189
|
__setPlatformConfig(platformConfig: ?PlatformConfig) {
|
|
204
190
|
this._platformConfig = platformConfig;
|
|
205
191
|
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* NOTE: This is intended to prevent `JSON.stringify` from throwing "cyclic
|
|
195
|
+
* structure" errors in React DevTools. Avoid depending on this!
|
|
196
|
+
*/
|
|
197
|
+
toJSON(): mixed {
|
|
198
|
+
return this.__getValue();
|
|
199
|
+
}
|
|
206
200
|
}
|
|
@@ -19,9 +19,11 @@ import * as React from 'react';
|
|
|
19
19
|
|
|
20
20
|
const MAX_DEPTH = 5;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
export function isPlainObject(
|
|
23
|
+
value: mixed,
|
|
24
|
+
/* $FlowIssue[incompatible-type-guard] - Flow does not know that the prototype
|
|
25
|
+
and ReactElement checks preserve the type refinement of `value`. */
|
|
26
|
+
): value is $ReadOnly<{[string]: mixed}> {
|
|
25
27
|
return (
|
|
26
28
|
value !== null &&
|
|
27
29
|
typeof value === 'object' &&
|
|
@@ -109,6 +111,14 @@ export default class AnimatedObject extends AnimatedWithChildren {
|
|
|
109
111
|
});
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
__getValueWithStaticObject(staticObject: mixed): any {
|
|
115
|
+
const nodes = this.#nodes;
|
|
116
|
+
let index = 0;
|
|
117
|
+
// NOTE: We can depend on `this._value` and `staticObject` sharing a
|
|
118
|
+
// structure because of `useAnimatedPropsMemo`.
|
|
119
|
+
return mapAnimatedNodes(staticObject, () => nodes[index++].__getValue());
|
|
120
|
+
}
|
|
121
|
+
|
|
112
122
|
__getAnimatedValue(): any {
|
|
113
123
|
return mapAnimatedNodes(this._value, node => {
|
|
114
124
|
return node.__getAnimatedValue();
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
'use strict';
|
|
12
|
-
|
|
13
11
|
import type {PlatformConfig} from '../AnimatedPlatformConfig';
|
|
12
|
+
import type {AnimatedStyleAllowlist} from './AnimatedStyle';
|
|
14
13
|
|
|
15
14
|
import {findNodeHandle} from '../../ReactNative/RendererProxy';
|
|
16
15
|
import {AnimatedEvent} from '../AnimatedEvent';
|
|
@@ -20,30 +19,33 @@ import AnimatedObject from './AnimatedObject';
|
|
|
20
19
|
import AnimatedStyle from './AnimatedStyle';
|
|
21
20
|
import invariant from 'invariant';
|
|
22
21
|
|
|
22
|
+
export type AnimatedPropsAllowlist = $ReadOnly<{
|
|
23
|
+
style?: ?AnimatedStyleAllowlist,
|
|
24
|
+
[string]: true,
|
|
25
|
+
}>;
|
|
26
|
+
|
|
23
27
|
function createAnimatedProps(
|
|
24
|
-
inputProps:
|
|
25
|
-
|
|
28
|
+
inputProps: {[string]: mixed},
|
|
29
|
+
allowlist: ?AnimatedPropsAllowlist,
|
|
30
|
+
): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, {[string]: mixed}] {
|
|
26
31
|
const nodeKeys: Array<string> = [];
|
|
27
32
|
const nodes: Array<AnimatedNode> = [];
|
|
28
|
-
const props:
|
|
33
|
+
const props: {[string]: mixed} = {};
|
|
29
34
|
|
|
30
35
|
const keys = Object.keys(inputProps);
|
|
31
36
|
for (let ii = 0, length = keys.length; ii < length; ii++) {
|
|
32
37
|
const key = keys[ii];
|
|
33
38
|
const value = inputProps[key];
|
|
34
39
|
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
props[key] = node;
|
|
45
|
-
} else {
|
|
46
|
-
const node = AnimatedObject.from(value);
|
|
40
|
+
if (allowlist == null || Object.hasOwn(allowlist, key)) {
|
|
41
|
+
let node;
|
|
42
|
+
if (key === 'style') {
|
|
43
|
+
node = AnimatedStyle.from(value, allowlist?.style);
|
|
44
|
+
} else if (value instanceof AnimatedNode) {
|
|
45
|
+
node = value;
|
|
46
|
+
} else {
|
|
47
|
+
node = AnimatedObject.from(value);
|
|
48
|
+
}
|
|
47
49
|
if (node == null) {
|
|
48
50
|
props[key] = value;
|
|
49
51
|
} else {
|
|
@@ -51,6 +53,20 @@ function createAnimatedProps(
|
|
|
51
53
|
nodes.push(node);
|
|
52
54
|
props[key] = node;
|
|
53
55
|
}
|
|
56
|
+
} else {
|
|
57
|
+
if (__DEV__) {
|
|
58
|
+
// WARNING: This is a potentially expensive check that we should only
|
|
59
|
+
// do in development. Without this check in development, it might be
|
|
60
|
+
// difficult to identify which props need to be allowlisted.
|
|
61
|
+
if (AnimatedObject.from(inputProps[key]) != null) {
|
|
62
|
+
console.error(
|
|
63
|
+
`AnimatedProps: ${key} is not allowlisted for animation, but it ` +
|
|
64
|
+
'contains AnimatedNode values; props allowing animation: ',
|
|
65
|
+
allowlist,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
props[key] = value;
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
|
|
@@ -58,29 +74,32 @@ function createAnimatedProps(
|
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
export default class AnimatedProps extends AnimatedNode {
|
|
77
|
+
#animatedView: any = null;
|
|
78
|
+
#callback: () => void;
|
|
61
79
|
#nodeKeys: $ReadOnlyArray<string>;
|
|
62
80
|
#nodes: $ReadOnlyArray<AnimatedNode>;
|
|
81
|
+
#props: {[string]: mixed};
|
|
63
82
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
constructor(
|
|
84
|
+
inputProps: {[string]: mixed},
|
|
85
|
+
callback: () => void,
|
|
86
|
+
allowlist?: ?AnimatedPropsAllowlist,
|
|
87
|
+
) {
|
|
69
88
|
super();
|
|
70
|
-
const [nodeKeys, nodes, props] = createAnimatedProps(inputProps);
|
|
89
|
+
const [nodeKeys, nodes, props] = createAnimatedProps(inputProps, allowlist);
|
|
71
90
|
this.#nodeKeys = nodeKeys;
|
|
72
91
|
this.#nodes = nodes;
|
|
73
|
-
this
|
|
74
|
-
this
|
|
92
|
+
this.#props = props;
|
|
93
|
+
this.#callback = callback;
|
|
75
94
|
}
|
|
76
95
|
|
|
77
96
|
__getValue(): Object {
|
|
78
|
-
const props: {[string]:
|
|
97
|
+
const props: {[string]: mixed} = {};
|
|
79
98
|
|
|
80
|
-
const keys = Object.keys(this
|
|
99
|
+
const keys = Object.keys(this.#props);
|
|
81
100
|
for (let ii = 0, length = keys.length; ii < length; ii++) {
|
|
82
101
|
const key = keys[ii];
|
|
83
|
-
const value = this
|
|
102
|
+
const value = this.#props[key];
|
|
84
103
|
|
|
85
104
|
if (value instanceof AnimatedNode) {
|
|
86
105
|
props[key] = value.__getValue();
|
|
@@ -94,8 +113,33 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
94
113
|
return props;
|
|
95
114
|
}
|
|
96
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Creates a new `props` object that contains the same props as the supplied
|
|
118
|
+
* `staticProps` object, except with animated nodes for any props that were
|
|
119
|
+
* created by this `AnimatedProps` instance.
|
|
120
|
+
*/
|
|
121
|
+
__getValueWithStaticProps(staticProps: Object): Object {
|
|
122
|
+
const props: {[string]: mixed} = {...staticProps};
|
|
123
|
+
|
|
124
|
+
const keys = Object.keys(staticProps);
|
|
125
|
+
for (let ii = 0, length = keys.length; ii < length; ii++) {
|
|
126
|
+
const key = keys[ii];
|
|
127
|
+
const maybeNode = this.#props[key];
|
|
128
|
+
|
|
129
|
+
if (key === 'style' && maybeNode instanceof AnimatedStyle) {
|
|
130
|
+
props[key] = maybeNode.__getValueWithStaticStyle(staticProps.style);
|
|
131
|
+
} else if (maybeNode instanceof AnimatedNode) {
|
|
132
|
+
props[key] = maybeNode.__getValue();
|
|
133
|
+
} else if (maybeNode instanceof AnimatedEvent) {
|
|
134
|
+
props[key] = maybeNode.__getHandler();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return props;
|
|
139
|
+
}
|
|
140
|
+
|
|
97
141
|
__getAnimatedValue(): Object {
|
|
98
|
-
const props: {[string]:
|
|
142
|
+
const props: {[string]: mixed} = {};
|
|
99
143
|
|
|
100
144
|
const nodeKeys = this.#nodeKeys;
|
|
101
145
|
const nodes = this.#nodes;
|
|
@@ -117,10 +161,10 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
117
161
|
}
|
|
118
162
|
|
|
119
163
|
__detach(): void {
|
|
120
|
-
if (this.__isNative && this
|
|
164
|
+
if (this.__isNative && this.#animatedView) {
|
|
121
165
|
this.__disconnectAnimatedView();
|
|
122
166
|
}
|
|
123
|
-
this
|
|
167
|
+
this.#animatedView = null;
|
|
124
168
|
|
|
125
169
|
const nodes = this.#nodes;
|
|
126
170
|
for (let ii = 0, length = nodes.length; ii < length; ii++) {
|
|
@@ -132,7 +176,7 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
132
176
|
}
|
|
133
177
|
|
|
134
178
|
update(): void {
|
|
135
|
-
this
|
|
179
|
+
this.#callback();
|
|
136
180
|
}
|
|
137
181
|
|
|
138
182
|
__makeNative(platformConfig: ?PlatformConfig): void {
|
|
@@ -150,17 +194,17 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
150
194
|
// where it will be needed to traverse the graph of attached values.
|
|
151
195
|
super.__setPlatformConfig(platformConfig);
|
|
152
196
|
|
|
153
|
-
if (this
|
|
197
|
+
if (this.#animatedView) {
|
|
154
198
|
this.__connectAnimatedView();
|
|
155
199
|
}
|
|
156
200
|
}
|
|
157
201
|
}
|
|
158
202
|
|
|
159
203
|
setNativeView(animatedView: any): void {
|
|
160
|
-
if (this
|
|
204
|
+
if (this.#animatedView === animatedView) {
|
|
161
205
|
return;
|
|
162
206
|
}
|
|
163
|
-
this
|
|
207
|
+
this.#animatedView = animatedView;
|
|
164
208
|
if (this.__isNative) {
|
|
165
209
|
this.__connectAnimatedView();
|
|
166
210
|
}
|
|
@@ -168,7 +212,7 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
168
212
|
|
|
169
213
|
__connectAnimatedView(): void {
|
|
170
214
|
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
|
171
|
-
const nativeViewTag: ?number = findNodeHandle(this
|
|
215
|
+
const nativeViewTag: ?number = findNodeHandle(this.#animatedView);
|
|
172
216
|
invariant(
|
|
173
217
|
nativeViewTag != null,
|
|
174
218
|
'Unable to locate attached view in the native tree',
|
|
@@ -181,7 +225,7 @@ export default class AnimatedProps extends AnimatedNode {
|
|
|
181
225
|
|
|
182
226
|
__disconnectAnimatedView(): void {
|
|
183
227
|
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
|
184
|
-
const nativeViewTag: ?number = findNodeHandle(this
|
|
228
|
+
const nativeViewTag: ?number = findNodeHandle(this.#animatedView);
|
|
185
229
|
invariant(
|
|
186
230
|
nativeViewTag != null,
|
|
187
231
|
'Unable to locate attached view in the native tree',
|