"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.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); 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;