@tamagui/use-element-layout 3.0.0-beta.831.1 → 3.0.0-beta.889.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/use-element-layout",
3
- "version": "3.0.0-beta.831.1",
3
+ "version": "3.0.0-beta.889.1",
4
4
  "gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
5
5
  "files": [
6
6
  "src",
@@ -34,11 +34,11 @@
34
34
  "clean:build": "tamagui-build clean:build"
35
35
  },
36
36
  "dependencies": {
37
- "@tamagui/constants": "3.0.0-beta.831.1",
38
- "@tamagui/is-equal-shallow": "3.0.0-beta.831.1"
37
+ "@tamagui/constants": "3.0.0-beta.889.1",
38
+ "@tamagui/is-equal-shallow": "3.0.0-beta.889.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@tamagui/build": "3.0.0-beta.831.1",
41
+ "@tamagui/build": "3.0.0-beta.889.1",
42
42
  "react": "19.2.3"
43
43
  },
44
44
  "peerDependencies": {
package/src/index.tsx CHANGED
@@ -4,35 +4,22 @@ import { createContext, useContext, useId, type ReactNode, type RefObject } from
4
4
  const LayoutHandlers = new WeakMap<HTMLElement, Function>()
5
5
  const LayoutDisableKey = new WeakMap<HTMLElement, string>()
6
6
  const Nodes = new Set<HTMLElement>()
7
+ const NodeRectCache = new WeakMap<HTMLElement, DOMRectReadOnly>()
8
+ const PrevHostNode = new WeakMap<object, HTMLElement | undefined>()
7
9
 
8
- // feature flag to enable pre-transform dimension reporting (matches RN behavior)
9
- // can be set via env var at build time or runtime global for testing
10
- // see: https://github.com/tamagui/tamagui/pull/2329
11
10
  const usePretransformDimensions = () =>
12
11
  (globalThis as any).__TAMAGUI_ONLAYOUT_PRETRANSFORM === true ||
13
12
  process.env.TAMAGUI_ONLAYOUT_PRETRANSFORM === '1'
14
13
 
15
- let _debugLayout: boolean | undefined
16
-
17
- function isDebugLayout() {
18
- if (_debugLayout === undefined) {
19
- _debugLayout =
20
- typeof window !== 'undefined' &&
21
- new URLSearchParams(window.location.search).has('__tamaDebugLayout')
22
- }
23
- return _debugLayout
24
- }
14
+ const isDebugLayout = () =>
15
+ typeof window !== 'undefined' && window.location?.search?.includes('__tamaDebugLayout')
25
16
 
26
- // separating to avoid all re-rendering
27
17
  const DisableLayoutContextValues: Record<string, boolean> = {}
28
18
  const DisableLayoutContextKey = createContext<string>('')
29
19
 
30
20
  const ENABLE =
31
21
  process.env.TAMAGUI_TARGET === 'web' && typeof IntersectionObserver !== 'undefined'
32
22
 
33
- // internal testing - advanced helper to turn off layout measurement for extra performance
34
- // TODO document!
35
- // TODO could add frame skip control here
36
23
  export const LayoutMeasurementController = ({
37
24
  disable,
38
25
  children,
@@ -41,16 +28,10 @@ export const LayoutMeasurementController = ({
41
28
  children: ReactNode
42
29
  }): ReactNode => {
43
30
  const id = useId()
44
-
45
31
  useIsomorphicLayoutEffect(() => {
46
32
  const wasDisabled = DisableLayoutContextValues[id] === true
47
33
  DisableLayoutContextValues[id] = disable
48
- // a controller flipping to enabled (a sheet or popper opening) is often
49
- // waiting on a measurement to position itself, so don't make it sit out
50
- // the frame-skip window
51
- if (wasDisabled && !disable) {
52
- measureOnNextFrame?.()
53
- }
34
+ if (wasDisabled && !disable) measureOnNextFrame?.()
54
35
  }, [disable, id])
55
36
 
56
37
  return (
@@ -60,22 +41,11 @@ export const LayoutMeasurementController = ({
60
41
  )
61
42
  }
62
43
 
63
- type TamaguiComponentStatePartial = {
64
- host?: any
65
- }
66
-
44
+ type TamaguiComponentStatePartial = { host?: any }
67
45
  type LayoutMeasurementStrategy = 'off' | 'sync' | 'async'
68
46
 
69
47
  let strategy: LayoutMeasurementStrategy = 'async'
70
-
71
- // the measurement loop parks itself whenever it provably has nothing to do: no
72
- // registered nodes, a hidden document, or measurement turned off. these are the
73
- // only three ways work can reappear, so each one restarts it.
74
48
  let resumeLayoutLoop: (() => void) | undefined
75
-
76
- // restarts the loop AND makes its next frame a measuring frame, skipping the
77
- // frame-skip backoff once. for consumers whose position depends on a pending
78
- // measurement (an opening sheet parked off-screen).
79
49
  let measureOnNextFrame: (() => void) | undefined
80
50
 
81
51
  export type LayoutValue = {
@@ -88,16 +58,10 @@ export type LayoutValue = {
88
58
  }
89
59
 
90
60
  export type LayoutEvent = {
91
- nativeEvent: {
92
- layout: LayoutValue
93
- target: any
94
- }
61
+ nativeEvent: { layout: LayoutValue; target: any }
95
62
  timeStamp: number
96
63
  }
97
64
 
98
- const NodeRectCache = new WeakMap<HTMLElement, DOMRectReadOnly>()
99
-
100
- // prevent thrashing during first hydration (somewhat, streaming gets trickier)
101
65
  let avoidUpdates = true
102
66
  const queuedUpdates = new Map<HTMLElement, Function>()
103
67
 
@@ -111,15 +75,12 @@ export function enable(): void {
111
75
  }
112
76
  }
113
77
 
114
- // optimization: inline rect comparison to avoid function call overhead on hot path
115
78
  function rectsEqual(a: DOMRectReadOnly, b: DOMRectReadOnly): boolean {
116
79
  return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height
117
80
  }
118
81
 
119
82
  if (ENABLE) {
120
83
  const BoundingRects = new WeakMap<Element, DOMRectReadOnly>()
121
-
122
- // optimization: persistent IO for rect fetching, reused across cycles
123
84
  let rectFetchObserver: IntersectionObserver | null = null
124
85
  let rectFetchResolve: ((value: boolean) => void) | null = null
125
86
  let rectFetchStartTime = 0
@@ -127,16 +88,12 @@ if (ENABLE) {
127
88
 
128
89
  function ensureRectFetchObserver() {
129
90
  if (rectFetchObserver) return rectFetchObserver
130
-
131
91
  rectFetchObserver = new IntersectionObserver(
132
92
  (entries) => {
133
93
  lastCallbackDelay = Math.round(performance.now() - rectFetchStartTime)
134
-
135
- // store all rects
136
94
  for (let i = 0; i < entries.length; i++) {
137
95
  BoundingRects.set(entries[i].target, entries[i].boundingClientRect)
138
96
  }
139
-
140
97
  if (
141
98
  process.env.NODE_ENV === 'development' &&
142
99
  isDebugLayout() &&
@@ -149,90 +106,64 @@ if (ENABLE) {
149
106
  'entries'
150
107
  )
151
108
  }
152
-
153
109
  if (rectFetchResolve) {
154
110
  rectFetchResolve(true)
155
111
  rectFetchResolve = null
156
112
  }
157
113
  },
158
- {
159
- threshold: 0,
160
- }
114
+ { threshold: 0 }
161
115
  )
162
-
163
116
  return rectFetchObserver
164
117
  }
165
118
 
166
- async function updateLayoutIfChanged(node: HTMLElement) {
119
+ function updateLayoutIfChanged(node: HTMLElement) {
167
120
  const onLayout = LayoutHandlers.get(node)
168
121
  if (typeof onLayout !== 'function') return
169
-
170
122
  const parentNode = node.parentElement
171
123
  if (!parentNode) return
172
124
 
173
125
  let nodeRect: DOMRectReadOnly | undefined
174
126
  let parentRect: DOMRectReadOnly | undefined
175
127
 
176
- // respect the strategy contract
177
128
  if (strategy === 'async') {
178
129
  nodeRect = BoundingRects.get(node)
179
130
  parentRect = BoundingRects.get(parentNode)
180
-
181
- if (!nodeRect || !parentRect) {
182
- return
183
- }
131
+ if (!nodeRect || !parentRect) return
184
132
  } else {
185
133
  nodeRect = node.getBoundingClientRect()
186
134
  parentRect = parentNode.getBoundingClientRect()
187
135
  }
188
-
189
136
  emitLayoutIfChanged(node, parentNode, nodeRect, parentRect)
190
137
  }
191
138
 
192
139
  const rAF =
193
140
  typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame : undefined
194
-
195
- // adaptive frame skipping with backoff
196
141
  const userSkipVal = process.env.TAMAGUI_LAYOUT_FRAME_SKIP
197
142
  const BASE_SKIP_FRAMES = userSkipVal ? +userSkipVal : 10
198
143
  const MAX_SKIP_FRAMES = 20
199
144
  let skipFrames = BASE_SKIP_FRAMES
200
145
  let frameCount = 0
201
-
202
- // stays true across the await below so a node registering mid-cycle cannot
203
- // start a second concurrent loop
204
146
  let frameScheduled = false
205
147
 
206
148
  function scheduleLayoutFrame() {
207
- if (frameScheduled || strategy === 'off' || Nodes.size === 0 || document.hidden) {
149
+ if (frameScheduled || strategy === 'off' || Nodes.size === 0 || document.hidden)
208
150
  return
209
- }
210
151
  frameScheduled = true
211
152
  rAF ? rAF(layoutOnAnimationFrame) : setTimeout(layoutOnAnimationFrame, 16)
212
153
  }
213
154
 
214
155
  async function layoutOnAnimationFrame() {
215
- // skip frames based on adaptive rate
216
156
  if (frameCount++ % skipFrames !== 0) {
217
157
  frameScheduled = false
218
158
  scheduleLayoutFrame()
219
159
  return
220
160
  }
221
-
222
- // reset frame count to avoid overflow
223
- if (frameCount >= Number.MAX_SAFE_INTEGER) {
224
- frameCount = 0
225
- }
161
+ if (frameCount >= Number.MAX_SAFE_INTEGER) frameCount = 0
226
162
 
227
163
  if (strategy !== 'off') {
228
164
  const activeNodes: HTMLElement[] = []
229
- // optimization: deduplicate parent observations
230
165
  const parentsToObserve = new Set<HTMLElement>()
231
166
 
232
- // collect non-disabled nodes and their unique parents. off-viewport
233
- // nodes stay in: a sheet or popper parks off-screen until its own
234
- // measurement arrives, so gating measurement on visibility deadlocks it
235
- // there, and RN fires onLayout for off-screen views anyway
236
167
  for (const node of Nodes) {
237
168
  const parentElement = node.parentElement
238
169
  if (!(parentElement instanceof HTMLElement)) {
@@ -248,45 +179,26 @@ if (ENABLE) {
248
179
  if (activeNodes.length > 0) {
249
180
  const io = ensureRectFetchObserver()
250
181
  rectFetchStartTime = performance.now()
182
+ for (let i = 0; i < activeNodes.length; i++) io.observe(activeNodes[i])
183
+ for (const parent of parentsToObserve) io.observe(parent)
251
184
 
252
- // observe all nodes
253
- for (let i = 0; i < activeNodes.length; i++) {
254
- io.observe(activeNodes[i])
255
- }
256
- // optimization: observe unique parents only (not N times for N children)
257
- for (const parent of parentsToObserve) {
258
- io.observe(parent)
259
- }
260
-
261
- // wait for callback
262
185
  await new Promise<boolean>((res) => {
263
186
  rectFetchResolve = res
264
187
  })
265
188
 
266
- // unobserve all to reset for next cycle
267
- for (let i = 0; i < activeNodes.length; i++) {
268
- io.unobserve(activeNodes[i])
269
- }
270
- for (const parent of parentsToObserve) {
271
- io.unobserve(parent)
272
- }
189
+ for (let i = 0; i < activeNodes.length; i++) io.unobserve(activeNodes[i])
190
+ for (const parent of parentsToObserve) io.unobserve(parent)
273
191
 
274
- // adaptive backoff: if IO was slow, skip more frames next cycle
275
192
  if (lastCallbackDelay > 50) {
276
193
  skipFrames = Math.min(skipFrames + 2, MAX_SKIP_FRAMES)
277
194
  } else if (lastCallbackDelay < 20) {
278
- // recover back to base rate when things are fast
279
195
  skipFrames = Math.max(skipFrames - 1, BASE_SKIP_FRAMES)
280
196
  }
281
197
 
282
- // process updates
283
- for (let i = 0; i < activeNodes.length; i++) {
284
- updateLayoutIfChanged(activeNodes[i])
285
- }
198
+ for (let i = 0; i < activeNodes.length; i++) updateLayoutIfChanged(activeNodes[i])
286
199
  }
287
200
  }
288
201
 
289
- // schedule next frame
290
202
  frameScheduled = false
291
203
  scheduleLayoutFrame()
292
204
  }
@@ -304,48 +216,33 @@ export const getElementLayoutEvent = (
304
216
  nodeRect: DOMRectReadOnly,
305
217
  parentRect: DOMRectReadOnly,
306
218
  node?: HTMLElement
307
- ): LayoutEvent => {
308
- return {
309
- nativeEvent: {
310
- layout: getRelativeDimensions(nodeRect, parentRect, node),
311
- target: nodeRect,
312
- },
313
- timeStamp: Date.now(),
314
- }
315
- }
219
+ ): LayoutEvent => ({
220
+ nativeEvent: {
221
+ layout: getRelativeDimensions(nodeRect, parentRect, node),
222
+ target: nodeRect,
223
+ },
224
+ timeStamp: Date.now(),
225
+ })
316
226
 
317
- /**
318
- * get pre-transform dimensions for a node.
319
- * uses offsetWidth/offsetHeight which report CSS layout dimensions
320
- * unaffected by transforms - this matches React Native's onLayout behavior.
321
- *
322
- * see: https://github.com/tamagui/tamagui/pull/2329
323
- */
324
227
  const getPreTransformDimensions = (
325
228
  node: HTMLElement
326
- ): { width: number; height: number } => {
327
- return {
328
- width: node.offsetWidth,
329
- height: node.offsetHeight,
330
- }
331
- }
229
+ ): { width: number; height: number } => ({
230
+ width: node.offsetWidth,
231
+ height: node.offsetHeight,
232
+ })
332
233
 
333
234
  const getRelativeDimensions = (
334
235
  a: DOMRectReadOnly,
335
236
  b: DOMRectReadOnly,
336
237
  aNode?: HTMLElement
337
238
  ) => {
338
- const { left, top } = a
339
- const x = left - b.left
340
- const y = top - b.top
341
-
342
- // get pre-transform dimensions when flag is enabled and node is available
239
+ const left = a.left - b.left
240
+ const top = a.top - b.top
343
241
  const { width, height } =
344
242
  usePretransformDimensions() && aNode
345
243
  ? getPreTransformDimensions(aNode)
346
244
  : { width: a.width, height: a.height }
347
-
348
- return { x, y, width, height, pageX: a.left, pageY: a.top }
245
+ return { x: left, y: top, width, height, pageX: a.left, pageY: a.top }
349
246
  }
350
247
 
351
248
  function emitLayoutIfChanged(
@@ -359,7 +256,6 @@ function emitLayoutIfChanged(
359
256
 
360
257
  const cachedRect = NodeRectCache.get(node)
361
258
  const cachedParentRect = NodeRectCache.get(parentNode)
362
-
363
259
  const nodeChanged = !cachedRect || !rectsEqual(cachedRect, nodeRect)
364
260
  const parentChanged = !cachedParentRect || !rectsEqual(cachedParentRect, parentRect)
365
261
 
@@ -369,17 +265,6 @@ function emitLayoutIfChanged(
369
265
  NodeRectCache.set(parentNode, parentRect)
370
266
 
371
267
  const event = getElementLayoutEvent(nodeRect, parentRect, node)
372
-
373
- if (process.env.NODE_ENV === 'development' && isDebugLayout()) {
374
- console.log('[useElementLayout] change', {
375
- tag: node.tagName,
376
- id: node.id || undefined,
377
- className: (node.className || '').slice(0, 60) || undefined,
378
- layout: event.nativeEvent.layout,
379
- first: !cachedRect,
380
- })
381
- }
382
-
383
268
  if (avoidUpdates) {
384
269
  queuedUpdates.set(node, () => onLayout(event))
385
270
  } else {
@@ -389,15 +274,11 @@ function emitLayoutIfChanged(
389
274
 
390
275
  function observeLayoutNode(node: HTMLElement, disableKey?: string) {
391
276
  Nodes.add(node)
392
- if (disableKey) {
393
- LayoutDisableKey.set(node, disableKey)
394
- } else {
395
- LayoutDisableKey.delete(node)
396
- }
277
+ if (disableKey) LayoutDisableKey.set(node, disableKey)
278
+ else LayoutDisableKey.delete(node)
397
279
  resumeLayoutLoop?.()
398
280
  }
399
281
 
400
- // register an arbitrary DOM element into the measurement loop without React lifecycle
401
282
  export function registerLayoutNode(
402
283
  node: HTMLElement,
403
284
  onChange: () => void,
@@ -415,12 +296,6 @@ function cleanupNode(node: HTMLElement) {
415
296
  NodeRectCache.delete(node)
416
297
  }
417
298
 
418
- const PrevHostNode = new WeakMap<object, HTMLElement | undefined>()
419
-
420
- // spec: onLayout fires one synchronous initial event on mount and on host swap
421
- // (RN parity, and before-paint so consumers can position without flicker).
422
- // bypasses the avoidUpdates queue on purpose; seeds the rect cache so the
423
- // measurement loop doesn't re-emit an identical event a frame later.
424
299
  function emitLayoutSync(node: HTMLElement) {
425
300
  const onLayout = LayoutHandlers.get(node)
426
301
  if (typeof onLayout !== 'function') return
@@ -439,85 +314,51 @@ export function useElementLayout(
439
314
  onLayout?: ((e: LayoutEvent) => void) | null
440
315
  ): void {
441
316
  const disableKey = useContext(DisableLayoutContextKey)
442
-
443
- // keep handlers up to date so polling always calls the latest callback
444
317
  const node = ensureWebElement(ref.current?.host)
445
318
  if (node && onLayout) {
446
319
  LayoutHandlers.set(node, onLayout)
447
320
  LayoutDisableKey.set(node, disableKey)
448
321
  }
449
322
 
450
- // detect mounts + host swaps after commit and fire the immediate sync layout event
451
323
  useIsomorphicLayoutEffect(() => {
452
324
  if (!onLayout) return
453
325
  const nextNode = ensureWebElement(ref.current?.host)
454
326
  const prevNode = PrevHostNode.get(ref)
455
- if (nextNode === prevNode) return
456
-
457
- if (prevNode) cleanupNode(prevNode)
458
- PrevHostNode.set(ref, nextNode)
459
- if (!nextNode) return
460
-
461
- LayoutHandlers.set(nextNode, onLayout)
462
- observeLayoutNode(nextNode, disableKey)
463
- emitLayoutSync(nextNode)
464
- })
465
-
466
- useIsomorphicLayoutEffect(() => {
467
- if (!onLayout) return
468
- const node = ref.current?.host
469
- if (!node) return
470
-
471
- LayoutHandlers.set(node, onLayout)
472
- observeLayoutNode(node, disableKey)
473
-
474
- if (process.env.NODE_ENV === 'development' && isDebugLayout()) {
475
- console.log('[useElementLayout] register', {
476
- tag: node.tagName,
477
- id: node.id || undefined,
478
- className: (node.className || '').slice(0, 60) || undefined,
479
- totalNodes: Nodes.size,
480
- })
327
+ if (nextNode !== prevNode) {
328
+ if (prevNode) cleanupNode(prevNode)
329
+ PrevHostNode.set(ref, nextNode)
330
+ if (nextNode) {
331
+ LayoutHandlers.set(nextNode, onLayout)
332
+ observeLayoutNode(nextNode, disableKey)
333
+ emitLayoutSync(nextNode)
334
+ }
481
335
  }
482
-
483
336
  return () => {
484
- cleanupNode(node)
485
-
486
- // also clean up any node from a mid-lifecycle host swap
487
- const swappedNode = PrevHostNode.get(ref)
488
- if (swappedNode && swappedNode !== node) {
489
- cleanupNode(swappedNode)
490
- }
337
+ const activeNode = ensureWebElement(ref.current?.host)
338
+ if (activeNode) cleanupNode(activeNode)
339
+ const swapped = PrevHostNode.get(ref)
340
+ if (swapped && swapped !== activeNode) cleanupNode(swapped)
491
341
  PrevHostNode.delete(ref)
492
342
  }
493
343
  }, [ref, !!onLayout])
494
344
  }
495
345
 
496
346
  function ensureWebElement<X>(x: X): HTMLElement | undefined {
497
- if (typeof HTMLElement === 'undefined') {
498
- return undefined
499
- }
347
+ if (typeof HTMLElement === 'undefined') return undefined
500
348
  return x instanceof HTMLElement ? x : undefined
501
349
  }
502
350
 
503
351
  export const getBoundingClientRectAsync = (
504
352
  node: HTMLElement | null
505
- ): Promise<DOMRectReadOnly | false> => {
506
- return new Promise<DOMRectReadOnly | false>((res) => {
353
+ ): Promise<DOMRectReadOnly | false> =>
354
+ new Promise((res) => {
507
355
  if (!node || node.nodeType !== 1) return res(false)
508
-
509
- const io = new IntersectionObserver(
510
- (entries) => {
511
- io.disconnect()
512
- return res(entries[0].boundingClientRect)
513
- },
514
- {
515
- threshold: 0,
516
- }
517
- )
356
+ const io = new IntersectionObserver((entries) => {
357
+ io.disconnect()
358
+ res(entries[0].boundingClientRect)
359
+ })
518
360
  io.observe(node)
519
361
  })
520
- }
521
362
 
522
363
  export const measureNode = async (
523
364
  node: HTMLElement,
@@ -536,9 +377,13 @@ export const measureNode = async (
536
377
  return null
537
378
  }
538
379
 
539
- type MeasureInWindowCb = (x: number, y: number, width: number, height: number) => void
540
-
541
- type MeasureCb = (
380
+ export type MeasureInWindowCb = (
381
+ x: number,
382
+ y: number,
383
+ width: number,
384
+ height: number
385
+ ) => void
386
+ export type MeasureCb = (
542
387
  x: number,
543
388
  y: number,
544
389
  width: number,
@@ -546,45 +391,35 @@ type MeasureCb = (
546
391
  pageX: number,
547
392
  pageY: number
548
393
  ) => void
394
+ export type WindowLayout = { pageX: number; pageY: number; width: number; height: number }
549
395
 
550
396
  export const measure = async (
551
397
  node: HTMLElement,
552
398
  callback: MeasureCb
553
399
  ): Promise<LayoutValue | null> => {
554
- const out = await measureNode(
555
- node,
556
- node.parentNode instanceof HTMLElement ? node.parentNode : null
557
- )
558
- if (out) {
559
- callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY)
560
- }
400
+ const out = await measureNode(node, node.parentElement)
401
+ if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY)
561
402
  return out
562
403
  }
563
404
 
564
- export function createMeasure(
565
- node: HTMLElement
566
- ): (callback: MeasureCb) => Promise<LayoutValue | null> {
567
- return (callback) => measure(node, callback)
568
- }
569
-
570
- type WindowLayout = { pageX: number; pageY: number; width: number; height: number }
405
+ export const createMeasure =
406
+ (node: HTMLElement): ((callback: MeasureCb) => Promise<LayoutValue | null>) =>
407
+ (callback: MeasureCb) =>
408
+ measure(node, callback)
571
409
 
572
410
  export const measureInWindow = async (
573
411
  node: HTMLElement,
574
412
  callback: MeasureInWindowCb
575
413
  ): Promise<WindowLayout | null> => {
576
414
  const out = await measureNode(node, null)
577
- if (out) {
578
- callback?.(out.pageX, out.pageY, out.width, out.height)
579
- }
415
+ if (out) callback?.(out.pageX, out.pageY, out.width, out.height)
580
416
  return out
581
417
  }
582
418
 
583
- export const createMeasureInWindow = (
584
- node: HTMLElement
585
- ): ((callback: MeasureInWindowCb) => Promise<WindowLayout | null>) => {
586
- return (callback) => measureInWindow(node, callback)
587
- }
419
+ export const createMeasureInWindow =
420
+ (node: HTMLElement): ((callback: MeasureInWindowCb) => Promise<WindowLayout | null>) =>
421
+ (callback: MeasureInWindowCb) =>
422
+ measureInWindow(node, callback)
588
423
 
589
424
  export const measureLayout = async (
590
425
  node: HTMLElement,
@@ -592,14 +427,13 @@ export const measureLayout = async (
592
427
  callback: MeasureCb
593
428
  ): Promise<LayoutValue | null> => {
594
429
  const out = await measureNode(node, relativeNode)
595
- if (out) {
596
- callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY)
597
- }
430
+ if (out) callback?.(out.x, out.y, out.width, out.height, out.pageX, out.pageY)
598
431
  return out
599
432
  }
600
433
 
601
- export function createMeasureLayout(
602
- node: HTMLElement
603
- ): (relativeTo: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null> {
604
- return (relativeTo, callback) => measureLayout(node, relativeTo, callback)
605
- }
434
+ export const createMeasureLayout =
435
+ (
436
+ node: HTMLElement
437
+ ): ((relativeTo: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>) =>
438
+ (relativeTo: HTMLElement, callback: MeasureCb) =>
439
+ measureLayout(node, relativeTo, callback)
package/types/index.d.ts CHANGED
@@ -27,20 +27,20 @@ export declare function registerLayoutNode(node: HTMLElement, onChange: () => vo
27
27
  export declare function useElementLayout(ref: RefObject<TamaguiComponentStatePartial>, onLayout?: ((e: LayoutEvent) => void) | null): void;
28
28
  export declare const getBoundingClientRectAsync: (node: HTMLElement | null) => Promise<DOMRectReadOnly | false>;
29
29
  export declare const measureNode: (node: HTMLElement, relativeTo?: HTMLElement | null) => Promise<null | LayoutValue>;
30
- type MeasureInWindowCb = (x: number, y: number, width: number, height: number) => void;
31
- type MeasureCb = (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void;
32
- export declare const measure: (node: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>;
33
- export declare function createMeasure(node: HTMLElement): (callback: MeasureCb) => Promise<LayoutValue | null>;
34
- type WindowLayout = {
30
+ export type MeasureInWindowCb = (x: number, y: number, width: number, height: number) => void;
31
+ export type MeasureCb = (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void;
32
+ export type WindowLayout = {
35
33
  pageX: number;
36
34
  pageY: number;
37
35
  width: number;
38
36
  height: number;
39
37
  };
38
+ export declare const measure: (node: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>;
39
+ export declare const createMeasure: (node: HTMLElement) => ((callback: MeasureCb) => Promise<LayoutValue | null>);
40
40
  export declare const measureInWindow: (node: HTMLElement, callback: MeasureInWindowCb) => Promise<WindowLayout | null>;
41
41
  export declare const createMeasureInWindow: (node: HTMLElement) => ((callback: MeasureInWindowCb) => Promise<WindowLayout | null>);
42
42
  export declare const measureLayout: (node: HTMLElement, relativeNode: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>;
43
- export declare function createMeasureLayout(node: HTMLElement): (relativeTo: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>;
43
+ export declare const createMeasureLayout: (node: HTMLElement) => ((relativeTo: HTMLElement, callback: MeasureCb) => Promise<LayoutValue | null>);
44
44
  export {};
45
45
 
46
46
  //# sourceMappingURL=index.d.ts.map