@hanzogui/use-element-layout 2.0.0-rc.41-hanzoai.5
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/LICENSE +21 -0
- package/dist/cjs/index.cjs +363 -0
- package/dist/cjs/index.native.js +436 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/esm/index.js +325 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.mjs +325 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +395 -0
- package/dist/esm/index.native.js.map +1 -0
- package/package.json +47 -0
- package/src/index.tsx +597 -0
- package/types/index.d.ts +48 -0
- package/types/index.d.ts.map +11 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { useIsomorphicLayoutEffect } from "@hanzogui/constants";
|
|
2
|
+
import { createContext, useContext, useId } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
const LayoutHandlers = /* @__PURE__ */new WeakMap();
|
|
5
|
+
const LayoutDisableKey = /* @__PURE__ */new WeakMap();
|
|
6
|
+
const Nodes = /* @__PURE__ */new Set();
|
|
7
|
+
const IntersectionState = /* @__PURE__ */new WeakMap();
|
|
8
|
+
const usePretransformDimensions = () => globalThis.__TAMAGUI_ONLAYOUT_PRETRANSFORM === true || process.env.TAMAGUI_ONLAYOUT_PRETRANSFORM === "1";
|
|
9
|
+
let _debugLayout;
|
|
10
|
+
function isDebugLayout() {
|
|
11
|
+
if (_debugLayout === void 0) _debugLayout = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("__tamaDebugLayout");
|
|
12
|
+
return _debugLayout;
|
|
13
|
+
}
|
|
14
|
+
const DisableLayoutContextValues = {};
|
|
15
|
+
const DisableLayoutContextKey = createContext("");
|
|
16
|
+
const ENABLE = typeof IntersectionObserver !== "undefined";
|
|
17
|
+
const LayoutMeasurementController = ({
|
|
18
|
+
disable,
|
|
19
|
+
children
|
|
20
|
+
}) => {
|
|
21
|
+
const id = useId();
|
|
22
|
+
useIsomorphicLayoutEffect(() => {
|
|
23
|
+
DisableLayoutContextValues[id] = disable;
|
|
24
|
+
}, [disable, id]);
|
|
25
|
+
return /* @__PURE__ */jsx(DisableLayoutContextKey.Provider, {
|
|
26
|
+
value: id,
|
|
27
|
+
children
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
let globalIntersectionObserver = null;
|
|
31
|
+
let strategy = "async";
|
|
32
|
+
function setOnLayoutStrategy(state) {
|
|
33
|
+
strategy = state;
|
|
34
|
+
}
|
|
35
|
+
const NodeRectCache = /* @__PURE__ */new WeakMap();
|
|
36
|
+
let avoidUpdates = true;
|
|
37
|
+
const queuedUpdates = /* @__PURE__ */new Map();
|
|
38
|
+
function enable() {
|
|
39
|
+
if (avoidUpdates) {
|
|
40
|
+
avoidUpdates = false;
|
|
41
|
+
if (queuedUpdates) {
|
|
42
|
+
queuedUpdates.forEach(cb => cb());
|
|
43
|
+
queuedUpdates.clear();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function startGlobalObservers() {
|
|
48
|
+
if (!ENABLE || globalIntersectionObserver) return;
|
|
49
|
+
globalIntersectionObserver = new IntersectionObserver(entries => {
|
|
50
|
+
for (let i = 0; i < entries.length; i++) {
|
|
51
|
+
const entry = entries[i];
|
|
52
|
+
const node = entry.target;
|
|
53
|
+
if (IntersectionState.get(node) !== entry.isIntersecting) IntersectionState.set(node, entry.isIntersecting);
|
|
54
|
+
}
|
|
55
|
+
}, {
|
|
56
|
+
threshold: 0
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function rectsEqual(a, b) {
|
|
60
|
+
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
61
|
+
}
|
|
62
|
+
if (ENABLE) {
|
|
63
|
+
let ensureRectFetchObserver = function () {
|
|
64
|
+
if (rectFetchObserver) return rectFetchObserver;
|
|
65
|
+
rectFetchObserver = new IntersectionObserver(entries => {
|
|
66
|
+
lastCallbackDelay = Math.round(performance.now() - rectFetchStartTime);
|
|
67
|
+
for (let i = 0; i < entries.length; i++) BoundingRects.set(entries[i].target, entries[i].boundingClientRect);
|
|
68
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout() && lastCallbackDelay > 50) console.warn("[onLayout-io-delay]", lastCallbackDelay + "ms", entries.length, "entries");
|
|
69
|
+
if (rectFetchResolve) {
|
|
70
|
+
rectFetchResolve(true);
|
|
71
|
+
rectFetchResolve = null;
|
|
72
|
+
}
|
|
73
|
+
}, {
|
|
74
|
+
threshold: 0
|
|
75
|
+
});
|
|
76
|
+
return rectFetchObserver;
|
|
77
|
+
};
|
|
78
|
+
const BoundingRects = /* @__PURE__ */new WeakMap();
|
|
79
|
+
let rectFetchObserver = null;
|
|
80
|
+
let rectFetchResolve = null;
|
|
81
|
+
let rectFetchStartTime = 0;
|
|
82
|
+
let lastCallbackDelay = 0;
|
|
83
|
+
async function updateLayoutIfChanged(node) {
|
|
84
|
+
const onLayout = LayoutHandlers.get(node);
|
|
85
|
+
if (typeof onLayout !== "function") return;
|
|
86
|
+
const parentNode = node.parentElement;
|
|
87
|
+
if (!parentNode) return;
|
|
88
|
+
let nodeRect;
|
|
89
|
+
let parentRect;
|
|
90
|
+
if (strategy === "async") {
|
|
91
|
+
nodeRect = BoundingRects.get(node);
|
|
92
|
+
parentRect = BoundingRects.get(parentNode);
|
|
93
|
+
if (!nodeRect || !parentRect) return;
|
|
94
|
+
} else {
|
|
95
|
+
nodeRect = node.getBoundingClientRect();
|
|
96
|
+
parentRect = parentNode.getBoundingClientRect();
|
|
97
|
+
}
|
|
98
|
+
const cachedRect = NodeRectCache.get(node);
|
|
99
|
+
const cachedParentRect = NodeRectCache.get(parentNode);
|
|
100
|
+
const nodeChanged = !cachedRect || !rectsEqual(cachedRect, nodeRect);
|
|
101
|
+
const parentChanged = !cachedParentRect || !rectsEqual(cachedParentRect, parentRect);
|
|
102
|
+
if (nodeChanged || parentChanged) {
|
|
103
|
+
NodeRectCache.set(node, nodeRect);
|
|
104
|
+
NodeRectCache.set(parentNode, parentRect);
|
|
105
|
+
const event = getElementLayoutEvent(nodeRect, parentRect, node);
|
|
106
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout()) console.log("[useElementLayout] change", {
|
|
107
|
+
tag: node.tagName,
|
|
108
|
+
id: node.id || void 0,
|
|
109
|
+
className: (node.className || "").slice(0, 60) || void 0,
|
|
110
|
+
layout: event.nativeEvent.layout,
|
|
111
|
+
first: !cachedRect
|
|
112
|
+
});
|
|
113
|
+
if (avoidUpdates) queuedUpdates.set(node, () => onLayout(event));else onLayout(event);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const rAF = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : void 0;
|
|
117
|
+
const userSkipVal = process.env.TAMAGUI_LAYOUT_FRAME_SKIP;
|
|
118
|
+
const BASE_SKIP_FRAMES = userSkipVal ? +userSkipVal : 10;
|
|
119
|
+
const MAX_SKIP_FRAMES = 20;
|
|
120
|
+
let skipFrames = BASE_SKIP_FRAMES;
|
|
121
|
+
let frameCount = 0;
|
|
122
|
+
async function layoutOnAnimationFrame() {
|
|
123
|
+
if (frameCount++ % skipFrames !== 0) {
|
|
124
|
+
rAF ? rAF(layoutOnAnimationFrame) : setTimeout(layoutOnAnimationFrame, 16);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (frameCount >= Number.MAX_SAFE_INTEGER) frameCount = 0;
|
|
128
|
+
if (strategy !== "off") {
|
|
129
|
+
const visibleNodes = [];
|
|
130
|
+
const parentsToObserve = /* @__PURE__ */new Set();
|
|
131
|
+
for (const node of Nodes) {
|
|
132
|
+
const parentElement = node.parentElement;
|
|
133
|
+
if (!(parentElement instanceof HTMLElement)) {
|
|
134
|
+
cleanupNode(node);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const disableKey = LayoutDisableKey.get(node);
|
|
138
|
+
if (disableKey && DisableLayoutContextValues[disableKey] === true) continue;
|
|
139
|
+
if (IntersectionState.get(node) === false) continue;
|
|
140
|
+
visibleNodes.push(node);
|
|
141
|
+
parentsToObserve.add(parentElement);
|
|
142
|
+
}
|
|
143
|
+
if (visibleNodes.length > 0) {
|
|
144
|
+
const io = ensureRectFetchObserver();
|
|
145
|
+
rectFetchStartTime = performance.now();
|
|
146
|
+
for (let i = 0; i < visibleNodes.length; i++) io.observe(visibleNodes[i]);
|
|
147
|
+
for (const parent of parentsToObserve) io.observe(parent);
|
|
148
|
+
await new Promise(res => {
|
|
149
|
+
rectFetchResolve = res;
|
|
150
|
+
});
|
|
151
|
+
for (let i = 0; i < visibleNodes.length; i++) io.unobserve(visibleNodes[i]);
|
|
152
|
+
for (const parent of parentsToObserve) io.unobserve(parent);
|
|
153
|
+
if (lastCallbackDelay > 50) skipFrames = Math.min(skipFrames + 2, MAX_SKIP_FRAMES);else if (lastCallbackDelay < 20) skipFrames = Math.max(skipFrames - 1, BASE_SKIP_FRAMES);
|
|
154
|
+
for (let i = 0; i < visibleNodes.length; i++) updateLayoutIfChanged(visibleNodes[i]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
rAF ? rAF(layoutOnAnimationFrame) : setTimeout(layoutOnAnimationFrame, 16);
|
|
158
|
+
}
|
|
159
|
+
layoutOnAnimationFrame();
|
|
160
|
+
}
|
|
161
|
+
const getElementLayoutEvent = (nodeRect, parentRect, node) => {
|
|
162
|
+
return {
|
|
163
|
+
nativeEvent: {
|
|
164
|
+
layout: getRelativeDimensions(nodeRect, parentRect, node),
|
|
165
|
+
target: nodeRect
|
|
166
|
+
},
|
|
167
|
+
timeStamp: Date.now()
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const getPreTransformDimensions = node => {
|
|
171
|
+
return {
|
|
172
|
+
width: node.offsetWidth,
|
|
173
|
+
height: node.offsetHeight
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
const getRelativeDimensions = (a, b, aNode) => {
|
|
177
|
+
const {
|
|
178
|
+
left,
|
|
179
|
+
top
|
|
180
|
+
} = a;
|
|
181
|
+
const x = left - b.left;
|
|
182
|
+
const y = top - b.top;
|
|
183
|
+
const {
|
|
184
|
+
width,
|
|
185
|
+
height
|
|
186
|
+
} = usePretransformDimensions() && aNode ? getPreTransformDimensions(aNode) : {
|
|
187
|
+
width: a.width,
|
|
188
|
+
height: a.height
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
x,
|
|
192
|
+
y,
|
|
193
|
+
width,
|
|
194
|
+
height,
|
|
195
|
+
pageX: a.left,
|
|
196
|
+
pageY: a.top
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
function registerLayoutNode(node, onChange, disableKey) {
|
|
200
|
+
Nodes.add(node);
|
|
201
|
+
LayoutHandlers.set(node, onChange);
|
|
202
|
+
if (disableKey) LayoutDisableKey.set(node, disableKey);
|
|
203
|
+
startGlobalObservers();
|
|
204
|
+
if (globalIntersectionObserver) {
|
|
205
|
+
globalIntersectionObserver.observe(node);
|
|
206
|
+
IntersectionState.set(node, true);
|
|
207
|
+
}
|
|
208
|
+
return () => cleanupNode(node);
|
|
209
|
+
}
|
|
210
|
+
function cleanupNode(node) {
|
|
211
|
+
Nodes.delete(node);
|
|
212
|
+
LayoutHandlers.delete(node);
|
|
213
|
+
LayoutDisableKey.delete(node);
|
|
214
|
+
NodeRectCache.delete(node);
|
|
215
|
+
IntersectionState.delete(node);
|
|
216
|
+
if (globalIntersectionObserver) globalIntersectionObserver.unobserve(node);
|
|
217
|
+
}
|
|
218
|
+
const PrevHostNode = /* @__PURE__ */new WeakMap();
|
|
219
|
+
function useElementLayout(ref, onLayout) {
|
|
220
|
+
const disableKey = useContext(DisableLayoutContextKey);
|
|
221
|
+
const node = ensureWebElement(ref.current?.host);
|
|
222
|
+
if (node && onLayout) {
|
|
223
|
+
LayoutHandlers.set(node, onLayout);
|
|
224
|
+
LayoutDisableKey.set(node, disableKey);
|
|
225
|
+
}
|
|
226
|
+
useIsomorphicLayoutEffect(() => {
|
|
227
|
+
if (!onLayout) return;
|
|
228
|
+
const nextNode = ensureWebElement(ref.current?.host);
|
|
229
|
+
const prevNode = PrevHostNode.get(ref);
|
|
230
|
+
if (nextNode === prevNode) return;
|
|
231
|
+
if (prevNode) cleanupNode(prevNode);
|
|
232
|
+
PrevHostNode.set(ref, nextNode);
|
|
233
|
+
if (!nextNode) return;
|
|
234
|
+
Nodes.add(nextNode);
|
|
235
|
+
startGlobalObservers();
|
|
236
|
+
if (globalIntersectionObserver) {
|
|
237
|
+
globalIntersectionObserver.observe(nextNode);
|
|
238
|
+
IntersectionState.set(nextNode, true);
|
|
239
|
+
}
|
|
240
|
+
const handler = LayoutHandlers.get(nextNode);
|
|
241
|
+
if (typeof handler !== "function") return;
|
|
242
|
+
const parentNode = nextNode.parentElement;
|
|
243
|
+
if (!parentNode) return;
|
|
244
|
+
const nodeRect = nextNode.getBoundingClientRect();
|
|
245
|
+
const parentRect = parentNode.getBoundingClientRect();
|
|
246
|
+
NodeRectCache.set(nextNode, nodeRect);
|
|
247
|
+
NodeRectCache.set(parentNode, parentRect);
|
|
248
|
+
handler(getElementLayoutEvent(nodeRect, parentRect, nextNode));
|
|
249
|
+
});
|
|
250
|
+
useIsomorphicLayoutEffect(() => {
|
|
251
|
+
if (!onLayout) return;
|
|
252
|
+
const node2 = ref.current?.host;
|
|
253
|
+
if (!node2) return;
|
|
254
|
+
Nodes.add(node2);
|
|
255
|
+
startGlobalObservers();
|
|
256
|
+
if (globalIntersectionObserver) {
|
|
257
|
+
globalIntersectionObserver.observe(node2);
|
|
258
|
+
IntersectionState.set(node2, true);
|
|
259
|
+
}
|
|
260
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout()) console.log("[useElementLayout] register", {
|
|
261
|
+
tag: node2.tagName,
|
|
262
|
+
id: node2.id || void 0,
|
|
263
|
+
className: (node2.className || "").slice(0, 60) || void 0,
|
|
264
|
+
totalNodes: Nodes.size
|
|
265
|
+
});
|
|
266
|
+
const parentNode = node2.parentNode;
|
|
267
|
+
if (parentNode) onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect(), node2));
|
|
268
|
+
return () => {
|
|
269
|
+
cleanupNode(node2);
|
|
270
|
+
const swappedNode = PrevHostNode.get(ref);
|
|
271
|
+
if (swappedNode && swappedNode !== node2) cleanupNode(swappedNode);
|
|
272
|
+
PrevHostNode.delete(ref);
|
|
273
|
+
};
|
|
274
|
+
}, [ref, !!onLayout]);
|
|
275
|
+
}
|
|
276
|
+
function ensureWebElement(x) {
|
|
277
|
+
if (typeof HTMLElement === "undefined") return;
|
|
278
|
+
return x instanceof HTMLElement ? x : void 0;
|
|
279
|
+
}
|
|
280
|
+
const getBoundingClientRectAsync = node => {
|
|
281
|
+
return new Promise(res => {
|
|
282
|
+
if (!node || node.nodeType !== 1) return res(false);
|
|
283
|
+
const io = new IntersectionObserver(entries => {
|
|
284
|
+
io.disconnect();
|
|
285
|
+
return res(entries[0].boundingClientRect);
|
|
286
|
+
}, {
|
|
287
|
+
threshold: 0
|
|
288
|
+
});
|
|
289
|
+
io.observe(node);
|
|
290
|
+
});
|
|
291
|
+
};
|
|
292
|
+
const measureNode = async (node, relativeTo) => {
|
|
293
|
+
const relativeNode = relativeTo || node?.parentElement;
|
|
294
|
+
if (relativeNode instanceof HTMLElement) {
|
|
295
|
+
const [nodeDim, relativeNodeDim] = await Promise.all([getBoundingClientRectAsync(node), getBoundingClientRectAsync(relativeNode)]);
|
|
296
|
+
if (relativeNodeDim && nodeDim) return getRelativeDimensions(nodeDim, relativeNodeDim, node);
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
};
|
|
300
|
+
const measure = async (node, callback) => {
|
|
301
|
+
const out = await measureNode(node, node.parentNode instanceof HTMLElement ? node.parentNode : null);
|
|
302
|
+
if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY);
|
|
303
|
+
return out;
|
|
304
|
+
};
|
|
305
|
+
function createMeasure(node) {
|
|
306
|
+
return callback => measure(node, callback);
|
|
307
|
+
}
|
|
308
|
+
const measureInWindow = async (node, callback) => {
|
|
309
|
+
const out = await measureNode(node, null);
|
|
310
|
+
if (out) callback?.(out.pageX, out.pageY, out.width, out.height);
|
|
311
|
+
return out;
|
|
312
|
+
};
|
|
313
|
+
const createMeasureInWindow = node => {
|
|
314
|
+
return callback => measureInWindow(node, callback);
|
|
315
|
+
};
|
|
316
|
+
const measureLayout = async (node, relativeNode, callback) => {
|
|
317
|
+
const out = await measureNode(node, relativeNode);
|
|
318
|
+
if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY);
|
|
319
|
+
return out;
|
|
320
|
+
};
|
|
321
|
+
function createMeasureLayout(node) {
|
|
322
|
+
return (relativeTo, callback) => measureLayout(node, relativeTo, callback);
|
|
323
|
+
}
|
|
324
|
+
export { LayoutMeasurementController, createMeasure, createMeasureInWindow, createMeasureLayout, enable, getBoundingClientRectAsync, getElementLayoutEvent, measure, measureInWindow, measureLayout, measureNode, registerLayoutNode, setOnLayoutStrategy, useElementLayout };
|
|
325
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useIsomorphicLayoutEffect","createContext","useContext","useId","jsx","LayoutHandlers","WeakMap","LayoutDisableKey","Nodes","Set","IntersectionState","usePretransformDimensions","globalThis","__TAMAGUI_ONLAYOUT_PRETRANSFORM","process","env","TAMAGUI_ONLAYOUT_PRETRANSFORM","_debugLayout","isDebugLayout","window","URLSearchParams","location","search","has","DisableLayoutContextValues","DisableLayoutContextKey","ENABLE","IntersectionObserver","LayoutMeasurementController","disable","children","id","Provider","value","globalIntersectionObserver","strategy","setOnLayoutStrategy","state","NodeRectCache","avoidUpdates","queuedUpdates","Map","enable","forEach","cb","clear","startGlobalObservers","entries","i","length","entry","node","target","get","isIntersecting","set","threshold","rectsEqual","a","b","x","y","width","height","ensureRectFetchObserver","rectFetchObserver","lastCallbackDelay","Math","round","performance","now","rectFetchStartTime","BoundingRects","boundingClientRect","NODE_ENV","console","warn","rectFetchResolve","updateLayoutIfChanged","onLayout","parentNode","parentElement","nodeRect","parentRect","getBoundingClientRect","cachedRect","cachedParentRect","nodeChanged","parentChanged","event","getElementLayoutEvent","log","tag","tagName","className","slice","layout","nativeEvent","first","rAF","requestAnimationFrame","userSkipVal","TAMAGUI_LAYOUT_FRAME_SKIP","BASE_SKIP_FRAMES","MAX_SKIP_FRAMES","skipFrames","frameCount","layoutOnAnimationFrame","setTimeout","Number","MAX_SAFE_INTEGER","visibleNodes","parentsToObserve","HTMLElement","cleanupNode","disableKey","push","add","io","observe","parent","Promise","res","unobserve","min","max","getRelativeDimensions","timeStamp","Date","getPreTransformDimensions","offsetWidth","offsetHeight","aNode","left","top","pageX","pageY","registerLayoutNode","onChange","delete","PrevHostNode","useElementLayout","ref","ensureWebElement","current","host","nextNode","prevNode","handler","node2","totalNodes","size","swappedNode","getBoundingClientRectAsync","nodeType","disconnect","measureNode","relativeTo","relativeNode","nodeDim","relativeNodeDim","all","measure","callback","out","createMeasure","measureInWindow","createMeasureInWindow","measureLayout","createMeasureLayout"],"sources":["../../src/index.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { useIsomorphicLayoutEffect } from "@hanzogui/constants";
|
|
2
|
+
import { createContext, useContext, useId } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
const LayoutHandlers = /* @__PURE__ */new WeakMap();
|
|
5
|
+
const LayoutDisableKey = /* @__PURE__ */new WeakMap();
|
|
6
|
+
const Nodes = /* @__PURE__ */new Set();
|
|
7
|
+
const IntersectionState = /* @__PURE__ */new WeakMap();
|
|
8
|
+
const usePretransformDimensions = () => globalThis.__TAMAGUI_ONLAYOUT_PRETRANSFORM === true || process.env.TAMAGUI_ONLAYOUT_PRETRANSFORM === "1";
|
|
9
|
+
let _debugLayout;
|
|
10
|
+
function isDebugLayout() {
|
|
11
|
+
if (_debugLayout === void 0) _debugLayout = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("__tamaDebugLayout");
|
|
12
|
+
return _debugLayout;
|
|
13
|
+
}
|
|
14
|
+
const DisableLayoutContextValues = {};
|
|
15
|
+
const DisableLayoutContextKey = createContext("");
|
|
16
|
+
const ENABLE = typeof IntersectionObserver !== "undefined";
|
|
17
|
+
const LayoutMeasurementController = ({
|
|
18
|
+
disable,
|
|
19
|
+
children
|
|
20
|
+
}) => {
|
|
21
|
+
const id = useId();
|
|
22
|
+
useIsomorphicLayoutEffect(() => {
|
|
23
|
+
DisableLayoutContextValues[id] = disable;
|
|
24
|
+
}, [disable, id]);
|
|
25
|
+
return /* @__PURE__ */jsx(DisableLayoutContextKey.Provider, {
|
|
26
|
+
value: id,
|
|
27
|
+
children
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
let globalIntersectionObserver = null;
|
|
31
|
+
let strategy = "async";
|
|
32
|
+
function setOnLayoutStrategy(state) {
|
|
33
|
+
strategy = state;
|
|
34
|
+
}
|
|
35
|
+
const NodeRectCache = /* @__PURE__ */new WeakMap();
|
|
36
|
+
let avoidUpdates = true;
|
|
37
|
+
const queuedUpdates = /* @__PURE__ */new Map();
|
|
38
|
+
function enable() {
|
|
39
|
+
if (avoidUpdates) {
|
|
40
|
+
avoidUpdates = false;
|
|
41
|
+
if (queuedUpdates) {
|
|
42
|
+
queuedUpdates.forEach(cb => cb());
|
|
43
|
+
queuedUpdates.clear();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function startGlobalObservers() {
|
|
48
|
+
if (!ENABLE || globalIntersectionObserver) return;
|
|
49
|
+
globalIntersectionObserver = new IntersectionObserver(entries => {
|
|
50
|
+
for (let i = 0; i < entries.length; i++) {
|
|
51
|
+
const entry = entries[i];
|
|
52
|
+
const node = entry.target;
|
|
53
|
+
if (IntersectionState.get(node) !== entry.isIntersecting) IntersectionState.set(node, entry.isIntersecting);
|
|
54
|
+
}
|
|
55
|
+
}, {
|
|
56
|
+
threshold: 0
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function rectsEqual(a, b) {
|
|
60
|
+
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
61
|
+
}
|
|
62
|
+
if (ENABLE) {
|
|
63
|
+
let ensureRectFetchObserver = function () {
|
|
64
|
+
if (rectFetchObserver) return rectFetchObserver;
|
|
65
|
+
rectFetchObserver = new IntersectionObserver(entries => {
|
|
66
|
+
lastCallbackDelay = Math.round(performance.now() - rectFetchStartTime);
|
|
67
|
+
for (let i = 0; i < entries.length; i++) BoundingRects.set(entries[i].target, entries[i].boundingClientRect);
|
|
68
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout() && lastCallbackDelay > 50) console.warn("[onLayout-io-delay]", lastCallbackDelay + "ms", entries.length, "entries");
|
|
69
|
+
if (rectFetchResolve) {
|
|
70
|
+
rectFetchResolve(true);
|
|
71
|
+
rectFetchResolve = null;
|
|
72
|
+
}
|
|
73
|
+
}, {
|
|
74
|
+
threshold: 0
|
|
75
|
+
});
|
|
76
|
+
return rectFetchObserver;
|
|
77
|
+
};
|
|
78
|
+
const BoundingRects = /* @__PURE__ */new WeakMap();
|
|
79
|
+
let rectFetchObserver = null;
|
|
80
|
+
let rectFetchResolve = null;
|
|
81
|
+
let rectFetchStartTime = 0;
|
|
82
|
+
let lastCallbackDelay = 0;
|
|
83
|
+
async function updateLayoutIfChanged(node) {
|
|
84
|
+
const onLayout = LayoutHandlers.get(node);
|
|
85
|
+
if (typeof onLayout !== "function") return;
|
|
86
|
+
const parentNode = node.parentElement;
|
|
87
|
+
if (!parentNode) return;
|
|
88
|
+
let nodeRect;
|
|
89
|
+
let parentRect;
|
|
90
|
+
if (strategy === "async") {
|
|
91
|
+
nodeRect = BoundingRects.get(node);
|
|
92
|
+
parentRect = BoundingRects.get(parentNode);
|
|
93
|
+
if (!nodeRect || !parentRect) return;
|
|
94
|
+
} else {
|
|
95
|
+
nodeRect = node.getBoundingClientRect();
|
|
96
|
+
parentRect = parentNode.getBoundingClientRect();
|
|
97
|
+
}
|
|
98
|
+
const cachedRect = NodeRectCache.get(node);
|
|
99
|
+
const cachedParentRect = NodeRectCache.get(parentNode);
|
|
100
|
+
const nodeChanged = !cachedRect || !rectsEqual(cachedRect, nodeRect);
|
|
101
|
+
const parentChanged = !cachedParentRect || !rectsEqual(cachedParentRect, parentRect);
|
|
102
|
+
if (nodeChanged || parentChanged) {
|
|
103
|
+
NodeRectCache.set(node, nodeRect);
|
|
104
|
+
NodeRectCache.set(parentNode, parentRect);
|
|
105
|
+
const event = getElementLayoutEvent(nodeRect, parentRect, node);
|
|
106
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout()) console.log("[useElementLayout] change", {
|
|
107
|
+
tag: node.tagName,
|
|
108
|
+
id: node.id || void 0,
|
|
109
|
+
className: (node.className || "").slice(0, 60) || void 0,
|
|
110
|
+
layout: event.nativeEvent.layout,
|
|
111
|
+
first: !cachedRect
|
|
112
|
+
});
|
|
113
|
+
if (avoidUpdates) queuedUpdates.set(node, () => onLayout(event));else onLayout(event);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const rAF = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : void 0;
|
|
117
|
+
const userSkipVal = process.env.TAMAGUI_LAYOUT_FRAME_SKIP;
|
|
118
|
+
const BASE_SKIP_FRAMES = userSkipVal ? +userSkipVal : 10;
|
|
119
|
+
const MAX_SKIP_FRAMES = 20;
|
|
120
|
+
let skipFrames = BASE_SKIP_FRAMES;
|
|
121
|
+
let frameCount = 0;
|
|
122
|
+
async function layoutOnAnimationFrame() {
|
|
123
|
+
if (frameCount++ % skipFrames !== 0) {
|
|
124
|
+
rAF ? rAF(layoutOnAnimationFrame) : setTimeout(layoutOnAnimationFrame, 16);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (frameCount >= Number.MAX_SAFE_INTEGER) frameCount = 0;
|
|
128
|
+
if (strategy !== "off") {
|
|
129
|
+
const visibleNodes = [];
|
|
130
|
+
const parentsToObserve = /* @__PURE__ */new Set();
|
|
131
|
+
for (const node of Nodes) {
|
|
132
|
+
const parentElement = node.parentElement;
|
|
133
|
+
if (!(parentElement instanceof HTMLElement)) {
|
|
134
|
+
cleanupNode(node);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const disableKey = LayoutDisableKey.get(node);
|
|
138
|
+
if (disableKey && DisableLayoutContextValues[disableKey] === true) continue;
|
|
139
|
+
if (IntersectionState.get(node) === false) continue;
|
|
140
|
+
visibleNodes.push(node);
|
|
141
|
+
parentsToObserve.add(parentElement);
|
|
142
|
+
}
|
|
143
|
+
if (visibleNodes.length > 0) {
|
|
144
|
+
const io = ensureRectFetchObserver();
|
|
145
|
+
rectFetchStartTime = performance.now();
|
|
146
|
+
for (let i = 0; i < visibleNodes.length; i++) io.observe(visibleNodes[i]);
|
|
147
|
+
for (const parent of parentsToObserve) io.observe(parent);
|
|
148
|
+
await new Promise(res => {
|
|
149
|
+
rectFetchResolve = res;
|
|
150
|
+
});
|
|
151
|
+
for (let i = 0; i < visibleNodes.length; i++) io.unobserve(visibleNodes[i]);
|
|
152
|
+
for (const parent of parentsToObserve) io.unobserve(parent);
|
|
153
|
+
if (lastCallbackDelay > 50) skipFrames = Math.min(skipFrames + 2, MAX_SKIP_FRAMES);else if (lastCallbackDelay < 20) skipFrames = Math.max(skipFrames - 1, BASE_SKIP_FRAMES);
|
|
154
|
+
for (let i = 0; i < visibleNodes.length; i++) updateLayoutIfChanged(visibleNodes[i]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
rAF ? rAF(layoutOnAnimationFrame) : setTimeout(layoutOnAnimationFrame, 16);
|
|
158
|
+
}
|
|
159
|
+
layoutOnAnimationFrame();
|
|
160
|
+
}
|
|
161
|
+
const getElementLayoutEvent = (nodeRect, parentRect, node) => {
|
|
162
|
+
return {
|
|
163
|
+
nativeEvent: {
|
|
164
|
+
layout: getRelativeDimensions(nodeRect, parentRect, node),
|
|
165
|
+
target: nodeRect
|
|
166
|
+
},
|
|
167
|
+
timeStamp: Date.now()
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const getPreTransformDimensions = node => {
|
|
171
|
+
return {
|
|
172
|
+
width: node.offsetWidth,
|
|
173
|
+
height: node.offsetHeight
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
const getRelativeDimensions = (a, b, aNode) => {
|
|
177
|
+
const {
|
|
178
|
+
left,
|
|
179
|
+
top
|
|
180
|
+
} = a;
|
|
181
|
+
const x = left - b.left;
|
|
182
|
+
const y = top - b.top;
|
|
183
|
+
const {
|
|
184
|
+
width,
|
|
185
|
+
height
|
|
186
|
+
} = usePretransformDimensions() && aNode ? getPreTransformDimensions(aNode) : {
|
|
187
|
+
width: a.width,
|
|
188
|
+
height: a.height
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
x,
|
|
192
|
+
y,
|
|
193
|
+
width,
|
|
194
|
+
height,
|
|
195
|
+
pageX: a.left,
|
|
196
|
+
pageY: a.top
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
function registerLayoutNode(node, onChange, disableKey) {
|
|
200
|
+
Nodes.add(node);
|
|
201
|
+
LayoutHandlers.set(node, onChange);
|
|
202
|
+
if (disableKey) LayoutDisableKey.set(node, disableKey);
|
|
203
|
+
startGlobalObservers();
|
|
204
|
+
if (globalIntersectionObserver) {
|
|
205
|
+
globalIntersectionObserver.observe(node);
|
|
206
|
+
IntersectionState.set(node, true);
|
|
207
|
+
}
|
|
208
|
+
return () => cleanupNode(node);
|
|
209
|
+
}
|
|
210
|
+
function cleanupNode(node) {
|
|
211
|
+
Nodes.delete(node);
|
|
212
|
+
LayoutHandlers.delete(node);
|
|
213
|
+
LayoutDisableKey.delete(node);
|
|
214
|
+
NodeRectCache.delete(node);
|
|
215
|
+
IntersectionState.delete(node);
|
|
216
|
+
if (globalIntersectionObserver) globalIntersectionObserver.unobserve(node);
|
|
217
|
+
}
|
|
218
|
+
const PrevHostNode = /* @__PURE__ */new WeakMap();
|
|
219
|
+
function useElementLayout(ref, onLayout) {
|
|
220
|
+
const disableKey = useContext(DisableLayoutContextKey);
|
|
221
|
+
const node = ensureWebElement(ref.current?.host);
|
|
222
|
+
if (node && onLayout) {
|
|
223
|
+
LayoutHandlers.set(node, onLayout);
|
|
224
|
+
LayoutDisableKey.set(node, disableKey);
|
|
225
|
+
}
|
|
226
|
+
useIsomorphicLayoutEffect(() => {
|
|
227
|
+
if (!onLayout) return;
|
|
228
|
+
const nextNode = ensureWebElement(ref.current?.host);
|
|
229
|
+
const prevNode = PrevHostNode.get(ref);
|
|
230
|
+
if (nextNode === prevNode) return;
|
|
231
|
+
if (prevNode) cleanupNode(prevNode);
|
|
232
|
+
PrevHostNode.set(ref, nextNode);
|
|
233
|
+
if (!nextNode) return;
|
|
234
|
+
Nodes.add(nextNode);
|
|
235
|
+
startGlobalObservers();
|
|
236
|
+
if (globalIntersectionObserver) {
|
|
237
|
+
globalIntersectionObserver.observe(nextNode);
|
|
238
|
+
IntersectionState.set(nextNode, true);
|
|
239
|
+
}
|
|
240
|
+
const handler = LayoutHandlers.get(nextNode);
|
|
241
|
+
if (typeof handler !== "function") return;
|
|
242
|
+
const parentNode = nextNode.parentElement;
|
|
243
|
+
if (!parentNode) return;
|
|
244
|
+
const nodeRect = nextNode.getBoundingClientRect();
|
|
245
|
+
const parentRect = parentNode.getBoundingClientRect();
|
|
246
|
+
NodeRectCache.set(nextNode, nodeRect);
|
|
247
|
+
NodeRectCache.set(parentNode, parentRect);
|
|
248
|
+
handler(getElementLayoutEvent(nodeRect, parentRect, nextNode));
|
|
249
|
+
});
|
|
250
|
+
useIsomorphicLayoutEffect(() => {
|
|
251
|
+
if (!onLayout) return;
|
|
252
|
+
const node2 = ref.current?.host;
|
|
253
|
+
if (!node2) return;
|
|
254
|
+
Nodes.add(node2);
|
|
255
|
+
startGlobalObservers();
|
|
256
|
+
if (globalIntersectionObserver) {
|
|
257
|
+
globalIntersectionObserver.observe(node2);
|
|
258
|
+
IntersectionState.set(node2, true);
|
|
259
|
+
}
|
|
260
|
+
if (process.env.NODE_ENV === "development" && isDebugLayout()) console.log("[useElementLayout] register", {
|
|
261
|
+
tag: node2.tagName,
|
|
262
|
+
id: node2.id || void 0,
|
|
263
|
+
className: (node2.className || "").slice(0, 60) || void 0,
|
|
264
|
+
totalNodes: Nodes.size
|
|
265
|
+
});
|
|
266
|
+
const parentNode = node2.parentNode;
|
|
267
|
+
if (parentNode) onLayout(getElementLayoutEvent(node2.getBoundingClientRect(), parentNode.getBoundingClientRect(), node2));
|
|
268
|
+
return () => {
|
|
269
|
+
cleanupNode(node2);
|
|
270
|
+
const swappedNode = PrevHostNode.get(ref);
|
|
271
|
+
if (swappedNode && swappedNode !== node2) cleanupNode(swappedNode);
|
|
272
|
+
PrevHostNode.delete(ref);
|
|
273
|
+
};
|
|
274
|
+
}, [ref, !!onLayout]);
|
|
275
|
+
}
|
|
276
|
+
function ensureWebElement(x) {
|
|
277
|
+
if (typeof HTMLElement === "undefined") return;
|
|
278
|
+
return x instanceof HTMLElement ? x : void 0;
|
|
279
|
+
}
|
|
280
|
+
const getBoundingClientRectAsync = node => {
|
|
281
|
+
return new Promise(res => {
|
|
282
|
+
if (!node || node.nodeType !== 1) return res(false);
|
|
283
|
+
const io = new IntersectionObserver(entries => {
|
|
284
|
+
io.disconnect();
|
|
285
|
+
return res(entries[0].boundingClientRect);
|
|
286
|
+
}, {
|
|
287
|
+
threshold: 0
|
|
288
|
+
});
|
|
289
|
+
io.observe(node);
|
|
290
|
+
});
|
|
291
|
+
};
|
|
292
|
+
const measureNode = async (node, relativeTo) => {
|
|
293
|
+
const relativeNode = relativeTo || node?.parentElement;
|
|
294
|
+
if (relativeNode instanceof HTMLElement) {
|
|
295
|
+
const [nodeDim, relativeNodeDim] = await Promise.all([getBoundingClientRectAsync(node), getBoundingClientRectAsync(relativeNode)]);
|
|
296
|
+
if (relativeNodeDim && nodeDim) return getRelativeDimensions(nodeDim, relativeNodeDim, node);
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
};
|
|
300
|
+
const measure = async (node, callback) => {
|
|
301
|
+
const out = await measureNode(node, node.parentNode instanceof HTMLElement ? node.parentNode : null);
|
|
302
|
+
if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY);
|
|
303
|
+
return out;
|
|
304
|
+
};
|
|
305
|
+
function createMeasure(node) {
|
|
306
|
+
return callback => measure(node, callback);
|
|
307
|
+
}
|
|
308
|
+
const measureInWindow = async (node, callback) => {
|
|
309
|
+
const out = await measureNode(node, null);
|
|
310
|
+
if (out) callback?.(out.pageX, out.pageY, out.width, out.height);
|
|
311
|
+
return out;
|
|
312
|
+
};
|
|
313
|
+
const createMeasureInWindow = node => {
|
|
314
|
+
return callback => measureInWindow(node, callback);
|
|
315
|
+
};
|
|
316
|
+
const measureLayout = async (node, relativeNode, callback) => {
|
|
317
|
+
const out = await measureNode(node, relativeNode);
|
|
318
|
+
if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY);
|
|
319
|
+
return out;
|
|
320
|
+
};
|
|
321
|
+
function createMeasureLayout(node) {
|
|
322
|
+
return (relativeTo, callback) => measureLayout(node, relativeTo, callback);
|
|
323
|
+
}
|
|
324
|
+
export { LayoutMeasurementController, createMeasure, createMeasureInWindow, createMeasureLayout, enable, getBoundingClientRectAsync, getElementLayoutEvent, measure, measureInWindow, measureLayout, measureNode, registerLayoutNode, setOnLayoutStrategy, useElementLayout };
|
|
325
|
+
//# sourceMappingURL=index.mjs.map
|