You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Previously we held back on releasing our DrawerManager / useDrawerManager feature (see this RFC) because of the bug that we just mentioned. This feature comes into play when there are multiple help drawer links on a page and defines the behavior of what happens when an end-user already has one open and tries to open another. Now that the bug is fixed, we can roll this new feature out, and app teams will be able to offload some of their logic to the design system.
To go along with a convenience feature for Drawer, we can provide some new tools for Dialog as well. Everyone has to manage state for dialogs declaratively, even though modal dialogs are most often triggered imperatively. Consider the ease of using the built-in prompt function. Even though I believe strongly in the overall clearer design of declaratively built apps, I think a strong case can be made for imperative interfaces in some cases. When I was doing research for the focus-management bug, I came across this article about imperative dialog interfaces in React, and it really got me thinking. Being able to call a function to open the dialog and then wait on the response and do something about it could make application logic a lot easier to read, reason about, and manage. I believe this kind of an optional imperative interface for our Dialog component could be really handy for our users.
Proposal
This proposal contains two features:
Releasing our DrawerManager feature with some updates
Creating a new imperative interface for Dialog
Drawer manager
We'll finally start exporting the DrawerManagercontext provider component as well as its corresponding useDrawerManager interface. We'll open up the existing documentation that was hidden and expand on it. And we'll update the naming in the API to fit better with the new dialog API described in the next section.
Imperative dialog interface
Because modal dialogs have to be interacted with and closed before anything else can be done, they lend themselves to a fairly straightforward interface where we call a function and get a result, whether that's synchronous and asynchronous. We can't actually hope for synchronous, but these days in the JavaScript world, asynchronous is almost just as easy. Here's an example of how it could be used:
functionDeleteImportantSetting(){const[dialog,openDialog]=useDialog<boolean>((controlProps)=>(<Dialog{...controlProps}>
Your custom dialog goes here
</Dialog>));asyncfunctionhandleDelete(){constconfirmed=awaitopenDialog();if(confirmed){awaitdeleteTheThing();}}return(<div><buttononClick={handleDelete}>Delete important thing</button>{dialog}</div>)}
The user will be in charge of defining what the promise resolves to, so it's very customizable. They could have the dialog contain a form and resolve to an object or a string, or it could be a binary question with a boolean value. Having them pass a render function also makes it so they don't actually have to use a Dialog directly. It could be their own wrapper for Dialog or something else entirely.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Problem
In v9, we've had to change the dialog and drawer APIs slightly in order to fix a focus-management bug. While it isn't a big change, it requires action on the part of our users to update their code. Wouldn't it be nice if they got something out of the deal beyond a bugfix? How about some new functionality?
Previously we held back on releasing our
DrawerManager
/useDrawerManager
feature (see this RFC) because of the bug that we just mentioned. This feature comes into play when there are multiple help drawer links on a page and defines the behavior of what happens when an end-user already has one open and tries to open another. Now that the bug is fixed, we can roll this new feature out, and app teams will be able to offload some of their logic to the design system.To go along with a convenience feature for
Drawer
, we can provide some new tools forDialog
as well. Everyone has to manage state for dialogs declaratively, even though modal dialogs are most often triggered imperatively. Consider the ease of using the built-in prompt function. Even though I believe strongly in the overall clearer design of declaratively built apps, I think a strong case can be made for imperative interfaces in some cases. When I was doing research for the focus-management bug, I came across this article about imperative dialog interfaces in React, and it really got me thinking. Being able to call a function to open the dialog and then wait on the response and do something about it could make application logic a lot easier to read, reason about, and manage. I believe this kind of an optional imperative interface for ourDialog
component could be really handy for our users.Proposal
This proposal contains two features:
DrawerManager
feature with some updatesDialog
Drawer manager
We'll finally start exporting the
DrawerManager
context provider component as well as its correspondinguseDrawerManager
interface. We'll open up the existing documentation that was hidden and expand on it. And we'll update the naming in the API to fit better with the new dialog API described in the next section.Imperative dialog interface
Because modal dialogs have to be interacted with and closed before anything else can be done, they lend themselves to a fairly straightforward interface where we call a function and get a result, whether that's synchronous and asynchronous. We can't actually hope for synchronous, but these days in the JavaScript world, asynchronous is almost just as easy. Here's an example of how it could be used:
The user will be in charge of defining what the promise resolves to, so it's very customizable. They could have the dialog contain a form and resolve to an object or a string, or it could be a binary question with a boolean value. Having them pass a render function also makes it so they don't actually have to use a
Dialog
directly. It could be their own wrapper forDialog
or something else entirely.Beta Was this translation helpful? Give feedback.
All reactions