Skip to content

Conversation

@mrjo118
Copy link
Contributor

@mrjo118 mrjo118 commented Nov 17, 2025

When running the Joplin web app, nested dialogs display underneath the parent dialog. A particular example of this is when opening plugin details on the plugin screen, and clicking the delete button (which uses the PromptDialog component for the child dialog). This problem is due the the way React Native Web uses components internally, compared to the Android and iOS apps. Despite the fact that the particular example of the nested dialog uses a native Alert.alert on the mobile platforms, when changing the code locally to use the PromptDialog component instead, the modal correctly opened on top of the parent dialog and displayed a veil over it.

I attempted to use a native React dialog as suggested here #11799 (comment), but this did not help. The issue seems to be with the way that the react-native Modal component takes precedence to display on top, when other type of modal components are opened. In order to workaround this, it is possible to make another dialog sit on top of react-native Modal by using another react-native Modal. This will then make the child modal display on top of it, with the caveat that the parent modal is not covered by the veil. This however is easily solved, by applying a filter over the background of the child modal. I have implemented the change in the PR in this way. For simplicity, I have added a veil / filter for all usages of this type of dialog, which results in a slightly darker veil compared to normal usages of Modals, but this isn't really a big deal, and this is already the case on the mobile apps, where Alert.alert is used.

In addition, the described approach causes issues on the native mobile app (tested on Android), so I have therefore made this change only apply on the web platform. In addition, to avoid over complicating the logic in the PromptDialog component to make the logic conditional for web, I simply duplicated the component and made a WebPromptDialog with the appropriate changes, which is conditionally used for web.

This fixes #11799

Testing

On the mobile / web app, there are 3 types of dialog which are currently using a react-native-paper Dialog rather than a react-native Modal (which could therefore exhibit the issue):

  1. PromptDialog (menu type) - used on the view / edit note, attach menu option
  2. PromptDialog (non menu type) - used for the delete plugin dialog and the prompt to save changes when leaving the configuration screen with unsaved changes
  3. TextInputDialog - the only current usage of this is on the screen after the scan note screen, via the create notebook button. There is no display issue on web for this usage

This PR covers implementing a web variant of types 1 and 2, which will correctly work when nested. If a dialog of type 3 is used in future as a nested dialog, a WebTextInputDialog could be created in a similar way. For dialogs which already use a react-native Modal (such as DismissibleDialog), even on the native mobile app there are display issues if nesting this kind of dialog (tested by changing the code locally), so it can be assumed this does not need to be catered for unless there is a particular requirement for this in future.

Things I have tested:

  1. That a dialog of all 3 types looks and functions as expected
  2. The web dialog buttons correctly apply the appropriate action
  3. The web dialog is dismissible by pressing escape
  4. The web dialog is dismissible by clicking the veil around the dialog
  5. The web dialog is responsive and resizes the screen in a similar way to the original dialog used for web (including testing on a real Android device)
  6. The web dialog shows a veil over the parent dialog when it is nested
  7. Behaviour is unaffected on the Android app

See videos:

firefox_7ctHPV4bLS.mp4
firefox_vc1SYCnobE.mp4

In addition, when a dialog opens another dialog but closes the original dialog before opening the new one, there is brief fade and and fade in animation on the web app with this changes, where previously the veil remained without any transition. A brief fade out and fade in is also present in the native mobile app though, so this should not be a problem:

nested.modal.on.web.issue.3.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Confirmation message box appears below dialog

1 participant