@patreon/studio
Version:
Patreon Studio Design System
47 lines • 1.62 kB
JSX
'use client';
import React, { useEffect, useMemo, useState } from 'react';
const OverlayStackContext = React.createContext({
stack: [],
setStack: () => {
// do nothing
},
});
/**
* Provider for overlay nesting context
*/
export function OverlayStackProvider({ children }) {
const [stack, setStack] = useState([]);
const providerValue = useMemo(() => ({ stack, setStack }), [stack, setStack]);
return <OverlayStackContext.Provider value={providerValue}>{children}</OverlayStackContext.Provider>;
}
/**
* Hook to manage stacked overlays, returns a isTopOverlay flag which is enabled the overlay
* is the top most overlay.
*/
export function useOverlayStack(id, open) {
const { stack, setStack } = React.useContext(OverlayStackContext);
useEffect(() => {
if (open) {
setStack((prevStack) => [...prevStack, id]);
}
else {
setStack((prevStack) => prevStack.filter((nodeId) => nodeId !== id));
}
return () => {
setStack((prevStack) => prevStack.filter((nodeId) => nodeId !== id));
};
}, [id, open, setStack]);
return {
isTopOverlay: stack[stack.length - 1] === id,
};
}
/**
* Component to register an overlay with the overlay stack context, should only be used
* in class components where the useOverlayStack hook can't be used directly.
* @deprecated please use useOverlayStack hook where possible instead of this component.
*/
export function OverlayStackComponent({ id, isOpen }) {
useOverlayStack(id, isOpen);
return null;
}
//# sourceMappingURL=index.jsx.map