Skip to content

Commit eec6be0

Browse files
committed
refactor(ui): compute size without using getBoundingClientRect
When the element contains transition, using `getBoundingClientRect` will often not get the original size.
1 parent a1de215 commit eec6be0

File tree

19 files changed

+47
-73
lines changed

19 files changed

+47
-73
lines changed

packages/platform/src/app/components/map/MapMarker.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ export function AppMapMarker(props: AppMapMarkerProps): JSX.Element | null {
3737
div.innerHTML = elRef.current.outerHTML;
3838
div.style.cssText = 'position:fixed;top:-200vh;left:-200vw;';
3939
document.body.appendChild(div);
40-
const rect = div.firstElementChild!.getBoundingClientRect();
40+
const width = (div.firstElementChild as HTMLElement).offsetWidth;
41+
const height = (div.firstElementChild as HTMLElement).offsetHeight;
4142
document.body.removeChild(div);
4243

43-
return new AMap.Pixel(-(rect.width / 2), -rect.height);
44+
return new AMap.Pixel(-(width / 2), -height);
4445
})()
4546
: isArray(aOptions.offset)
4647
? new AMap.Pixel(...aOptions.offset)

packages/ui/src/components/_date-input/DateInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ReactDOM from 'react-dom';
77

88
import { useAsync, useEvent, useEventCallback, useForceUpdate, useForkRef, useImmer, useRefExtra, useResize } from '@react-devui/hooks';
99
import { CloseCircleFilled, SwapRightOutlined } from '@react-devui/icons';
10-
import { checkNodeExist, getClassName, getOriginalSize, getVerticalSidePosition } from '@react-devui/utils';
10+
import { checkNodeExist, getClassName, getVerticalSidePosition } from '@react-devui/utils';
1111

