Select a ☕
- Decaf with caffeine
- Mild and smooth
- Balanced daily brew
- Strong bold morning boost
- Extra intense flavor
- Rocket fuel power shot
September 2025
Select a ☕
"use client";
"use client";
import {Slider} from "@/components/Headless/Slider";
import {cn} from "@/lib/cn";
import {calculatePercentage} from "@/utilities/calculate-percentage";
import React, {useMemo, useRef, useState} from "react";
const array = [
"Decaf with caffeine",
"Mild and smooth",
"Balanced daily brew",
"Strong bold morning boost",
"Extra intense flavor",
"Rocket fuel power shot",
];
export const FrequencySlider = () => {
const [selectedValue, setSelectedValue] = useState<number | null>(null);
const [value, setValue] = useState([(array.length - 1) / 2]);
const toolTipRef = useRef<HTMLDivElement>(null);
const maxValue = array.length - 1;
const isSelectedValueNull = selectedValue === null;
const tooltipPositions = useMemo(() => {
const listItems = toolTipRef.current?.querySelectorAll("li");
if (!listItems) return [];
return array.map((_, index) => {
const itemWidth = listItems[index].clientWidth;
const offsetLeft = -listItems[index].offsetLeft;
const x =
index === 0 ? "0%" : index === maxValue ? "-100%" : "-50%";
const left =
index === 0 || index === maxValue
? `${calculatePercentage(index, maxValue)}%`
: `calc(${calculatePercentage(index, maxValue)}% + ${19 - (index / maxValue) * 38}px)`;
return {
left: left,
x,
width: itemWidth,
offsetLeft,
id: index,
};
});
}, [array, maxValue, toolTipRef.current]);
const handleSliderChange = (sliderValue: number[]) => {
const selectedIndex = sliderValue[0];
setValue(sliderValue);
setSelectedValue(selectedIndex);
};
return (
<div className="relative mx-auto w-8/9 sm:w-3/4">
<Slider
min={0}
max={maxValue}
value={value}
onValueChange={handleSliderChange}
/>
<p
className={cn(
"text-text-medium-accent pointer-events-none absolute bottom-[calc(1.2rem+100%)] left-1/2 -translate-x-1/2 text-sm transition-opacity duration-300",
selectedValue !== null && "opacity-0"
)}>
Select a ☕
</p>
<div
className="pointer-events-none absolute bottom-[calc(1.2rem+100%)] overflow-hidden rounded-lg bg-amber-700 shadow-[2px_2px_4px_rgba(0,0,0,0.8)] transition-all duration-300"
ref={toolTipRef}
style={{
left: !isSelectedValueNull
? tooltipPositions[selectedValue]?.left
: "50%",
transform: `translateX(${!isSelectedValueNull ? tooltipPositions[selectedValue]?.x : "-50%"})`,
width: `${!isSelectedValueNull ? tooltipPositions[selectedValue]?.width : 0}px`,
opacity: !isSelectedValueNull ? 1 : 0,
}}>
<ul
className="flex whitespace-nowrap transition-all duration-300"
style={{
transform: `translateX(${!isSelectedValueNull ? tooltipPositions[selectedValue]?.offsetLeft : 0}px)`,
}}>
{array.map((item, index) => {
return (
<li
className={cn(
"text-text-accent px-2 py-1.5 text-sm font-medium transition-all duration-300",
index === selectedValue
? "delay-75"
: "opacity-0 blur-xs"
)}
key={index}>
{item}
</li>
);
})}
</ul>
</div>
</div>
);
};
const DraggingSlider = () => {
return (
<article className="grid min-h-96 place-items-center bg-white/5 sm:aspect-video sm:min-h-0">
<FrequencySlider />
</article>
);
};
export default DraggingSlider;