@tamagui/use-element-layout 1.130.0 → 1.130.2
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/dist/cjs/index.cjs +32 -18
- package/dist/cjs/index.js +28 -11
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +52 -41
- package/dist/cjs/index.native.js.map +2 -2
- package/dist/esm/index.js +28 -11
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +32 -18
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +51 -37
- package/dist/esm/index.native.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +53 -9
- package/types/index.d.ts.map +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -33,8 +33,10 @@ module.exports = __toCommonJS(index_exports);
|
|
|
33
33
|
var import_constants = require("@tamagui/constants"),
|
|
34
34
|
import_is_equal_shallow = require("@tamagui/is-equal-shallow");
|
|
35
35
|
const LayoutHandlers = /* @__PURE__ */new WeakMap(),
|
|
36
|
-
Nodes = /* @__PURE__ */new Set()
|
|
37
|
-
|
|
36
|
+
Nodes = /* @__PURE__ */new Set(),
|
|
37
|
+
IntersectionState = /* @__PURE__ */new WeakMap();
|
|
38
|
+
let globalIntersectionObserver = null,
|
|
39
|
+
strategy = "async";
|
|
38
40
|
function setOnLayoutStrategy(state) {
|
|
39
41
|
strategy = state;
|
|
40
42
|
}
|
|
@@ -49,20 +51,32 @@ function enable() {
|
|
|
49
51
|
}
|
|
50
52
|
const expectedFrameTime = 16.67,
|
|
51
53
|
numDroppedFramesUntilPause = 10;
|
|
54
|
+
function startGlobalIntersectionObserver() {
|
|
55
|
+
!import_constants.isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(entries => {
|
|
56
|
+
entries.forEach(entry => {
|
|
57
|
+
const node = entry.target;
|
|
58
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
59
|
+
});
|
|
60
|
+
}, {
|
|
61
|
+
threshold: 0
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
52
64
|
if (import_constants.isClient) if (rAF) {
|
|
53
65
|
let layoutOnAnimationFrame = function () {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
const now = Date.now(),
|
|
67
|
+
timeSinceLastFrame = now - lastFrameAt;
|
|
68
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
69
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
strategy !== "off" && (timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause || Nodes.forEach(node => {
|
|
73
|
+
updateLayoutIfChanged(node, lastFrameAt);
|
|
74
|
+
})), rAF(layoutOnAnimationFrame);
|
|
75
|
+
};
|
|
76
|
+
const supportsCheckVisibility = "checkVisibility" in document.body;
|
|
77
|
+
let lastFrameAt = Date.now();
|
|
65
78
|
async function updateLayoutIfChanged(node, frameId) {
|
|
79
|
+
if (supportsCheckVisibility && !node.checkVisibility() || IntersectionState.get(node) === !1) return;
|
|
66
80
|
const onLayout = LayoutHandlers.get(node);
|
|
67
81
|
if (typeof onLayout != "function") return;
|
|
68
82
|
const parentNode = node.parentElement;
|
|
@@ -88,7 +102,7 @@ if (import_constants.isClient) if (rAF) {
|
|
|
88
102
|
}
|
|
89
103
|
rAF(layoutOnAnimationFrame);
|
|
90
104
|
let frameCount = 0;
|
|
91
|
-
const
|
|
105
|
+
const RUN_EVERY_X_FRAMES = 4;
|
|
92
106
|
} else process.env.NODE_ENV === "development" && console.warn("No requestAnimationFrame - please polyfill for onLayout to work correctly");
|
|
93
107
|
const getElementLayoutEvent = (nodeRect, parentRect) => ({
|
|
94
108
|
nativeEvent: {
|
|
@@ -175,10 +189,10 @@ function useElementLayout(ref, onLayout) {
|
|
|
175
189
|
if (!onLayout) return;
|
|
176
190
|
const node2 = ref.current?.host;
|
|
177
191
|
if (!node2) return;
|
|
178
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
192
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
179
193
|
const parentNode = node2.parentNode;
|
|
180
194
|
return parentNode && onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect())), () => {
|
|
181
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
195
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
182
196
|
};
|
|
183
197
|
}, [ref, !!onLayout]);
|
|
184
198
|
}
|
|
@@ -186,8 +200,8 @@ function ensureWebElement(x) {
|
|
|
186
200
|
if (!(typeof HTMLElement > "u")) return x instanceof HTMLElement ? x : void 0;
|
|
187
201
|
}
|
|
188
202
|
const getBoundingClientRectAsync = node => new Promise(res => {
|
|
189
|
-
if (!node || node.nodeType !== 1) return;
|
|
190
|
-
const io = new IntersectionObserver(entries =>
|
|
203
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
204
|
+
const io = new IntersectionObserver(entries => (io.disconnect(), res(entries[0].boundingClientRect)), {
|
|
191
205
|
threshold: 0
|
|
192
206
|
});
|
|
193
207
|
io.observe(node);
|
package/dist/cjs/index.js
CHANGED
|
@@ -25,8 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(index_exports);
|
|
27
27
|
var import_constants = require("@tamagui/constants"), import_is_equal_shallow = require("@tamagui/is-equal-shallow");
|
|
28
|
-
const LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set();
|
|
29
|
-
let strategy = "async";
|
|
28
|
+
const LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set(), IntersectionState = /* @__PURE__ */ new WeakMap();
|
|
29
|
+
let globalIntersectionObserver = null, strategy = "async";
|
|
30
30
|
function setOnLayoutStrategy(state) {
|
|
31
31
|
strategy = state;
|
|
32
32
|
}
|
|
@@ -37,19 +37,36 @@ function enable() {
|
|
|
37
37
|
avoidUpdates && (avoidUpdates = !1, queuedUpdates && (queuedUpdates.forEach((cb) => cb()), queuedUpdates.clear()));
|
|
38
38
|
}
|
|
39
39
|
const expectedFrameTime = 16.67, numDroppedFramesUntilPause = 10;
|
|
40
|
+
function startGlobalIntersectionObserver() {
|
|
41
|
+
!import_constants.isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(
|
|
42
|
+
(entries) => {
|
|
43
|
+
entries.forEach((entry) => {
|
|
44
|
+
const node = entry.target;
|
|
45
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
threshold: 0
|
|
50
|
+
}
|
|
51
|
+
));
|
|
52
|
+
}
|
|
40
53
|
if (import_constants.isClient)
|
|
41
54
|
if (rAF) {
|
|
42
55
|
let layoutOnAnimationFrame = function() {
|
|
43
56
|
const now = Date.now(), timeSinceLastFrame = now - lastFrameAt;
|
|
44
|
-
if (lastFrameAt = now, frameCount
|
|
45
|
-
frameCount
|
|
57
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
58
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
46
59
|
return;
|
|
47
60
|
}
|
|
48
|
-
|
|
61
|
+
strategy !== "off" && (timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause || Nodes.forEach((node) => {
|
|
49
62
|
updateLayoutIfChanged(node, lastFrameAt);
|
|
50
63
|
})), rAF(layoutOnAnimationFrame);
|
|
51
|
-
}
|
|
64
|
+
};
|
|
65
|
+
const supportsCheckVisibility = "checkVisibility" in document.body;
|
|
66
|
+
let lastFrameAt = Date.now();
|
|
52
67
|
async function updateLayoutIfChanged(node, frameId) {
|
|
68
|
+
if (supportsCheckVisibility && !node.checkVisibility() || IntersectionState.get(node) === !1)
|
|
69
|
+
return;
|
|
53
70
|
const onLayout = LayoutHandlers.get(node);
|
|
54
71
|
if (typeof onLayout != "function") return;
|
|
55
72
|
const parentNode = node.parentElement;
|
|
@@ -77,7 +94,7 @@ if (import_constants.isClient)
|
|
|
77
94
|
}
|
|
78
95
|
rAF(layoutOnAnimationFrame);
|
|
79
96
|
let frameCount = 0;
|
|
80
|
-
const
|
|
97
|
+
const RUN_EVERY_X_FRAMES = 4;
|
|
81
98
|
} else
|
|
82
99
|
process.env.NODE_ENV === "development" && console.warn(
|
|
83
100
|
"No requestAnimationFrame - please polyfill for onLayout to work correctly"
|
|
@@ -137,7 +154,7 @@ function useElementLayout(ref, onLayout) {
|
|
|
137
154
|
if (!onLayout) return;
|
|
138
155
|
const node2 = ref.current?.host;
|
|
139
156
|
if (!node2) return;
|
|
140
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
157
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
141
158
|
const parentNode = node2.parentNode;
|
|
142
159
|
return parentNode && onLayout(
|
|
143
160
|
getElementLayoutEvent(
|
|
@@ -145,7 +162,7 @@ function useElementLayout(ref, onLayout) {
|
|
|
145
162
|
parentNode.getBoundingClientRect()
|
|
146
163
|
)
|
|
147
164
|
), () => {
|
|
148
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
165
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
149
166
|
};
|
|
150
167
|
}, [ref, !!onLayout]);
|
|
151
168
|
}
|
|
@@ -154,9 +171,9 @@ function ensureWebElement(x) {
|
|
|
154
171
|
return x instanceof HTMLElement ? x : void 0;
|
|
155
172
|
}
|
|
156
173
|
const getBoundingClientRectAsync = (node) => new Promise((res) => {
|
|
157
|
-
if (!node || node.nodeType !== 1) return;
|
|
174
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
158
175
|
const io = new IntersectionObserver(
|
|
159
|
-
(entries) =>
|
|
176
|
+
(entries) => (io.disconnect(), res(entries[0].boundingClientRect)),
|
|
160
177
|
{
|
|
161
178
|
threshold: 0
|
|
162
179
|
}
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAoD,+BACpD,0BAA+B;AAG/B,MAAM,iBAAiB,oBAAI,QAA+B,GACpD,QAAQ,oBAAI,IAAiB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["node"]
|
|
6
6
|
}
|
package/dist/cjs/index.native.js
CHANGED
|
@@ -25,7 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
useElementLayout: () => useElementLayout
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
|
-
var import_constants = require("@tamagui/constants"), import_is_equal_shallow = require("@tamagui/is-equal-shallow"), LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set(), strategy = "async";
|
|
28
|
+
var import_constants = require("@tamagui/constants"), import_is_equal_shallow = require("@tamagui/is-equal-shallow"), LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set(), IntersectionState = /* @__PURE__ */ new WeakMap(), globalIntersectionObserver = null, strategy = "async";
|
|
29
29
|
function setOnLayoutStrategy(state) {
|
|
30
30
|
strategy = state;
|
|
31
31
|
}
|
|
@@ -36,15 +36,25 @@ function enable() {
|
|
|
36
36
|
}), queuedUpdates.clear()));
|
|
37
37
|
}
|
|
38
38
|
var expectedFrameTime = 16.67, numDroppedFramesUntilPause = 10;
|
|
39
|
+
function startGlobalIntersectionObserver() {
|
|
40
|
+
!import_constants.isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(function(entries) {
|
|
41
|
+
entries.forEach(function(entry) {
|
|
42
|
+
var node = entry.target;
|
|
43
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
44
|
+
});
|
|
45
|
+
}, {
|
|
46
|
+
threshold: 0
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
39
49
|
if (import_constants.isClient)
|
|
40
50
|
if (rAF) {
|
|
41
51
|
let layoutOnAnimationFrame = function() {
|
|
42
52
|
var now = Date.now(), timeSinceLastFrame = now - lastFrameAt;
|
|
43
|
-
if (lastFrameAt = now, frameCount
|
|
44
|
-
frameCount
|
|
53
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
54
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
45
55
|
return;
|
|
46
56
|
}
|
|
47
|
-
if (
|
|
57
|
+
if (strategy !== "off") {
|
|
48
58
|
var hasRecentSyncWork = timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause;
|
|
49
59
|
hasRecentSyncWork || Nodes.forEach(function(node) {
|
|
50
60
|
updateLayoutIfChanged(node, lastFrameAt);
|
|
@@ -52,39 +62,41 @@ if (import_constants.isClient)
|
|
|
52
62
|
}
|
|
53
63
|
rAF(layoutOnAnimationFrame);
|
|
54
64
|
};
|
|
55
|
-
var layoutOnAnimationFrame2 = layoutOnAnimationFrame, lastFrameAt = Date.now();
|
|
65
|
+
var layoutOnAnimationFrame2 = layoutOnAnimationFrame, supportsCheckVisibility = "checkVisibility" in document.body, lastFrameAt = Date.now();
|
|
56
66
|
async function updateLayoutIfChanged(node, frameId) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
if (!(supportsCheckVisibility && !node.checkVisibility()) && IntersectionState.get(node) !== !1) {
|
|
68
|
+
var onLayout = LayoutHandlers.get(node);
|
|
69
|
+
if (typeof onLayout == "function") {
|
|
70
|
+
var parentNode = node.parentElement;
|
|
71
|
+
if (parentNode) {
|
|
72
|
+
var nodeRect, parentRect;
|
|
73
|
+
if (strategy === "async") {
|
|
74
|
+
var [nr, pr] = await Promise.all([
|
|
75
|
+
getBoundingClientRectAsync(node),
|
|
76
|
+
getBoundingClientRectAsync(parentNode)
|
|
77
|
+
]);
|
|
78
|
+
if (nr === !1 || pr === !1 || frameId !== lastFrameAt)
|
|
79
|
+
return;
|
|
80
|
+
nodeRect = nr, parentRect = pr;
|
|
81
|
+
} else
|
|
82
|
+
nodeRect = node.getBoundingClientRect(), parentRect = parentNode.getBoundingClientRect();
|
|
83
|
+
var cachedRect = NodeRectCache.get(node), cachedParentRect = NodeRectCache.get(parentNode);
|
|
84
|
+
if (!cachedRect || // has changed one rect
|
|
85
|
+
// @ts-expect-error DOMRectReadOnly can go into object
|
|
86
|
+
!(0, import_is_equal_shallow.isEqualShallow)(cachedRect, nodeRect) && // @ts-expect-error DOMRectReadOnly can go into object
|
|
87
|
+
(!cachedParentRect || !(0, import_is_equal_shallow.isEqualShallow)(cachedParentRect, parentRect))) {
|
|
88
|
+
NodeRectCache.set(node, nodeRect), ParentRectCache.set(parentNode, parentRect);
|
|
89
|
+
var event = getElementLayoutEvent(nodeRect, parentRect);
|
|
90
|
+
avoidUpdates ? queuedUpdates.set(node, function() {
|
|
91
|
+
return onLayout(event);
|
|
92
|
+
}) : onLayout(event);
|
|
93
|
+
}
|
|
82
94
|
}
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
}
|
|
86
98
|
rAF(layoutOnAnimationFrame);
|
|
87
|
-
var frameCount = 0,
|
|
99
|
+
var frameCount = 0, RUN_EVERY_X_FRAMES = 4;
|
|
88
100
|
} else
|
|
89
101
|
process.env.NODE_ENV === "development" && console.warn("No requestAnimationFrame - please polyfill for onLayout to work correctly");
|
|
90
102
|
var getElementLayoutEvent = function(nodeRect, parentRect) {
|
|
@@ -153,10 +165,10 @@ function useElementLayout(ref, onLayout) {
|
|
|
153
165
|
if (onLayout) {
|
|
154
166
|
var node2 = (_ref_current2 = ref.current) === null || _ref_current2 === void 0 ? void 0 : _ref_current2.host;
|
|
155
167
|
if (node2) {
|
|
156
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
168
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
157
169
|
var parentNode = node2.parentNode;
|
|
158
170
|
return parentNode && onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect())), function() {
|
|
159
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
171
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
160
172
|
};
|
|
161
173
|
}
|
|
162
174
|
}
|
|
@@ -171,14 +183,13 @@ function ensureWebElement(x) {
|
|
|
171
183
|
}
|
|
172
184
|
var getBoundingClientRectAsync = function(node) {
|
|
173
185
|
return new Promise(function(res) {
|
|
174
|
-
if (!
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
186
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
187
|
+
var io = new IntersectionObserver(function(entries) {
|
|
188
|
+
return io.disconnect(), res(entries[0].boundingClientRect);
|
|
189
|
+
}, {
|
|
190
|
+
threshold: 0
|
|
191
|
+
});
|
|
192
|
+
io.observe(node);
|
|
182
193
|
});
|
|
183
194
|
}, getBoundingClientRect = function(node) {
|
|
184
195
|
var _node_getBoundingClientRect;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;uBAAoD,+BACpD,0BAA+B,sCAGzBA,iBAAiB,oBAAIC,QAAAA,GACrBC,QAAQ,oBAAIC,IAAAA,
|
|
5
|
-
"names": ["LayoutHandlers", "WeakMap", "Nodes", "Set", "strategy", "setOnLayoutStrategy", "state", "NodeRectCache", "ParentRectCache", "LastChangeTime", "rAF", "window", "requestAnimationFrame", "undefined", "avoidUpdates", "queuedUpdates", "Map", "enable", "forEach", "cb", "clear", "expectedFrameTime", "numDroppedFramesUntilPause", "isClient", "layoutOnAnimationFrame", "now", "Date", "timeSinceLastFrame", "lastFrameAt", "frameCount", "
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["LayoutHandlers", "WeakMap", "Nodes", "Set", "IntersectionState", "globalIntersectionObserver", "strategy", "setOnLayoutStrategy", "state", "NodeRectCache", "ParentRectCache", "LastChangeTime", "rAF", "window", "requestAnimationFrame", "undefined", "avoidUpdates", "queuedUpdates", "Map", "enable", "forEach", "cb", "clear", "expectedFrameTime", "numDroppedFramesUntilPause", "startGlobalIntersectionObserver", "isClient", "IntersectionObserver", "entries", "entry", "node", "target", "get", "isIntersecting", "set", "threshold", "layoutOnAnimationFrame", "now", "Date", "timeSinceLastFrame", "lastFrameAt", "frameCount", "RUN_EVERY_X_FRAMES", "hasRecentSyncWork", "updateLayoutIfChanged", "supportsCheckVisibility", "document", "body", "frameId", "checkVisibility", "onLayout", "parentNode", "parentElement", "nodeRect", "parentRect", "nr", "pr", "Promise", "all", "getBoundingClientRectAsync", "getBoundingClientRect", "cachedRect", "cachedParentRect", "isEqualShallow", "event", "getElementLayoutEvent", "process", "env", "NODE_ENV", "console", "warn", "nativeEvent", "layout", "getRelativeDimensions", "timeStamp", "measureLayout", "relativeTo", "callback", "relativeNode", "HTMLElement", "nodeDim", "relativeNodeDim", "x", "y", "width", "height", "left", "top", "getElementLayoutEventAsync", "measureLayoutAsync", "Error", "a", "b", "useElementLayout", "ref", "ensureWebElement", "current", "host", "useIsomorphicLayoutEffect", "add", "observe", "delete", "unobserve", "res", "nodeType", "io", "disconnect", "boundingClientRect", "getRect", "rect", "offsetWidth", "offsetHeight"]
|
|
6
6
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isClient, useIsomorphicLayoutEffect } from "@tamagui/constants";
|
|
2
2
|
import { isEqualShallow } from "@tamagui/is-equal-shallow";
|
|
3
|
-
const LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set();
|
|
4
|
-
let strategy = "async";
|
|
3
|
+
const LayoutHandlers = /* @__PURE__ */ new WeakMap(), Nodes = /* @__PURE__ */ new Set(), IntersectionState = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
let globalIntersectionObserver = null, strategy = "async";
|
|
5
5
|
function setOnLayoutStrategy(state) {
|
|
6
6
|
strategy = state;
|
|
7
7
|
}
|
|
@@ -12,19 +12,36 @@ function enable() {
|
|
|
12
12
|
avoidUpdates && (avoidUpdates = !1, queuedUpdates && (queuedUpdates.forEach((cb) => cb()), queuedUpdates.clear()));
|
|
13
13
|
}
|
|
14
14
|
const expectedFrameTime = 16.67, numDroppedFramesUntilPause = 10;
|
|
15
|
+
function startGlobalIntersectionObserver() {
|
|
16
|
+
!isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(
|
|
17
|
+
(entries) => {
|
|
18
|
+
entries.forEach((entry) => {
|
|
19
|
+
const node = entry.target;
|
|
20
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
threshold: 0
|
|
25
|
+
}
|
|
26
|
+
));
|
|
27
|
+
}
|
|
15
28
|
if (isClient)
|
|
16
29
|
if (rAF) {
|
|
17
30
|
let layoutOnAnimationFrame = function() {
|
|
18
31
|
const now = Date.now(), timeSinceLastFrame = now - lastFrameAt;
|
|
19
|
-
if (lastFrameAt = now, frameCount
|
|
20
|
-
frameCount
|
|
32
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
33
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
21
34
|
return;
|
|
22
35
|
}
|
|
23
|
-
|
|
36
|
+
strategy !== "off" && (timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause || Nodes.forEach((node) => {
|
|
24
37
|
updateLayoutIfChanged(node, lastFrameAt);
|
|
25
38
|
})), rAF(layoutOnAnimationFrame);
|
|
26
|
-
}
|
|
39
|
+
};
|
|
40
|
+
const supportsCheckVisibility = "checkVisibility" in document.body;
|
|
41
|
+
let lastFrameAt = Date.now();
|
|
27
42
|
async function updateLayoutIfChanged(node, frameId) {
|
|
43
|
+
if (supportsCheckVisibility && !node.checkVisibility() || IntersectionState.get(node) === !1)
|
|
44
|
+
return;
|
|
28
45
|
const onLayout = LayoutHandlers.get(node);
|
|
29
46
|
if (typeof onLayout != "function") return;
|
|
30
47
|
const parentNode = node.parentElement;
|
|
@@ -52,7 +69,7 @@ if (isClient)
|
|
|
52
69
|
}
|
|
53
70
|
rAF(layoutOnAnimationFrame);
|
|
54
71
|
let frameCount = 0;
|
|
55
|
-
const
|
|
72
|
+
const RUN_EVERY_X_FRAMES = 4;
|
|
56
73
|
} else
|
|
57
74
|
process.env.NODE_ENV === "development" && console.warn(
|
|
58
75
|
"No requestAnimationFrame - please polyfill for onLayout to work correctly"
|
|
@@ -112,7 +129,7 @@ function useElementLayout(ref, onLayout) {
|
|
|
112
129
|
if (!onLayout) return;
|
|
113
130
|
const node2 = ref.current?.host;
|
|
114
131
|
if (!node2) return;
|
|
115
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
132
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
116
133
|
const parentNode = node2.parentNode;
|
|
117
134
|
return parentNode && onLayout(
|
|
118
135
|
getElementLayoutEvent(
|
|
@@ -120,7 +137,7 @@ function useElementLayout(ref, onLayout) {
|
|
|
120
137
|
parentNode.getBoundingClientRect()
|
|
121
138
|
)
|
|
122
139
|
), () => {
|
|
123
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
140
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
124
141
|
};
|
|
125
142
|
}, [ref, !!onLayout]);
|
|
126
143
|
}
|
|
@@ -129,9 +146,9 @@ function ensureWebElement(x) {
|
|
|
129
146
|
return x instanceof HTMLElement ? x : void 0;
|
|
130
147
|
}
|
|
131
148
|
const getBoundingClientRectAsync = (node) => new Promise((res) => {
|
|
132
|
-
if (!node || node.nodeType !== 1) return;
|
|
149
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
133
150
|
const io = new IntersectionObserver(
|
|
134
|
-
(entries) =>
|
|
151
|
+
(entries) => (io.disconnect(), res(entries[0].boundingClientRect)),
|
|
135
152
|
{
|
|
136
153
|
threshold: 0
|
|
137
154
|
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,UAAU,iCAAiC;AACpD,SAAS,sBAAsB;AAG/B,MAAM,iBAAiB,oBAAI,QAA+B,GACpD,QAAQ,oBAAI,IAAiB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["node"]
|
|
6
6
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { isClient, useIsomorphicLayoutEffect } from "@tamagui/constants";
|
|
2
2
|
import { isEqualShallow } from "@tamagui/is-equal-shallow";
|
|
3
3
|
const LayoutHandlers = /* @__PURE__ */new WeakMap(),
|
|
4
|
-
Nodes = /* @__PURE__ */new Set()
|
|
5
|
-
|
|
4
|
+
Nodes = /* @__PURE__ */new Set(),
|
|
5
|
+
IntersectionState = /* @__PURE__ */new WeakMap();
|
|
6
|
+
let globalIntersectionObserver = null,
|
|
7
|
+
strategy = "async";
|
|
6
8
|
function setOnLayoutStrategy(state) {
|
|
7
9
|
strategy = state;
|
|
8
10
|
}
|
|
@@ -17,20 +19,32 @@ function enable() {
|
|
|
17
19
|
}
|
|
18
20
|
const expectedFrameTime = 16.67,
|
|
19
21
|
numDroppedFramesUntilPause = 10;
|
|
22
|
+
function startGlobalIntersectionObserver() {
|
|
23
|
+
!isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(entries => {
|
|
24
|
+
entries.forEach(entry => {
|
|
25
|
+
const node = entry.target;
|
|
26
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
27
|
+
});
|
|
28
|
+
}, {
|
|
29
|
+
threshold: 0
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
20
32
|
if (isClient) if (rAF) {
|
|
21
33
|
let layoutOnAnimationFrame = function () {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
const now = Date.now(),
|
|
35
|
+
timeSinceLastFrame = now - lastFrameAt;
|
|
36
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
37
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
strategy !== "off" && (timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause || Nodes.forEach(node => {
|
|
41
|
+
updateLayoutIfChanged(node, lastFrameAt);
|
|
42
|
+
})), rAF(layoutOnAnimationFrame);
|
|
43
|
+
};
|
|
44
|
+
const supportsCheckVisibility = "checkVisibility" in document.body;
|
|
45
|
+
let lastFrameAt = Date.now();
|
|
33
46
|
async function updateLayoutIfChanged(node, frameId) {
|
|
47
|
+
if (supportsCheckVisibility && !node.checkVisibility() || IntersectionState.get(node) === !1) return;
|
|
34
48
|
const onLayout = LayoutHandlers.get(node);
|
|
35
49
|
if (typeof onLayout != "function") return;
|
|
36
50
|
const parentNode = node.parentElement;
|
|
@@ -56,7 +70,7 @@ if (isClient) if (rAF) {
|
|
|
56
70
|
}
|
|
57
71
|
rAF(layoutOnAnimationFrame);
|
|
58
72
|
let frameCount = 0;
|
|
59
|
-
const
|
|
73
|
+
const RUN_EVERY_X_FRAMES = 4;
|
|
60
74
|
} else process.env.NODE_ENV === "development" && console.warn("No requestAnimationFrame - please polyfill for onLayout to work correctly");
|
|
61
75
|
const getElementLayoutEvent = (nodeRect, parentRect) => ({
|
|
62
76
|
nativeEvent: {
|
|
@@ -143,10 +157,10 @@ function useElementLayout(ref, onLayout) {
|
|
|
143
157
|
if (!onLayout) return;
|
|
144
158
|
const node2 = ref.current?.host;
|
|
145
159
|
if (!node2) return;
|
|
146
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
160
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
147
161
|
const parentNode = node2.parentNode;
|
|
148
162
|
return parentNode && onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect())), () => {
|
|
149
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
163
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
150
164
|
};
|
|
151
165
|
}, [ref, !!onLayout]);
|
|
152
166
|
}
|
|
@@ -154,8 +168,8 @@ function ensureWebElement(x) {
|
|
|
154
168
|
if (!(typeof HTMLElement > "u")) return x instanceof HTMLElement ? x : void 0;
|
|
155
169
|
}
|
|
156
170
|
const getBoundingClientRectAsync = node => new Promise(res => {
|
|
157
|
-
if (!node || node.nodeType !== 1) return;
|
|
158
|
-
const io = new IntersectionObserver(entries =>
|
|
171
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
172
|
+
const io = new IntersectionObserver(entries => (io.disconnect(), res(entries[0].boundingClientRect)), {
|
|
159
173
|
threshold: 0
|
|
160
174
|
});
|
|
161
175
|
io.observe(node);
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isClient","useIsomorphicLayoutEffect","isEqualShallow","LayoutHandlers","WeakMap","Nodes","Set","strategy","setOnLayoutStrategy","state","NodeRectCache","ParentRectCache","LastChangeTime","rAF","window","requestAnimationFrame","avoidUpdates","queuedUpdates","Map","enable","forEach","cb","clear","expectedFrameTime","numDroppedFramesUntilPause","layoutOnAnimationFrame","now","Date","timeSinceLastFrame","lastFrameAt","frameCount","
|
|
1
|
+
{"version":3,"names":["isClient","useIsomorphicLayoutEffect","isEqualShallow","LayoutHandlers","WeakMap","Nodes","Set","IntersectionState","globalIntersectionObserver","strategy","setOnLayoutStrategy","state","NodeRectCache","ParentRectCache","LastChangeTime","rAF","window","requestAnimationFrame","avoidUpdates","queuedUpdates","Map","enable","forEach","cb","clear","expectedFrameTime","numDroppedFramesUntilPause","startGlobalIntersectionObserver","IntersectionObserver","entries","entry","node","target","get","isIntersecting","set","threshold","layoutOnAnimationFrame","now","Date","timeSinceLastFrame","lastFrameAt","frameCount","RUN_EVERY_X_FRAMES","updateLayoutIfChanged","supportsCheckVisibility","document","body","frameId","checkVisibility","onLayout","parentNode","parentElement","nodeRect","parentRect","nr","pr","Promise","all","getBoundingClientRectAsync","getBoundingClientRect","cachedRect","cachedParentRect","event","getElementLayoutEvent","process","env","NODE_ENV","console","warn","nativeEvent","layout","getRelativeDimensions","timeStamp","measureLayout","relativeTo","callback","relativeNode","HTMLElement","nodeDim","relativeNodeDim","x","y","width","height","left","top","getElementLayoutEventAsync","measureLayoutAsync","Error","a","b","useElementLayout","ref","ensureWebElement","current","host","node2","add","observe","delete","unobserve","res","nodeType","io","disconnect","boundingClientRect","getRect","rect","offsetWidth","offsetHeight"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/esm/index.native.js
CHANGED
|
@@ -2,6 +2,8 @@ import { isClient, useIsomorphicLayoutEffect } from "@tamagui/constants";
|
|
|
2
2
|
import { isEqualShallow } from "@tamagui/is-equal-shallow";
|
|
3
3
|
var LayoutHandlers = /* @__PURE__ */new WeakMap(),
|
|
4
4
|
Nodes = /* @__PURE__ */new Set(),
|
|
5
|
+
IntersectionState = /* @__PURE__ */new WeakMap(),
|
|
6
|
+
globalIntersectionObserver = null,
|
|
5
7
|
strategy = "async";
|
|
6
8
|
function setOnLayoutStrategy(state) {
|
|
7
9
|
strategy = state;
|
|
@@ -19,15 +21,25 @@ function enable() {
|
|
|
19
21
|
}
|
|
20
22
|
var expectedFrameTime = 16.67,
|
|
21
23
|
numDroppedFramesUntilPause = 10;
|
|
24
|
+
function startGlobalIntersectionObserver() {
|
|
25
|
+
!isClient || globalIntersectionObserver || (globalIntersectionObserver = new IntersectionObserver(function (entries) {
|
|
26
|
+
entries.forEach(function (entry) {
|
|
27
|
+
var node = entry.target;
|
|
28
|
+
IntersectionState.get(node) !== entry.isIntersecting && IntersectionState.set(node, entry.isIntersecting);
|
|
29
|
+
});
|
|
30
|
+
}, {
|
|
31
|
+
threshold: 0
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
22
34
|
if (isClient) if (rAF) {
|
|
23
35
|
let layoutOnAnimationFrame = function () {
|
|
24
36
|
var now = Date.now(),
|
|
25
37
|
timeSinceLastFrame = now - lastFrameAt;
|
|
26
|
-
if (lastFrameAt = now, frameCount
|
|
27
|
-
frameCount
|
|
38
|
+
if (lastFrameAt = now, frameCount++, frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
39
|
+
frameCount = 0, rAF(layoutOnAnimationFrame);
|
|
28
40
|
return;
|
|
29
41
|
}
|
|
30
|
-
if (
|
|
42
|
+
if (strategy !== "off") {
|
|
31
43
|
var hasRecentSyncWork = timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause;
|
|
32
44
|
hasRecentSyncWork || Nodes.forEach(function (node) {
|
|
33
45
|
updateLayoutIfChanged(node, lastFrameAt);
|
|
@@ -36,38 +48,41 @@ if (isClient) if (rAF) {
|
|
|
36
48
|
rAF(layoutOnAnimationFrame);
|
|
37
49
|
};
|
|
38
50
|
var layoutOnAnimationFrame2 = layoutOnAnimationFrame,
|
|
51
|
+
supportsCheckVisibility = "checkVisibility" in document.body,
|
|
39
52
|
lastFrameAt = Date.now();
|
|
40
53
|
async function updateLayoutIfChanged(node, frameId) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
if (!(supportsCheckVisibility && !node.checkVisibility()) && IntersectionState.get(node) !== !1) {
|
|
55
|
+
var onLayout = LayoutHandlers.get(node);
|
|
56
|
+
if (typeof onLayout == "function") {
|
|
57
|
+
var parentNode = node.parentElement;
|
|
58
|
+
if (parentNode) {
|
|
59
|
+
var nodeRect, parentRect;
|
|
60
|
+
if (strategy === "async") {
|
|
61
|
+
var [nr, pr] = await Promise.all([getBoundingClientRectAsync(node), getBoundingClientRectAsync(parentNode)]);
|
|
62
|
+
if (nr === !1 || pr === !1 || frameId !== lastFrameAt) return;
|
|
63
|
+
nodeRect = nr, parentRect = pr;
|
|
64
|
+
} else nodeRect = node.getBoundingClientRect(), parentRect = parentNode.getBoundingClientRect();
|
|
65
|
+
var cachedRect = NodeRectCache.get(node),
|
|
66
|
+
cachedParentRect = NodeRectCache.get(parentNode);
|
|
67
|
+
if (!cachedRect ||
|
|
68
|
+
// has changed one rect
|
|
69
|
+
// @ts-expect-error DOMRectReadOnly can go into object
|
|
70
|
+
!isEqualShallow(cachedRect, nodeRect) && (
|
|
71
|
+
// @ts-expect-error DOMRectReadOnly can go into object
|
|
72
|
+
!cachedParentRect || !isEqualShallow(cachedParentRect, parentRect))) {
|
|
73
|
+
NodeRectCache.set(node, nodeRect), ParentRectCache.set(parentNode, parentRect);
|
|
74
|
+
var event = getElementLayoutEvent(nodeRect, parentRect);
|
|
75
|
+
avoidUpdates ? queuedUpdates.set(node, function () {
|
|
76
|
+
return onLayout(event);
|
|
77
|
+
}) : onLayout(event);
|
|
78
|
+
}
|
|
64
79
|
}
|
|
65
80
|
}
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
rAF(layoutOnAnimationFrame);
|
|
69
84
|
var frameCount = 0,
|
|
70
|
-
|
|
85
|
+
RUN_EVERY_X_FRAMES = 4;
|
|
71
86
|
} else process.env.NODE_ENV === "development" && console.warn("No requestAnimationFrame - please polyfill for onLayout to work correctly");
|
|
72
87
|
var getElementLayoutEvent = function (nodeRect, parentRect) {
|
|
73
88
|
return {
|
|
@@ -158,10 +173,10 @@ function useElementLayout(ref, onLayout) {
|
|
|
158
173
|
if (onLayout) {
|
|
159
174
|
var node2 = (_ref_current2 = ref.current) === null || _ref_current2 === void 0 ? void 0 : _ref_current2.host;
|
|
160
175
|
if (node2) {
|
|
161
|
-
LayoutHandlers.set(node2, onLayout), Nodes.add(node2);
|
|
176
|
+
LayoutHandlers.set(node2, onLayout), Nodes.add(node2), startGlobalIntersectionObserver(), globalIntersectionObserver && (globalIntersectionObserver.observe(node2), IntersectionState.set(node2, !0));
|
|
162
177
|
var parentNode = node2.parentNode;
|
|
163
178
|
return parentNode && onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect())), function () {
|
|
164
|
-
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2);
|
|
179
|
+
Nodes.delete(node2), LayoutHandlers.delete(node2), NodeRectCache.delete(node2), LastChangeTime.delete(node2), IntersectionState.delete(node2), globalIntersectionObserver && globalIntersectionObserver.unobserve(node2);
|
|
165
180
|
};
|
|
166
181
|
}
|
|
167
182
|
}
|
|
@@ -172,14 +187,13 @@ function ensureWebElement(x) {
|
|
|
172
187
|
}
|
|
173
188
|
var getBoundingClientRectAsync = function (node) {
|
|
174
189
|
return new Promise(function (res) {
|
|
175
|
-
if (!
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
190
|
+
if (!node || node.nodeType !== 1) return res(!1);
|
|
191
|
+
var io = new IntersectionObserver(function (entries) {
|
|
192
|
+
return io.disconnect(), res(entries[0].boundingClientRect);
|
|
193
|
+
}, {
|
|
194
|
+
threshold: 0
|
|
195
|
+
});
|
|
196
|
+
io.observe(node);
|
|
183
197
|
});
|
|
184
198
|
},
|
|
185
199
|
getBoundingClientRect = function (node) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isClient","useIsomorphicLayoutEffect","isEqualShallow","LayoutHandlers","WeakMap","Nodes","Set","strategy","setOnLayoutStrategy","state","NodeRectCache","ParentRectCache","LastChangeTime","rAF","window","requestAnimationFrame","avoidUpdates","queuedUpdates","Map","enable","forEach","cb","clear","expectedFrameTime","numDroppedFramesUntilPause","layoutOnAnimationFrame","now","Date","timeSinceLastFrame","lastFrameAt","frameCount","
|
|
1
|
+
{"version":3,"names":["isClient","useIsomorphicLayoutEffect","isEqualShallow","LayoutHandlers","WeakMap","Nodes","Set","IntersectionState","globalIntersectionObserver","strategy","setOnLayoutStrategy","state","NodeRectCache","ParentRectCache","LastChangeTime","rAF","window","requestAnimationFrame","avoidUpdates","queuedUpdates","Map","enable","forEach","cb","clear","expectedFrameTime","numDroppedFramesUntilPause","startGlobalIntersectionObserver","IntersectionObserver","entries","entry","node","target","get","isIntersecting","set","threshold","layoutOnAnimationFrame","now","Date","timeSinceLastFrame","lastFrameAt","frameCount","RUN_EVERY_X_FRAMES","hasRecentSyncWork","updateLayoutIfChanged","layoutOnAnimationFrame2","supportsCheckVisibility","document","body","frameId","checkVisibility","onLayout","parentNode","parentElement","nodeRect","parentRect","nr","pr","Promise","all","getBoundingClientRectAsync","getBoundingClientRect","cachedRect","cachedParentRect","event","getElementLayoutEvent","process","env","NODE_ENV","console","warn","nativeEvent","layout","getRelativeDimensions","timeStamp","measureLayout","relativeTo","callback","relativeNode","HTMLElement","nodeDim","relativeNodeDim","x","y","width","height","left","top","getElementLayoutEventAsync","measureLayoutAsync","Error","a","b","useElementLayout","ref","_ref_current","ensureWebElement","current","host","_ref_current2","node2","add","observe","delete","unobserve","res","nodeType","io","disconnect","boundingClientRect"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/use-element-layout",
|
|
3
|
-
"version": "1.130.
|
|
3
|
+
"version": "1.130.2",
|
|
4
4
|
"types": "./types/index.d.ts",
|
|
5
5
|
"main": "dist/cjs",
|
|
6
6
|
"module": "dist/esm",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@tamagui/constants": "1.130.
|
|
35
|
-
"@tamagui/is-equal-shallow": "1.130.
|
|
34
|
+
"@tamagui/constants": "1.130.2",
|
|
35
|
+
"@tamagui/is-equal-shallow": "1.130.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@tamagui/build": "1.130.
|
|
38
|
+
"@tamagui/build": "1.130.2",
|
|
39
39
|
"react": "*"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,10 @@ import type { RefObject } from 'react'
|
|
|
4
4
|
|
|
5
5
|
const LayoutHandlers = new WeakMap<HTMLElement, Function>()
|
|
6
6
|
const Nodes = new Set<HTMLElement>()
|
|
7
|
+
const IntersectionState = new WeakMap<HTMLElement, boolean>()
|
|
8
|
+
|
|
9
|
+
// Single persistent IntersectionObserver for all nodes
|
|
10
|
+
let globalIntersectionObserver: IntersectionObserver | null = null
|
|
7
11
|
|
|
8
12
|
type TamaguiComponentStatePartial = {
|
|
9
13
|
host?: any
|
|
@@ -57,12 +61,40 @@ export function enable(): void {
|
|
|
57
61
|
const expectedFrameTime = 16.67 // ~60fps
|
|
58
62
|
const numDroppedFramesUntilPause = 10
|
|
59
63
|
|
|
64
|
+
function startGlobalIntersectionObserver() {
|
|
65
|
+
if (!isClient || globalIntersectionObserver) return
|
|
66
|
+
|
|
67
|
+
globalIntersectionObserver = new IntersectionObserver(
|
|
68
|
+
(entries) => {
|
|
69
|
+
entries.forEach((entry) => {
|
|
70
|
+
const node = entry.target as HTMLElement
|
|
71
|
+
if (IntersectionState.get(node) !== entry.isIntersecting) {
|
|
72
|
+
IntersectionState.set(node, entry.isIntersecting)
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
threshold: 0,
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
60
82
|
if (isClient) {
|
|
61
83
|
if (rAF) {
|
|
84
|
+
const supportsCheckVisibility = 'checkVisibility' in document.body
|
|
62
85
|
// track frame timing to detect sync work and avoid updates during heavy periods
|
|
63
86
|
let lastFrameAt = Date.now()
|
|
64
87
|
|
|
65
88
|
async function updateLayoutIfChanged(node: HTMLElement, frameId: number) {
|
|
89
|
+
if (supportsCheckVisibility && !(node as any).checkVisibility()) {
|
|
90
|
+
// avoid due to not visible
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
if (IntersectionState.get(node) === false) {
|
|
94
|
+
// avoid due to not intersecting
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
66
98
|
const onLayout = LayoutHandlers.get(node)
|
|
67
99
|
if (typeof onLayout !== 'function') return
|
|
68
100
|
|
|
@@ -123,21 +155,21 @@ if (isClient) {
|
|
|
123
155
|
|
|
124
156
|
// only run once in a few frames, this could be adjustable
|
|
125
157
|
let frameCount = 0
|
|
126
|
-
const
|
|
158
|
+
const RUN_EVERY_X_FRAMES = 4
|
|
127
159
|
|
|
128
160
|
function layoutOnAnimationFrame() {
|
|
129
161
|
const now = Date.now()
|
|
130
162
|
const timeSinceLastFrame = now - lastFrameAt
|
|
131
163
|
lastFrameAt = now
|
|
132
164
|
|
|
133
|
-
|
|
134
|
-
|
|
165
|
+
frameCount++
|
|
166
|
+
|
|
167
|
+
if (frameCount % RUN_EVERY_X_FRAMES === 0) {
|
|
168
|
+
frameCount = 0
|
|
135
169
|
rAF!(layoutOnAnimationFrame)
|
|
136
170
|
return
|
|
137
171
|
}
|
|
138
172
|
|
|
139
|
-
frameCount = 0
|
|
140
|
-
|
|
141
173
|
if (strategy !== 'off') {
|
|
142
174
|
// for both strategies:
|
|
143
175
|
// avoid updates if we've been dropping frames (indicates sync work happening)
|
|
@@ -265,6 +297,14 @@ export function useElementLayout(
|
|
|
265
297
|
LayoutHandlers.set(node, onLayout)
|
|
266
298
|
Nodes.add(node)
|
|
267
299
|
|
|
300
|
+
// Add node to intersection observer
|
|
301
|
+
startGlobalIntersectionObserver()
|
|
302
|
+
if (globalIntersectionObserver) {
|
|
303
|
+
globalIntersectionObserver.observe(node)
|
|
304
|
+
// Initialize as intersecting by default
|
|
305
|
+
IntersectionState.set(node, true)
|
|
306
|
+
}
|
|
307
|
+
|
|
268
308
|
// always do one immediate sync layout event no matter the strategy for accuracy
|
|
269
309
|
const parentNode = node.parentNode
|
|
270
310
|
if (parentNode) {
|
|
@@ -281,6 +321,12 @@ export function useElementLayout(
|
|
|
281
321
|
LayoutHandlers.delete(node)
|
|
282
322
|
NodeRectCache.delete(node)
|
|
283
323
|
LastChangeTime.delete(node)
|
|
324
|
+
IntersectionState.delete(node)
|
|
325
|
+
|
|
326
|
+
// Remove from intersection observer
|
|
327
|
+
if (globalIntersectionObserver) {
|
|
328
|
+
globalIntersectionObserver.unobserve(node)
|
|
329
|
+
}
|
|
284
330
|
}
|
|
285
331
|
}, [ref, !!onLayout])
|
|
286
332
|
}
|
|
@@ -296,12 +342,10 @@ const getBoundingClientRectAsync = (
|
|
|
296
342
|
node: HTMLElement | null
|
|
297
343
|
): Promise<DOMRectReadOnly | false> => {
|
|
298
344
|
return new Promise<DOMRectReadOnly | false>((res) => {
|
|
299
|
-
if (!node || node.nodeType !== 1) return
|
|
345
|
+
if (!node || node.nodeType !== 1) return res(false)
|
|
346
|
+
|
|
300
347
|
const io = new IntersectionObserver(
|
|
301
348
|
(entries) => {
|
|
302
|
-
if (!entries[0].isIntersecting) {
|
|
303
|
-
return res(false)
|
|
304
|
-
}
|
|
305
349
|
io.disconnect()
|
|
306
350
|
return res(entries[0].boundingClientRect)
|
|
307
351
|
},
|
package/types/index.d.ts.map
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"mappings": "AAEA,cAAc,iBAAiB,OAAO;
|
|
2
|
+
"mappings": "AAEA,cAAc,iBAAiB,OAAO;KASjC,+BAA+B;CAClC;AACD;KAEI,4BAA4B,QAAQ,SAAS;AAIlD,OAAO,iBAAS,oBAAoBA,OAAO;AAI3C,YAAY,cAAc;CACxB;CACA;CACA;CACA;CACA;CACA;AACD;AAED,YAAY,cAAc;CACxB,aAAa;EACX,QAAQ;EACR;CACD;CACD;AACD;AAYD,OAAO,iBAAS;AAkJhB,OAAO,cAAM,wBACXC,UAAU,iBACVC,YAAY,oBACX;AAUH,OAAO,cAAM,gBACXC,MAAM,aACNC,YAAY,oBACZC,WACEC,WACAC,WACAC,eACAC,gBACAC,cACAC;AAkBJ,OAAO,cAAM,6BACXC,QAAQ,gBACP,QAAQ;AAcX,OAAO,cAAM,qBACXT,MAAM,aACNU,aAAa,uBACZ,eAAe;AA0BlB,OAAO,iBAAS,iBACdC,KAAK,UAAU,+BACfC,aAAaC,GAAG;AAiFlB,OAAO,cAAM,UAAWb,MAAM,gBAAc",
|
|
3
3
|
"names": [
|
|
4
4
|
"state: LayoutMeasurementStrategy",
|
|
5
5
|
"nodeRect: DOMRectReadOnly",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"src/index.ts"
|
|
24
24
|
],
|
|
25
25
|
"sourcesContent": [
|
|
26
|
-
"import { isClient, useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport { isEqualShallow } from '@tamagui/is-equal-shallow'\nimport type { RefObject } from 'react'\n\nconst LayoutHandlers = new WeakMap<HTMLElement, Function>()\nconst Nodes = new Set<HTMLElement>()\n\ntype TamaguiComponentStatePartial = {\n host?: any\n}\n\ntype LayoutMeasurementStrategy = 'off' | 'sync' | 'async'\n\nlet strategy: LayoutMeasurementStrategy = 'async'\n\nexport function setOnLayoutStrategy(state: LayoutMeasurementStrategy): void {\n strategy = state\n}\n\nexport type LayoutValue = {\n x: number\n y: number\n width: number\n height: number\n left: number\n top: number\n}\n\nexport type LayoutEvent = {\n nativeEvent: {\n layout: LayoutValue\n target: any\n }\n timeStamp: number\n}\n\nconst NodeRectCache = new WeakMap<HTMLElement, DOMRect>()\nconst ParentRectCache = new WeakMap<HTMLElement, DOMRect>()\nconst LastChangeTime = new WeakMap<HTMLElement, number>()\n\nconst rAF = typeof window !== 'undefined' ? window.requestAnimationFrame : undefined\n\n// prevent thrashing during first hydration (somewhat, streaming gets trickier)\nlet avoidUpdates = true\nconst queuedUpdates = new Map<HTMLElement, Function>()\n\nexport function enable(): void {\n if (avoidUpdates) {\n avoidUpdates = false\n if (queuedUpdates) {\n queuedUpdates.forEach((cb) => cb())\n queuedUpdates.clear()\n }\n }\n}\n\nconst expectedFrameTime = 16.67 // ~60fps\nconst numDroppedFramesUntilPause = 10\n\nif (isClient) {\n if (rAF) {\n // track frame timing to detect sync work and avoid updates during heavy periods\n let lastFrameAt = Date.now()\n\n async function updateLayoutIfChanged(node: HTMLElement, frameId: number) {\n const onLayout = LayoutHandlers.get(node)\n if (typeof onLayout !== 'function') return\n\n const parentNode = node.parentElement\n if (!parentNode) return\n\n let nodeRect: DOMRectReadOnly\n let parentRect: DOMRectReadOnly\n\n if (strategy === 'async') {\n const [nr, pr] = await Promise.all([\n getBoundingClientRectAsync(node),\n getBoundingClientRectAsync(parentNode),\n ])\n\n if (nr === false || pr === false) {\n return\n }\n\n // cancel if we skipped a frame\n if (frameId !== lastFrameAt) {\n return\n }\n\n nodeRect = nr\n parentRect = pr\n } else {\n nodeRect = node.getBoundingClientRect()\n parentRect = parentNode.getBoundingClientRect()\n }\n\n const cachedRect = NodeRectCache.get(node)\n const cachedParentRect = NodeRectCache.get(parentNode)\n\n if (\n !cachedRect ||\n // has changed one rect\n // @ts-expect-error DOMRectReadOnly can go into object\n (!isEqualShallow(cachedRect, nodeRect) &&\n // @ts-expect-error DOMRectReadOnly can go into object\n (!cachedParentRect || !isEqualShallow(cachedParentRect, parentRect)))\n ) {\n NodeRectCache.set(node, nodeRect)\n ParentRectCache.set(parentNode, parentRect)\n\n const event = getElementLayoutEvent(nodeRect, parentRect)\n\n if (avoidUpdates) {\n queuedUpdates.set(node, () => onLayout(event))\n } else {\n onLayout(event)\n }\n }\n }\n\n // note that getBoundingClientRect() does not thrash layout if its after an animation frame\n rAF!(layoutOnAnimationFrame)\n\n // only run once in a few frames, this could be adjustable\n let frameCount = 0\n const runEveryXFrames = 6\n\n function layoutOnAnimationFrame() {\n const now = Date.now()\n const timeSinceLastFrame = now - lastFrameAt\n lastFrameAt = now\n\n if (frameCount < runEveryXFrames) {\n frameCount++\n rAF!(layoutOnAnimationFrame)\n return\n }\n\n frameCount = 0\n\n if (strategy !== 'off') {\n // for both strategies:\n // avoid updates if we've been dropping frames (indicates sync work happening)\n const hasRecentSyncWork =\n timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause\n\n if (!hasRecentSyncWork) {\n Nodes.forEach((node) => {\n updateLayoutIfChanged(node, lastFrameAt)\n })\n }\n }\n\n rAF!(layoutOnAnimationFrame)\n }\n } else {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `No requestAnimationFrame - please polyfill for onLayout to work correctly`\n )\n }\n }\n}\n\nexport const getElementLayoutEvent = (\n nodeRect: DOMRectReadOnly,\n parentRect: DOMRectReadOnly\n): LayoutEvent => {\n return {\n nativeEvent: {\n layout: getRelativeDimensions(nodeRect, parentRect),\n target: nodeRect,\n },\n timeStamp: Date.now(),\n }\n}\n\nexport const measureLayout = (\n node: HTMLElement,\n relativeTo: HTMLElement | null,\n callback: (\n x: number,\n y: number,\n width: number,\n height: number,\n left: number,\n top: number\n ) => void\n): void => {\n const relativeNode = relativeTo || node?.parentElement\n if (relativeNode instanceof HTMLElement) {\n const nodeDim = node.getBoundingClientRect()\n const relativeNodeDim = relativeNode.getBoundingClientRect()\n\n if (relativeNodeDim && nodeDim) {\n const { x, y, width, height, left, top } = getRelativeDimensions(\n nodeDim,\n relativeNodeDim\n )\n callback(x, y, width, height, left, top)\n }\n }\n}\n\nexport const getElementLayoutEventAsync = async (\n target: HTMLElement\n): Promise<LayoutEvent> => {\n const layout = await measureLayoutAsync(target)\n if (!layout) {\n throw new Error(`‼️`) // impossible\n }\n return {\n nativeEvent: {\n layout,\n target,\n },\n timeStamp: Date.now(),\n }\n}\n\nexport const measureLayoutAsync = async (\n node: HTMLElement,\n relativeTo?: HTMLElement | null\n): Promise<null | LayoutValue> => {\n const relativeNode = relativeTo || node?.parentElement\n if (relativeNode instanceof HTMLElement) {\n const [nodeDim, relativeNodeDim] = await Promise.all([\n getBoundingClientRectAsync(node),\n getBoundingClientRectAsync(relativeNode),\n ])\n\n if (relativeNodeDim && nodeDim) {\n const { x, y, width, height, left, top } = getRelativeDimensions(\n nodeDim,\n relativeNodeDim\n )\n return { x, y, width, height, left, top }\n }\n }\n return null\n}\n\nconst getRelativeDimensions = (a: DOMRectReadOnly, b: DOMRectReadOnly) => {\n const { height, left, top, width } = a\n const x = left - b.left\n const y = top - b.top\n return { x, y, width, height, left, top }\n}\n\nexport function useElementLayout(\n ref: RefObject<TamaguiComponentStatePartial>,\n onLayout?: ((e: LayoutEvent) => void) | null\n): void {\n // ensure always up to date so we can avoid re-running effect\n const node = ensureWebElement(ref.current?.host)\n if (node && onLayout) {\n LayoutHandlers.set(node, onLayout)\n }\n\n useIsomorphicLayoutEffect(() => {\n if (!onLayout) return\n const node = ref.current?.host\n if (!node) return\n\n LayoutHandlers.set(node, onLayout)\n Nodes.add(node)\n\n // always do one immediate sync layout event no matter the strategy for accuracy\n const parentNode = node.parentNode\n if (parentNode) {\n onLayout(\n getElementLayoutEvent(\n node.getBoundingClientRect(),\n parentNode.getBoundingClientRect()\n )\n )\n }\n\n return () => {\n Nodes.delete(node)\n LayoutHandlers.delete(node)\n NodeRectCache.delete(node)\n LastChangeTime.delete(node)\n }\n }, [ref, !!onLayout])\n}\n\nfunction ensureWebElement<X>(x: X): HTMLElement | undefined {\n if (typeof HTMLElement === 'undefined') {\n return undefined\n }\n return x instanceof HTMLElement ? x : undefined\n}\n\nconst getBoundingClientRectAsync = (\n node: HTMLElement | null\n): Promise<DOMRectReadOnly | false> => {\n return new Promise<DOMRectReadOnly | false>((res) => {\n if (!node || node.nodeType !== 1) return\n const io = new IntersectionObserver(\n (entries) => {\n if (!entries[0].isIntersecting) {\n return res(false)\n }\n io.disconnect()\n return res(entries[0].boundingClientRect)\n },\n {\n threshold: 0,\n }\n )\n io.observe(node)\n })\n}\n\nconst getBoundingClientRect = (node: HTMLElement | null): undefined | DOMRect => {\n if (!node || node.nodeType !== 1) return\n return node.getBoundingClientRect?.()\n}\n\nexport const getRect = (node: HTMLElement): LayoutValue | undefined => {\n const rect = getBoundingClientRect(node)\n if (!rect) return\n const { x, y, top, left } = rect\n return { x, y, width: node.offsetWidth, height: node.offsetHeight, top, left }\n}\n"
|
|
26
|
+
"import { isClient, useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport { isEqualShallow } from '@tamagui/is-equal-shallow'\nimport type { RefObject } from 'react'\n\nconst LayoutHandlers = new WeakMap<HTMLElement, Function>()\nconst Nodes = new Set<HTMLElement>()\nconst IntersectionState = new WeakMap<HTMLElement, boolean>()\n\n// Single persistent IntersectionObserver for all nodes\nlet globalIntersectionObserver: IntersectionObserver | null = null\n\ntype TamaguiComponentStatePartial = {\n host?: any\n}\n\ntype LayoutMeasurementStrategy = 'off' | 'sync' | 'async'\n\nlet strategy: LayoutMeasurementStrategy = 'async'\n\nexport function setOnLayoutStrategy(state: LayoutMeasurementStrategy): void {\n strategy = state\n}\n\nexport type LayoutValue = {\n x: number\n y: number\n width: number\n height: number\n left: number\n top: number\n}\n\nexport type LayoutEvent = {\n nativeEvent: {\n layout: LayoutValue\n target: any\n }\n timeStamp: number\n}\n\nconst NodeRectCache = new WeakMap<HTMLElement, DOMRect>()\nconst ParentRectCache = new WeakMap<HTMLElement, DOMRect>()\nconst LastChangeTime = new WeakMap<HTMLElement, number>()\n\nconst rAF = typeof window !== 'undefined' ? window.requestAnimationFrame : undefined\n\n// prevent thrashing during first hydration (somewhat, streaming gets trickier)\nlet avoidUpdates = true\nconst queuedUpdates = new Map<HTMLElement, Function>()\n\nexport function enable(): void {\n if (avoidUpdates) {\n avoidUpdates = false\n if (queuedUpdates) {\n queuedUpdates.forEach((cb) => cb())\n queuedUpdates.clear()\n }\n }\n}\n\nconst expectedFrameTime = 16.67 // ~60fps\nconst numDroppedFramesUntilPause = 10\n\nfunction startGlobalIntersectionObserver() {\n if (!isClient || globalIntersectionObserver) return\n\n globalIntersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n const node = entry.target as HTMLElement\n if (IntersectionState.get(node) !== entry.isIntersecting) {\n IntersectionState.set(node, entry.isIntersecting)\n }\n })\n },\n {\n threshold: 0,\n }\n )\n}\n\nif (isClient) {\n if (rAF) {\n const supportsCheckVisibility = 'checkVisibility' in document.body\n // track frame timing to detect sync work and avoid updates during heavy periods\n let lastFrameAt = Date.now()\n\n async function updateLayoutIfChanged(node: HTMLElement, frameId: number) {\n if (supportsCheckVisibility && !(node as any).checkVisibility()) {\n // avoid due to not visible\n return\n }\n if (IntersectionState.get(node) === false) {\n // avoid due to not intersecting\n return\n }\n\n const onLayout = LayoutHandlers.get(node)\n if (typeof onLayout !== 'function') return\n\n const parentNode = node.parentElement\n if (!parentNode) return\n\n let nodeRect: DOMRectReadOnly\n let parentRect: DOMRectReadOnly\n\n if (strategy === 'async') {\n const [nr, pr] = await Promise.all([\n getBoundingClientRectAsync(node),\n getBoundingClientRectAsync(parentNode),\n ])\n\n if (nr === false || pr === false) {\n return\n }\n\n // cancel if we skipped a frame\n if (frameId !== lastFrameAt) {\n return\n }\n\n nodeRect = nr\n parentRect = pr\n } else {\n nodeRect = node.getBoundingClientRect()\n parentRect = parentNode.getBoundingClientRect()\n }\n\n const cachedRect = NodeRectCache.get(node)\n const cachedParentRect = NodeRectCache.get(parentNode)\n\n if (\n !cachedRect ||\n // has changed one rect\n // @ts-expect-error DOMRectReadOnly can go into object\n (!isEqualShallow(cachedRect, nodeRect) &&\n // @ts-expect-error DOMRectReadOnly can go into object\n (!cachedParentRect || !isEqualShallow(cachedParentRect, parentRect)))\n ) {\n NodeRectCache.set(node, nodeRect)\n ParentRectCache.set(parentNode, parentRect)\n\n const event = getElementLayoutEvent(nodeRect, parentRect)\n\n if (avoidUpdates) {\n queuedUpdates.set(node, () => onLayout(event))\n } else {\n onLayout(event)\n }\n }\n }\n\n // note that getBoundingClientRect() does not thrash layout if its after an animation frame\n rAF!(layoutOnAnimationFrame)\n\n // only run once in a few frames, this could be adjustable\n let frameCount = 0\n const RUN_EVERY_X_FRAMES = 4\n\n function layoutOnAnimationFrame() {\n const now = Date.now()\n const timeSinceLastFrame = now - lastFrameAt\n lastFrameAt = now\n\n frameCount++\n\n if (frameCount % RUN_EVERY_X_FRAMES === 0) {\n frameCount = 0\n rAF!(layoutOnAnimationFrame)\n return\n }\n\n if (strategy !== 'off') {\n // for both strategies:\n // avoid updates if we've been dropping frames (indicates sync work happening)\n const hasRecentSyncWork =\n timeSinceLastFrame > expectedFrameTime * numDroppedFramesUntilPause\n\n if (!hasRecentSyncWork) {\n Nodes.forEach((node) => {\n updateLayoutIfChanged(node, lastFrameAt)\n })\n }\n }\n\n rAF!(layoutOnAnimationFrame)\n }\n } else {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `No requestAnimationFrame - please polyfill for onLayout to work correctly`\n )\n }\n }\n}\n\nexport const getElementLayoutEvent = (\n nodeRect: DOMRectReadOnly,\n parentRect: DOMRectReadOnly\n): LayoutEvent => {\n return {\n nativeEvent: {\n layout: getRelativeDimensions(nodeRect, parentRect),\n target: nodeRect,\n },\n timeStamp: Date.now(),\n }\n}\n\nexport const measureLayout = (\n node: HTMLElement,\n relativeTo: HTMLElement | null,\n callback: (\n x: number,\n y: number,\n width: number,\n height: number,\n left: number,\n top: number\n ) => void\n): void => {\n const relativeNode = relativeTo || node?.parentElement\n if (relativeNode instanceof HTMLElement) {\n const nodeDim = node.getBoundingClientRect()\n const relativeNodeDim = relativeNode.getBoundingClientRect()\n\n if (relativeNodeDim && nodeDim) {\n const { x, y, width, height, left, top } = getRelativeDimensions(\n nodeDim,\n relativeNodeDim\n )\n callback(x, y, width, height, left, top)\n }\n }\n}\n\nexport const getElementLayoutEventAsync = async (\n target: HTMLElement\n): Promise<LayoutEvent> => {\n const layout = await measureLayoutAsync(target)\n if (!layout) {\n throw new Error(`‼️`) // impossible\n }\n return {\n nativeEvent: {\n layout,\n target,\n },\n timeStamp: Date.now(),\n }\n}\n\nexport const measureLayoutAsync = async (\n node: HTMLElement,\n relativeTo?: HTMLElement | null\n): Promise<null | LayoutValue> => {\n const relativeNode = relativeTo || node?.parentElement\n if (relativeNode instanceof HTMLElement) {\n const [nodeDim, relativeNodeDim] = await Promise.all([\n getBoundingClientRectAsync(node),\n getBoundingClientRectAsync(relativeNode),\n ])\n\n if (relativeNodeDim && nodeDim) {\n const { x, y, width, height, left, top } = getRelativeDimensions(\n nodeDim,\n relativeNodeDim\n )\n return { x, y, width, height, left, top }\n }\n }\n return null\n}\n\nconst getRelativeDimensions = (a: DOMRectReadOnly, b: DOMRectReadOnly) => {\n const { height, left, top, width } = a\n const x = left - b.left\n const y = top - b.top\n return { x, y, width, height, left, top }\n}\n\nexport function useElementLayout(\n ref: RefObject<TamaguiComponentStatePartial>,\n onLayout?: ((e: LayoutEvent) => void) | null\n): void {\n // ensure always up to date so we can avoid re-running effect\n const node = ensureWebElement(ref.current?.host)\n if (node && onLayout) {\n LayoutHandlers.set(node, onLayout)\n }\n\n useIsomorphicLayoutEffect(() => {\n if (!onLayout) return\n const node = ref.current?.host\n if (!node) return\n\n LayoutHandlers.set(node, onLayout)\n Nodes.add(node)\n\n // Add node to intersection observer\n startGlobalIntersectionObserver()\n if (globalIntersectionObserver) {\n globalIntersectionObserver.observe(node)\n // Initialize as intersecting by default\n IntersectionState.set(node, true)\n }\n\n // always do one immediate sync layout event no matter the strategy for accuracy\n const parentNode = node.parentNode\n if (parentNode) {\n onLayout(\n getElementLayoutEvent(\n node.getBoundingClientRect(),\n parentNode.getBoundingClientRect()\n )\n )\n }\n\n return () => {\n Nodes.delete(node)\n LayoutHandlers.delete(node)\n NodeRectCache.delete(node)\n LastChangeTime.delete(node)\n IntersectionState.delete(node)\n\n // Remove from intersection observer\n if (globalIntersectionObserver) {\n globalIntersectionObserver.unobserve(node)\n }\n }\n }, [ref, !!onLayout])\n}\n\nfunction ensureWebElement<X>(x: X): HTMLElement | undefined {\n if (typeof HTMLElement === 'undefined') {\n return undefined\n }\n return x instanceof HTMLElement ? x : undefined\n}\n\nconst getBoundingClientRectAsync = (\n node: HTMLElement | null\n): Promise<DOMRectReadOnly | false> => {\n return new Promise<DOMRectReadOnly | false>((res) => {\n if (!node || node.nodeType !== 1) return res(false)\n\n const io = new IntersectionObserver(\n (entries) => {\n io.disconnect()\n return res(entries[0].boundingClientRect)\n },\n {\n threshold: 0,\n }\n )\n io.observe(node)\n })\n}\n\nconst getBoundingClientRect = (node: HTMLElement | null): undefined | DOMRect => {\n if (!node || node.nodeType !== 1) return\n return node.getBoundingClientRect?.()\n}\n\nexport const getRect = (node: HTMLElement): LayoutValue | undefined => {\n const rect = getBoundingClientRect(node)\n if (!rect) return\n const { x, y, top, left } = rect\n return { x, y, width: node.offsetWidth, height: node.offsetHeight, top, left }\n}\n"
|
|
27
27
|
],
|
|
28
28
|
"version": 3
|
|
29
29
|
}
|