import type { JSX } from 'react' import { cloneElement, useCallback } from 'react' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '../base/portal-to-follow-elem' import { RiMoreLine } from '@remixicon/react' export type Operation = { id: string; title: string; icon: JSX.Element; onClick: () => void } const AppOperations = ({ operations, gap }: { operations: Operation[] gap: number }) => { const { t } = useTranslation() const [visibleOpreations, setVisibleOperations] = useState([]) const [moreOperations, setMoreOperations] = useState([]) const [showMore, setShowMore] = useState(false) const navRef = useRef(null) const handleTriggerMore = useCallback(() => { setShowMore(true) }, [setShowMore]) useEffect(() => { const moreElement = document.getElementById('more') const navElement = document.getElementById('nav') let width = 0 const containerWidth = navElement?.clientWidth ?? 0 const moreWidth = moreElement?.clientWidth ?? 0 if (containerWidth === 0 || moreWidth === 0) return const updatedEntries: Record = operations.reduce((pre, cur) => { pre[cur.id] = false return pre }, {} as Record) const childrens = Array.from(navRef.current!.children).slice(0, -1) for (let i = 0; i < childrens.length; i++) { const child: any = childrens[i] const id = child.dataset.targetid if (!id) break const childWidth = child.clientWidth if (width + gap + childWidth + moreWidth <= containerWidth) { updatedEntries[id] = true width += gap + childWidth } else { if (i === childrens.length - 1 && width + childWidth <= containerWidth) updatedEntries[id] = true else updatedEntries[id] = false break } } setVisibleOperations(operations.filter(item => updatedEntries[item.id])) setMoreOperations(operations.filter(item => !updatedEntries[item.id])) }, [operations, gap]) return ( <> {!visibleOpreations.length && }
{visibleOpreations.map(operation => , )} {visibleOpreations.length < operations.length &&
{moreOperations.map(item =>
{cloneElement(item.icon, { className: 'h-4 w-4 text-text-tertiary' })} {item.title}
)}
}
) } export default AppOperations