How a toast component would interact with a modal dialog #1450
Replies: 7 comments 4 replies
-
Thanks for the write up @xander-marjoram, this seems like a great approach! 🙌 |
Beta Was this translation helpful? Give feedback.
-
Thanks for organizing the discussion! |
Beta Was this translation helpful? Give feedback.
-
@xander-marjoram Nice write up 🔥 Out of interest, and not something I've read much about, but did we look at a combination of our normal dialog element (pie-modal) and using the HTML popover feature? I know these can be opened as dialogs too but wondered if that would potentially be something that is worth having a quick look at too. |
Beta Was this translation helpful? Give feedback.
-
Somewhat related, after chatting with Ziv, I reminded of a case that might be something to think of. Long ago we had to update Snacks Modal to cater a specific usage in CW. It was necessary to provide a way of modifying modals order in runtime, as that couldn't be easily solved by moving the markup around. I can find the ticket, but explained in a shortly manner, depending on the application state, a modal should have to be displayed above the current ones, regardless of the markup. We ended up introducing a prop called priority, and if you search in CW for I wonder if using dialog we will be able to solve this need. |
Beta Was this translation helpful? Give feedback.
-
This is all great as an investigation - thanks for looking at this. I think my main thoughts off the back of it are – we should likely also start a discussion with design around how we advise consumers to use modals and toasts together (to give recommendations of usage). It's great to have the flexibility to display toasts wherever we want to, but providing consumers with advice on whether a toast should appear above/below/alongside modals would be useful too, as otherwise, we'll likely end up with inconsistency across applications. Also tagging in @thejfreitas as well, as will likely inform the dev of the component. |
Beta Was this translation helpful? Give feedback.
-
I've had a chat with Design and here are the main takeaways from that:
Design will be updating their toast documentation to add guidance around positioning with modals. |
Beta Was this translation helpful? Give feedback.
-
Having thought about this for a little longer, I wonder if this might be a strange developer experience. Are we imagining users write code like this if they want a toast to sit at the same level as a modal? <pie-modal>
<pie-toast></pie-toast>
</pie-modal> |
Beta Was this translation helpful? Give feedback.
-
Dialogs and modals
The
pie-modal
component uses the nativedialog
element, opened withshowModal()
, which adds the element to the top layer. The element also has an accompanying::backdrop
pseudo-element which provides a visual indicator that the content on the rest of the page is currently unavailable.The top layer spans the full height and width of the viewport, and is stacked on top of the main DOM. Users are also prevented from interacting with other elements (focus is also trapped) until top layer is closed.
This behaviour is very useful as it means that developers don't have to recreate it when building a modal to follow focus management and accessibility best practices.
It is also possible to use the
dialog
element in another way, by opening it withshow()
instead ofshowModal()
. This does not add the dialog to the top layer and therefore does not block interactions with other elements on the page. This means the dialog element can be used for building popovers, tooltips, and more.From testing, it has been confirmed that multiple dialog elements can be added to the page. Each one that is opened modally will be added to the top layer with their own backdrop.
Note
It's important to note that the most recently (modally-)opened dialog will be on the top, and therefore must be closed before the other dialogs can once again be interacted with.
Toast
Toast components are used to notify users of something. This could be letting them know that a restaurant is temporarily unavailable, or perhaps that the status of their order has changed.
Positioning a toast element relative to a modal dialog
The main purpose of this discussion is to explore how elements can be placed relative to a modal. If there are any limitations here, it may shape how we build the toast component.
There are naturally three possibilities of where elements can sit relative to the modal's stacking context:
Above
This would be relatively straightforward. To appear above a modally-opened dialog, the toast would have to also be added to the top layer (for example, by also using a modally-opened dialog). Then, if it is opened after the modal, it would appear above it. This would block interaction with the modal until the toast is dismissed.
Below
This is the simplest scenario. If the toast is created like any regular element, it will automatically appear below the modal. The implied behaviour here is that the modal must be closed before the toast can be interacted with.
Adjacent
This is the case where we might want to give the toast component equal priority to the modal, allowing them both to be interacted with at the same time. For this to be possible, the toast component would need to have the same stacking context as the modally-opened dialog.
Any element outside the modal will be below the top layer, so cannot be interacted with while the modal is open.
If we were to also use a modally-opened dialog for the toast component, it would be inside the top layer, however it would be given its own stacking context, preventing interaction with the modal; this is also out of the question.
I believe the only solution is for the toast component to be placed inside the modal. As a child element, it would naturally be inside its stacking context. This would allow both elements to be interacted with at the same time, and keyboard focus could move freely between them. This would almost certainly mean that closing the modal also dismisses the toast.
Initial testing shows that it is possible for children of the dialog element to be visually positioned outside the modal by using
position: fixed;
.Conclusion
I believe the best and most flexible approach would be to create the toast component using a
dialog
element, as this would allow us to cater for all three scenarios, if required.It would need to be able to be opened modally or modelessly; this could be controlled by a prop.
Example CodePens
Beta Was this translation helpful? Give feedback.
All reactions