formaat-design / reshaped

Community repository for storing examples, reporting issues and tracking roadmap
https://reshaped.so
120 stars 4 forks source link

onBeforeClose hook for Overlay #304

Closed chrismcv closed 2 months ago

chrismcv commented 3 months ago

Is your feature request related to a problem? Please describe. I've had to fork Overlay to deal with interacting with non-reshaped components. My hacks basically cover checking for clicks in other portals.

const isInsideChild = (el: HTMLElement) => {
        if (!contentRef.current) return;
        let inLegacyModal = false;

        document.querySelectorAll("[role=dialog]").forEach((x) => {
            if (x.contains(el)) inLegacyModal = true;
        });
        document.querySelectorAll("[role=presentation]").forEach((x) => {
            if (x.contains(el)) inLegacyModal = true;
        });
        document.querySelectorAll("#headlessui-portal-root").forEach((x) => {
            if (x.contains(el)) inLegacyModal = true;
        });
        if (inLegacyModal) return true;

        const firstChild = contentRef.current!.firstChild;

        if (!firstChild) return;
        return firstChild.contains(el);
    };

Describe the solution you'd like Ideally there would be an onBeforeClose(e) hook that could be applied to the mouse up.


    const handleMouseUp = (event: React.MouseEvent<HTMLElement>) => {
        const isMouseUpValid = !isInsideChild(event.target as HTMLElement);
        const shouldClose = isMouseDownValidRef.current && isMouseUpValid && !clickThrough;
                 // add the following
                 if (shouldClose && onBeforeClose) shouldClose = onBeforeClose(e)

        if (!shouldClose) return;
        close();
    };

**Describe alternatives you've considered**
Potentially the new prevent close trigger could also help to create a manual workaround to this.

**Additional context**
Using material ui, headless ui components.
blvdmitry commented 3 months ago

What would we the difference between onClose and onBeforeClose? onClose is already behaving like a trigger since modals state are fully controlled on your side and you can decide when you want to forward with changing the state. In case this helps, there is also a new disableCloseOnOutsideClick flag that we've shipped in v3.1

chrismcv commented 3 months ago

The difference is passing the event through so we can tell where the click was made that is triggering the close. And onBeforeClose could work controlled or uncontrolled.

blvdmitry commented 3 months ago

So technically, having an event passed in the onClose whenever it's available would solve this for you too?

chrismcv commented 3 months ago

Yeah I think it would - which might be simpler... that's what material-ui do: (along with a reason) https://mui.com/material-ui/api/modal/

blvdmitry commented 2 months ago

Added support for the onClose={({ reason }) => {}} for the next patch release for both Modal and Overlay. Overlay and Modal both use overlay-click and escape-key reasons while Modal also has an additional drag reason for the bottom and side sheets

image