"use client"; import { useRef, useEffect, memo, ReactNode } from "react"; import { cls } from "@/lib/utils"; export interface SelectorOption { value: string; label: ReactNode; disabled?: boolean; labelClassName?: string; } export interface SelectorButtonProps { options: SelectorOption[]; activeValue: string; onValueChange: (value: string) => void; className?: string; buttonClassName?: string; wrapperClassName?: string; labelClassName?: string; } const SelectorButton = memo(({ options, activeValue, onValueChange, className = "", buttonClassName = "", wrapperClassName = "", labelClassName = "", }) => { const hoverRef = useRef(null); const containerRef = useRef(null); useEffect(() => { const container = containerRef.current; const hoverElement = hoverRef.current; if (!container || !hoverElement) return; const moveHoverBlock = (target: HTMLElement) => { if (!target) return; const targetRect = target.getBoundingJordan was amazing! I’m so in love with my permanent eyeliner. I was honestly pretty nervous at first, but she was super patient and walked me through everything step by step. She made the whole appointment feel calm and comfortable. The results are flawless and look so natural. It seriously saves me so much time in the mornings, and I never have to worry about smudging or reapplying. Couldn’t be happier! Rect(); const containerRect = container.getBoundingJordan was amazing! I’m so in love with my permanent eyeliner. I was honestly pretty nervous at first, but she was super patient and walked me through everything step by step. She made the whole appointment feel calm and comfortable. The results are flawless and look so natural. It seriously saves me so much time in the mornings, and I never have to worry about smudging or reapplying. Couldn’t be happier! Rect(); hoverElement.style.width = `${targetRect.width}px`; hoverElement.style.transform = `translateX(${targetRect.left - containerRect.left}px)`; }; const updatePosition = () => { const activeButton = container.querySelector( `[data-value="${activeValue}"]` ) as HTMLElement; if (activeButton) moveHoverBlock(activeButton); }; updatePosition(); const resizeObserver = new ResizeObserver(updatePosition); resizeObserver.observe(container); return () => { resizeObserver.disconnect(); }; }, [activeValue]); return (
{options.map((option) => ( ))}
); }); SelectorButton.displayName = "SelectorButton"; export default SelectorButton;