Skip to content

Commit 2d54b97

Browse files
Merge pull request #5483 from vdegenne:quick-dialog
PiperOrigin-RevId: 609527362
2 parents ce41b7b + ee591b3 commit 2d54b97

File tree

3 files changed

+64
-30
lines changed

3 files changed

+64
-30
lines changed

dialog/demo/demo.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ import {
1313
materialInitsToStoryInits,
1414
setUpDemo,
1515
} from './material-collection.js';
16-
import {Knob, textInput} from './index.js';
16+
import {boolInput, Knob, textInput} from './index.js';
1717

1818
import {stories, StoryKnobs} from './stories.js';
1919

2020
const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
2121
'Dialog',
2222
[
23+
new Knob('quick', {
24+
defaultValue: false,
25+
ui: boolInput(),
26+
}),
2327
new Knob('icon', {defaultValue: '', ui: textInput()}),
2428
new Knob('headline', {defaultValue: 'Dialog', ui: textInput()}),
2529
new Knob('supportingText', {

dialog/demo/stories.ts

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {css, html, nothing} from 'lit';
1919

2020
/** Knob types for dialog stories. */
2121
export interface StoryKnobs {
22+
quick: boolean;
2223
icon: string;
2324
headline: string;
2425
supportingText: string;
@@ -30,13 +31,15 @@ function showDialog(event: Event) {
3031

3132
const standard: MaterialStoryInit<StoryKnobs> = {
3233
name: 'Dialog',
33-
render({icon, headline, supportingText}) {
34+
render({icon, headline, supportingText, quick}) {
3435
return html`
35-
<md-filled-button @click=${showDialog} aria-label="Open a dialog"
36-
>Open</md-filled-button
37-
>
36+
<md-filled-button @click=${showDialog} aria-label="Open a dialog">
37+
Open
38+
</md-filled-button>
3839
39-
<md-dialog aria-label=${headline ? nothing : 'A simple dialog'}>
40+
<md-dialog
41+
aria-label=${headline ? nothing : 'A simple dialog'}
42+
?quick=${quick}>
4043
${icon ? html`<md-icon slot="icon">${icon}</md-icon>` : nothing}
4144
<div slot="headline">${headline}</div>
4245
<form id="form" slot="content" method="dialog">
@@ -53,13 +56,13 @@ const standard: MaterialStoryInit<StoryKnobs> = {
5356

5457
const alert: MaterialStoryInit<StoryKnobs> = {
5558
name: 'Alert',
56-
render() {
59+
render({quick}) {
5760
return html`
58-
<md-filled-button @click=${showDialog} aria-label="Open an alert dialog"
59-
>Alert</md-filled-button
60-
>
61+
<md-filled-button @click=${showDialog} aria-label="Open an alert dialog">
62+
Alert
63+
</md-filled-button>
6164
62-
<md-dialog type="alert">
65+
<md-dialog type="alert" ?quick=${quick}>
6366
<div slot="headline">Alert dialog</div>
6467
<form id="form" slot="content" method="dialog">
6568
This is a standard alert dialog. Alert dialogs interrupt users with
@@ -75,15 +78,15 @@ const alert: MaterialStoryInit<StoryKnobs> = {
7578

7679
const confirm: MaterialStoryInit<StoryKnobs> = {
7780
name: 'Confirm',
78-
render() {
81+
render({quick}) {
7982
return html`
8083
<md-filled-button
8184
@click=${showDialog}
82-
aria-label="Open a confirmation dialog"
83-
>Confirm</md-filled-button
84-
>
85+
aria-label="Open a confirmation dialog">
86+
Confirm
87+
</md-filled-button>
8588
86-
<md-dialog style="max-width: 320px;">
89+
<md-dialog style="max-width: 320px;" ?quick=${quick}>
8790
<div slot="headline">Permanently delete?</div>
8891
<md-icon slot="icon">delete_outline</md-icon>
8992
<form id="form" slot="content" method="dialog">
@@ -109,13 +112,13 @@ const choose: MaterialStoryInit<StoryKnobs> = {
109112
align-items: center;
110113
}
111114
`,
112-
render() {
115+
render({quick}) {
113116
return html`
114-
<md-filled-button @click=${showDialog} aria-label="Open a choice dialog"
115-
>Choice</md-filled-button
116-
>
117+
<md-filled-button @click=${showDialog} aria-label="Open a choice dialog">
118+
Choice
119+
</md-filled-button>
117120
118-
<md-dialog>
121+
<md-dialog ?quick=${quick}>
119122
<div slot="headline">Choose your favorite pet</div>
120123
<form id="form" slot="content" method="dialog">
121124
<label>
@@ -184,13 +187,13 @@ const contacts: MaterialStoryInit<StoryKnobs> = {
184187
flex: 1;
185188
}
186189
`,
187-
render() {
190+
render({quick}) {
188191
return html`
189-
<md-filled-button @click=${showDialog} aria-label="Open a form dialog"
190-
>Form</md-filled-button
191-
>
192+
<md-filled-button @click=${showDialog} aria-label="Open a form dialog">
193+
Form
194+
</md-filled-button>
192195
193-
<md-dialog class="contacts">
196+
<md-dialog class="contacts" ?quick=${quick}>
194197
<span slot="headline">
195198
<md-icon-button form="form" value="close" aria-label="Close dialog">
196199
<md-icon>close</md-icon>
@@ -226,13 +229,13 @@ const contacts: MaterialStoryInit<StoryKnobs> = {
226229

227230
const floatingSheet: MaterialStoryInit<StoryKnobs> = {
228231
name: 'Floating sheet',
229-
render() {
232+
render({quick}) {
230233
return html`
231234
<md-filled-button @click=${showDialog} aria-label="Open a floating sheet">
232235
Floating sheet
233236
</md-filled-button>
234237
235-
<md-dialog>
238+
<md-dialog ?quick=${quick}>
236239
<span slot="headline">
237240
<span style="flex: 1;">Floating Sheet</span>
238241
<md-icon-button form="form" value="close" aria-label="Close dialog">

dialog/internal/dialog.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ export class Dialog extends LitElement {
5959
}
6060
}
6161

62+
/**
63+
* Skips the opening and closing animations.
64+
*/
65+
@property({type: Boolean}) quick = false;
66+
6267
/**
6368
* Gets or sets the dialog's return value, usually to indicate which button
6469
* a user pressed to close it.
@@ -107,6 +112,7 @@ export class Dialog extends LitElement {
107112
@state() private hasHeadline = false;
108113
@state() private hasActions = false;
109114
@state() private hasIcon = false;
115+
private cancelAnimations?: AbortController;
110116

111117
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1512224
112118
// Chrome v120 has a bug where escape keys do not trigger cancels. If we get
@@ -396,6 +402,16 @@ export class Dialog extends LitElement {
396402
}
397403

398404
private async animateDialog(animation: DialogAnimation) {
405+
// Always cancel the previous animations. Animations can include `fill`
406+
// modes that need to be cleared when `quick` is toggled. If not, content
407+
// that faded out will remain hidden when a `quick` dialog re-opens after
408+
// previously opening and closing without `quick`.
409+
this.cancelAnimations?.abort();
410+
this.cancelAnimations = new AbortController();
411+
if (this.quick) {
412+
return;
413+
}
414+
399415
const {dialog, scrim, container, headline, content, actions} = this;
400416
if (!dialog || !scrim || !container || !headline || !content || !actions) {
401417
return;
@@ -422,11 +438,22 @@ export class Dialog extends LitElement {
422438
const animations: Animation[] = [];
423439
for (const [element, animation] of elementAndAnimation) {
424440
for (const animateArgs of animation) {
425-
animations.push(element.animate(...animateArgs));
441+
const animation = element.animate(...animateArgs);
442+
this.cancelAnimations.signal.addEventListener('abort', () => {
443+
animation.cancel();
444+
});
445+
446+
animations.push(animation);
426447
}
427448
}
428449

429-
await Promise.all(animations.map((animation) => animation.finished));
450+
await Promise.all(
451+
animations.map((animation) =>
452+
animation.finished.catch(() => {
453+
// Ignore intentional AbortErrors when calling `animation.cancel()`.
454+
}),
455+
),
456+
);
430457
}
431458

432459
private handleHeadlineChange(event: Event) {

0 commit comments

Comments
 (0)