-
Notifications
You must be signed in to change notification settings - Fork 61
Description
I've been enjoying using overlay-kit, and I appreciate the library's functionality!
I'd like to propose a small improvement based on my experience. The current implementation takes snapshots to create modals, which allows opening or closing them from anywhere in the application, even outside of JSX. This is a powerful feature.
However, I've noticed that in most real-world scenarios, overlays are typically associated with specific components, and ideally should be unmounted when those components are unmounted (e.g., during navigation or when using browser back buttons). Currently, this doesn't happen automatically.
To address this, I've created a simple useOverlay hook that maintains all the original functionality while adding automatic cleanup:
export const useOverlay = () => {
const [defaultOverlayId] = useState<string>(randomId());
const [overlayId, setOverlayId] = useState<string>(defaultOverlayId);
const open = useCallback(
(controller: Parameters<typeof overlay.open>[0], options?: Parameters<typeof overlay.open>[1]) => {
const overlayId = options?.overlayId ? options.overlayId : defaultOverlayId;
setOverlayId(overlayId);
return overlay.open(controller, { ...options, overlayId });
},
[defaultOverlayId]
);
const close = useCallback(() => overlay.close(overlayId), [overlayId]);
const unmount = useCallback(() => overlay.unmount(overlayId), [overlayId]);
const openAsync = useCallback(
<T>(
controller: OverlayAsyncControllerComponent<T>,
options?: { overlayId?: string | undefined } | undefined
): Promise<T> => {
const overlayId = options?.overlayId ? options.overlayId : defaultOverlayId;
setOverlayId(overlayId);
return overlay.openAsync<T>(controller, { ...options, overlayId });
},
[defaultOverlayId]
);
useEffect(() => {
return () => {
unmount();
};
}, [unmount]);
return { open, close, unmount, openAsync };
};
This hook unmounts the overlay when the component using it is unmounted, while maintaining the same API.
I've been using this hook in my own projects and found it very useful. I'm sharing it here in case other users might benefit from it as well. Would this be something you'd consider adding to the library, perhaps as an optional utility?
What are your thoughts on this approach?