-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Dialogs: Add docs for async #5376
base: main
Are you sure you want to change the base?
Conversation
Thanks for the PR! 🎉 We've deployed an automatic preview for this PR - you can see your changes here:
Note The build needs to finish before your changes are deployed. |
@@ -258,6 +258,80 @@ document.querySelector('#open').addEventListener('click', () => { | |||
}); | |||
``` | |||
|
|||
## Async Dialogs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this a level 2 section rather than putting it under general since it is available in fullscreen. Could also put it under general then point at it from fullscreen.
|
||
The `async` attribute is supported by the General Dialog (`d2l-dialog`) and the fullscreen dialog (`d2l-dialog-fullscreen`). This indicates to the dialog component that the content is async, and a loading-spinner will be displayed until the content is ready. The expectation of the dialog is that the nested content will dispatch a promise-carrying `pending-state` event. When the promise is fulfilled the dialog hides the spinner, shows the content, and sizes the dialog. This functionality can be implemented with help from the [RunAsync Directive](#runasync-directive). | ||
|
||
<!-- docs: demo code autoSize:false size:medium --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified the demo from core. Let me know if there is anything crucial that I left out.
<d2l-button id="open">Show Dialog</d2l-button> | ||
``` | ||
|
||
### RunAsync Directive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put this here since we don't have a section on Daylight for directives. Ideally if/when that happens we would move this there and point at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth reviewing/discussing the options for handling async dialog content.
Option 1: Using d2l-dialog
's async property
This is the approach that you've documented here, which follows the example on our core demo page. The consumer puts the async
attribute on the dialog, and the dialog renders a d2l-loading-spinner
until the AsyncContainerMixin
's asyncState
is complete, which happens once all pending-state
event promises are resolved. Once complete, it hides the spinner, shows their content, and resizes the dialog.
What is the current focus behaviour when using this approach? I did a quick test in our core demo page and it looks like we end up placing focus on the workflow button while the async content loads, and it would be up to the consumer to move it elsewhere. This is probably not the ideal focus behaviour.
This provides some UX consistency, but is it too limiting? On the technical side, it requires the consumer to provide content that dispatches the pending-state
event, for which we've provided the runAsync
directive and AsyncStateEvent
. Originally we intended HM calls to include dispatching that event and consumers wouldn't have to do it themselves, but I'm not sure how much we/they can rely on that being the case.
The runAsync
directive was originally proposed by the Google devs and we adapted it for our purpose. I believe the idea eventually landed as the until
directive in later versions, but the API is different.
Option 2: Using the until directive
With this option, consumers are in complete control. They use the until
directive which gives them the ability to provide async content as well as a fallback such as a loading indicator however they want. This approach doesn't rely on the content dispatching pending-state
events, but it requires that the consumer knows when to resolve the promise provided to until
. Once the consumer resolves the promise, they are required to call the dialog's resize
method. As above, the consumer is also responsible for placing focus - and currently, I think focus would initially be placed on the workflow buttons, which is likely not the desired behaviour.
Jira ticket
I'm not overly familiar with this so definitely open to mass changes here.