UNPKG

4.5 kBPlain TextView Raw
1'use strict';
2import type { MeasuredDimensions, ShadowNodeWrapper } from '../commonTypes';
3import {
4 isChromeDebugger,
5 isFabric,
6 isJest,
7 shouldBeUseWeb,
8} from '../PlatformChecker';
9import type {
10 AnimatedRef,
11 AnimatedRefOnJS,
12 AnimatedRefOnUI,
13} from '../hook/commonTypes';
14import type { Component } from 'react';
15
16type Measure = <T extends Component>(
17 animatedRef: AnimatedRef<T>
18) => MeasuredDimensions | null;
19
20/**
21 * Lets you synchronously get the dimensions and position of a view on the screen.
22 *
23 * @param animatedRef - An [animated ref](https://docs.swmansion.com/react-native-reanimated/docs/core/useAnimatedRef#returns) connected to the component you'd want to get the measurements from.
24 * @returns An object containing component measurements or null when the measurement couldn't be performed- {@link MeasuredDimensions}.
25 * @see https://docs.swmansion.com/react-native-reanimated/docs/advanced/measure/
26 */
27export let measure: Measure;
28
29function measureFabric(animatedRef: AnimatedRefOnJS | AnimatedRefOnUI) {
30 'worklet';
31 if (!_WORKLET) {
32 return null;
33 }
34
35 const viewTag = animatedRef();
36 if (viewTag === -1) {
37 console.warn(
38 `[Reanimated] The view with tag ${viewTag} is not a valid argument for measure(). This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
39 );
40 return null;
41 }
42
43 const measured = global._measureFabric!(viewTag as ShadowNodeWrapper);
44 if (measured === null) {
45 console.warn(
46 `[Reanimated] The view has some undefined, not-yet-computed or meaningless value of \`LayoutMetrics\` type. This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
47 );
48 return null;
49 } else if (measured.x === -1234567) {
50 console.warn(
51 `[Reanimated] The view returned an invalid measurement response. Please make sure the view is currently rendered.`
52 );
53 return null;
54 } else if (isNaN(measured.x)) {
55 console.warn(
56 `[Reanimated] The view gets view-flattened on Android. To disable view-flattening, set \`collapsable={false}\` on this component.`
57 );
58 return null;
59 } else {
60 return measured;
61 }
62}
63
64function measurePaper(animatedRef: AnimatedRefOnJS | AnimatedRefOnUI) {
65 'worklet';
66 if (!_WORKLET) {
67 return null;
68 }
69
70 const viewTag = animatedRef();
71 if (viewTag === -1) {
72 console.warn(
73 `[Reanimated] The view with tag ${viewTag} is not a valid argument for measure(). This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
74 );
75 return null;
76 }
77
78 const measured = global._measurePaper!(viewTag as number);
79 if (measured === null) {
80 console.warn(
81 `[Reanimated] The view with tag ${
82 viewTag as number
83 } has some undefined, not-yet-computed or meaningless value of \`LayoutMetrics\` type. This may be because the view is not currently rendered, which may not be a bug (e.g. an off-screen FlatList item).`
84 );
85 return null;
86 } else if (measured.x === -1234567) {
87 console.warn(
88 `[Reanimated] The view with tag ${
89 viewTag as number
90 } returned an invalid measurement response. Please make sure the view is currently rendered.`
91 );
92 return null;
93 } else if (isNaN(measured.x)) {
94 console.warn(
95 `[Reanimated] The view with tag ${
96 viewTag as number
97 } gets view-flattened on Android. To disable view-flattening, set \`collapsable={false}\` on this component.`
98 );
99 return null;
100 } else {
101 return measured;
102 }
103}
104
105function measureJest() {
106 console.warn('[Reanimated] measure() cannot be used with Jest.');
107 return null;
108}
109
110function measureChromeDebugger() {
111 console.warn('[Reanimated] measure() cannot be used with Chrome Debugger.');
112 return null;
113}
114
115function measureDefault() {
116 console.warn(
117 '[Reanimated] measure() is not supported on this configuration.'
118 );
119 return null;
120}
121
122if (!shouldBeUseWeb()) {
123 // Those assertions are actually correct since on Native platforms `AnimatedRef` is
124 // mapped as a different function in `shareableMappingCache` and
125 // TypeScript is not able to infer that.
126 if (isFabric()) {
127 measure = measureFabric as unknown as Measure;
128 } else {
129 measure = measurePaper as unknown as Measure;
130 }
131} else if (isJest()) {
132 measure = measureJest;
133} else if (isChromeDebugger()) {
134 measure = measureChromeDebugger;
135} else {
136 measure = measureDefault;
137}