1212
import { dayjs } from '../../dayjs';
1313
import { useDValue, useMaxIndex } from '../../hooks';
@@ -210,7 +210,7 @@ function DateInput(props: DDateInputProps, ref: React.ForwardedRef<DDateInputRef
210210
const [transformOrigin, setTransformOrigin] = useState<string>();
211211
const updatePosition = useEventCallback(() => {
212212
if (visible && boxRef.current && popupRef.current) {
213-
const { height } = getOriginalSize(popupRef.current);
213+
const height = popupRef.current.offsetHeight;
214214
const maxWidth = window.innerWidth - WINDOW_SPACE * 2;
215215
const width = Math.min(popupRef.current.scrollWidth, maxWidth);
216216
const { top, left, transformOrigin } = getVerticalSidePosition(

packages/ui/src/components/_transition/CollapseTransition.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ export function DCollapseTransition(props: DCollapseTransitionProps): JSX.Elemen
5959
ref.current.style.width = 'auto';
6060
ref.current.style.paddingLeft = getSizeStyle(dOriginalSize.padding?.[3]);
6161
ref.current.style.paddingRight = getSizeStyle(dOriginalSize.padding?.[1]);
62-
const { width } = ref.current.getBoundingClientRect();
63-
dataRef.current.width = width;
62+
dataRef.current.width = ref.current.offsetWidth;
6463
ref.current.style.cssText = cssText;
6564
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
6665
ref.current.offsetTop;
@@ -69,8 +68,7 @@ export function DCollapseTransition(props: DCollapseTransitionProps): JSX.Elemen
6968
ref.current.style.height = 'auto';
7069
ref.current.style.paddingTop = getSizeStyle(dOriginalSize.padding?.[0]);
7170
ref.current.style.paddingBottom = getSizeStyle(dOriginalSize.padding?.[2]);
72-
const { height } = ref.current.getBoundingClientRect();
73-
dataRef.current.height = height;
71+
dataRef.current.height = ref.current.offsetHeight;
7472
ref.current.style.cssText = cssText;
7573
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
7674
ref.current.offsetTop;

packages/ui/src/components/auto-complete/AutoComplete.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ReactDOM from 'react-dom';
77

88
import { useEvent, useEventCallback, useId, useRefExtra, useResize } from '@react-devui/hooks';
99
import { LoadingOutlined } from '@react-devui/icons';
10-
import { findNested, getClassName, getOriginalSize, getVerticalSidePosition } from '@react-devui/utils';
10+
import { findNested, getClassName, getVerticalSidePosition } from '@react-devui/utils';
1111

1212
import { useMaxIndex, useDValue } from '../../hooks';
1313
import { cloneHTMLElement, registerComponentMate, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../utils';
@@ -100,8 +100,8 @@ function AutoComplete<T extends DAutoCompleteItem>(
100100
const [transformOrigin, setTransformOrigin] = useState<string>();
101101
const updatePosition = useEventCallback(() => {
102102
if (visible && boxRef.current && popupRef.current) {
103-
const boxWidth = boxRef.current.getBoundingClientRect().width;
104-
const { height } = getOriginalSize(popupRef.current);
103+
const boxWidth = boxRef.current.offsetWidth;
104+
const height = popupRef.current.offsetHeight;
105105
const maxWidth = window.innerWidth - WINDOW_SPACE * 2;
106106
const width = Math.min(Math.max(popupRef.current.scrollWidth, boxWidth), maxWidth);
107107
const { top, left, transformOrigin } = getVerticalSidePosition(

packages/ui/src/components/cascader/Cascader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import React, { useCallback, useState, useMemo, useRef, useImperativeHandle } fr
1010

1111
import { useEventCallback, useId } from '@react-devui/hooks';
1212
import { CloseOutlined, LoadingOutlined } from '@react-devui/icons';
13-
import { findNested, getClassName, getOriginalSize, getVerticalSidePosition } from '@react-devui/utils';
13+
import { findNested, getClassName, getVerticalSidePosition } from '@react-devui/utils';
1414

1515
import { useGeneralContext, useDValue } from '../../hooks';
1616
import { cloneHTMLElement, registerComponentMate, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../utils';
@@ -277,7 +277,7 @@ function Cascader<V extends DId, T extends DCascaderItem<V>>(
277277
const [transformOrigin, setTransformOrigin] = useState<string>();
278278
const updatePosition = useEventCallback(() => {
279279
if (visible && boxRef.current && popupRef.current) {
280-
const { height } = getOriginalSize(popupRef.current);
280+
const height = popupRef.current.offsetHeight;
281281
const maxWidth = window.innerWidth - WINDOW_SPACE * 2;
282282
const width = Math.min(popupRef.current.scrollWidth, maxWidth);
283283
const { top, left, transformOrigin } = getVerticalSidePosition(

packages/ui/src/components/dropdown/Dropdown.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import React, { useImperativeHandle, useRef, useState } from 'react';
55
import ReactDOM from 'react-dom';
66

77
import { useEventCallback, useId, useRefExtra } from '@react-devui/hooks';
8-
import { getClassName, getOriginalSize, getVerticalSidePosition, scrollToView } from '@react-devui/utils';
8+
import { getClassName, getVerticalSidePosition, scrollToView } from '@react-devui/utils';
99

1010
import { useMaxIndex, useDValue } from '../../hooks';
1111
import { registerComponentMate, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../utils';
@@ -181,7 +181,7 @@ function Dropdown<ID extends DId, T extends DDropdownItem<ID>>(
181181
const [arrowPosition, setArrowPosition] = useState<React.CSSProperties>();
182182
const updatePosition = useEventCallback(() => {
183183
if (visible && childRef.current && dropdownRef.current) {
184-
const { width, height } = getOriginalSize(dropdownRef.current);
184+
const [width, height] = [dropdownRef.current.offsetWidth, dropdownRef.current.offsetHeight];
185185
const { top, left, transformOrigin, arrowPosition } = getVerticalSidePosition(
186186
childRef.current,
187187
{ width, height },

packages/ui/src/components/dropdown/Sub.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ReactDOM from 'react-dom';
44

55
import { useEventCallback, useRefExtra } from '@react-devui/hooks';
66
import { RightOutlined } from '@react-devui/icons';
7-
import { checkNodeExist, getClassName, getHorizontalSidePosition, getOriginalSize } from '@react-devui/utils';
7+
import { checkNodeExist, getClassName, getHorizontalSidePosition } from '@react-devui/utils';
88

99
import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../utils';
1010
import { DPopup } from '../_popup';
@@ -58,7 +58,7 @@ function Sub(props: DSubProps, ref: React.ForwardedRef<() => void>): JSX.Element
5858
const [transformOrigin, setTransformOrigin] = useState<string>();
5959
const updatePosition = useEventCallback(() => {
6060
if (isVisible && ulRef.current && liRef.current) {
61-
const { width, height } = getOriginalSize(ulRef.current);
61+
const [width, height] = [ulRef.current.offsetWidth, ulRef.current.offsetHeight];
6262
const { top, left, transformOrigin } = getHorizontalSidePosition(
6363
liRef.current,
6464
{ width, height },

packages/ui/src/components/menu/Sub.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import React, { useState, useRef, useImperativeHandle, useEffect } from 'react';
55
import ReactDOM from 'react-dom';
66

77
import { useEventCallback, useRefExtra } from '@react-devui/hooks';
8-
import { checkNodeExist, getClassName, getHorizontalSidePosition, getOriginalSize, getVerticalSidePosition } from '@react-devui/utils';
8+
import { checkNodeExist, getClassName, getHorizontalSidePosition, getVerticalSidePosition } from '@react-devui/utils';
99

1010
import { useMaxIndex } from '../../hooks';
1111
import { TTANSITION_DURING_BASE, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../utils';
@@ -98,12 +98,11 @@ function Sub(props: DSubProps, ref: React.ForwardedRef<() => void>): JSX.Element
9898
const [transformOrigin, setTransformOrigin] = useState<string>();
9999
const updatePosition = useEventCallback(() => {
100100
if (isVisible && ulRef.current && liRef.current) {
101-
const size = getOriginalSize(ulRef.current);
102-
const height = size.height;
101+
const height = ulRef.current.offsetHeight;
103102

104-
let width = size.width;
103+
let width = ulRef.current.offsetWidth;
105104
if (inHorizontalNav) {
106-
width = liRef.current.getBoundingClientRect().width - 32;
105+
width = liRef.current.offsetWidth - 32;
107106
}
108107

109108
const { top, left, transformOrigin } = inHorizontalNav

packages/ui/src/components/modal/Modal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ export const DModal: {
144144
if (isUndefined(ROOT_DATA.clickEvent) || performance.now() - ROOT_DATA.clickEvent.time > 100) {
145145
dataRef.current.transformOrigin = undefined;
146146
} else if (modalContentRef.current) {
147-
const left = `${(window.innerWidth - modalContentRef.current.clientWidth) / 2}px`;
148-
const top = dTop === 'center' ? `${(window.innerHeight - modalContentRef.current.clientHeight) / 2}px` : topStyle;
147+
const left = `${(window.innerWidth - modalContentRef.current.offsetWidth) / 2}px`;
148+
const top = dTop === 'center' ? `${(window.innerHeight - modalContentRef.current.offsetHeight) / 2}px` : topStyle;
149149
dataRef.current.transformOrigin = `calc(${ROOT_DATA.clickEvent.e.clientX}px - ${left}) calc(${ROOT_DATA.clickEvent.e.clientY}px - ${top})`;
150150
}
151151
}}

packages/ui/src/components/notification/Notification.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function DNotification(props: DNotificationProps & { dVisible: boolean })
6060

6161
case 'leave':
6262
if (panelRef.current) {
63-
const { height } = panelRef.current.getBoundingClientRect();
63+
const height = panelRef.current.offsetHeight;
6464
transitionStyle = { height, overflow: 'hidden' };
6565
}
6666
break;

0 commit comments

Comments
 (0)