UNPKG

@angular/material

Version:
518 lines (503 loc) 19.5 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, Directive, ElementRef, Host, Input, NgModule, Optional, TemplateRef, ViewContainerRef, ViewEncapsulation } from '@angular/core'; import { UNIQUE_SELECTION_DISPATCHER_PROVIDER, UniqueSelectionDispatcher } from '@angular/cdk/collections'; import { CdkAccordion, CdkAccordionItem, CdkAccordionModule } from '@angular/cdk/accordion'; import { A11yModule, FocusMonitor } from '@angular/cdk/a11y'; import { PortalModule, TemplatePortal } from '@angular/cdk/portal'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Subject } from 'rxjs/Subject'; import { take } from 'rxjs/operators/take'; import { filter } from 'rxjs/operators/filter'; import { startWith } from 'rxjs/operators/startWith'; import { animate, state, style, transition, trigger } from '@angular/animations'; import { ENTER, SPACE } from '@angular/cdk/keycodes'; import { merge } from 'rxjs/observable/merge'; import { Subscription } from 'rxjs/Subscription'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Directive for a Material Design Accordion. */ class MatAccordion extends CdkAccordion { constructor() { super(...arguments); this._hideToggle = 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. */ this.displayMode = 'default'; } /** * Whether the expansion indicator should be hidden. * @return {?} */ get hideToggle() { return this._hideToggle; } /** * @param {?} show * @return {?} */ set hideToggle(show) { this._hideToggle = coerceBooleanProperty(show); } } MatAccordion.decorators = [ { type: Directive, args: [{ selector: 'mat-accordion', exportAs: 'matAccordion', host: { class: 'mat-accordion' } },] }, ]; /** @nocollapse */ MatAccordion.ctorParameters = () => []; MatAccordion.propDecorators = { "hideToggle": [{ type: Input },], "displayMode": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Expansion panel content that will be rendered lazily * after the panel is opened for the first time. */ class MatExpansionPanelContent { /** * @param {?} _template */ constructor(_template) { this._template = _template; } } MatExpansionPanelContent.decorators = [ { type: Directive, args: [{ selector: 'ng-template[matExpansionPanelContent]' },] }, ]; /** @nocollapse */ MatExpansionPanelContent.ctorParameters = () => [ { type: TemplateRef, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Time and timing curve for expansion panel animations. */ const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)'; /** * Animations used by the Material expansion panel. */ const matExpansionAnimations = { /** Animation that rotates the indicator arrow. */ indicatorRotate: trigger('indicatorRotate', [ state('collapsed', style({ transform: 'rotate(0deg)' })), state('expanded', style({ transform: 'rotate(180deg)' })), transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)), ]), /** Animation that expands and collapses the panel header height. */ expansionHeaderHeight: trigger('expansionHeight', [ state('collapsed', style({ height: '{{collapsedHeight}}', }), { params: { collapsedHeight: '48px' }, }), state('expanded', style({ height: '{{expandedHeight}}' }), { params: { expandedHeight: '64px' } }), transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)), ]), /** Animation that expands and collapses the panel content. */ bodyExpansion: trigger('bodyExpansion', [ state('collapsed', style({ height: '0px', visibility: 'hidden' })), state('expanded', style({ height: '*', visibility: 'visible' })), transition('expanded <=> collapsed', animate(EXPANSION_PANEL_ANIMATION_TIMING)), ]) }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Counter for generating unique element ids. */ let uniqueId = 0; /** * `<mat-expansion-panel>` * * This component can be used as a single element to show expandable content, or as one of * multiple children of an element with the MdAccordion directive attached. */ class MatExpansionPanel extends CdkAccordionItem { /** * @param {?} accordion * @param {?} _changeDetectorRef * @param {?} _uniqueSelectionDispatcher * @param {?} _viewContainerRef */ constructor(accordion, _changeDetectorRef, _uniqueSelectionDispatcher, _viewContainerRef) { super(accordion, _changeDetectorRef, _uniqueSelectionDispatcher); this._viewContainerRef = _viewContainerRef; this._hideToggle = false; /** * Stream that emits for changes in `\@Input` properties. */ this._inputChanges = new Subject(); /** * ID for the associated header element. Used for a11y labelling. */ this._headerId = `mat-expansion-panel-header-${uniqueId++}`; this.accordion = accordion; } /** * Whether the toggle indicator should be hidden. * @return {?} */ get hideToggle() { return this._hideToggle; } /** * @param {?} value * @return {?} */ set hideToggle(value) { this._hideToggle = coerceBooleanProperty(value); } /** * Whether the expansion indicator should be hidden. * @return {?} */ _getHideToggle() { if (this.accordion) { return this.accordion.hideToggle; } return this.hideToggle; } /** * Determines whether the expansion panel should have spacing between it and its siblings. * @return {?} */ _hasSpacing() { if (this.accordion) { return (this.expanded ? this.accordion.displayMode : this._getExpandedState()) === 'default'; } return false; } /** * Gets the expanded state string. * @return {?} */ _getExpandedState() { return this.expanded ? 'expanded' : 'collapsed'; } /** * @return {?} */ ngAfterContentInit() { if (this._lazyContent) { // Render the content as soon as the panel becomes open. this.opened.pipe(startWith(/** @type {?} */ ((null))), filter(() => this.expanded && !this._portal), take(1)).subscribe(() => { this._portal = new TemplatePortal(this._lazyContent._template, this._viewContainerRef); }); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { this._inputChanges.next(changes); } /** * @return {?} */ ngOnDestroy() { super.ngOnDestroy(); this._inputChanges.complete(); } /** * @param {?} event * @return {?} */ _bodyAnimation(event) { const /** @type {?} */ classList = event.element.classList; const /** @type {?} */ cssClass = 'mat-expanded'; const { phaseName, toState } = 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') { classList.remove(cssClass); } } } MatExpansionPanel.decorators = [ { type: Component, args: [{styles: [".mat-expansion-panel{transition:box-shadow 280ms cubic-bezier(.4,0,.2,1);box-sizing:content-box;display:block;margin:0;transition:margin 225ms cubic-bezier(.4,0,.2,1)}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-expansion-panel-content{overflow:hidden}.mat-expansion-panel-content.mat-expanded{overflow:visible}.mat-expansion-panel-body{padding:0 24px 16px}.mat-expansion-panel-spacing{margin:16px 0}.mat-accordion .mat-expansion-panel-spacing:first-child{margin-top:0}.mat-accordion .mat-expansion-panel-spacing:last-child{margin-bottom:0}.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}.mat-action-row button.mat-button{margin-left:8px}[dir=rtl] .mat-action-row button.mat-button{margin-left:0;margin-right:8px}"], selector: 'mat-expansion-panel', exportAs: 'matExpansionPanel', template: "<ng-content select=\"mat-expansion-panel-header\"></ng-content><div class=\"mat-expansion-panel-content\" role=\"region\" [@bodyExpansion]=\"_getExpandedState()\" (@bodyExpansion.done)=\"_bodyAnimation($event)\" (@bodyExpansion.start)=\"_bodyAnimation($event)\" [class.mat-expanded]=\"expanded\" [attr.aria-labelledby]=\"_headerId\" [id]=\"id\" #body><div class=\"mat-expansion-panel-body\"><ng-content></ng-content><ng-template [cdkPortalOutlet]=\"_portal\"></ng-template></div><ng-content select=\"mat-action-row\"></ng-content></div>", encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, inputs: ['disabled', 'expanded'], outputs: ['opened', 'closed', 'expandedChange'], animations: [matExpansionAnimations.bodyExpansion], host: { 'class': 'mat-expansion-panel', '[class.mat-expanded]': 'expanded', '[class.mat-expansion-panel-spacing]': '_hasSpacing()', } },] }, ]; /** @nocollapse */ MatExpansionPanel.ctorParameters = () => [ { type: MatAccordion, decorators: [{ type: Optional }, { type: Host },] }, { type: ChangeDetectorRef, }, { type: UniqueSelectionDispatcher, }, { type: ViewContainerRef, }, ]; MatExpansionPanel.propDecorators = { "hideToggle": [{ type: Input },], "_lazyContent": [{ type: ContentChild, args: [MatExpansionPanelContent,] },], }; class MatExpansionPanelActionRow { } MatExpansionPanelActionRow.decorators = [ { type: Directive, args: [{ selector: 'mat-action-row', host: { class: 'mat-action-row' } },] }, ]; /** @nocollapse */ MatExpansionPanelActionRow.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * `<mat-expansion-panel-header>` * * This component corresponds to the header element of an `<mat-expansion-panel>`. */ class MatExpansionPanelHeader { /** * @param {?} panel * @param {?} _element * @param {?} _focusMonitor * @param {?} _changeDetectorRef */ constructor(panel, _element, _focusMonitor, _changeDetectorRef) { this.panel = panel; this._element = _element; this._focusMonitor = _focusMonitor; this._changeDetectorRef = _changeDetectorRef; this._parentChangeSubscription = Subscription.EMPTY; // Since the toggle state depends on an @Input on the panel, we // need to subscribe and trigger change detection manually. this._parentChangeSubscription = merge(panel.opened, panel.closed, panel._inputChanges.pipe(filter(changes => !!(changes["hideToggle"] || changes["disabled"])))) .subscribe(() => this._changeDetectorRef.markForCheck()); _focusMonitor.monitor(_element.nativeElement); } /** * Toggles the expanded state of the panel. * @return {?} */ _toggle() { this.panel.toggle(); } /** * Gets whether the panel is expanded. * @return {?} */ _isExpanded() { return this.panel.expanded; } /** * Gets the expanded state string of the panel. * @return {?} */ _getExpandedState() { return this.panel._getExpandedState(); } /** * Gets the panel id. * @return {?} */ _getPanelId() { return this.panel.id; } /** * Gets whether the expand indicator should be shown. * @return {?} */ _showToggle() { return !this.panel.hideToggle && !this.panel.disabled; } /** * Handle keydown event calling to toggle() if appropriate. * @param {?} event * @return {?} */ _keydown(event) { switch (event.keyCode) { // Toggle for space and enter keys. case SPACE: case ENTER: event.preventDefault(); this._toggle(); break; default: return; } } /** * @return {?} */ ngOnDestroy() { this._parentChangeSubscription.unsubscribe(); this._focusMonitor.stopMonitoring(this._element.nativeElement); } } MatExpansionPanelHeader.decorators = [ { type: Component, args: [{selector: 'mat-expansion-panel-header', styles: [".mat-expansion-panel-header{display:flex;flex-direction:row;align-items:center;padding:0 24px}.mat-expansion-panel-header:focus,.mat-expansion-panel-header:hover{outline:0}.mat-expansion-panel-header.mat-expanded:focus,.mat-expansion-panel-header.mat-expanded:hover{background:inherit}.mat-expansion-panel-header:not([aria-disabled=true]){cursor:pointer}.mat-content{display:flex;flex:1;flex-direction:row;overflow:hidden}.mat-expansion-panel-header-description,.mat-expansion-panel-header-title{display:flex;flex-grow:1;margin-right:16px}[dir=rtl] .mat-expansion-panel-header-description,[dir=rtl] .mat-expansion-panel-header-title{margin-right:0;margin-left:16px}.mat-expansion-panel-header-description{flex-grow:2}.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}"], template: "<span class=\"mat-content\"><ng-content select=\"mat-panel-title\"></ng-content><ng-content select=\"mat-panel-description\"></ng-content><ng-content></ng-content></span><span [@indicatorRotate]=\"_getExpandedState()\" *ngIf=\"_showToggle()\" class=\"mat-expansion-indicator\"></span>", encapsulation: ViewEncapsulation.None, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, animations: [ matExpansionAnimations.indicatorRotate, matExpansionAnimations.expansionHeaderHeight ], host: { 'class': 'mat-expansion-panel-header', 'role': 'button', '[attr.id]': 'panel._headerId', '[attr.tabindex]': 'panel.disabled ? -1 : 0', '[attr.aria-controls]': '_getPanelId()', '[attr.aria-expanded]': '_isExpanded()', '[attr.aria-disabled]': 'panel.disabled', '[class.mat-expanded]': '_isExpanded()', '(click)': '_toggle()', '(keydown)': '_keydown($event)', '[@expansionHeight]': `{ value: _getExpandedState(), params: { collapsedHeight: collapsedHeight, expandedHeight: expandedHeight } }`, }, },] }, ]; /** @nocollapse */ MatExpansionPanelHeader.ctorParameters = () => [ { type: MatExpansionPanel, decorators: [{ type: Host },] }, { type: ElementRef, }, { type: FocusMonitor, }, { type: ChangeDetectorRef, }, ]; MatExpansionPanelHeader.propDecorators = { "expandedHeight": [{ type: Input },], "collapsedHeight": [{ type: Input },], }; /** * `<mat-panel-description>` * * This direction is to be used inside of the MatExpansionPanelHeader component. */ class MatExpansionPanelDescription { } MatExpansionPanelDescription.decorators = [ { type: Directive, args: [{ selector: 'mat-panel-description', host: { class: 'mat-expansion-panel-header-description' } },] }, ]; /** @nocollapse */ MatExpansionPanelDescription.ctorParameters = () => []; /** * `<mat-panel-title>` * * This direction is to be used inside of the MatExpansionPanelHeader component. */ class MatExpansionPanelTitle { } MatExpansionPanelTitle.decorators = [ { type: Directive, args: [{ selector: 'mat-panel-title', host: { class: 'mat-expansion-panel-header-title' } },] }, ]; /** @nocollapse */ MatExpansionPanelTitle.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class MatExpansionModule { } MatExpansionModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule, A11yModule, CdkAccordionModule, PortalModule], exports: [ MatAccordion, MatExpansionPanel, MatExpansionPanelActionRow, MatExpansionPanelHeader, MatExpansionPanelTitle, MatExpansionPanelDescription, MatExpansionPanelContent, ], declarations: [ MatAccordion, MatExpansionPanel, MatExpansionPanelActionRow, MatExpansionPanelHeader, MatExpansionPanelTitle, MatExpansionPanelDescription, MatExpansionPanelContent, ], providers: [UNIQUE_SELECTION_DISPATCHER_PROVIDER] },] }, ]; /** @nocollapse */ MatExpansionModule.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Generated bundle index. Do not edit. */ export { MatExpansionModule, MatAccordion, MatExpansionPanel, MatExpansionPanelActionRow, MatExpansionPanelHeader, MatExpansionPanelDescription, MatExpansionPanelTitle, MatExpansionPanelContent, EXPANSION_PANEL_ANIMATION_TIMING, matExpansionAnimations }; //# sourceMappingURL=expansion.js.map