|
1 |
| -import type { RefObject } from 'react'; |
2 |
| -import { useEffect, useRef } from 'react'; |
| 1 | +import type { AllHTMLAttributes, RefObject } from 'react'; |
| 2 | +import { useState, useEffect, useRef } from 'react'; |
3 | 3 |
|
4 |
| -import { useDebouncedState } from './useDebouncedState'; |
| 4 | +import { useDebouncedCallback } from './useDebouncedCallback'; |
5 | 5 | import { useMutableCallback } from './useMutableCallback';
|
6 | 6 |
|
7 | 7 | export type Positions = 'top' | 'left' | 'bottom' | 'right';
|
@@ -51,26 +51,8 @@ type VariantBoundaries = {
|
51 | 51 | hm: number;
|
52 | 52 | };
|
53 | 53 |
|
54 |
| -type PositionStyle = { |
55 |
| - top: string; |
56 |
| - left: string; |
57 |
| - position?: 'fixed'; |
58 |
| - ZIndex: '9999'; |
59 |
| - transition: 'none !important'; |
60 |
| - bottom?: '0px'; |
61 |
| - overflowY?: 'auto'; |
62 |
| -}; |
63 |
| - |
64 |
| -type PositionEmptyResult = { |
65 |
| - visibility: 'hidden'; |
66 |
| - top: '-9999px'; |
67 |
| - left: '-9999px'; |
68 |
| - position: 'fixed'; |
69 |
| - overflowY?: 'initial'; |
70 |
| -}; |
71 |
| - |
72 | 54 | type PositionResult = {
|
73 |
| - style: PositionStyle | PositionEmptyResult; |
| 55 | + style: AllHTMLAttributes<HTMLElement>['style']; |
74 | 56 | placement?: Placements;
|
75 | 57 | };
|
76 | 58 |
|
@@ -101,8 +83,6 @@ const emptyStyle: PositionResult = {
|
101 | 83 | style: {
|
102 | 84 | position: 'fixed',
|
103 | 85 | visibility: 'hidden',
|
104 |
| - top: '-9999px', |
105 |
| - left: '-9999px', |
106 | 86 | },
|
107 | 87 | };
|
108 | 88 |
|
@@ -247,7 +227,7 @@ export const getPositionStyle = ({
|
247 | 227 | bottom: `${margin}px`,
|
248 | 228 | overflowY: 'auto',
|
249 | 229 | }),
|
250 |
| - ZIndex: '9999', |
| 230 | + ...({ zIndex: '9999' } as any), |
251 | 231 | },
|
252 | 232 | placement: `${PlacementMap[placementAttempt]}-${
|
253 | 233 | PlacementMap[variantsAttempts[0]]
|
@@ -311,30 +291,41 @@ export const usePosition = <T extends Element, R extends Element>(
|
311 | 291 | } = options;
|
312 | 292 | const container = useRef(containerElement);
|
313 | 293 |
|
314 |
| - const [style, setStyle] = useDebouncedState<PositionResult>(emptyStyle, 10); |
| 294 | + const [style, setStyle] = useState<PositionResult>(emptyStyle); |
315 | 295 |
|
316 |
| - const callback = useMutableCallback(() => { |
317 |
| - const boundaries = target.current.getBoundingClientRect(); |
318 |
| - const targetBoundaries = getTargetBoundaries({ |
319 |
| - referenceBox: reference.current.getBoundingClientRect(), |
320 |
| - target: boundaries, |
321 |
| - margin, |
322 |
| - }); |
323 |
| - const variantStore = getVariantBoundaries({ |
324 |
| - referenceBox: reference.current.getBoundingClientRect(), |
325 |
| - target: boundaries, |
326 |
| - }); |
327 |
| - setStyle( |
328 |
| - getPositionStyle({ |
329 |
| - placement, |
330 |
| - container: container.current.getBoundingClientRect(), |
331 |
| - targetBoundaries, |
332 |
| - variantStore, |
| 296 | + const callback = useDebouncedCallback( |
| 297 | + useMutableCallback(() => { |
| 298 | + const clone = target.current.cloneNode(true) as HTMLElement; |
| 299 | + |
| 300 | + clone.style.bottom = ''; |
| 301 | + clone.id = 'clone'; |
| 302 | + target.current.parentElement.appendChild(clone); |
| 303 | + const boundaries = clone.getBoundingClientRect(); |
| 304 | + target.current.parentElement.removeChild(clone); |
| 305 | + |
| 306 | + const targetBoundaries = getTargetBoundaries({ |
| 307 | + referenceBox: reference.current.getBoundingClientRect(), |
333 | 308 | target: boundaries,
|
334 | 309 | margin,
|
335 |
| - }) |
336 |
| - ); |
337 |
| - }); |
| 310 | + }); |
| 311 | + const variantStore = getVariantBoundaries({ |
| 312 | + referenceBox: reference.current.getBoundingClientRect(), |
| 313 | + target: boundaries, |
| 314 | + }); |
| 315 | + |
| 316 | + setStyle( |
| 317 | + getPositionStyle({ |
| 318 | + placement, |
| 319 | + container: container.current.getBoundingClientRect(), |
| 320 | + targetBoundaries, |
| 321 | + variantStore, |
| 322 | + target: boundaries, |
| 323 | + margin, |
| 324 | + }) |
| 325 | + ); |
| 326 | + }), |
| 327 | + 10 |
| 328 | + ); |
338 | 329 |
|
339 | 330 | useBoundingClientRect(target, watch, callback);
|
340 | 331 | useBoundingClientRect(reference, watch, callback);
|
|
0 commit comments