Skip to content

Commit

Permalink
[fix] layout measurement API consistency with React Native
Browse files Browse the repository at this point in the history
* Ignore CSS transforms in measurement.
* Cancel measurement if elements are unmounted.

Close #2501
Fix #1254
  • Loading branch information
LucioChavezFuentes authored and necolas committed Mar 28, 2023
1 parent 782a19a commit 03ddd95
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions packages/react-native-web/src/exports/UIManager/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,38 @@
* @noflow
*/

import getBoundingClientRect from '../../modules/getBoundingClientRect';
import setValueForStyles from '../../modules/setValueForStyles';

const getRect = (node) => {
// Unlike the DOM's getBoundingClientRect, React Native layout measurements
// for "height" and "width" ignore scale transforms.
// https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
const { x, y, top, left } = getBoundingClientRect(node);
const width = node.offsetWidth;
const height = node.offsetHeight;
return { x, y, width, height, top, left };
const width = node.offsetWidth;
let left = node.offsetLeft;
let top = node.offsetTop;
node = node.offsetParent;

while (node && node.nodeType === 1 /* Node.ELEMENT_NODE */) {
left += node.offsetLeft + node.clientLeft - node.scrollLeft;
top += node.offsetTop + node.clientTop - node.scrollTop;
node = node.offsetParent;
}

top -= window.scrollY;
left -= window.scrollX;

return { width, height, top, left };
};

const measureLayout = (node, relativeToNativeNode, callback) => {
const relativeNode = relativeToNativeNode || (node && node.parentNode);
if (node && relativeNode) {
setTimeout(() => {
const relativeRect = getBoundingClientRect(relativeNode);
const { height, left, top, width } = getRect(node);
const x = left - relativeRect.left;
const y = top - relativeRect.top;
callback(x, y, width, height, left, top);
if (node.isConnected && relativeNode.isConnected) {
const relativeRect = getRect(relativeNode);
const { height, left, top, width } = getRect(node);
const x = left - relativeRect.left;
const y = top - relativeRect.top;
callback(x, y, width, height, left, top);
}
}, 0);
}
};
Expand Down

0 comments on commit 03ddd95

Please sign in to comment.