"use client"; import { useLayoutEffect, useRef, useState } from "react"; import type { QuestionField } from "@/data/question-data"; import { useQuestionAnswers } from "./question-answer-storage"; import QuestionTitle from "./question-title"; type QuestionSliderProps = { question: QuestionField; questionIndex: number; disabled?: boolean; }; export function QuestionSlider({ question, questionIndex, disabled, }: QuestionSliderProps) { const [min, max] = question.extras.range; const initialValue = Math.round((min + max) / 2); const { getAnswerValue, setAnswerValue } = useQuestionAnswers(); const storedValue = getAnswerValue(question, questionIndex); const value = typeof storedValue === "number" ? storedValue : initialValue; const progress = max === min ? 0 : ((value - min) / (max - min)) * 100; const sliderWrapperRef = useRef(null); const sliderRef = useRef(null); const thumbWidth = 18; const bubbleHalfWidth = 20; const [bubblePosition, setBubblePosition] = useState(bubbleHalfWidth); const steps = Array.from( { length: max - min + 1 }, (_, index) => min + index, ); useLayoutEffect(() => { const wrapper = sliderWrapperRef.current; const slider = sliderRef.current; if (!wrapper || !slider) { return; } const updateBubblePosition = () => { const wrapperRect = wrapper.getBoundingClientRect(); const sliderRect = slider.getBoundingClientRect(); const sliderLeft = sliderRect.left - wrapperRect.left; const thumbCenter = sliderLeft + thumbWidth / 2 + (progress / 100) * (sliderRect.width - thumbWidth); setBubblePosition( Math.min( Math.max(thumbCenter, bubbleHalfWidth), wrapperRect.width - bubbleHalfWidth, ), ); }; updateBubblePosition(); const resizeObserver = new ResizeObserver(updateBubblePosition); resizeObserver.observe(wrapper); resizeObserver.observe(slider); return () => resizeObserver.disconnect(); }, [progress]); return (
{value}
setAnswerValue( question, questionIndex, Number(event.target.value), ) } disabled={disabled} className="question-slider-range w-full" style={{ background: `linear-gradient(to right, #F43F5E 0%, #F43F5E ${progress}%, #FAD1D8 ${progress}%, #FAD1D8 100%)`, }} />
{steps.map((step) => ( {step} ))}
); } export default QuestionSlider;