From 8724f1c4fa17745b7fe6463b2d3cdebacc2504fa Mon Sep 17 00:00:00 2001 From: Aswath K Date: Wed, 20 Jul 2022 11:35:44 +0530 Subject: [PATCH] fix: Unwanted width calculation in Dropdown (#15239) --- app/client/src/components/ads/Dropdown.tsx | 36 ++++++++++++++++++---- app/client/test/setup.ts | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/client/src/components/ads/Dropdown.tsx b/app/client/src/components/ads/Dropdown.tsx index a48a4f5b97..b8456d5dfe 100644 --- a/app/client/src/components/ads/Dropdown.tsx +++ b/app/client/src/components/ads/Dropdown.tsx @@ -21,7 +21,7 @@ import { TooltipComponent as Tooltip } from "design-system"; import { isEllipsisActive } from "utils/helpers"; import SegmentHeader from "components/ads/ListSegmentHeader"; import { useTheme } from "styled-components"; -import { findIndex, isArray } from "lodash"; +import { debounce, findIndex, isArray } from "lodash"; import { TooltipComponent } from "design-system"; import { SubTextPosition } from "components/constants"; import { DSEventTypes, emitDSEvent } from "utils/AppsmithUtils"; @@ -1149,12 +1149,36 @@ export default function Dropdown(props: DropdownProps) { [isOpen, props.options, props.selected, selected, highlight], ); - let dropdownWrapperWidth = "100%"; + const [dropdownWrapperWidth, setDropdownWrapperWidth] = useState( + "100%", + ); - if (dropdownWrapperRef.current) { - const { width } = dropdownWrapperRef.current.getBoundingClientRect(); - dropdownWrapperWidth = `${width}px`; - } + const prevWidth = useRef(0); + + const onParentResize = useCallback( + debounce((entries) => { + requestAnimationFrame(() => { + if (dropdownWrapperRef.current) { + const width = entries[0].borderBoxSize?.[0].inlineSize; + if (typeof width === "number" && width !== prevWidth.current) { + prevWidth.current = width; + setDropdownWrapperWidth(`${width}px`); + } + } + }); + }, 300), + [dropdownWrapperRef.current], + ); + + useEffect(() => { + const resizeObserver = new ResizeObserver(onParentResize); + if (dropdownWrapperRef.current && props.fillOptions) + resizeObserver.observe(dropdownWrapperRef.current); + + return () => { + resizeObserver.disconnect(); + }; + }, [dropdownWrapperRef.current, props.fillOptions]); let dropdownHeight = props.isMultiSelect ? "auto" : "36px"; if (props.height) { diff --git a/app/client/test/setup.ts b/app/client/test/setup.ts index ceac3d56d5..731fd9bbb1 100644 --- a/app/client/test/setup.ts +++ b/app/client/test/setup.ts @@ -14,6 +14,7 @@ const mockObserveFn = () => { }; window.IntersectionObserver = jest.fn().mockImplementation(mockObserveFn); +window.ResizeObserver = jest.fn().mockImplementation(mockObserveFn); // establish API mocking before all tests beforeAll(() => server.listen());