import React, { forwardRef, useRef, useState, useEffect } from 'react'; import { Flex, Box, type BoxProps, HStack } from '@chakra-ui/react'; import MyIcon from '../Icon'; type Props = Omit & { list: { icon?: string; label: string | React.ReactNode; value: T; }[]; value: T; onChange: (e: T) => void; iconSize?: string; labelSize?: string; iconGap?: number; }; const FillRowTabs = ({ list, value, onChange, py = '2.5', px = '4', iconSize = '18px', labelSize = 'sm', iconGap = 2, ...props }: Props) => { const tabsRef = useRef(null); const itemsRef = useRef>(new Map()); const [sliderStyle, setSliderStyle] = useState({ width: 0, left: 0, opacity: 0 }); useEffect(() => { const updateSlider = () => { const activeItem = itemsRef.current.get(value); if (activeItem && tabsRef.current) { const tabsRect = tabsRef.current.getBoundingClientRect(); const itemRect = activeItem.getBoundingClientRect(); setSliderStyle({ width: itemRect.width, left: itemRect.left - tabsRect.left, opacity: 1 }); } }; updateSlider(); window.addEventListener('resize', updateSlider); return () => { window.removeEventListener('resize', updateSlider); }; }, [value]); return ( {/* 滑动背景元素 */} {list.map((item) => ( { if (el) itemsRef.current.set(item.value, el); }} flex={'1 0 0'} alignItems={'center'} justifyContent={'center'} cursor={'pointer'} borderRadius={'xs'} px={px} py={py} userSelect={'none'} whiteSpace={'noWrap'} gap={iconGap} zIndex={1} position="relative" transition="color 0.25s ease" onClick={() => onChange(item.value)} color={value === item.value ? 'primary.600' : 'myGray.500'} _hover={{ color: 'primary.600' }} > {item.icon && } {item.label} ))} ); }; export default forwardRef(FillRowTabs) as ( props: Props & { ref?: React.Ref } ) => JSX.Element;