Skip to content

Commit

Permalink
Merge pull request #5483 from vdegenne:quick-dialog
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 609527362
  • Loading branch information
copybara-github committed Feb 22, 2024
2 parents ce41b7b + ee591b3 commit 2d54b97
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 30 deletions.
6 changes: 5 additions & 1 deletion dialog/demo/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import {
materialInitsToStoryInits,
setUpDemo,
} from './material-collection.js';
import {Knob, textInput} from './index.js';
import {boolInput, Knob, textInput} from './index.js';

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

const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
'Dialog',
[
new Knob('quick', {
defaultValue: false,
ui: boolInput(),
}),
new Knob('icon', {defaultValue: '', ui: textInput()}),
new Knob('headline', {defaultValue: 'Dialog', ui: textInput()}),
new Knob('supportingText', {
Expand Down
57 changes: 30 additions & 27 deletions dialog/demo/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {css, html, nothing} from 'lit';

/** Knob types for dialog stories. */
export interface StoryKnobs {
quick: boolean;
icon: string;
headline: string;
supportingText: string;
Expand All @@ -30,13 +31,15 @@ function showDialog(event: Event) {

const standard: MaterialStoryInit<StoryKnobs> = {
name: 'Dialog',
render({icon, headline, supportingText}) {
render({icon, headline, supportingText, quick}) {
return html`
<md-filled-button @click=${showDialog} aria-label="Open a dialog"
>Open</md-filled-button
>
<md-filled-button @click=${showDialog} aria-label="Open a dialog">
Open
</md-filled-button>
<md-dialog aria-label=${headline ? nothing : 'A simple dialog'}>
<md-dialog
aria-label=${headline ? nothing : 'A simple dialog'}
?quick=${quick}>
${icon ? html`<md-icon slot="icon">${icon}</md-icon>` : nothing}
<div slot="headline">${headline}</div>
<form id="form" slot="content" method="dialog">
Expand All @@ -53,13 +56,13 @@ const standard: MaterialStoryInit<StoryKnobs> = {

const alert: MaterialStoryInit<StoryKnobs> = {
name: 'Alert',
render() {
render({quick}) {
return html`
<md-filled-button @click=${showDialog} aria-label="Open an alert dialog"
>Alert</md-filled-button
>
<md-filled-button @click=${showDialog} aria-label="Open an alert dialog">
Alert
</md-filled-button>
<md-dialog type="alert">
<md-dialog type="alert" ?quick=${quick}>
<div slot="headline">Alert dialog</div>
<form id="form" slot="content" method="dialog">
This is a standard alert dialog. Alert dialogs interrupt users with
Expand All @@ -75,15 +78,15 @@ const alert: MaterialStoryInit<StoryKnobs> = {

const confirm: MaterialStoryInit<StoryKnobs> = {
name: 'Confirm',
render() {
render({quick}) {
return html`
<md-filled-button
@click=${showDialog}
aria-label="Open a confirmation dialog"
>Confirm</md-filled-button
>
aria-label="Open a confirmation dialog">
Confirm
</md-filled-button>
<md-dialog style="max-width: 320px;">
<md-dialog style="max-width: 320px;" ?quick=${quick}>
<div slot="headline">Permanently delete?</div>
<md-icon slot="icon">delete_outline</md-icon>
<form id="form" slot="content" method="dialog">
Expand All @@ -109,13 +112,13 @@ const choose: MaterialStoryInit<StoryKnobs> = {
align-items: center;
}
`,
render() {
render({quick}) {
return html`
<md-filled-button @click=${showDialog} aria-label="Open a choice dialog"
>Choice</md-filled-button
>
<md-filled-button @click=${showDialog} aria-label="Open a choice dialog">
Choice
</md-filled-button>
<md-dialog>
<md-dialog ?quick=${quick}>
<div slot="headline">Choose your favorite pet</div>
<form id="form" slot="content" method="dialog">
<label>
Expand Down Expand Up @@ -184,13 +187,13 @@ const contacts: MaterialStoryInit<StoryKnobs> = {
flex: 1;
}
`,
render() {
render({quick}) {
return html`
<md-filled-button @click=${showDialog} aria-label="Open a form dialog"
>Form</md-filled-button
>
<md-filled-button @click=${showDialog} aria-label="Open a form dialog">
Form
</md-filled-button>
<md-dialog class="contacts">
<md-dialog class="contacts" ?quick=${quick}>
<span slot="headline">
<md-icon-button form="form" value="close" aria-label="Close dialog">
<md-icon>close</md-icon>
Expand Down Expand Up @@ -226,13 +229,13 @@ const contacts: MaterialStoryInit<StoryKnobs> = {

const floatingSheet: MaterialStoryInit<StoryKnobs> = {
name: 'Floating sheet',
render() {
render({quick}) {
return html`
<md-filled-button @click=${showDialog} aria-label="Open a floating sheet">
Floating sheet
</md-filled-button>
<md-dialog>
<md-dialog ?quick=${quick}>
<span slot="headline">
<span style="flex: 1;">Floating Sheet</span>
<md-icon-button form="form" value="close" aria-label="Close dialog">
Expand Down
31 changes: 29 additions & 2 deletions dialog/internal/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ export class Dialog extends LitElement {
}
}

/**
* Skips the opening and closing animations.
*/
@property({type: Boolean}) quick = false;

/**
* Gets or sets the dialog's return value, usually to indicate which button
* a user pressed to close it.
Expand Down Expand Up @@ -107,6 +112,7 @@ export class Dialog extends LitElement {
@state() private hasHeadline = false;
@state() private hasActions = false;
@state() private hasIcon = false;
private cancelAnimations?: AbortController;

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

private async animateDialog(animation: DialogAnimation) {
// Always cancel the previous animations. Animations can include `fill`
// modes that need to be cleared when `quick` is toggled. If not, content
// that faded out will remain hidden when a `quick` dialog re-opens after
// previously opening and closing without `quick`.
this.cancelAnimations?.abort();
this.cancelAnimations = new AbortController();
if (this.quick) {
return;
}

const {dialog, scrim, container, headline, content, actions} = this;
if (!dialog || !scrim || !container || !headline || !content || !actions) {
return;
Expand All @@ -422,11 +438,22 @@ export class Dialog extends LitElement {
const animations: Animation[] = [];
for (const [element, animation] of elementAndAnimation) {
for (const animateArgs of animation) {
animations.push(element.animate(...animateArgs));
const animation = element.animate(...animateArgs);
this.cancelAnimations.signal.addEventListener('abort', () => {
animation.cancel();
});

animations.push(animation);
}
}

await Promise.all(animations.map((animation) => animation.finished));
await Promise.all(
animations.map((animation) =>
animation.finished.catch(() => {
// Ignore intentional AbortErrors when calling `animation.cancel()`.
}),
),
);
}

private handleHeadlineChange(event: Event) {
Expand Down

0 comments on commit 2d54b97

Please sign in to comment.