Skip to content

Commit

Permalink
feat(expansion): add animation events for expansion panels (#12412)
Browse files Browse the repository at this point in the history
  • Loading branch information
josephperrott authored and mmalerba committed Aug 16, 2018
1 parent 9d882a0 commit f6b1002
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 14 deletions.
11 changes: 9 additions & 2 deletions src/demo-app/expansion/expansion-demo.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<h1>Single Expansion Panel</h1>

<mat-expansion-panel class="demo-expansion-width" #myPanel>
<mat-expansion-panel class="demo-expansion-width" #myPanel
(afterExpand)="addEvent('afterExpand')"
(afterCollapse)="addEvent('afterCollapse')">
<mat-expansion-panel-header [expandedHeight]="expandedHeight" [collapsedHeight]="collapsedHeight">
<mat-panel-description>This is a panel description.</mat-panel-description>
<mat-panel-title>Panel Title</mat-panel-title>
Expand Down Expand Up @@ -29,6 +31,11 @@ <h1>Single Expansion Panel</h1>
</mat-form-field>
<br>

<p>Expansion Panel Animation Events</p>
<code class="demo-expansion-code">
<pre *ngFor="let event of events">{{event}}</pre>
</code>

<h1>matAccordion</h1>
<div>
<p>Accordion Options</p>
Expand Down Expand Up @@ -56,7 +63,7 @@ <h1>matAccordion</h1>
</div>
<br>
<mat-accordion [displayMode]="displayMode" [multi]="multi"
class="demo-expansion-width">
class="demo-expansion-width">
<mat-expansion-panel #panel1 [hideToggle]="hideToggle">
<mat-expansion-panel-header>Section 1</mat-expansion-panel-header>
<p>This is the content text that makes sense here.</p>
Expand Down
13 changes: 13 additions & 0 deletions src/demo-app/expansion/expansion-demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@
width: 600px;
display: block;
}

.demo-expansion-code {
background: #d3d3d3;
display: block;
height: 10em;
overflow: auto;
padding: 0 5px;
width: 400px;

pre {
margin: 0.25em 0;
}
}
5 changes: 5 additions & 0 deletions src/demo-app/expansion/expansion-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ export class ExpansionDemo {
showPanel3 = true;
expandedHeight: string;
collapsedHeight: string;
events: string[] = [];

addEvent(eventName: string) {
this.events.push(`${eventName} - ${new Date().toISOString()}`);
}
}
22 changes: 19 additions & 3 deletions src/lib/expansion/expansion-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import {
Component,
ContentChild,
Directive,
EventEmitter,
Input,
OnChanges,
OnDestroy,
Optional,
Output,
SimpleChanges,
SkipSelf,
ViewContainerRef,
Expand Down Expand Up @@ -69,7 +71,7 @@ let uniqueId = 0;
}
})
export class MatExpansionPanel extends CdkAccordionItem
implements AfterContentInit, OnChanges, OnDestroy {
implements AfterContentInit, OnChanges, OnDestroy {
/** Whether the toggle indicator should be hidden. */
@Input()
get hideToggle(): boolean { return this._hideToggle; }
Expand All @@ -78,6 +80,12 @@ export class MatExpansionPanel extends CdkAccordionItem
}
private _hideToggle = false;

/** An event emitted after the body's expansion animation happens. */
@Output() afterExpand = new EventEmitter<void>();

/** An event emitted after the body's collapse animation happens. */
@Output() afterCollapse = new EventEmitter<void>();

/** Stream that emits for changes in `@Input` properties. */
readonly _inputChanges = new Subject<SimpleChanges>();

Expand Down Expand Up @@ -147,17 +155,25 @@ export class MatExpansionPanel extends CdkAccordionItem
_bodyAnimation(event: AnimationEvent) {
const classList = event.element.classList;
const cssClass = 'mat-expanded';
const {phaseName, toState} = event;
const {phaseName, toState, fromState} = event;

// Toggle the body's `overflow: hidden` class when closing starts or when expansion ends in
// order to prevent the cases where switching too early would cause the animation to jump.
// Note that we do it directly on the DOM element to avoid the slight delay that comes
// with doing it via change detection.
if (phaseName === 'done' && toState === 'expanded') {
classList.add(cssClass);
} else if (phaseName === 'start' && toState === 'collapsed') {
}
if (phaseName === 'start' && toState === 'collapsed') {
classList.remove(cssClass);
}

if (phaseName === 'done' && toState === 'expanded' && fromState !== 'void') {
this.afterExpand.emit();
}
if (phaseName === 'done' && toState === 'collapsed' && fromState !== 'void') {
this.afterCollapse.emit();
}
}
}

