import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext, useState, useCallback, useMemo, useRef, useEffect, } from 'react';
const OverflowStateContext = createContext(undefined);
const OverflowActionsContext = createContext(undefined);
export const useOverflowState = () => useContext(OverflowStateContext);
export const useOverflowActions = () => useContext(OverflowActionsContext);
export const OverflowProvider = ({ children, }) => {
    const [overflowingIds, setOverflowingIds] = useState(new Set());
    /**
     * We use a ref to track the current set of overflowing IDs and a timeout to
     * batch updates to the next tick. This prevents infinite render loops (layout
     * oscillation) where showing an overflow hint causes a layout shift that
     * hides the hint, which then restores the layout and shows the hint again.
     */
    const idsRef = useRef(new Set());
    const timeoutRef = useRef(null);
    const syncState = useCallback(() => {
        if (timeoutRef.current)
            return;
        // Use a microtask to batch updates and break synchronous recursive loops.
        // This prevents "Maximum update depth exceeded" errors during layout shifts.
        timeoutRef.current = setTimeout(() => {
            timeoutRef.current = null;
            setOverflowingIds((prevIds) => {
                // Optimization: only update state if the set has actually changed
                if (prevIds.size === idsRef.current.size &&
                    [...prevIds].every((id) => idsRef.current.has(id))) {
                    return prevIds;
                }
                return new Set(idsRef.current);
            });
        }, 0);
    }, []);
    useEffect(() => () => {
        if (timeoutRef.current) {
            clearTimeout(timeoutRef.current);
        }
    }, []);
    const addOverflowingId = useCallback((id) => {
        if (!idsRef.current.has(id)) {
            idsRef.current.add(id);
            syncState();
        }
    }, [syncState]);
    const removeOverflowingId = useCallback((id) => {
        if (idsRef.current.has(id)) {
            idsRef.current.delete(id);
            syncState();
        }
    }, [syncState]);
    const reset = useCallback(() => {
        if (idsRef.current.size > 0) {
            idsRef.current.clear();
            syncState();
        }
    }, [syncState]);
    const stateValue = useMemo(() => ({
        overflowingIds,
    }), [overflowingIds]);
    const actionsValue = useMemo(() => ({
        addOverflowingId,
        removeOverflowingId,
        reset,
    }), [addOverflowingId, removeOverflowingId, reset]);
    return (_jsx(OverflowStateContext.Provider, { value: stateValue, children: _jsx(OverflowActionsContext.Provider, { value: actionsValue, children: children }) }));
};
//# sourceMappingURL=OverflowContext.js.map