adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.17k stars 1.06k forks source link

Using nested dialogs seems to depend on including a custom `<ModalOverlay/>` #6531

Open jhackett1 opened 3 weeks ago

jhackett1 commented 3 weeks ago

๐Ÿ™‹ Documentation Request

I've been trying to use several dialog components nested inside each other.

I've noticed through trial and error that without a <ModalOverlay/> in the mix, this simply doesn't work at all: opening one dialog opens them all simultaneously, and once open they can't be closed again.

My code now resembles this, which works:

    <DialogTrigger>
      <Button>Open me!</Button>
      <ModalOverlay>
        <Modal>
          <Dialog>
            {({ close }) => (
              <>
                <button onClick={close}>Close</button>
                <h2>Example dialog</h2>
                Example content
                <DialogTrigger>
                  <Button>Open me!</Button>
                  <ModalOverlay>
                    <Modal>
                      <Dialog>
                        {({ close }) => (
                          <>
                            <button onClick={close}>Close</button>
                            <h2>Example dialog</h2>
                            Example content
                          </>
                        )}
                      </Dialog>
                    </Modal>
                  </ModalOverlay>
                </DialogTrigger>
              </>
            )}
          </Dialog>
        </Modal>
      </ModalOverlay>
    </DialogTrigger>

I'm not sure why including <ModalOverlay/> has this effect, so it could be worth a note in the docs on how to properly orchestrate nested dialogs?

๐Ÿงข Your Company/Team

No response

LFDanLu commented 3 weeks ago

This seems to be because we will only conditionally render the nested Modal based on its actual tracked isOpen state if you have a wrapping ModalOverlay. Without that wrapping ModalOverlay around the nested Modal, the nested Modal is rendered and gets access to the internal Modal context here which is setup by the parent Modal here, resulting in every nested Modal rendering its contents instead of automatically setting up their own ModalOverlay. This doesn't feel quite right to me, perhaps it shouldn't be accessing that internal context since it will setup its own ModalOverlay + ModalContents but I might be missing something here. If it turns out that we do require a ModalOverlay around every nested Modal, then we can definitely update the docs accordingly.