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