Skip to content

Ability to dismiss all open modals at once #37

@furkanarabaci

Description

@furkanarabaci

It would be nice to dismiss all open modals at once, based on the needs of not being able to push a different route ( parent directory ) inside of a modal. For example :

/user/register
/user/signIn/forgot/password ( modal )
/user/signIn/forgot/password/verify/email ( modal only accessible from modal )

When the user wants to navigate from /user/signIn/forgot/password/verify to /user/register, we need to dismiss both modals in order, otherwise it is not possible to navigate. To tackle that, we use a workaround to dismiss modals programmatically inside of routerDidEnter of the previous modal.

const DISMISS_TIMEOUT = 400;
...
StackRouter.of({
    path: "/user/signIn/forgot",
    modal: true,
    build: buildExtender({
    // Not necessary
    }),
    Route.of({
        path: "/user/signIn/forgot/password",
        build: {
             // Not necessary
        },
        routeDidEnter: (router, route) => {
            let { action, prevUrl } = router.getState();
            if (action === "POP" && prevUrl === "/user/signIn/forgot/password/verify/email") {
                setTimeout(() => {
                    router.dismiss(() => {}, false);
                }, DISMISS_TIMEOUT);
            }
         }
    }),
}),
Route.of({
    path: "/user/signIn",
    build: buildExtender({
    // Not necessary
    }),
    routeDidEnter: (router, route) => {
        if (router.getState().action === "POP") {
            setTimeout(() => {
                router.push("/user/register");
            }, DISMISS_TIMEOUT);
        }
    }
}),

The reason for timeout is explained in the #34
This will dismiss both modal and will navigate to the route in the parent directory.

Note: This code snippet is just a brief prototype of the case, it is not to take reference for best practice or an example of the router implementation.

With the feature of dismissAll() ( just an example for the name ), all of the routeEnter methods will not be needed. For example, inside of the page that has the modal of /user/signIn/forgot/password/verify/email

function goToRegister() {
    const page = this;
    page.router.dismissAll(() => {
        page.router.push("/user/register", false); // Not sure about the pushes without animation, did not test the exact usage.
   }, false);
}

Risks:

  • This will probably require to log every state of opened/closed modals in a different history
  • Modals ( routes ) which have a different parent directory might cause crashes or unexpected behaviors
  • Calling onShow() method on the page on dismiss action might cause some unexpected behaviors, since the modals will close instantly.

Remarks:

  • A different method like canDismissAll() to control the availability to dismiss every modal might be needed.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions