feat(expansion-panel): introduce expansion panel"

This commit is contained in:
Joey Perrott
2017-06-07 16:54:31 -07:00
committed by Andrew Seguin
parent 37df5d3c15
commit cac7610460
22 changed files with 775 additions and 6 deletions
+4
View File
@@ -41,6 +41,7 @@ import {DataTableDemo} from './data-table/data-table-demo';
import {PeopleDatabase} from './data-table/people-database';
import {DatepickerDemo} from './datepicker/datepicker-demo';
import {TypographyDemo} from './typography/typography-demo';
import {ExpansionDemo} from './expansion/expansion-demo';
import {
CdkDataTableModule,
FullscreenOverlayContainer,
@@ -53,6 +54,7 @@ import {
MdCoreModule,
MdDatepickerModule,
MdDialogModule,
MdExpansionModule,
MdGridListModule,
MdIconModule,
MdInputModule,
@@ -87,6 +89,7 @@ import {
MdChipsModule,
MdDatepickerModule,
MdDialogModule,
MdExpansionModule,
MdGridListModule,
MdIconModule,
MdInputModule,
@@ -170,6 +173,7 @@ export class DemoMaterialModule {}
FoggyTabContent,
PlatformDemo,
TypographyDemo,
ExpansionDemo,
],
providers: [
{provide: OverlayContainer, useClass: FullscreenOverlayContainer},
+1
View File
@@ -43,6 +43,7 @@ export class DemoApp {
{name: 'Data Table', route: 'data-table'},
{name: 'Datepicker', route: 'datepicker'},
{name: 'Dialog', route: 'dialog'},
{name: 'Expansion Panel', route: 'expansion'},
{name: 'Gestures', route: 'gestures'},
{name: 'Grid List', route: 'grid-list'},
{name: 'Icon', route: 'icon'},
+3 -1
View File
@@ -35,6 +35,7 @@ import {StyleDemo} from '../style/style-demo';
import {DatepickerDemo} from '../datepicker/datepicker-demo';
import {DataTableDemo} from '../data-table/data-table-demo';
import {TypographyDemo} from '../typography/typography-demo';
import {ExpansionDemo} from '../expansion/expansion-demo';
export const DEMO_APP_ROUTES: Routes = [
{path: '', component: Home},
@@ -71,5 +72,6 @@ export const DEMO_APP_ROUTES: Routes = [
{path: 'snack-bar', component: SnackBarDemo},
{path: 'platform', component: PlatformDemo},
{path: 'style', component: StyleDemo},
{path: 'typography', component: TypographyDemo}
{path: 'typography', component: TypographyDemo},
{path: 'expansion', component: ExpansionDemo},
];
@@ -0,0 +1,52 @@
<h1>Single Expansion Panel</h1>
<md-expansion-panel class="md-expansion-demo-width" #myPanel>
<md-expansion-panel-header>
<mat-panel-description>This is a panel description.</mat-panel-description>
<mat-panel-title>Panel Title</mat-panel-title>
</md-expansion-panel-header>
This is the content text that makes sense here.
<md-action-row>
<button md-button (click)="myPanel.expanded = false">CANCEL</button>
<button md-button>SAVE</button>
</md-action-row>
</md-expansion-panel>
<br>
<h1>Accordion</h1>
<div>
<p>Accordion Options</p>
<div>
<md-slide-toggle [(ngModel)]="multi">Allow Multi Expansion</md-slide-toggle>
<md-slide-toggle [(ngModel)]="hideToggle">Hide Indicators</md-slide-toggle>
<md-slide-toggle [(ngModel)]="showPanel3">Show Panel 3</md-slide-toggle>
</div>
<p>Accordion Style</p>
<md-radio-group [(ngModel)]="displayMode">
<md-radio-button value="default">Default</md-radio-button>
<md-radio-button value="flat">Flat</md-radio-button>
</md-radio-group>
<p>Accordion Panel(s)</p>
<div>
<md-checkbox [(ngModel)]="panel1.expanded">Panel 1</md-checkbox>
<md-checkbox [(ngModel)]="panel2.expanded">Panel 2</md-checkbox>
</div>
</div>
<br>
<md-accordion [displayMode]="displayMode" [multi]="multi"
class="md-expansion-demo-width">
<md-expansion-panel #panel1 [hideToggle]="hideToggle">
<md-expansion-panel-header>Section 1</md-expansion-panel-header>
<p>This is the content text that makes sense here.</p>
</md-expansion-panel>
<md-expansion-panel #panel2 [hideToggle]="hideToggle">
<md-expansion-panel-header>Section 2</md-expansion-panel-header>
<p>This is the content text that makes sense here.</p>
</md-expansion-panel>
<md-expansion-panel #panel3 *ngIf="showPanel3" [hideToggle]="hideToggle">
<md-expansion-panel-header>Section 3</md-expansion-panel-header>
<md-checkbox #showButtons>Reveal Buttons Below</md-checkbox>
<md-action-row *ngIf="showButtons.checked">
<button md-button (click)="panel2.expanded = true">OPEN SECTION 2</button>
<button md-button (click)="panel3.expanded = false">CLOSE</button>
</md-action-row>
</md-expansion-panel>
</md-accordion>
@@ -0,0 +1,4 @@
.md-expansion-demo-width {
width: 600px;
display: block;
}
+15
View File
@@ -0,0 +1,15 @@
import {Component, ViewEncapsulation} from '@angular/core';
@Component({
moduleId: module.id,
selector: 'expansion-demo',
styleUrls: ['expansion-demo.css'],
templateUrl: 'expansion-demo.html',
encapsulation: ViewEncapsulation.None,
})
export class ExpansionDemo {
displayMode: string = 'default';
multi: boolean = false;
hideToggle: boolean = false;
showPanel3 = true;
}
+2
View File
@@ -8,6 +8,7 @@
@import '../../chips/chips-theme';
@import '../../datepicker/datepicker-theme';
@import '../../dialog/dialog-theme';
@import '../../expansion/expansion-theme';
@import '../../grid-list/grid-list-theme';
@import '../../icon/icon-theme';
@import '../../input/input-theme';
@@ -37,6 +38,7 @@
@include mat-chips-theme($theme);
@include mat-datepicker-theme($theme);
@include mat-dialog-theme($theme);
@include mat-expansion-panel-theme($theme);
@include mat-grid-list-theme($theme);
@include mat-icon-theme($theme);
@include mat-input-theme($theme);
+32
View File
@@ -0,0 +1,32 @@
@import '../core/theming/palette';
@import '../core/theming/theming';
@mixin mat-expansion-panel-theme($theme) {
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
.mat-expansion-panel {
background: mat-color($background, card);
color: mat-color($foreground, base);
}
.mat-action-row {
border-top-color: mat-color($foreground, divider);
}
.mat-expansion-panel-header:focus,
.mat-expansion-panel-header:hover {
background: mat-color($background, hover);
}
.mat-expansion-panel-header-title {
color: mat-color($foreground, text);
}
.mat-expansion-panel-header-description {
color: mat-color($foreground, secondary-text);
}
.mat-expansion-indicator::after {
color: mat-color($foreground, secondary-text);
}
}
+72
View File
@@ -0,0 +1,72 @@
import {Output, EventEmitter, Input, Injectable, OnDestroy, Optional} from '@angular/core';
import {UniqueSelectionDispatcher} from '../core';
import {CdkAccordion} from './accordion';
/** Used to generate unique ID for each expansion panel. */
let nextId = 0;
/**
* An abstract class to be extended and decorated as a component. Sets up all
* events and attributes needed to be managed by a CdkAccordion parent.
*/
@Injectable()
export class AccordionItem implements OnDestroy {
/** Event emitted every time the MdAccordianChild is closed. */
@Output() closed = new EventEmitter<void>();
/** Event emitted every time the MdAccordianChild is opened. */
@Output() opened = new EventEmitter<void>();
/** Event emitted when the MdAccordianChild is destroyed. */
@Output() destroyed = new EventEmitter<void>();
/** The unique MdAccordianChild id. */
readonly id = `cdk-accordion-child-${nextId++}`;
/** Whether the MdAccordianChild is expanded. */
@Input() get expanded(): boolean { return this._expanded; }
set expanded(expanded: boolean) {
// Only emit events and update the internal value if the value changes.
if (this._expanded !== expanded) {
this._expanded = expanded;
if (expanded) {
this.opened.emit();
/**
* In the unique selection dispatcher, the id parameter is the id of the CdkAccordonItem,
* the name value is the id of the accordion.
*/
let accordionId = this.accordion ? this.accordion.id : this.id;
this._expansionDispatcher.notify(this.id, accordionId);
} else {
this.closed.emit();
}
}
}
private _expanded: boolean;
constructor(@Optional() public accordion: CdkAccordion,
protected _expansionDispatcher: UniqueSelectionDispatcher) {
_expansionDispatcher.listen((id: string, accordionId: string) => {
if (this.accordion && !this.accordion.multi &&
this.accordion.id === accordionId && this.id !== id) {
this.expanded = false;
}
});
}
/** Emits an event for the accordion item being destroyed. */
ngOnDestroy() {
this.destroyed.emit();
}
/** Toggles the expanded state of the accordion item. */
toggle(): void {
this.expanded = !this.expanded;
}
/** Sets the expanded state of the accordion item to false. */
close(): void {
this.expanded = false;
}
/** Sets the expanded state of the accordion item to true. */
open(): void {
this.expanded = true;
}
}
+66
View File
@@ -0,0 +1,66 @@
import {async, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MdExpansionModule} from './index';
describe('CdkAccordion', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
MdExpansionModule
],
declarations: [
SetOfItems
],
});
TestBed.compileComponents();
}));
it('should ensure only one item is expanded at a time', () => {
let fixture = TestBed.createComponent(SetOfItems);
let items = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
fixture.componentInstance.firstPanelExpanded = true;
fixture.detectChanges();
expect(items[0].classes['mat-expanded']).toBeTruthy();
expect(items[1].classes['mat-expanded']).toBeFalsy();
fixture.componentInstance.secondPanelExpanded = true;
fixture.detectChanges();
expect(items[0].classes['mat-expanded']).toBeFalsy();
expect(items[1].classes['mat-expanded']).toBeTruthy();
});
it('should allow multiple items to be expanded simultaneously', () => {
let fixture = TestBed.createComponent(SetOfItems);
let panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
fixture.componentInstance.multi = true;
fixture.componentInstance.firstPanelExpanded = true;
fixture.componentInstance.secondPanelExpanded = true;
fixture.detectChanges();
expect(panels[0].classes['mat-expanded']).toBeTruthy();
expect(panels[1].classes['mat-expanded']).toBeTruthy();
});
});
@Component({template: `
<md-accordion [multi]="multi">
<md-expansion-panel [expanded]="firstPanelExpanded">
<md-expansion-panel-header>Summary</md-expansion-panel-header>
<p>Content</p>
</md-expansion-panel>
<md-expansion-panel [expanded]="secondPanelExpanded">
<md-expansion-panel-header>Summary</md-expansion-panel-header>
<p>Content</p>
</md-expansion-panel>
</md-accordion>`})
class SetOfItems {
multi: boolean = false;
firstPanelExpanded: boolean = false;
secondPanelExpanded: boolean = false;
}
+50
View File
@@ -0,0 +1,50 @@
import {Directive, Input} from '@angular/core';
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
/** MdAccordion's display modes. */
export type MdAccordionDisplayMode = 'default' | 'flat';
/** Unique ID counter */
let nextId = 0;
/**
* Directive whose purpose is to manage the expanded state of CdkAccordionItem children.
*/
@Directive({
selector: '[cdk-accordion]',
})
export class CdkAccordion {
/** A readonly id value to use for unique selection coordination. */
readonly id = `cdk-accordion-${nextId++}`;
/** Whether the accordion should allow multiple expanded accordion items simulateously. */
@Input() get multi(): boolean { return this._multi; }
set multi(multi: boolean) { this._multi = coerceBooleanProperty(multi); }
private _multi: boolean = false;
/** Whether the expansion indicator should be hidden. */
@Input() get hideToggle(): boolean { return this._hideToggle; }
set hideToggle(show: boolean) { this._hideToggle = coerceBooleanProperty(show); }
private _hideToggle: boolean = false;
/**
* The display mode used for all expansion panels in the accordion. Currently two display
* modes exist:
* default - a gutter-like spacing is placed around any expanded panel, placing the expanded
* panel at a different elevation from the reset of the accordion.
* flat - no spacing is placed around expanded panels, showing all panels at the same
* elevation.
*/
@Input() displayMode: MdAccordionDisplayMode = 'default';
}
/**
* Directive for a Material Design Accordion.
*/
@Directive({
selector: 'mat-accordion, md-accordion',
host: {
class: 'mat-accordion'
}
})
export class MdAccordion extends CdkAccordion {}
@@ -0,0 +1,7 @@
<span class="mat-content">
<ng-content select="md-panel-title, mat-panel-title"></ng-content>
<ng-content select="md-panel-description, mat-panel-description"></ng-content>
<ng-content></ng-content>
</span>
<span [@indicatorRotate]="_getExpandedState()" *ngIf="!_getHideToggle()"
class="mat-expansion-indicator"></span>
@@ -0,0 +1,61 @@
$mat-expansion-panel-header-height: 48px;
$mat-expansion-panel-header-height-expanded: 64px;
.mat-expansion-panel-header {
cursor: pointer;
display: flex;
flex-direction: row;
height: $mat-expansion-panel-header-height;
line-height: $mat-expansion-panel-header-height;
padding: 0 24px;
&.mat-expanded {
height: $mat-expansion-panel-header-height-expanded;
line-height: $mat-expansion-panel-header-height-expanded;
}
&:focus,
&:hover {
outline: none;
}
&.mat-expanded:focus,
&.mat-expanded:hover, {
background: inherit;
}
}
.mat-content {
display: flex;
flex: 1;
flex-direction: row;
overflow: hidden;
}
.mat-expansion-panel-header-title {
display: flex;
flex-grow: 1;
font-size: 15px;
margin-right: 16px;
}
.mat-expansion-panel-header-description {
display: flex;
flex-grow: 2;
font-size: 15px;
margin-right: 16px;
}
/**
* Creates the expansion indicator arrow. Done using ::after rather than having
* additional nodes in the template.
*/
.mat-expansion-indicator::after {
border-style: solid;
border-width: 0 2px 2px 0;
content: '';
display: inline-block;
padding: 3px;
transform: rotate(45deg);
vertical-align: middle;
}
+122
View File
@@ -0,0 +1,122 @@
import {
Component,
Directive,
Host,
ViewEncapsulation,
} from '@angular/core';
import {
trigger,
state,
style,
transition,
animate,
} from '@angular/animations';
import {SPACE, ENTER} from '../core/keyboard/keycodes';
import {MdExpansionPanel, EXPANSION_PANEL_ANIMATION_TIMING} from './expansion-panel';
/**
* <md-expansion-panel-header> component.
*
* This component corresponds to the header element of an <md-expansion-panel>.
*
* Please refer to README.md for examples on how to use it.
*/
@Component({
moduleId: module.id,
selector: 'md-expansion-panel-header, mat-expansion-panel-header',
styleUrls: ['./expansion-panel-header.css'],
templateUrl: './expansion-panel-header.html',
encapsulation: ViewEncapsulation.None,
host: {
'class': 'mat-expansion-panel-header',
'role': 'button',
'tabindex': '0',
'[attr.aria-controls]': '_getPanelId()',
'[attr.aria-expanded]': '_isExpanded()',
'[class.mat-expanded]': '_isExpanded()',
'(click)': '_toggle()',
'(keyup)': '_keyup($event)',
'[@expansionHeight]': '_getExpandedState()',
},
animations: [
trigger('indicatorRotate', [
state('collapsed', style({transform: 'rotate(0deg)'})),
state('expanded', style({transform: 'rotate(180deg)'})),
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
]),
trigger('expansionHeight', [
state('collapsed', style({height: '48px', 'line-height': '48px'})),
state('expanded', style({height: '64px', 'line-height': '68px'})),
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
]),
],
})
export class MdExpansionPanelHeader {
constructor(@Host() public panel: MdExpansionPanel) {}
/** Toggles the expanded state of the panel. */
_toggle(event?: KeyboardEvent): void {
this.panel.toggle();
}
/** Gets whether the panel is expanded. */
_isExpanded(): boolean {
return this.panel.expanded;
}
/** Gets the expanded state string of the panel. */
_getExpandedState(): string {
return this.panel._getExpandedState();
}
/** Gets the panel id. */
_getPanelId(): string {
return this.panel.id;
}
/** Gets whether the expand indicator is hidden. */
_getHideToggle(): boolean {
return this.panel.hideToggle;
}
/** Handle keyup event calling to toggle() if appropriate. */
_keyup(event: KeyboardEvent) {
switch (event.keyCode) {
// Toggle for space and enter keys.
case SPACE:
case ENTER:
event.preventDefault();
this._toggle();
break;
default:
return;
}
}
}
/**
* <md-panel-description> directive.
*
* This direction is to be used inside of the MdExpansionPanelHeader component.
*/
@Directive({
selector: 'md-panel-description, mat-panel-description',
host : {
class: 'mat-expansion-panel-header-description'
}
})
export class MdExpansionPanelDescription {}
/**
* <md-panel-title> directive.
*
* This direction is to be used inside of the MdExpansionPanelHeader component.
*/
@Directive({
selector: 'md-panel-title, mat-panel-title',
host : {
class: 'mat-expansion-panel-header-title'
}
})
export class MdExpansionPanelTitle {}
+8
View File
@@ -0,0 +1,8 @@
<ng-content select="mat-expansion-panel-header, md-expansion-panel-header"></ng-content>
<div [class.mat-expanded]="expanded" class="mat-expansion-panel-content"
[@bodyExpansion]="_getExpandedState()" [id]="id">
<div class="mat-expansion-panel-body">
<ng-content></ng-content>
</div>
<ng-content select="mat-action-row, md-action-row"></ng-content>
</div>
+33
View File
@@ -0,0 +1,33 @@
@import '../core/style/variables';
@import '../core/style/elevation';
.mat-expansion-panel {
@include mat-elevation-transition;
box-sizing: content-box;
display: block;
&:not([class*='mat-elevation-z']) {
@include mat-elevation(2);
}
}
.mat-expansion-panel-content {
overflow: hidden;
}
.mat-expansion-panel-body {
padding: 0 24px 16px;
}
.mat-action-row {
border-top-style: solid;
border-top-width: 1px;
display: flex;
flex-direction: row;
justify-content: flex-end;
padding: 16px 8px 16px 24px;
button.mat-button {
margin-left: 8px;
}
}
+106
View File
@@ -0,0 +1,106 @@
import {
Component,
Directive,
Host,
Input,
ViewEncapsulation,
Optional,
forwardRef,
} from '@angular/core';
import {
trigger,
state,
style,
transition,
animate,
} from '@angular/animations';
import {MdAccordion, MdAccordionDisplayMode} from './accordion';
import {AccordionItem} from './accordion-item';
import {UniqueSelectionDispatcher} from '../core';
/** MdExpansionPanel's states. */
export type MdExpansionPanelState = 'expanded' | 'collapsed';
/** Time and timing curve for expansion panel animations. */
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
/**
* <md-expansion-panel> component.
*
* This component can be used as a single element to show expandable content, or as one of
* multiple children of an element with the CdkAccordion directive attached.
*
* Please refer to README.md for examples on how to use it.
*/
@Component({
moduleId: module.id,
styleUrls: ['./expansion-panel.css'],
selector: 'md-expansion-panel, mat-expansion-panel',
templateUrl: './expansion-panel.html',
encapsulation: ViewEncapsulation.None,
host: {
'class': 'mat-expansion-panel',
'[class.mat-expanded]': 'expanded',
'[@displayMode]': '_getDisplayMode()',
},
providers: [
{provide: AccordionItem, useExisting: forwardRef(() => MdExpansionPanel)}
],
animations: [
trigger('bodyExpansion', [
state('collapsed', style({height: '0px'})),
state('expanded', style({height: '*'})),
transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)),
]),
trigger('displayMode', [
state('collapsed', style({margin: '0'})),
state('default', style({margin: '16px 0'})),
state('flat', style({margin: '0'})),
transition('flat <=> collapsed, default <=> collapsed, flat <=> default',
animate(EXPANSION_PANEL_ANIMATION_TIMING)),
]),
],
})
export class MdExpansionPanel extends AccordionItem {
/** Whether the toggle indicator should be hidden. */
@Input() hideToggle: boolean = false;
constructor(@Optional() @Host() accordion: MdAccordion,
_uniqueSelectionDispatcher: UniqueSelectionDispatcher) {
super(accordion, _uniqueSelectionDispatcher);
this.accordion = accordion;
}
/** Whether the expansion indicator should be hidden. */
_getHideToggle(): boolean {
if (this.accordion) {
return this.accordion.hideToggle;
}
return this.hideToggle;
}
/** Gets the panel's display mode. */
_getDisplayMode(): MdAccordionDisplayMode | MdExpansionPanelState {
if (!this.expanded) {
return this._getExpandedState();
}
if (this.accordion) {
return this.accordion.displayMode;
}
return this._getExpandedState();
}
/** Gets the expanded state string. */
_getExpandedState(): MdExpansionPanelState {
return this.expanded ? 'expanded' : 'collapsed';
}
}
@Directive({
selector: 'mat-action-row, md-action-row',
host: {
class: 'mat-action-row'
}
})
export class MdExpansionPanelActionRow {}
+73
View File
@@ -0,0 +1,73 @@
import {async, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MdExpansionModule} from './index';
describe('MdExpansionPanel', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
MdExpansionModule
],
declarations: [
PanelWithContent
],
});
TestBed.compileComponents();
}));
it('should expanded and collapse the panel', () => {
let fixture = TestBed.createComponent(PanelWithContent);
let contentEl = fixture.debugElement.query(By.css('.mat-expansion-panel-content'));
let headerEl = fixture.debugElement.query(By.css('.mat-expansion-panel-header'));
fixture.detectChanges();
expect(headerEl.classes['mat-expanded']).toBeFalsy();
expect(contentEl.classes['mat-expanded']).toBeFalsy();
fixture.componentInstance.expanded = true;
fixture.detectChanges();
expect(headerEl.classes['mat-expanded']).toBeTruthy();
expect(contentEl.classes['mat-expanded']).toBeTruthy();
});
it('emit correct events for change in panel expanded state', () => {
let fixture = TestBed.createComponent(PanelWithContent);
fixture.componentInstance.expanded = true;
fixture.detectChanges();
expect(fixture.componentInstance.openCallback).toHaveBeenCalled();
fixture.componentInstance.expanded = false;
fixture.detectChanges();
expect(fixture.componentInstance.closeCallback).toHaveBeenCalled();
});
it('creates a unique panel id for each panel', () => {
let fixtureOne = TestBed.createComponent(PanelWithContent);
let headerElOne = fixtureOne.nativeElement.querySelector('.mat-expansion-panel-header');
let fixtureTwo = TestBed.createComponent(PanelWithContent);
let headerElTwo = fixtureTwo.nativeElement.querySelector('.mat-expansion-panel-header');
fixtureOne.detectChanges();
fixtureTwo.detectChanges();
let panelIdOne = headerElOne.getAttribute('aria-controls');
let panelIdTwo = headerElTwo.getAttribute('aria-controls');
expect(panelIdOne).not.toBe(panelIdTwo);
});
});
@Component({template: `
<md-expansion-panel [expanded]="expanded"
(opened)="openCallback()"
(closed)="closeCallback()">
<md-expansion-panel-header>Panel Title</md-expansion-panel-header>
<p>Some content</p>
</md-expansion-panel>`})
class PanelWithContent {
expanded: boolean = false;
openCallback = jasmine.createSpy('openCallback');
closeCallback = jasmine.createSpy('closeCallback');
}
+57
View File
@@ -0,0 +1,57 @@
import {NgModule, ModuleWithProviders} from '@angular/core';
import {CommonModule} from '@angular/common';
import {CompatibilityModule, UNIQUE_SELECTION_DISPATCHER_PROVIDER} from '../core';
import {
MdExpansionPanelHeader,
MdExpansionPanelDescription,
MdExpansionPanelTitle
} from './expansion-panel-header';
import {
MdExpansionPanel,
MdExpansionPanelActionRow,
} from './expansion-panel';
import {
CdkAccordion,
MdAccordion,
} from './accordion';
@NgModule({
imports: [CompatibilityModule, CommonModule],
exports: [
CdkAccordion,
MdAccordion,
MdExpansionPanel,
MdExpansionPanelActionRow,
MdExpansionPanelHeader,
MdExpansionPanelTitle,
MdExpansionPanelDescription
],
declarations: [
CdkAccordion,
MdAccordion,
MdExpansionPanel,
MdExpansionPanelActionRow,
MdExpansionPanelHeader,
MdExpansionPanelTitle,
MdExpansionPanelDescription
],
providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER]
})
export class MdExpansionModule {}
export {
CdkAccordion,
MdAccordion,
MdAccordionDisplayMode
} from './accordion';
export {AccordionItem} from './accordion-item';
export {
MdExpansionPanel,
MdExpansionPanelState,
MdExpansionPanelActionRow
} from './expansion-panel';
export {
MdExpansionPanelHeader,
MdExpansionPanelDescription,
MdExpansionPanelTitle
} from './expansion-panel-header';
+2
View File
@@ -37,6 +37,7 @@ import {MdAutocompleteModule} from './autocomplete/index';
import {StyleModule} from './core/style/index';
import {MdDatepickerModule} from './datepicker/index';
import {CdkDataTableModule} from './core/data-table/index';
import {MdExpansionModule} from './expansion/index';
const MATERIAL_MODULES = [
MdAutocompleteModule,
@@ -47,6 +48,7 @@ const MATERIAL_MODULES = [
MdCheckboxModule,
MdDatepickerModule,
MdDialogModule,
MdExpansionModule,
MdGridListModule,
MdIconModule,
MdInputModule,
+1
View File
@@ -16,6 +16,7 @@ export * from './checkbox/index';
export * from './core/data-table/index';
export * from './datepicker/index';
export * from './dialog/index';
export * from './expansion/index';
export * from './grid-list/index';
export * from './icon/index';
export * from './input/index';