Disable Async Dialog trigger while the dialog is loading

This commit is contained in:
Klaus Zanders
2026-06-02 15:23:22 +02:00
parent 0769d3597b
commit 32e2002f8e
2 changed files with 30 additions and 0 deletions
@@ -33,6 +33,12 @@ import { renderStreamMessage } from '@hotwired/turbo';
import { TurboHelpers } from 'core-turbo/helpers';
export default class AsyncDialogController extends ApplicationController {
static values = { disableDuringLoad: { type: Boolean, default: true } };
declare disableDuringLoadValue:boolean;
private loading = false;
connect() {
// Only bind events if we have an href to work with
if (this.href) {
@@ -55,6 +61,12 @@ export default class AsyncDialogController extends ApplicationController {
}
private triggerTurboStream(url:string):void {
if (this.disableDuringLoadValue && this.loading) return;
if (this.disableDuringLoadValue) {
this.loading = true;
(this.element as HTMLElement).setAttribute('aria-disabled', 'true');
}
TurboHelpers.showProgressBar();
void fetch(url, {
@@ -74,6 +86,10 @@ export default class AsyncDialogController extends ApplicationController {
}).then((html) => {
renderStreamMessage(html);
}).finally(() => {
if (this.disableDuringLoadValue) {
this.loading = false;
(this.element as HTMLElement).removeAttribute('aria-disabled');
}
TurboHelpers.hideProgressBar();
});
}
+14
View File
@@ -23,6 +23,20 @@ end
%>
```
By default, the trigger element is disabled (via `aria-disabled`) while the request is in flight, preventing double-clicks from opening the dialog twice. This is especially useful when the dialog content is expensive to render. To opt out of this behaviour, set the `data-async-dialog-disable-during-load-value` attribute to `false`:
```erb
<%%= render(Primer::Beta::Button.new(
tag: :a,
href: link_to_dialog_path,
data: { controller: "async-dialog", async_dialog_disable_during_load_value: false }
)) do |button|
button.with_leading_visual_icon(icon: :edit)
"Edit something"
end
%>
```
On the Rails controller you wish to render the dialog, you need to respond to the request with the dialog content.
The async-controller stimulus controller will ensure that a loading progress bar will be shown on the top of the page.