"use client"; import { useState, useMemo, type FC, type ChangeEvent } from "react"; import { AnimatePresence, motion } from "motion/react"; import { cn } from "@/lib/utils"; interface AdaptiveSliderProps { value?: number; min?: number; max?: number; step?: number; defaultValue?: number; onChange?: (value: number) => void; } interface ColorSettings { text: string; gradient: string; thumbBorder: string; } const DEFAULT_MIN = 50; const DEFAULT_MAX = 350; const DEFAULT_STEP = 25; const DEFAULT_VALUE = 200; const getColorSettings = ( value: number, min: number, max: number ): ColorSettings => { const percentage = (value - min) / (max - min); if (percentage < 0.5) { return { text: "#10B981", gradient: "linear-gradient(to right, #FEB101, #FE7C09)", thumbBorder: "#10B981", }; } else if (percentage < 0.7) { return { text: "#FE55B7", gradient: "linear-gradient(to right, #FE55B74D, #FE55B7)", thumbBorder: "#F97316", }; } else { return { text: "#D946EF", gradient: "linear-gradient(to right, #DAB0FE, #4946FF)", thumbBorder: "#D946EF", }; } }; export const AdaptiveSlider: FC = ({ value, min = DEFAULT_MIN, max = DEFAULT_MAX, step = DEFAULT_STEP, defaultValue = DEFAULT_VALUE, onChange, }) => { const [internalValue, setInternalValue] = useState(defaultValue); const calories = value ?? internalValue; const colorSettings = useMemo( () => getColorSettings(calories, min, max), [calories, min, max] ); const percentage = ((calories - min) / (max - min)) * 100; const dots = useMemo( () => Array.from({ length: 6 }).map((_, i) => (
)), [] ); const handleSliderChange = (e: ChangeEvent) => { const val = Number(e.target.value); setInternalValue(val); onChange?.(val); }; return ( Calories
kCal
{dots}
); }; const AnimatedText = ({ value, className, }: { value: string; className?: string; }) => { return (
{value.split("").map((char, index) => { const displayChar = char === " " ? "\u00A0" : char; return ( {displayChar} ); })}
); };