From 251f3a89b94308e90d03953bf4c9038c8ee2bc80 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 20 Dec 2024 16:10:24 -0800 Subject: [PATCH] useMeasure instead of Measure in TypeScript components --- frontend/src/Calendar/CalendarPage.tsx | 39 +++++++++---------- .../Form/Select/EnhancedSelectInput.tsx | 15 ++----- frontend/src/Components/Scroller/Scroller.tsx | 25 ++++++------ 3 files changed, 35 insertions(+), 44 deletions(-) diff --git a/frontend/src/Calendar/CalendarPage.tsx b/frontend/src/Calendar/CalendarPage.tsx index f408b6a60..ec2f3ecb1 100644 --- a/frontend/src/Calendar/CalendarPage.tsx +++ b/frontend/src/Calendar/CalendarPage.tsx @@ -1,10 +1,9 @@ import moment from 'moment'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; import * as commandNames from 'Commands/commandNames'; -import Measure from 'Components/Measure'; import FilterMenu from 'Components/Menu/FilterMenu'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; @@ -12,6 +11,7 @@ import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; +import useMeasure from 'Helpers/Hooks/useMeasure'; import { align, icons } from 'Helpers/Props'; import NoSeries from 'Series/NoSeries'; import { @@ -96,27 +96,13 @@ function CalendarPage() { const customFilters = useSelector(createCustomFiltersSelector('calendar')); const hasSeries = !!useSelector(createSeriesCountSelector()); + const [pageContentRef, { width }] = useMeasure(); const [isCalendarLinkModalOpen, setIsCalendarLinkModalOpen] = useState(false); const [isOptionsModalOpen, setIsOptionsModalOpen] = useState(false); - const [width, setWidth] = useState(0); const isMeasured = width > 0; const PageComponent = hasSeries ? Calendar : NoSeries; - const handleMeasure = useCallback( - ({ width: newWidth }: { width: number }) => { - setWidth(newWidth); - - const dayCount = Math.max( - 3, - Math.min(7, Math.floor(newWidth / MINIMUM_DAY_WIDTH)) - ); - - dispatch(setCalendarDaysCount({ dayCount })); - }, - [dispatch] - ); - const handleGetCalendarLinkPress = useCallback(() => { setIsCalendarLinkModalOpen(true); }, []); @@ -152,6 +138,19 @@ function CalendarPage() { [dispatch] ); + useEffect(() => { + if (width === 0) { + return; + } + + const dayCount = Math.max( + 3, + Math.min(7, Math.floor(width / MINIMUM_DAY_WIDTH)) + ); + + dispatch(setCalendarDaysCount({ dayCount })); + }, [width, dispatch]); + return ( @@ -200,13 +199,11 @@ function CalendarPage() { - - {isMeasured ? :
} - - + {isMeasured ? :
} {hasSeries && } diff --git a/frontend/src/Components/Form/Select/EnhancedSelectInput.tsx b/frontend/src/Components/Form/Select/EnhancedSelectInput.tsx index f3b547082..c4e842887 100644 --- a/frontend/src/Components/Form/Select/EnhancedSelectInput.tsx +++ b/frontend/src/Components/Form/Select/EnhancedSelectInput.tsx @@ -13,11 +13,11 @@ import { Manager, Popper, Reference } from 'react-popper'; import Icon from 'Components/Icon'; import Link from 'Components/Link/Link'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import Measure from 'Components/Measure'; import Modal from 'Components/Modal/Modal'; import ModalBody from 'Components/Modal/ModalBody'; import Portal from 'Components/Portal'; import Scroller from 'Components/Scroller/Scroller'; +import useMeasure from 'Helpers/Hooks/useMeasure'; import { icons, scrollDirections, sizes } from 'Helpers/Props'; import ArrayElement from 'typings/Helpers/ArrayElement'; import { EnhancedSelectInputChanged, InputChanged } from 'typings/inputs'; @@ -160,13 +160,13 @@ function EnhancedSelectInput, V>( onOpen, } = props; + const [measureRef, { width }] = useMeasure(); const updater = useRef<(() => void) | null>(null); const buttonId = useMemo(() => getUniqueElementId(), []); const optionsId = useMemo(() => getUniqueElementId(), []); const [selectedIndex, setSelectedIndex] = useState( getSelectedIndex(value, values) ); - const [width, setWidth] = useState(0); const [isOpen, setIsOpen] = useState(false); const isMobile = useMemo(() => isMobileUtil(), []); @@ -381,13 +381,6 @@ function EnhancedSelectInput, V>( ] ); - const handleMeasure = useCallback( - ({ width: newWidth }: { width: number }) => { - setWidth(newWidth); - }, - [setWidth] - ); - const handleOptionsModalClose = useCallback(() => { setIsOpen(false); }, [setIsOpen]); @@ -421,7 +414,7 @@ function EnhancedSelectInput, V>( {({ ref }) => (
- +
{isEditable && typeof value === 'string' ? (
, V>(
)} - +
)}
diff --git a/frontend/src/Components/Scroller/Scroller.tsx b/frontend/src/Components/Scroller/Scroller.tsx index 787bb2bdc..b2780551a 100644 --- a/frontend/src/Components/Scroller/Scroller.tsx +++ b/frontend/src/Components/Scroller/Scroller.tsx @@ -4,9 +4,9 @@ import React, { ComponentProps, ForwardedRef, forwardRef, - MutableRefObject, ReactNode, useEffect, + useImperativeHandle, useRef, } from 'react'; import { ScrollDirection } from 'Helpers/Props/scrollDirections'; @@ -43,13 +43,14 @@ const Scroller = forwardRef( ...otherProps } = props; - const internalRef = useRef(); - const currentRef = (ref as MutableRefObject) ?? internalRef; + const internalRef = useRef(null); + + useImperativeHandle(ref, () => internalRef.current!, []); useEffect( () => { if (initialScrollTop != null) { - currentRef.current.scrollTop = initialScrollTop; + internalRef.current!.scrollTop = initialScrollTop; } }, // eslint-disable-next-line react-hooks/exhaustive-deps @@ -58,16 +59,16 @@ const Scroller = forwardRef( useEffect(() => { if (scrollTop != null) { - currentRef.current.scrollTop = scrollTop; + internalRef.current!.scrollTop = scrollTop; } if (autoFocus && scrollDirection !== 'none') { - currentRef.current.focus({ preventScroll: true }); + internalRef.current!.focus({ preventScroll: true }); } - }, [autoFocus, currentRef, scrollDirection, scrollTop]); + }, [autoFocus, scrollDirection, scrollTop]); useEffect(() => { - const div = currentRef.current; + const div = internalRef.current!; const handleScroll = throttle(() => { const scrollLeft = div.scrollLeft; @@ -76,17 +77,17 @@ const Scroller = forwardRef( onScroll?.({ scrollLeft, scrollTop }); }, 10); - div.addEventListener('scroll', handleScroll); + div?.addEventListener('scroll', handleScroll); return () => { - div.removeEventListener('scroll', handleScroll); + div?.removeEventListener('scroll', handleScroll); }; - }, [currentRef, onScroll]); + }, [onScroll]); return (