I want to create a follow effect. currently the when i move the slider.thumb the tool tip moves instantly with the slider.thumb. but i want when to create a pulling effect with slight delay.
🎞️ Here is the Video Showing Desired Effect 🔗
this is my current code. & stackblitz link
import * as Slider from '@radix-ui/react-slider'
import { useState } from 'react'
export const InputRange = () => {
const [value, setValue] = useState(2)
return (
<form>
<Slider.Root
className="relative flex items-center select-none touch-none w-full h-5 "
defaultValue={[value]}
min={1}
max={30}
step={1}
aria-label="Volume"
onValueChange={(e) => setValue(e[0])}
>
<Slider.Track className="bg-slate-200 relative grow rounded-full h-[3px]">
<Slider.Range className="absolute bg-black rounded-full h-full" />
</Slider.Track>
<Slider.Thumb className="relative group duration-150 block w-6 h-6 bg-black rounded-full active:scale-125 outline-none border-none cursor-pointer " >
<h1 className='absolute ease-in-out duration-150 opacity-0 group-active:opacity-100 group-active:-translate-y-12 -translate-x-8 -translate-y-6 px-5 py-2 bg-black text-center rounded-full text-white whitespace-nowrap text-xs font-bold'>{value} {value === 1 ? "night" : "nights"} </h1>
</Slider.Thumb>
</Slider.Root>
</form>
)
}
I tried to update the position of the tooltip for the radix-ui/react-slider component, but it caused the tooltip to move off the screen when I moved the slider.
const updateTooltipPosition = () => {
const thumb = thumbRef.current.getBoundingClientRect()
const tooltip = tooltipRef.current.getBoundingClientRect()
// console.log(thumb.x );
const tooltipCenter = tooltip.left + tooltip.width / 2
console.log(tooltip.left , tooltipCenter)
tooltipRef.current.style.transform = `translate(${}px, -120%)`
}
tried using useEffect but did nothing.
const [value, setValue] = useState(2)
const tooltipRef = useRef(null)
useEffect(() => {
if (tooltipRef.current) {
const tooltipWidth = tooltipRef.current.offsetWidth
const thumbPosition = ((value - 1) / 29) * 100 // calculate the position of the thumb
const tooltipPosition = thumbPosition - tooltipWidth / 2 // adjust for the width of the tooltip
tooltipRef.current.style.left = `${tooltipPosition}%` // set the left position of the tooltip
}
}, [value])
other possible ways i wanted to try like using a library like react-spring, framer motion but don't know how it will solve the issue.
export const InputRange = () => {
const [value, setValue] = useState(2);
// Positioning offset state. Default value is when `value = 2`.
const [offset, setOffset] = useState(14.8812);
// Tooltip element reference.
const ref = useRef(null);
useLayoutEffect(() => {
// Get the left and right edge coordinates of the tooltip element.
const { left, right } = ref.current.getBoundingClientRect();
// If left or right is positive, the tooltip element (or a parent)
// does not have `display: none`:
if (left + right > 0) {
// Get the box of the form, that we'll use as our layout "edge".
const containerRect = ref.current.closest('form').getBoundingClientRect();
// Adjust the left and right sides to account for the
// `active:scale-125` "extra". `12` is thumb width ÷ 2.
const limitLeft = containerRect.left - 12 * 0.25;
const limitRight = containerRect.right + 12 * 0.25;
// Get the overhang distance of the tooltip from its left and
// right edges, relative to the container's (adjusted) left and
// right edges, compensating for existing offset and the
// `active:scale-125`.
const offsetLeft = offset + (limitLeft - left) / 1.25;
const offsetRight = offset + (limitRight - right) / 1.25;
// If there is left overhang, set the offset.
if (offsetLeft > 0) {
setOffset(offsetLeft);
// If there is right overhang, set the offset.
} else if (offsetRight < 0) {
setOffset(offsetRight);
}
}
});
return (
<form>
{/* … */}
<div style={{ transform: `translateX(${offset}px)` }}>
<h1 className="… -translate-x-1/2 left-1/2 …" ref={ref}>
{value} {value === 1 ? 'time' : 'times'}{' '}
</h1>
</div>
{/* … */}
</form>
);
};