Skip to content
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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

feat: Dialogs: Add docs for async #5376

wants to merge 1 commit into from

Conversation

margaree
Copy link
Contributor

@margaree margaree commented Feb 7, 2025

Jira ticket

I'm not overly familiar with this so definitely open to mass changes here.

Copy link
Contributor

github-actions bot commented Feb 7, 2025

Thanks for the PR! 🎉

We've deployed an automatic preview for this PR - you can see your changes here:

URL https://live.d2l.dev/prs/BrightspaceUI/core/pr-5376/

Note

The build needs to finish before your changes are deployed.
Changes to the PR will automatically update the instance.

@@ -258,6 +258,80 @@ document.querySelector('#open').addEventListener('click', () => {
});
```

## Async Dialogs
Copy link
Contributor Author

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 -->
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@margaree margaree requested review from geurts and dbatiste February 7, 2025 14:00
Copy link
Contributor

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.

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.

2 participants