"use client"; import type { ComponentProps } from "react"; import { useCallback, useEffect, useRef } from "react"; import { cn } from "@/lib/utils"; import { Button } from "@/shared/ui/button"; export type SuggestionsProps = ComponentProps<"div">; const SCROLL_EASING = 0.28; const SCROLL_END_THRESHOLD = 0.5; export const Suggestions = ({ className, children, ...props }: SuggestionsProps) => { const containerRef = useRef(null); useEffect(() => { const element = containerRef.current; if (!element) { return; } let animationFrameId: number | null = null; let targetScrollLeft = element.scrollLeft; const animateScroll = () => { const distance = targetScrollLeft - element.scrollLeft; if (Math.abs(distance) <= SCROLL_END_THRESHOLD) { element.scrollLeft = targetScrollLeft; animationFrameId = null; return; } element.scrollLeft += distance * SCROLL_EASING; animationFrameId = window.requestAnimationFrame(animateScroll); }; const handleWheel = (event: globalThis.WheelEvent) => { const maxScrollLeft = element.scrollWidth - element.clientWidth; const rawDelta = Math.abs(event.deltaY) >= Math.abs(event.deltaX) ? event.deltaY : event.deltaX; const delta = event.deltaMode === 1 ? rawDelta * 16 : event.deltaMode === 2 ? rawDelta * element.clientWidth : rawDelta; const canScroll = delta > 0 ? element.scrollLeft < maxScrollLeft : element.scrollLeft > 0; if (maxScrollLeft <= 0 || delta === 0 || !canScroll) { return; } event.preventDefault(); targetScrollLeft = Math.min(maxScrollLeft, Math.max(0, targetScrollLeft + delta)); if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { element.scrollLeft = targetScrollLeft; return; } if (animationFrameId === null) { animationFrameId = window.requestAnimationFrame(animateScroll); } }; element.addEventListener("wheel", handleWheel, { passive: false }); return () => { element.removeEventListener("wheel", handleWheel); if (animationFrameId !== null) { window.cancelAnimationFrame(animationFrameId); } }; }, []); return (
{children}
); }; export type SuggestionProps = Omit, "onClick"> & { suggestion: string; onClick?: (suggestion: string) => void; }; export const Suggestion = ({ suggestion, onClick, className, variant = "outline", size = "sm", children, ...props }: SuggestionProps) => { const handleClick = useCallback(() => { onClick?.(suggestion); }, [onClick, suggestion]); return ( ); };