"use client" import { useLayoutEffect, useRef, useState } from "react" const OVERFLOW_BUTTON_WIDTH = 36 export function useToolbarOverflow(itemCount: number, reservedTrailingPx = 0) { const containerRef = useRef(null) const measureRef = useRef(null) const [visibleCount, setVisibleCount] = useState(itemCount) useLayoutEffect(() => { setVisibleCount(itemCount) }, [itemCount]) useLayoutEffect(() => { const container = containerRef.current const measure = measureRef.current if (!container || !measure) return const recalculate = () => { const children = Array.from(measure.children) as HTMLElement[] if (children.length === 0) { setVisibleCount(0) return } const containerWidth = container.clientWidth if (containerWidth <= 0) return const totalWidth = children.reduce((sum, child) => sum + child.offsetWidth, 0) const trailingReserve = reservedTrailingPx const maxWithoutOverflow = containerWidth - trailingReserve if (totalWidth <= maxWithoutOverflow) { setVisibleCount(children.length) return } const available = containerWidth - OVERFLOW_BUTTON_WIDTH - trailingReserve let used = 0 let fit = 0 for (const child of children) { const width = child.offsetWidth if (used + width > available) break used += width fit += 1 } setVisibleCount(Math.max(1, fit)) } recalculate() const ro = new ResizeObserver(recalculate) ro.observe(container) ro.observe(measure) for (const child of measure.children) { ro.observe(child) } const mo = new MutationObserver(recalculate) mo.observe(measure, { childList: true }) return () => { ro.disconnect() mo.disconnect() } }, [itemCount, reservedTrailingPx]) const hasOverflow = visibleCount < itemCount return { containerRef, measureRef, visibleCount, hasOverflow } }