Expand Down
41 changes: 32 additions & 9 deletions src/lib/expansion/expansion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ describe('MatExpansionPanel', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
MatExpansionModule,
NoopAnimationsModule,
MatExpansionModule
],
declarations: [
PanelWithContent,
Expand Down Expand Up @@ -44,8 +44,9 @@ describe('MatExpansionPanel', () => {
}));

it('should be able to render panel content lazily', fakeAsync(() => {
let fixture = TestBed.createComponent(LazyPanelWithContent);
let content = fixture.debugElement.query(By.css('.mat-expansion-panel-content')).nativeElement;
const fixture = TestBed.createComponent(LazyPanelWithContent);
const content = fixture.debugElement.query(
By.css('.mat-expansion-panel-content')).nativeElement;
fixture.detectChanges();

expect(content.textContent.trim()).toBe('', 'Expected content element to be empty.');
Expand All @@ -58,8 +59,9 @@ describe('MatExpansionPanel', () => {
}));

it('should render the content for a lazy-loaded panel that is opened on init', fakeAsync(() => {
let fixture = TestBed.createComponent(LazyPanelOpenOnLoad);
let content = fixture.debugElement.query(By.css('.mat-expansion-panel-content')).nativeElement;
const fixture = TestBed.createComponent(LazyPanelOpenOnLoad);
const content = fixture.debugElement.query(
By.css('.mat-expansion-panel-content')).nativeElement;
fixture.detectChanges();

expect(content.textContent.trim())
Expand Down Expand Up @@ -161,10 +163,10 @@ describe('MatExpansionPanel', () => {
}));

it('should not override the panel margin if it is not inside an accordion', fakeAsync(() => {
let fixture = TestBed.createComponent(PanelWithCustomMargin);
const fixture = TestBed.createComponent(PanelWithCustomMargin);
fixture.detectChanges();

let panel = fixture.debugElement.query(By.css('mat-expansion-panel'));
const panel = fixture.debugElement.query(By.css('mat-expansion-panel'));
let styles = getComputedStyle(panel.nativeElement);

expect(panel.componentInstance._hasSpacing()).toBe(false);
Expand Down Expand Up @@ -221,7 +223,7 @@ describe('MatExpansionPanel', () => {
}));

it('should make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
let fixture = TestBed.createComponent(PanelWithContentInNgIf);
const fixture = TestBed.createComponent(PanelWithContentInNgIf);
fixture.detectChanges();
let destroyedOk = false;
fixture.componentInstance.panel.destroyed.subscribe(() => destroyedOk = true);
Expand Down Expand Up @@ -264,6 +266,27 @@ describe('MatExpansionPanel', () => {
'Expected class to be added after the animation has finished');
}));

it('should emit events for body expanding and collapsing animations', fakeAsync(() => {
const fixture = TestBed.createComponent(PanelWithContent);
fixture.detectChanges();
let afterExpand = 0;
let afterCollapse = 0;
fixture.componentInstance.panel.afterExpand.subscribe(() => afterExpand++);
fixture.componentInstance.panel.afterCollapse.subscribe(() => afterCollapse++);

fixture.componentInstance.expanded = true;
fixture.detectChanges();
flush();
expect(afterExpand).toBe(1);
expect(afterCollapse).toBe(0);

fixture.componentInstance.expanded = false;
fixture.detectChanges();
flush();
expect(afterExpand).toBe(1);
expect(afterCollapse).toBe(1);
}));

describe('disabled state', () => {
let fixture: ComponentFixture<PanelWithContent>;
let panel: HTMLElement;
Expand Down Expand Up @@ -373,7 +396,7 @@ class PanelWithContentInNgIf {
</mat-expansion-panel>`
})
class PanelWithCustomMargin {
expanded: boolean = false;
expanded = false;
}

@Component({
Expand Down

0 comments on commit f6b1002

Please sign in to comment.