@angular-mdc/web
Version:
1,147 lines (1,141 loc) • 36.5 kB
JavaScript
/**
* @license
* Copyright (c) Dominic Carretto
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE
*/
import { Directive, ElementRef, Input, InjectionToken, EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, Optional, Self, Inject, Output, ViewChild, ContentChild, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MdcFloatingLabel, MdcFloatingLabelModule } from '@angular-mdc/web/floating-label';
import { MdcLineRipple, MdcLineRippleModule } from '@angular-mdc/web/line-ripple';
import { MdcNotchedOutline, MdcNotchedOutlineModule } from '@angular-mdc/web/notched-outline';
import { mixinErrorState, MdcFormFieldControl, ErrorStateMatcher, MdcFormField, MdcFormFieldModule } from '@angular-mdc/web/form-field';
import { MdcMenu, MdcMenuModule } from '@angular-mdc/web/menu';
import { MdcListModule } from '@angular-mdc/web/list';
import { __awaiter } from 'tslib';
import { NgControl, NgForm, FormGroupDirective } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Platform } from '@angular/cdk/platform';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { MDCComponent } from '@angular-mdc/web/base';
import { MdcRipple } from '@angular-mdc/web/ripple';
import { MDCRippleFoundation } from '@material/ripple';
import { MDCSelectFoundation, strings, MDCSelectHelperTextFoundation } from '@material/select';
/**
* @fileoverview added by tsickle
* Generated from: select/select-directives.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MdcSelectIcon {
}
MdcSelectIcon.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectIcon]',
exportAs: 'mdcSelectIcon',
host: { 'class': 'mdc-select__icon' }
},] },
];
class MdcSelectAnchor {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
this.elementRef = elementRef;
}
/**
* @return {?}
*/
get root() {
return this.elementRef.nativeElement;
}
}
MdcSelectAnchor.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectAnchor]',
exportAs: 'mdcSelectAnchor',
host: { 'class': 'mdc-select__anchor' }
},] },
];
/** @nocollapse */
MdcSelectAnchor.ctorParameters = () => [
{ type: ElementRef }
];
class MdcSelectedText {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
this.elementRef = elementRef;
}
/**
* @return {?}
*/
get root() {
return this.elementRef.nativeElement;
}
}
MdcSelectedText.decorators = [
{ type: Directive, args: [{
selector: '[mdcSelectedText]',
exportAs: 'mdcSelectedText',
host: {
'class': 'mdc-select__selected-text',
'role': 'button',
'aria-haspopup': 'listbox',
'[attr.aria-labelledby]': 'ariaLabelledby',
'[attr.aria-required]': 'ariaRequired'
}
},] },
];
/** @nocollapse */
MdcSelectedText.ctorParameters = () => [
{ type: ElementRef }
];
MdcSelectedText.propDecorators = {
ariaLabelledby: [{ type: Input }],
ariaRequired: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* Generated from: select/select.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Injection token that can be used to configure the default options for all
* mdc-select usage within an app.
* @type {?}
*/
const MDC_SELECT_DEFAULT_OPTIONS = new InjectionToken('MDC_SELECT_DEFAULT_OPTIONS');
class MdcSelectBase extends MDCComponent {
/**
* @param {?} _elementRef
* @param {?} _defaultErrorStateMatcher
* @param {?} _parentForm
* @param {?} _parentFormGroup
* @param {?} ngControl
*/
constructor(_elementRef, _defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl) {
super(_elementRef);
this._elementRef = _elementRef;
this._defaultErrorStateMatcher = _defaultErrorStateMatcher;
this._parentForm = _parentForm;
this._parentFormGroup = _parentFormGroup;
this.ngControl = ngControl;
}
}
/** @type {?} */
const _MdcSelectMixinBase = mixinErrorState(MdcSelectBase);
class MdcSelectChange {
/**
* @param {?} source
* @param {?} index
* @param {?} value
*/
constructor(source, index, value) {
this.source = source;
this.index = index;
this.value = value;
}
}
/** @type {?} */
let nextUniqueId = 0;
class MdcSelect extends _MdcSelectMixinBase {
/**
* @param {?} _platform
* @param {?} _changeDetectorRef
* @param {?} elementRef
* @param {?} _defaultErrorStateMatcher
* @param {?} _parentFormField
* @param {?} _ripple
* @param {?} ngControl
* @param {?} _parentForm
* @param {?} _parentFormGroup
* @param {?=} _defaults
*/
constructor(_platform, _changeDetectorRef, elementRef, _defaultErrorStateMatcher, _parentFormField, _ripple, ngControl, _parentForm, _parentFormGroup, _defaults) {
super(elementRef, _defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl);
this._platform = _platform;
this._changeDetectorRef = _changeDetectorRef;
this.elementRef = elementRef;
this._defaultErrorStateMatcher = _defaultErrorStateMatcher;
this._parentFormField = _parentFormField;
this._ripple = _ripple;
this.ngControl = ngControl;
this._defaults = _defaults;
/**
* Emits whenever the component is destroyed.
*/
this._destroyed = new Subject();
this._uniqueId = `mdc-select-${++nextUniqueId}`;
this._initialized = false;
this.id = this._uniqueId;
this._disabled = false;
this._floatLabel = true;
this._outlined = false;
this._required = false;
this.compareWith = (/**
* @param {?} a1
* @param {?} a2
* @return {?}
*/
(a1, a2) => a1 === a2);
/**
* Event emitted when the selected value has been changed by the user.
*/
this.selectionChange = new EventEmitter();
/**
* Event that emits whenever the raw value of the select changes. This is here primarily
* to facilitate the two-way binding for the `value` input.
*/
this.valueChange = new EventEmitter();
this.blur = new EventEmitter();
this._onFocus = new EventEmitter();
/**
* View to model callback called when value changes
*/
this._onChange = (/**
* @return {?}
*/
() => { });
/**
* View to model callback called when select has been touched
*/
this._onTouched = (/**
* @return {?}
*/
() => { });
this._root = this.elementRef.nativeElement;
if (this.ngControl) {
// Note: we provide the value accessor through here, instead of
// the `providers` to avoid running into a circular import.
this.ngControl.valueAccessor = this;
}
if (this._parentFormField) {
_parentFormField.elementRef.nativeElement.classList.add('ngx-form-field-select');
}
// Force setter to be called in case id was not specified.
this.id = this.id;
this._setDefaultGlobalOptions();
}
/**
* @return {?}
*/
get disabled() {
return this._disabled;
}
/**
* @param {?} value
* @return {?}
*/
set disabled(value) {
this.setDisabledState(value);
}
/**
* @return {?}
*/
get floatLabel() {
return this._floatLabel;
}
/**
* @param {?} value
* @return {?}
*/
set floatLabel(value) {
/** @type {?} */
const newValue = coerceBooleanProperty(value);
if (newValue !== this._floatLabel) {
this._floatLabel = newValue;
this.layout();
}
}
/**
* @return {?}
*/
get outlined() {
return this._outlined;
}
/**
* @param {?} value
* @return {?}
*/
set outlined(value) {
/** @type {?} */
const newValue = coerceBooleanProperty(value);
this._outlined = newValue;
this.layout();
}
/**
* @return {?}
*/
get required() {
return this._required;
}
/**
* @param {?} value
* @return {?}
*/
set required(value) {
/** @type {?} */
const newValue = coerceBooleanProperty(value);
if (newValue !== this._required) {
this._required = newValue;
if (this._initialized && !this._required) {
this.valid = true;
this._changeDetectorRef.markForCheck();
}
}
}
/**
* @return {?}
*/
get valid() {
return this._valid;
}
/**
* @param {?} value
* @return {?}
*/
set valid(value) {
var _a;
/** @type {?} */
const newValue = coerceBooleanProperty(value);
this._valid = newValue;
(_a = this._foundation) === null || _a === void 0 ? void 0 : _a.setValid(this._valid);
}
/**
* Value of the select
* @return {?}
*/
get value() {
return this._value;
}
/**
* @param {?} newValue
* @return {?}
*/
set value(newValue) {
if (newValue !== this._value) {
this.setSelectionByValue(newValue);
}
}
/**
* @return {?}
*/
get helperText() {
return this._helperText;
}
/**
* @param {?} helperText
* @return {?}
*/
set helperText(helperText) {
var _a;
this._helperText = helperText;
(_a = this.helperText) === null || _a === void 0 ? void 0 : _a.init();
}
/**
* @return {?}
*/
get _hasPlaceholder() {
return this.placeholder ? this.placeholder.length > 0 : false;
}
/**
* @return {?}
*/
getDefaultFoundation() {
// Do not initialize foundation until ngAfterViewInit runs
if (!this._initialized) {
return undefined;
}
/** @type {?} */
const adapter = Object.assign(Object.assign(Object.assign(Object.assign({}, this._getSelectAdapterMethods()), this._getCommonAdapterMethods()), this._getOutlineAdapterMethods()), this._getLabelAdapterMethods());
return new MDCSelectFoundation(adapter, this._getFoundationMap());
}
/**
* @private
* @return {?}
*/
_getSelectAdapterMethods() {
return {
getSelectedMenuItem: (/**
* @return {?}
*/
() => (/** @type {?} */ (this._menu)).elementRef.nativeElement.querySelector(strings.SELECTED_ITEM_SELECTOR)),
getMenuItemAttr: (/**
* @param {?} menuItem
* @param {?} attr
* @return {?}
*/
(menuItem, attr) => menuItem.getAttribute(attr)),
setSelectedText: (/**
* @param {?} text
* @return {?}
*/
(text) => this._selectedText.root.textContent = text),
isSelectedTextFocused: (/**
* @return {?}
*/
() => this._platform.isBrowser ?
document.activeElement === this._selectedText.root : false),
getSelectedTextAttr: (/**
* @param {?} attr
* @return {?}
*/
(attr) => this._selectedText.root.getAttribute(attr)),
setSelectedTextAttr: (/**
* @param {?} attr
* @param {?} value
* @return {?}
*/
(attr, value) => this._selectedText.root.setAttribute(attr, value)),
openMenu: (/**
* @return {?}
*/
() => this._menu.open = true),
closeMenu: (/**
* @return {?}
*/
() => this._menu.open = false),
getAnchorElement: (/**
* @return {?}
*/
() => this._selectAnchor.root),
setMenuAnchorElement: (/**
* @param {?} anchorEl
* @return {?}
*/
(anchorEl) => this._menu.anchorElement = anchorEl),
setMenuAnchorCorner: (/**
* @param {?} anchorCorner
* @return {?}
*/
(anchorCorner) => this._menu.anchorCorner = anchorCorner),
setMenuWrapFocus: (/**
* @param {?} wrapFocus
* @return {?}
*/
(wrapFocus) => this._menu.wrapFocus = wrapFocus),
setAttributeAtIndex: (/**
* @param {?} index
* @param {?} attributeName
* @param {?} attributeValue
* @return {?}
*/
(index, attributeName, attributeValue) => (/** @type {?} */ (this._menu._list)).items.toArray()[index].getListItemElement().setAttribute(attributeName, attributeValue)),
removeAttributeAtIndex: (/**
* @param {?} index
* @param {?} attributeName
* @return {?}
*/
(index, attributeName) => (/** @type {?} */ (this._menu._list)).items.toArray()[index].getListItemElement().removeAttribute(attributeName)),
focusMenuItemAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => (/** @type {?} */ (this._menu._list)).items.toArray()[index].focus()),
getMenuItemCount: (/**
* @return {?}
*/
() => (/** @type {?} */ (this._menu._list)).items.length),
getMenuItemValues: (/**
* @return {?}
*/
() => { var _a; return _a = (/** @type {?} */ (this._menu._list)).items.map((/**
* @param {?} el
* @return {?}
*/
el => el.getListItemElement().getAttribute(strings.VALUE_ATTR) || '')), (_a !== null && _a !== void 0 ? _a : []); }),
getMenuItemTextAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => { var _a; return _a = (/** @type {?} */ (this._menu._list)).items.toArray()[index].getListItemElement().textContent, (_a !== null && _a !== void 0 ? _a : ''); }),
addClassAtIndex: (/**
* @param {?} index
* @param {?} className
* @return {?}
*/
(index, className) => (/** @type {?} */ (this._menu._list)).items.toArray()[index].getListItemElement().classList.add(className)),
removeClassAtIndex: (/**
* @param {?} index
* @param {?} className
* @return {?}
*/
(index, className) => (/** @type {?} */ (this._menu._list)).items.toArray()[index].getListItemElement().classList.remove(className))
};
}
/**
* @private
* @return {?}
*/
_getCommonAdapterMethods() {
return {
addClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this._root.classList.add(className)),
removeClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this._root.classList.remove(className)),
hasClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this._root.classList.contains(className)),
setRippleCenter: (/**
* @param {?} normalizedX
* @return {?}
*/
(normalizedX) => { var _a; return (_a = this._lineRipple) === null || _a === void 0 ? void 0 : _a.setRippleCenter(normalizedX); }),
activateBottomLine: (/**
* @return {?}
*/
() => { var _a; return (_a = this._lineRipple) === null || _a === void 0 ? void 0 : _a.activate(); }),
deactivateBottomLine: (/**
* @return {?}
*/
() => { var _a; return (_a = this._lineRipple) === null || _a === void 0 ? void 0 : _a.deactivate(); }),
notifyChange: (/**
* @return {?}
*/
() => { })
};
}
/**
* @private
* @return {?}
*/
_getOutlineAdapterMethods() {
return {
hasOutline: (/**
* @return {?}
*/
() => !!this._notchedOutline),
notchOutline: (/**
* @param {?} labelWidth
* @return {?}
*/
(labelWidth) => { var _a; return (_a = this._notchedOutline) === null || _a === void 0 ? void 0 : _a.notch(labelWidth); }),
closeOutline: (/**
* @return {?}
*/
() => { var _a; return (_a = this._notchedOutline) === null || _a === void 0 ? void 0 : _a.closeNotch(); })
};
}
/**
* @private
* @return {?}
*/
_getLabelAdapterMethods() {
return {
hasLabel: (/**
* @return {?}
*/
() => this._hasPlaceholder),
floatLabel: (/**
* @param {?} shouldFloat
* @return {?}
*/
(shouldFloat) => this._getFloatingLabel().float(shouldFloat)),
getLabelWidth: (/**
* @return {?}
*/
() => { var _a; return (_a = this._getFloatingLabel()) === null || _a === void 0 ? void 0 : _a.getWidth(); })
};
}
/**
* Returns a map of all subcomponents to subfoundations.
* @private
* @return {?}
*/
_getFoundationMap() {
var _a;
return {
helperText: (_a = this._helperText) === null || _a === void 0 ? void 0 : _a.foundation
};
}
/**
* @return {?}
*/
ngAfterViewInit() {
this._initialized = true;
this._asyncBuildFoundation()
.then((/**
* @return {?}
*/
() => {
this._selectBuilder();
}));
this._initializeSelection();
this._subscribeToMenuEvents();
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy();
}
/**
* Override MdcSelectBase destroy method
* @return {?}
*/
destroy() {
var _a;
this._destroyed.next();
this._destroyed.complete();
(_a = this._lineRipple) === null || _a === void 0 ? void 0 : _a.destroy();
this._ripple.destroy();
this._foundation.destroy();
}
/**
* @return {?}
*/
ngDoCheck() {
if (this.ngControl) {
// We need to re-evaluate this on every change detection cycle, because there are some
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
// that whatever logic is in here has to be super lean or we risk destroying the performance.
this.updateErrorState();
}
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
if (this._initialized) {
this.setSelectionByValue(value, false);
}
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this._onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this._onTouched = fn;
}
/**
* @return {?}
*/
onFocus() {
if (!this.disabled) {
this._foundation.handleFocus();
this._onFocus.emit(true);
}
}
/**
* @return {?}
*/
onBlur() {
this._foundation.handleBlur();
}
/**
* @param {?} evt
* @return {?}
*/
onClick(evt) {
this._foundation.handleClick(this._getNormalizedXCoordinate(evt));
}
/**
* @param {?} evt
* @return {?}
*/
onKeydown(evt) {
this._foundation.handleKeydown(evt);
}
/**
* @return {?}
*/
getSelectedIndex() {
var _a, _b;
return _b = (_a = this._foundation) === null || _a === void 0 ? void 0 : _a.getSelectedIndex(), (_b !== null && _b !== void 0 ? _b : -1);
}
/**
* @return {?}
*/
focus() {
this._selectedText.root.focus();
}
/**
* @param {?} index
* @return {?}
*/
setSelectedIndex(index) {
var _a, _b;
this.setSelectionByValue((_b = (_a = this._menu._list) === null || _a === void 0 ? void 0 : _a.getListItemByIndex(index)) === null || _b === void 0 ? void 0 : _b.value, true, index);
}
/**
* @param {?} value
* @param {?=} isUserInput
* @param {?=} index
* @return {?}
*/
setSelectionByValue(value, isUserInput = true, index) {
var _a;
if (!this._value && !value) {
return;
}
if (!index) {
index = (_a = this._menu._list) === null || _a === void 0 ? void 0 : _a.getListItemIndexByValue(value);
}
this._value = value;
this._foundation.setSelectedIndex((index !== null && index !== void 0 ? index : -1), this._menu.closeSurfaceOnSelection);
if (isUserInput) {
this._onChange(this._value);
this.selectionChange.emit(new MdcSelectChange(this, this.getSelectedIndex(), value));
}
this.valueChange.emit({
index: this.getSelectedIndex(),
value: this._value
});
this._foundation.handleChange();
this._changeDetectorRef.markForCheck();
}
// Implemented as part of ControlValueAccessor.
/**
* @param {?} disabled
* @return {?}
*/
setDisabledState(disabled) {
var _a;
this._disabled = coerceBooleanProperty(disabled);
(_a = this._foundation) === null || _a === void 0 ? void 0 : _a.setDisabled(this._disabled);
this._changeDetectorRef.markForCheck();
}
/**
* @return {?}
*/
get _hasValue() {
var _a;
return ((_a = this._value) === null || _a === void 0 ? void 0 : _a.length) > 0;
}
/**
* Initialize Select internal state based on the environment state
* @private
* @return {?}
*/
layout() {
if (this._initialized) {
this._asyncBuildFoundation().then((/**
* @return {?}
*/
() => {
this._selectBuilder();
this._foundation.layout();
}));
}
}
/**
* @private
* @return {?}
*/
_initializeSelection() {
// Defer setting the value in order to avoid the "Expression
// has changed after it was checked" errors from Angular.
Promise.resolve().then((/**
* @return {?}
*/
() => {
var _a, _b;
/** @type {?} */
const value = (_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.value, (_b !== null && _b !== void 0 ? _b : this._value));
if (value) {
this.setSelectionByValue(value, false);
}
}));
}
/**
* Set the default options.
* @private
* @return {?}
*/
_setDefaultGlobalOptions() {
if (this._defaults) {
if (this._defaults.outlined != null) {
this.outlined = this._defaults.outlined;
}
}
}
/**
* @return {?}
*/
_asyncBuildFoundation() {
return __awaiter(this, void 0, void 0, function* () {
this._foundation = this.getDefaultFoundation();
});
}
/**
* @return {?}
*/
_asyncInitFoundation() {
return __awaiter(this, void 0, void 0, function* () {
this._foundation.init();
});
}
/**
* @private
* @return {?}
*/
_selectBuilder() {
this._changeDetectorRef.detectChanges();
// initialize after running a detectChanges()
this._asyncInitFoundation()
.then((/**
* @return {?}
*/
() => {
if (!this.outlined) {
this._ripple = this._createRipple();
this._ripple.init();
}
this._menu.wrapFocus = false;
this._menu.elementRef.nativeElement.setAttribute('role', 'listbox');
this._menu.elementRef.nativeElement.classList.add('mdc-select__menu');
if (this._menu._list) {
this._menu._list.useSelectedClass = true;
this._menu._list.singleSelection = true;
}
}));
}
/**
* @private
* @return {?}
*/
_subscribeToMenuEvents() {
// When the list items change, re-subscribe
(/** @type {?} */ (this._menu._list)).items.changes.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @return {?}
*/
() => this._initializeSelection()));
// Subscribe to menu opened event
this._menu.opened.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @return {?}
*/
() => this._foundation.handleMenuOpened()));
// Subscribe to menu closed event
this._menu.closed.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @return {?}
*/
() => {
this._foundation.handleMenuClosed();
this._blur();
}));
// Subscribe to list-item action event
this._menu.selected.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @param {?} evt
* @return {?}
*/
(evt) => this.setSelectedIndex(evt.index)));
}
/**
* @private
* @return {?}
*/
_blur() {
this._onTouched();
this.blur.emit(this.value);
this._onFocus.emit(false);
}
/**
* @private
* @return {?}
*/
_getFloatingLabel() {
var _a;
return _a = this._floatingLabel, (_a !== null && _a !== void 0 ? _a : (/** @type {?} */ (this._notchedOutline)).floatingLabel);
}
/**
* Calculates where the line ripple should start based on the x coordinate within the component.
* @private
* @param {?} evt
* @return {?}
*/
_getNormalizedXCoordinate(evt) {
/** @type {?} */
const targetClientRect = ((/** @type {?} */ (evt.target))).getBoundingClientRect();
if (evt instanceof MouseEvent) {
return evt.clientX - targetClientRect.left;
}
/** @type {?} */
const clientX = evt.touches[0] && evt.touches[0].clientX;
return clientX - targetClientRect.left;
}
/**
* @private
* @return {?}
*/
_createRipple() {
/** @type {?} */
const adapter = Object.assign(Object.assign({}, MdcRipple.createAdapter({ _root: this._selectAnchor.root })), { registerInteractionHandler: (/**
* @param {?} evtType
* @param {?} handler
* @return {?}
*/
(evtType, handler) => this._selectedText.root.addEventListener(evtType, handler)), deregisterInteractionHandler: (/**
* @param {?} evtType
* @param {?} handler
* @return {?}
*/
(evtType, handler) => this._selectedText.root.removeEventListener(evtType, handler)) });
return new MdcRipple(this._selectAnchor.elementRef, new MDCRippleFoundation(adapter));
}
}
MdcSelect.decorators = [
{ type: Component, args: [{selector: 'mdc-select',
exportAs: 'mdcSelect',
host: {
'[id]': 'id',
'class': 'mdc-select',
'[class.mdc-select--disabled]': 'disabled',
'[class.mdc-select--outlined]': 'outlined',
'[class.mdc-select--required]': 'required',
'[class.mdc-select--no-label]': '!_hasPlaceholder',
'[class.mdc-select--with-leading-icon]': 'leadingIcon',
'[class.mdc-select--invalid]': 'errorState'
},
template: `
<div mdcSelectAnchor>
<ng-content select="mdc-icon"></ng-content>
<i class="mdc-select__dropdown-icon"></i>
<div mdcSelectedText
[tabindex]="disabled ? '-1' : '0'"
(focus)="onFocus()"
(blur)="onBlur()"
(keydown)="onKeydown($event)"
(click)="onClick($event)"
[ariaRequired]="required"
[ariaLabelledby]="id"></div>
<label mdcFloatingLabel *ngIf="!outlined" [for]="id">{{placeholder}}</label>
<mdc-line-ripple *ngIf="!outlined"></mdc-line-ripple>
<mdc-notched-outline *ngIf="outlined" [label]="placeholder" [for]="id"></mdc-notched-outline>
</div>
<ng-content select="mdc-menu"></ng-content>
`,
providers: [
MdcRipple,
{ provide: MdcFormFieldControl, useExisting: MdcSelect }
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
},] },
];
/** @nocollapse */
MdcSelect.ctorParameters = () => [
{ type: Platform },
{ type: ChangeDetectorRef },
{ type: ElementRef },
{ type: ErrorStateMatcher },
{ type: MdcFormField, decorators: [{ type: Optional }] },
{ type: MdcRipple, decorators: [{ type: Optional }] },
{ type: NgControl, decorators: [{ type: Self }, { type: Optional }] },
{ type: NgForm, decorators: [{ type: Optional }] },
{ type: FormGroupDirective, decorators: [{ type: Optional }] },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MDC_SELECT_DEFAULT_OPTIONS,] }] }
];
MdcSelect.propDecorators = {
id: [{ type: Input }],
name: [{ type: Input }],
placeholder: [{ type: Input }],
disabled: [{ type: Input }],
floatLabel: [{ type: Input }],
outlined: [{ type: Input }],
required: [{ type: Input }],
valid: [{ type: Input }],
compareWith: [{ type: Input }],
value: [{ type: Input }],
helperText: [{ type: Input }],
errorStateMatcher: [{ type: Input }],
selectionChange: [{ type: Output }],
valueChange: [{ type: Output }],
blur: [{ type: Output }],
_onFocus: [{ type: Output, args: ['focus',] }],
_floatingLabel: [{ type: ViewChild, args: [MdcFloatingLabel, { static: false },] }],
_lineRipple: [{ type: ViewChild, args: [MdcLineRipple, { static: false },] }],
_notchedOutline: [{ type: ViewChild, args: [MdcNotchedOutline, { static: false },] }],
_selectAnchor: [{ type: ViewChild, args: [MdcSelectAnchor, { static: false },] }],
_selectedText: [{ type: ViewChild, args: [MdcSelectedText, { static: false },] }],
_menu: [{ type: ContentChild, args: [MdcMenu, { static: false },] }],
leadingIcon: [{ type: ContentChild, args: [MdcSelectIcon, { static: false },] }]
};
/**
* @fileoverview added by tsickle
* Generated from: select/select-helper-text.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MDCSelectHelperText extends MDCComponent {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
super(elementRef);
this.elementRef = elementRef;
this._persistent = false;
this._validation = false;
}
/**
* @return {?}
*/
get persistent() {
return this._persistent;
}
/**
* @param {?} value
* @return {?}
*/
set persistent(value) {
this._persistent = coerceBooleanProperty(value);
this._foundation.setPersistent(this._persistent);
}
/**
* @return {?}
*/
get validation() {
return this._validation;
}
/**
* @param {?} value
* @return {?}
*/
set validation(value) {
this._validation = coerceBooleanProperty(value);
this._foundation.setValidation(this._validation);
}
/**
* @return {?}
*/
get foundation() {
return this._foundation;
}
/**
* @return {?}
*/
getDefaultFoundation() {
/** @type {?} */
const adapter = {
addClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this.elementRef.nativeElement.classList.add(className)),
removeClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this.elementRef.nativeElement.classList.remove(className)),
hasClass: (/**
* @param {?} className
* @return {?}
*/
(className) => this.elementRef.nativeElement.classList.contains(className)),
setAttr: (/**
* @param {?} attr
* @param {?} value
* @return {?}
*/
(attr, value) => this.elementRef.nativeElement.setAttribute(attr, value)),
removeAttr: (/**
* @param {?} attr
* @return {?}
*/
(attr) => this.elementRef.nativeElement.removeAttribute(attr)),
setContent: (/**
* @return {?}
*/
() => { })
};
return new MDCSelectHelperTextFoundation(adapter);
}
/**
* Sets the validity of the helper text.
* @param {?} inputIsValid
* @return {?}
*/
setValidity(inputIsValid) {
this._foundation.setValidity(inputIsValid);
}
/**
* Makes the helper text visible to the screen reader.
* @return {?}
*/
showToScreenReader() {
this._foundation.showToScreenReader();
}
/**
* @return {?}
*/
init() {
this._foundation.setPersistent(this.persistent);
this._foundation.setValidation(this.validation);
}
}
MDCSelectHelperText.decorators = [
{ type: Component, args: [{selector: `mdc-select-helper-text, [mdcSelectHelperText]`,
exportAs: 'mdcSelectHelperText',
host: { 'class': 'mdc-select-helper-text' },
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
},] },
];
/** @nocollapse */
MDCSelectHelperText.ctorParameters = () => [
{ type: ElementRef }
];
MDCSelectHelperText.propDecorators = {
id: [{ type: Input }],
persistent: [{ type: Input }],
validation: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* Generated from: select/module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const SELECT_DECLARATIONS = [
MdcSelect,
MdcSelectAnchor,
MDCSelectHelperText,
MdcSelectIcon,
MdcSelectedText
];
class MdcSelectModule {
}
MdcSelectModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
MdcMenuModule,
MdcListModule,
MdcFormFieldModule,
MdcFloatingLabelModule,
MdcNotchedOutlineModule,
MdcLineRippleModule
],
exports: [
MdcMenuModule,
MdcListModule,
MdcFormFieldModule,
SELECT_DECLARATIONS
],
declarations: SELECT_DECLARATIONS
},] },
];
export { MDCSelectHelperText, MDC_SELECT_DEFAULT_OPTIONS, MdcSelect, MdcSelectAnchor, MdcSelectChange, MdcSelectIcon, MdcSelectModule, MdcSelectedText };
//# sourceMappingURL=select.js.map