From 7ba8dfdd41f04c18d66fda7ac8888b366fa7f72d Mon Sep 17 00:00:00 2001 From: TomasSlama Date: Thu, 3 Oct 2024 12:11:22 +0200 Subject: [PATCH] Fix initial position of Slider --- packages/base/Slider/src/Slider/Slider.tsx | 24 ++++++++----------- .../src/Slider/hooks/use-label-overlap.ts | 18 +++++++++++--- .../src/SliderValueLabel/SliderValueLabel.tsx | 2 +- .../src/utils/useOnScreen/use-on-screen.ts | 4 ++-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/base/Slider/src/Slider/Slider.tsx b/packages/base/Slider/src/Slider/Slider.tsx index 4cb2d0eeef..ba8bf75b4d 100644 --- a/packages/base/Slider/src/Slider/Slider.tsx +++ b/packages/base/Slider/src/Slider/Slider.tsx @@ -1,5 +1,5 @@ // import type { ComponentProps } from 'react' -import React, { forwardRef, useEffect, useRef } from 'react' +import React, { forwardRef, useRef } from 'react' import { Slider as MUIBaseSlider } from '@mui/base/Slider' import { useCombinedRefs, useOnScreen } from '@toptal/picasso-utils' import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge' @@ -66,7 +66,7 @@ export const Slider = forwardRef(function Slider( marks, value, defaultValue = 0, - tooltip: externalTooltip = 'off', + tooltip = 'off', tooltipFormat, step, disabled, @@ -82,15 +82,8 @@ export const Slider = forwardRef(function Slider( 'data-private': dataPrivate, 'data-testid': dataTestid, } = props - const [tooltip, setTooltip] = React.useState('off') const containerRef = useRef(null) const sliderRef = useCombinedRefs(ref, useRef(null)) - const { isPartiallyOverlapped, handleValueLabelOnRender } = useLabelOverlap({ - value, - }) - - const isThumbHidden = - hideThumbOnEmpty && (typeof value === 'undefined' || value === null) // The rootMargin is not working correctly in the storybooks iframe // To test properly we can open the iframe in new window @@ -100,11 +93,14 @@ export const Slider = forwardRef(function Slider( threshold: 1, }) - useEffect(() => { - if (containerRef.current) { - setTooltip(externalTooltip) - } - }, [externalTooltip]) + const { isPartiallyOverlapped, handleValueLabelOnRender } = useLabelOverlap({ + value, + // until IntersectionObserver starts observing the element, we don't render the tooltip + isTooltipRendered: isObserved, + }) + + const isThumbHidden = + hideThumbOnEmpty && (typeof value === 'undefined' || value === null) return (
{ +export const useLabelOverlap = ({ + value, + isTooltipRendered, +}: { + value?: number | number[] + isTooltipRendered: boolean +}) => { const [isPartiallyOverlapped, setIsPartiallyOverlapped] = useState(false) const [valueLabels, setValueLabels] = useState[]>( [] @@ -11,7 +17,7 @@ export const useLabelOverlap = ({ value }: { value?: number | number[] }) => { const isRangeSlider = Array.isArray(value) useEffect(() => { - if (!isRangeSlider) { + if (!isRangeSlider || !isTooltipRendered) { return } const isFullyOverlaped = value[0] === value[1] @@ -31,7 +37,13 @@ export const useLabelOverlap = ({ value }: { value?: number | number[] }) => { }) ) } - }, [value, isRangeSlider, isPartiallyOverlapped, valueLabels]) + }, [ + value, + isRangeSlider, + isPartiallyOverlapped, + valueLabels, + isTooltipRendered, + ]) const handleValueLabelOnRender = useCallback( (index: number, labelRef: RefObject) => { diff --git a/packages/base/Slider/src/SliderValueLabel/SliderValueLabel.tsx b/packages/base/Slider/src/SliderValueLabel/SliderValueLabel.tsx index 9de8b83af2..78999d04d3 100644 --- a/packages/base/Slider/src/SliderValueLabel/SliderValueLabel.tsx +++ b/packages/base/Slider/src/SliderValueLabel/SliderValueLabel.tsx @@ -67,7 +67,7 @@ const SliderValueLabel = ({ }) ) // we need to recalculate on value change to get new rect - }, [isOverlaped, index, xPlacement, value, tooltip]) + }, [isOverlaped, index, xPlacement, value]) return ( { - const [isOnScreen, setIntersecting] = useState(false) + const [isOnScreen, setIsOnScreen] = useState(false) const [isObserved, setObserved] = useState(false) const observer = useMemo( () => new IntersectionObserver( ([entry]) => { - setIntersecting(entry.isIntersecting) + setIsOnScreen(entry.isIntersecting) setObserved(true) }, {