UNPKG

@angular/material

Version:
886 lines (869 loc) 49 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 { Directive, Input, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, ElementRef, Inject, InjectionToken, NgZone, Optional, ViewChild, ViewEncapsulation, NgModule } from '@angular/core'; import { animate, state, style, transition, trigger } from '@angular/animations'; import { Directionality } from '@angular/cdk/bidi'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { MAT_LABEL_GLOBAL_OPTIONS, mixinColor } from '@angular/material/core'; import { fromEvent, merge, Subject } from 'rxjs'; import { startWith, take, takeUntil } from 'rxjs/operators'; import { Platform } from '@angular/cdk/platform'; import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations'; import { CommonModule } from '@angular/common'; import { ObserversModule } from '@angular/cdk/observers'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextUniqueId = 0; /** * Single error message to be shown underneath the form field. */ class MatError { constructor() { this.id = `mat-error-${nextUniqueId++}`; } } MatError.decorators = [ { type: Directive, args: [{ selector: 'mat-error', host: { 'class': 'mat-error', 'role': 'alert', '[attr.id]': 'id', } },] }, ]; MatError.propDecorators = { id: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Animations used by the MatFormField. * \@docs-private * @type {?} */ const matFormFieldAnimations = { /** * Animation that transitions the form field's error and hint messages. */ transitionMessages: trigger('transitionMessages', [ // TODO(mmalerba): Use angular animations for label animation as well. state('enter', style({ opacity: 1, transform: 'translateY(0%)' })), transition('void => enter', [ style({ opacity: 0, transform: 'translateY(-100%)' }), animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)'), ]), ]) }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * An interface which allows a control to work inside of a `MatFormField`. * @abstract * @template T */ class MatFormFieldControl { } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * \@docs-private * @return {?} */ function getMatFormFieldPlaceholderConflictError() { return Error('Placeholder attribute and child element were both specified.'); } /** * \@docs-private * @param {?} align * @return {?} */ function getMatFormFieldDuplicatedHintError(align) { return Error(`A hint was already declared for 'align="${align}"'.`); } /** * \@docs-private * @return {?} */ function getMatFormFieldMissingControlError() { return Error('mat-form-field must contain a MatFormFieldControl.'); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextUniqueId$1 = 0; /** * Hint text to be shown underneath the form field control. */ class MatHint { constructor() { /** * Whether to align the hint label at the start or end of the line. */ this.align = 'start'; /** * Unique ID for the hint. Used for the aria-describedby on the form field control. */ this.id = `mat-hint-${nextUniqueId$1++}`; } } MatHint.decorators = [ { type: Directive, args: [{ selector: 'mat-hint', host: { 'class': 'mat-hint', '[class.mat-right]': 'align == "end"', '[attr.id]': 'id', // Remove align attribute to prevent it from interfering with layout. '[attr.align]': 'null', } },] }, ]; MatHint.propDecorators = { align: [{ type: Input }], id: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The floating label for a `mat-form-field`. */ class MatLabel { } MatLabel.decorators = [ { type: Directive, args: [{ selector: 'mat-label' },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The placeholder text for an `MatFormField`. * @deprecated Use `<mat-label>` to specify the label and the `placeholder` attribute to specify the * placeholder. * \@breaking-change 8.0.0 */ class MatPlaceholder { } MatPlaceholder.decorators = [ { type: Directive, args: [{ selector: 'mat-placeholder' },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Prefix to be placed in front of the form field. */ class MatPrefix { } MatPrefix.decorators = [ { type: Directive, args: [{ selector: '[matPrefix]', },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Suffix to be placed at the end of the form field. */ class MatSuffix { } MatSuffix.decorators = [ { type: Directive, args: [{ selector: '[matSuffix]', },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextUniqueId$2 = 0; /** @type {?} */ const floatingLabelScale = 0.75; /** @type {?} */ const outlineGapPadding = 5; /** * Boilerplate for applying mixins to MatFormField. * \@docs-private */ class MatFormFieldBase { /** * @param {?} _elementRef */ constructor(_elementRef) { this._elementRef = _elementRef; } } /** * Base class to which we're applying the form field mixins. * \@docs-private * @type {?} */ const _MatFormFieldMixinBase = mixinColor(MatFormFieldBase, 'primary'); /** * Injection token that can be used to configure the * default options for all form field within an app. * @type {?} */ const MAT_FORM_FIELD_DEFAULT_OPTIONS = new InjectionToken('MAT_FORM_FIELD_DEFAULT_OPTIONS'); /** * Container for form controls that applies Material Design styling and behavior. */ class MatFormField extends _MatFormFieldMixinBase { /** * @param {?} _elementRef * @param {?} _changeDetectorRef * @param {?} labelOptions * @param {?} _dir * @param {?} _defaults * @param {?} _platform * @param {?} _ngZone * @param {?} _animationMode */ constructor(_elementRef, _changeDetectorRef, labelOptions, _dir, _defaults, _platform, _ngZone, _animationMode) { super(_elementRef); this._elementRef = _elementRef; this._changeDetectorRef = _changeDetectorRef; this._dir = _dir; this._defaults = _defaults; this._platform = _platform; this._ngZone = _ngZone; /** * Whether the outline gap needs to be calculated * immediately on the next change detection run. */ this._outlineGapCalculationNeededImmediately = false; /** * Whether the outline gap needs to be calculated next time the zone has stabilized. */ this._outlineGapCalculationNeededOnStable = false; this._destroyed = new Subject(); /** * Override for the logic that disables the label animation in certain cases. */ this._showAlwaysAnimate = false; /** * State of the mat-hint and mat-error animations. */ this._subscriptAnimationState = ''; this._hintLabel = ''; // Unique id for the hint label. this._hintLabelId = `mat-hint-${nextUniqueId$2++}`; // Unique id for the internal form field label. this._labelId = `mat-form-field-label-${nextUniqueId$2++}`; /* Holds the previous direction emitted by directionality service change emitter. This is used in updateOutlineGap() method to update the width and position of the gap in the outline. Only relevant for the outline appearance. The direction is getting updated in the UI after directionality service change emission. So the outlines gaps are getting updated in updateOutlineGap() method before connectionContainer child direction change in UI. We may get wrong calculations. So we are storing the previous direction to get the correct outline calculations*/ this._previousDirection = 'ltr'; this._labelOptions = labelOptions ? labelOptions : {}; this.floatLabel = this._labelOptions.float || 'auto'; this._animationsEnabled = _animationMode !== 'NoopAnimations'; // Set the default through here so we invoke the setter on the first run. this.appearance = (_defaults && _defaults.appearance) ? _defaults.appearance : 'legacy'; this._hideRequiredMarker = (_defaults && _defaults.hideRequiredMarker != null) ? _defaults.hideRequiredMarker : false; } /** * The form-field appearance style. * @return {?} */ get appearance() { return this._appearance; } /** * @param {?} value * @return {?} */ set appearance(value) { /** @type {?} */ const oldValue = this._appearance; this._appearance = value || (this._defaults && this._defaults.appearance) || 'legacy'; if (this._appearance === 'outline' && oldValue !== value) { this._outlineGapCalculationNeededOnStable = true; } } /** * Whether the required marker should be hidden. * @return {?} */ get hideRequiredMarker() { return this._hideRequiredMarker; } /** * @param {?} value * @return {?} */ set hideRequiredMarker(value) { this._hideRequiredMarker = coerceBooleanProperty(value); } /** * Whether the floating label should always float or not. * @return {?} */ get _shouldAlwaysFloat() { return this.floatLabel === 'always' && !this._showAlwaysAnimate; } /** * Whether the label can float or not. * @return {?} */ get _canLabelFloat() { return this.floatLabel !== 'never'; } /** * Text for the form field hint. * @return {?} */ get hintLabel() { return this._hintLabel; } /** * @param {?} value * @return {?} */ set hintLabel(value) { this._hintLabel = value; this._processHints(); } /** * Whether the label should always float, never float or float as the user types. * * Note: only the legacy appearance supports the `never` option. `never` was originally added as a * way to make the floating label emulate the behavior of a standard input placeholder. However * the form field now supports both floating labels and placeholders. Therefore in the non-legacy * appearances the `never` option has been disabled in favor of just using the placeholder. * @return {?} */ get floatLabel() { return this.appearance !== 'legacy' && this._floatLabel === 'never' ? 'auto' : this._floatLabel; } /** * @param {?} value * @return {?} */ set floatLabel(value) { if (value !== this._floatLabel) { this._floatLabel = value || this._labelOptions.float || 'auto'; this._changeDetectorRef.markForCheck(); } } /** * @return {?} */ get _control() { // TODO(crisbeto): we need this hacky workaround in order to support both Ivy // and ViewEngine. We should clean this up once Ivy is the default renderer. return this._explicitFormFieldControl || this._controlNonStatic || this._controlStatic; } /** * @param {?} value * @return {?} */ set _control(value) { this._explicitFormFieldControl = value; } /** * @return {?} */ get _labelChild() { return this._labelChildNonStatic || this._labelChildStatic; } /** * Gets an ElementRef for the element that a overlay attached to the form-field should be * positioned relative to. * @return {?} */ getConnectedOverlayOrigin() { return this._connectionContainerRef || this._elementRef; } /** * @return {?} */ ngAfterContentInit() { this._validateControlChild(); /** @type {?} */ const control = this._control; if (control.controlType) { this._elementRef.nativeElement.classList.add(`mat-form-field-type-${control.controlType}`); } // Subscribe to changes in the child control state in order to update the form field UI. control.stateChanges.pipe(startWith((/** @type {?} */ (null)))).subscribe((/** * @return {?} */ () => { this._validatePlaceholders(); this._syncDescribedByIds(); this._changeDetectorRef.markForCheck(); })); // Run change detection if the value changes. if (control.ngControl && control.ngControl.valueChanges) { control.ngControl.valueChanges .pipe(takeUntil(this._destroyed)) .subscribe((/** * @return {?} */ () => this._changeDetectorRef.markForCheck())); } // Note that we have to run outside of the `NgZone` explicitly, // in order to avoid throwing users into an infinite loop // if `zone-patch-rxjs` is included. this._ngZone.runOutsideAngular((/** * @return {?} */ () => { this._ngZone.onStable.asObservable().pipe(takeUntil(this._destroyed)).subscribe((/** * @return {?} */ () => { if (this._outlineGapCalculationNeededOnStable) { this.updateOutlineGap(); } })); })); // Run change detection and update the outline if the suffix or prefix changes. merge(this._prefixChildren.changes, this._suffixChildren.changes).subscribe((/** * @return {?} */ () => { this._outlineGapCalculationNeededOnStable = true; this._changeDetectorRef.markForCheck(); })); // Re-validate when the number of hints changes. this._hintChildren.changes.pipe(startWith(null)).subscribe((/** * @return {?} */ () => { this._processHints(); this._changeDetectorRef.markForCheck(); })); // Update the aria-described by when the number of errors changes. this._errorChildren.changes.pipe(startWith(null)).subscribe((/** * @return {?} */ () => { this._syncDescribedByIds(); this._changeDetectorRef.markForCheck(); })); if (this._dir) { this._dir.change.pipe(takeUntil(this._destroyed)).subscribe((/** * @return {?} */ () => { this.updateOutlineGap(); this._previousDirection = this._dir.value; })); } } /** * @return {?} */ ngAfterContentChecked() { this._validateControlChild(); if (this._outlineGapCalculationNeededImmediately) { this.updateOutlineGap(); } } /** * @return {?} */ ngAfterViewInit() { // Avoid animations on load. this._subscriptAnimationState = 'enter'; this._changeDetectorRef.detectChanges(); } /** * @return {?} */ ngOnDestroy() { this._destroyed.next(); this._destroyed.complete(); } /** * Determines whether a class from the NgControl should be forwarded to the host element. * @param {?} prop * @return {?} */ _shouldForward(prop) { /** @type {?} */ const ngControl = this._control ? this._control.ngControl : null; return ngControl && ngControl[prop]; } /** * @return {?} */ _hasPlaceholder() { return !!(this._control && this._control.placeholder || this._placeholderChild); } /** * @return {?} */ _hasLabel() { return !!this._labelChild; } /** * @return {?} */ _shouldLabelFloat() { return this._canLabelFloat && (this._control.shouldLabelFloat || this._shouldAlwaysFloat); } /** * @return {?} */ _hideControlPlaceholder() { // In the legacy appearance the placeholder is promoted to a label if no label is given. return this.appearance === 'legacy' && !this._hasLabel() || this._hasLabel() && !this._shouldLabelFloat(); } /** * @return {?} */ _hasFloatingLabel() { // In the legacy appearance the placeholder is promoted to a label if no label is given. return this._hasLabel() || this.appearance === 'legacy' && this._hasPlaceholder(); } /** * Determines whether to display hints or errors. * @return {?} */ _getDisplayedMessages() { return (this._errorChildren && this._errorChildren.length > 0 && this._control.errorState) ? 'error' : 'hint'; } /** * Animates the placeholder up and locks it in position. * @return {?} */ _animateAndLockLabel() { if (this._hasFloatingLabel() && this._canLabelFloat) { // If animations are disabled, we shouldn't go in here, // because the `transitionend` will never fire. if (this._animationsEnabled) { this._showAlwaysAnimate = true; fromEvent(this._label.nativeElement, 'transitionend').pipe(take(1)).subscribe((/** * @return {?} */ () => { this._showAlwaysAnimate = false; })); } this.floatLabel = 'always'; this._changeDetectorRef.markForCheck(); } } /** * Ensure that there is only one placeholder (either `placeholder` attribute on the child control * or child element with the `mat-placeholder` directive). * @private * @return {?} */ _validatePlaceholders() { if (this._control.placeholder && this._placeholderChild) { throw getMatFormFieldPlaceholderConflictError(); } } /** * Does any extra processing that is required when handling the hints. * @private * @return {?} */ _processHints() { this._validateHints(); this._syncDescribedByIds(); } /** * Ensure that there is a maximum of one of each `<mat-hint>` alignment specified, with the * attribute being considered as `align="start"`. * @private * @return {?} */ _validateHints() { if (this._hintChildren) { /** @type {?} */ let startHint; /** @type {?} */ let endHint; this._hintChildren.forEach((/** * @param {?} hint * @return {?} */ (hint) => { if (hint.align === 'start') { if (startHint || this.hintLabel) { throw getMatFormFieldDuplicatedHintError('start'); } startHint = hint; } else if (hint.align === 'end') { if (endHint) { throw getMatFormFieldDuplicatedHintError('end'); } endHint = hint; } })); } } /** * Sets the list of element IDs that describe the child control. This allows the control to update * its `aria-describedby` attribute accordingly. * @private * @return {?} */ _syncDescribedByIds() { if (this._control) { /** @type {?} */ let ids = []; if (this._getDisplayedMessages() === 'hint') { /** @type {?} */ const startHint = this._hintChildren ? this._hintChildren.find((/** * @param {?} hint * @return {?} */ hint => hint.align === 'start')) : null; /** @type {?} */ const endHint = this._hintChildren ? this._hintChildren.find((/** * @param {?} hint * @return {?} */ hint => hint.align === 'end')) : null; if (startHint) { ids.push(startHint.id); } else if (this._hintLabel) { ids.push(this._hintLabelId); } if (endHint) { ids.push(endHint.id); } } else if (this._errorChildren) { ids = this._errorChildren.map((/** * @param {?} error * @return {?} */ error => error.id)); } this._control.setDescribedByIds(ids); } } /** * Throws an error if the form field's control is missing. * @protected * @return {?} */ _validateControlChild() { if (!this._control) { throw getMatFormFieldMissingControlError(); } } /** * Updates the width and position of the gap in the outline. Only relevant for the outline * appearance. * @return {?} */ updateOutlineGap() { /** @type {?} */ const labelEl = this._label ? this._label.nativeElement : null; if (this.appearance !== 'outline' || !labelEl || !labelEl.children.length || !labelEl.textContent.trim()) { return; } if (!this._platform.isBrowser) { // getBoundingClientRect isn't available on the server. return; } // If the element is not present in the DOM, the outline gap will need to be calculated // the next time it is checked and in the DOM. if (!(/** @type {?} */ (document.documentElement)).contains(this._elementRef.nativeElement)) { this._outlineGapCalculationNeededImmediately = true; return; } /** @type {?} */ let startWidth = 0; /** @type {?} */ let gapWidth = 0; /** @type {?} */ const container = this._connectionContainerRef.nativeElement; /** @type {?} */ const startEls = container.querySelectorAll('.mat-form-field-outline-start'); /** @type {?} */ const gapEls = container.querySelectorAll('.mat-form-field-outline-gap'); if (this._label && this._label.nativeElement.children.length) { /** @type {?} */ const containerRect = container.getBoundingClientRect(); // If the container's width and height are zero, it means that the element is // invisible and we can't calculate the outline gap. Mark the element as needing // to be checked the next time the zone stabilizes. We can't do this immediately // on the next change detection, because even if the element becomes visible, // the `ClientRect` won't be reclaculated immediately. We reset the // `_outlineGapCalculationNeededImmediately` flag some we don't run the checks twice. if (containerRect.width === 0 && containerRect.height === 0) { this._outlineGapCalculationNeededOnStable = true; this._outlineGapCalculationNeededImmediately = false; return; } /** @type {?} */ const containerStart = this._getStartEnd(containerRect); /** @type {?} */ const labelStart = this._getStartEnd(labelEl.children[0].getBoundingClientRect()); /** @type {?} */ let labelWidth = 0; for (const child of labelEl.children) { labelWidth += child.offsetWidth; } startWidth = labelStart - containerStart - outlineGapPadding; gapWidth = labelWidth > 0 ? labelWidth * floatingLabelScale + outlineGapPadding * 2 : 0; } for (let i = 0; i < startEls.length; i++) { startEls.item(i).style.width = `${startWidth}px`; } for (let i = 0; i < gapEls.length; i++) { gapEls.item(i).style.width = `${gapWidth}px`; } this._outlineGapCalculationNeededOnStable = this._outlineGapCalculationNeededImmediately = false; } /** * Gets the start end of the rect considering the current directionality. * @private * @param {?} rect * @return {?} */ _getStartEnd(rect) { return this._previousDirection === 'rtl' ? rect.right : rect.left; } } MatFormField.decorators = [ { type: Component, args: [{selector: 'mat-form-field', exportAs: 'matFormField', template: "<div class=\"mat-form-field-wrapper\"><div class=\"mat-form-field-flex\" #connectionContainer (click)=\"_control.onContainerClick && _control.onContainerClick($event)\"><ng-container *ngIf=\"appearance == 'outline'\"><div class=\"mat-form-field-outline\"><div class=\"mat-form-field-outline-start\"></div><div class=\"mat-form-field-outline-gap\"></div><div class=\"mat-form-field-outline-end\"></div></div><div class=\"mat-form-field-outline mat-form-field-outline-thick\"><div class=\"mat-form-field-outline-start\"></div><div class=\"mat-form-field-outline-gap\"></div><div class=\"mat-form-field-outline-end\"></div></div></ng-container><div class=\"mat-form-field-prefix\" *ngIf=\"_prefixChildren.length\"><ng-content select=\"[matPrefix]\"></ng-content></div><div class=\"mat-form-field-infix\" #inputContainer><ng-content></ng-content><span class=\"mat-form-field-label-wrapper\"><label class=\"mat-form-field-label\" (cdkObserveContent)=\"updateOutlineGap()\" [cdkObserveContentDisabled]=\"appearance != 'outline'\" [id]=\"_labelId\" [attr.for]=\"_control.id\" [attr.aria-owns]=\"_control.id\" [class.mat-empty]=\"_control.empty && !_shouldAlwaysFloat\" [class.mat-form-field-empty]=\"_control.empty && !_shouldAlwaysFloat\" [class.mat-accent]=\"color == 'accent'\" [class.mat-warn]=\"color == 'warn'\" #label *ngIf=\"_hasFloatingLabel()\" [ngSwitch]=\"_hasLabel()\"><ng-container *ngSwitchCase=\"false\"><ng-content select=\"mat-placeholder\"></ng-content><span>{{_control.placeholder}}</span></ng-container><ng-content select=\"mat-label\" *ngSwitchCase=\"true\"></ng-content><span class=\"mat-placeholder-required mat-form-field-required-marker\" aria-hidden=\"true\" *ngIf=\"!hideRequiredMarker && _control.required && !_control.disabled\">&#32;*</span></label></span></div><div class=\"mat-form-field-suffix\" *ngIf=\"_suffixChildren.length\"><ng-content select=\"[matSuffix]\"></ng-content></div></div><div class=\"mat-form-field-underline\" #underline *ngIf=\"appearance != 'outline'\"><span class=\"mat-form-field-ripple\" [class.mat-accent]=\"color == 'accent'\" [class.mat-warn]=\"color == 'warn'\"></span></div><div class=\"mat-form-field-subscript-wrapper\" [ngSwitch]=\"_getDisplayedMessages()\"><div *ngSwitchCase=\"'error'\" [@transitionMessages]=\"_subscriptAnimationState\"><ng-content select=\"mat-error\"></ng-content></div><div class=\"mat-form-field-hint-wrapper\" *ngSwitchCase=\"'hint'\" [@transitionMessages]=\"_subscriptAnimationState\"><div *ngIf=\"hintLabel\" [id]=\"_hintLabelId\" class=\"mat-hint\">{{hintLabel}}</div><ng-content select=\"mat-hint:not([align='end'])\"></ng-content><div class=\"mat-form-field-hint-spacer\"></div><ng-content select=\"mat-hint[align='end']\"></ng-content></div></div></div>", // MatInput is a directive and can't have styles, so we need to include its styles here // in form-field-input.css. The MatInput styles are fairly minimal so it shouldn't be a // big deal for people who aren't using MatInput. styles: [".mat-form-field{display:inline-block;position:relative;text-align:left}[dir=rtl] .mat-form-field{text-align:right}.mat-form-field-wrapper{position:relative}.mat-form-field-flex{display:inline-flex;align-items:baseline;box-sizing:border-box;width:100%}.mat-form-field-prefix,.mat-form-field-suffix{white-space:nowrap;flex:none;position:relative}.mat-form-field-infix{display:block;position:relative;flex:auto;min-width:0;width:180px}@media (-ms-high-contrast:active){.mat-form-field-infix{border-image:linear-gradient(transparent,transparent)}}.mat-form-field-label-wrapper{position:absolute;left:0;box-sizing:content-box;width:100%;height:100%;overflow:hidden;pointer-events:none}[dir=rtl] .mat-form-field-label-wrapper{left:auto;right:0}.mat-form-field-label{position:absolute;left:0;font:inherit;pointer-events:none;width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),color .4s cubic-bezier(.25,.8,.25,1),width .4s cubic-bezier(.25,.8,.25,1);display:none}[dir=rtl] .mat-form-field-label{transform-origin:100% 0;left:auto;right:0}.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-empty.mat-form-field-label{display:block}.mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{display:none}.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{display:block;transition:none}.mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-input-server[placeholder]:not(:placeholder-shown)+.mat-form-field-label-wrapper .mat-form-field-label{display:none}.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label,.mat-form-field-can-float .mat-input-server[placeholder]:not(:placeholder-shown)+.mat-form-field-label-wrapper .mat-form-field-label{display:block}.mat-form-field-label:not(.mat-form-field-empty){transition:none}.mat-form-field-underline{position:absolute;width:100%;pointer-events:none;transform:scaleY(1.0001)}.mat-form-field-ripple{position:absolute;left:0;width:100%;transform-origin:50%;transform:scaleX(.5);opacity:0;transition:background-color .3s cubic-bezier(.55,0,.55,.2)}.mat-form-field.mat-focused .mat-form-field-ripple,.mat-form-field.mat-form-field-invalid .mat-form-field-ripple{opacity:1;transform:scaleX(1);transition:transform .3s cubic-bezier(.25,.8,.25,1),opacity .1s cubic-bezier(.25,.8,.25,1),background-color .3s cubic-bezier(.25,.8,.25,1)}.mat-form-field-subscript-wrapper{position:absolute;box-sizing:border-box;width:100%;overflow:hidden}.mat-form-field-label-wrapper .mat-icon,.mat-form-field-subscript-wrapper .mat-icon{width:1em;height:1em;font-size:inherit;vertical-align:baseline}.mat-form-field-hint-wrapper{display:flex}.mat-form-field-hint-spacer{flex:1 0 1em}.mat-error{display:block}.mat-form-field-control-wrapper{position:relative}.mat-form-field._mat-animation-noopable .mat-form-field-label,.mat-form-field._mat-animation-noopable .mat-form-field-ripple{transition:none} .mat-form-field-appearance-fill .mat-form-field-flex{border-radius:4px 4px 0 0;padding:.75em .75em 0 .75em}@media (-ms-high-contrast:active){.mat-form-field-appearance-fill .mat-form-field-flex{outline:solid 1px}}.mat-form-field-appearance-fill .mat-form-field-underline::before{content:'';display:block;position:absolute;bottom:0;height:1px;width:100%}.mat-form-field-appearance-fill .mat-form-field-ripple{bottom:0;height:2px}@media (-ms-high-contrast:active){.mat-form-field-appearance-fill .mat-form-field-ripple{height:0;border-top:solid 2px}}.mat-form-field-appearance-fill:not(.mat-form-field-disabled) .mat-form-field-flex:hover~.mat-form-field-underline .mat-form-field-ripple{opacity:1;transform:none;transition:opacity .6s cubic-bezier(.25,.8,.25,1)}.mat-form-field-appearance-fill._mat-animation-noopable:not(.mat-form-field-disabled) .mat-form-field-flex:hover~.mat-form-field-underline .mat-form-field-ripple{transition:none}.mat-form-field-appearance-fill .mat-form-field-subscript-wrapper{padding:0 1em} .mat-input-element{font:inherit;background:0 0;color:currentColor;border:none;outline:0;padding:0;margin:0;width:100%;max-width:100%;vertical-align:bottom;text-align:inherit}.mat-input-element:-moz-ui-invalid{box-shadow:none}.mat-input-element::-ms-clear,.mat-input-element::-ms-reveal{display:none}.mat-input-element,.mat-input-element::-webkit-search-cancel-button,.mat-input-element::-webkit-search-decoration,.mat-input-element::-webkit-search-results-button,.mat-input-element::-webkit-search-results-decoration{-webkit-appearance:none}.mat-input-element::-webkit-caps-lock-indicator,.mat-input-element::-webkit-contacts-auto-fill-button,.mat-input-element::-webkit-credentials-auto-fill-button{visibility:hidden}.mat-input-element[type=date]::after,.mat-input-element[type=datetime-local]::after,.mat-input-element[type=datetime]::after,.mat-input-element[type=month]::after,.mat-input-element[type=time]::after,.mat-input-element[type=week]::after{content:' ';white-space:pre;width:1px}.mat-input-element::-webkit-calendar-picker-indicator,.mat-input-element::-webkit-clear-button,.mat-input-element::-webkit-inner-spin-button{font-size:.75em}.mat-input-element::placeholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color .4s .133s cubic-bezier(.25,.8,.25,1)}.mat-input-element::placeholder:-ms-input-placeholder{-ms-user-select:text}.mat-input-element::-moz-placeholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color .4s .133s cubic-bezier(.25,.8,.25,1)}.mat-input-element::-moz-placeholder:-ms-input-placeholder{-ms-user-select:text}.mat-input-element::-webkit-input-placeholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color .4s .133s cubic-bezier(.25,.8,.25,1)}.mat-input-element::-webkit-input-placeholder:-ms-input-placeholder{-ms-user-select:text}.mat-input-element:-ms-input-placeholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color .4s .133s cubic-bezier(.25,.8,.25,1)}.mat-input-element:-ms-input-placeholder:-ms-input-placeholder{-ms-user-select:text}.mat-form-field-hide-placeholder .mat-input-element::placeholder{color:transparent!important;-webkit-text-fill-color:transparent;transition:none}.mat-form-field-hide-placeholder .mat-input-element::-moz-placeholder{color:transparent!important;-webkit-text-fill-color:transparent;transition:none}.mat-form-field-hide-placeholder .mat-input-element::-webkit-input-placeholder{color:transparent!important;-webkit-text-fill-color:transparent;transition:none}.mat-form-field-hide-placeholder .mat-input-element:-ms-input-placeholder{color:transparent!important;-webkit-text-fill-color:transparent;transition:none}textarea.mat-input-element{resize:vertical;overflow:auto}textarea.mat-input-element.cdk-textarea-autosize{resize:none}textarea.mat-input-element{padding:2px 0;margin:-2px 0}select.mat-input-element{-moz-appearance:none;-webkit-appearance:none;position:relative;background-color:transparent;display:inline-flex;box-sizing:border-box;padding-top:1em;top:-1em;margin-bottom:-1em}select.mat-input-element::-ms-expand{display:none}select.mat-input-element::-moz-focus-inner{border:0}select.mat-input-element:not(:disabled){cursor:pointer}select.mat-input-element::-ms-value{color:inherit;background:0 0}@media (-ms-high-contrast:active){.mat-focused select.mat-input-element::-ms-value{color:inherit}}.mat-form-field-type-mat-native-select .mat-form-field-infix::after{content:'';width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid;position:absolute;top:50%;right:0;margin-top:-2.5px;pointer-events:none}[dir=rtl] .mat-form-field-type-mat-native-select .mat-form-field-infix::after{right:auto;left:0}.mat-form-field-type-mat-native-select .mat-input-element{padding-right:15px}[dir=rtl] .mat-form-field-type-mat-native-select .mat-input-element{padding-right:0;padding-left:15px}.mat-form-field-type-mat-native-select .mat-form-field-label-wrapper{max-width:calc(100% - 10px)}.mat-form-field-type-mat-native-select.mat-form-field-appearance-outline .mat-form-field-infix::after{margin-top:-5px}.mat-form-field-type-mat-native-select.mat-form-field-appearance-fill .mat-form-field-infix::after{margin-top:-10px} .mat-form-field-appearance-legacy .mat-form-field-label{transform:perspective(100px);-ms-transform:none}.mat-form-field-appearance-legacy .mat-form-field-prefix .mat-icon,.mat-form-field-appearance-legacy .mat-form-field-suffix .mat-icon{width:1em}.mat-form-field-appearance-legacy .mat-form-field-prefix .mat-icon-button,.mat-form-field-appearance-legacy .mat-form-field-suffix .mat-icon-button{font:inherit;vertical-align:baseline}.mat-form-field-appearance-legacy .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-appearance-legacy .mat-form-field-suffix .mat-icon-button .mat-icon{font-size:inherit}.mat-form-field-appearance-legacy .mat-form-field-underline{height:1px}@media (-ms-high-contrast:active){.mat-form-field-appearance-legacy .mat-form-field-underline{height:0;border-top:solid 1px}}.mat-form-field-appearance-legacy .mat-form-field-ripple{top:0;height:2px;overflow:hidden}@media (-ms-high-contrast:active){.mat-form-field-appearance-legacy .mat-form-field-ripple{height:0;border-top:solid 2px}}.mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-position:0;background-color:transparent}@media (-ms-high-contrast:active){.mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{border-top-style:dotted;border-top-width:2px}}.mat-form-field-appearance-legacy.mat-form-field-invalid:not(.mat-focused) .mat-form-field-ripple{height:1px} .mat-form-field-appearance-outline .mat-form-field-wrapper{margin:.25em 0}.mat-form-field-appearance-outline .mat-form-field-flex{padding:0 .75em 0 .75em;margin-top:-.25em;position:relative}.mat-form-field-appearance-outline .mat-form-field-prefix,.mat-form-field-appearance-outline .mat-form-field-suffix{top:.25em}.mat-form-field-appearance-outline .mat-form-field-outline{display:flex;position:absolute;top:.25em;left:0;right:0;bottom:0;pointer-events:none}.mat-form-field-appearance-outline .mat-form-field-outline-end,.mat-form-field-appearance-outline .mat-form-field-outline-start{border:1px solid currentColor;min-width:5px}.mat-form-field-appearance-outline .mat-form-field-outline-start{border-radius:5px 0 0 5px;border-right-style:none}[dir=rtl] .mat-form-field-appearance-outline .mat-form-field-outline-start{border-right-style:solid;border-left-style:none;border-radius:0 5px 5px 0}.mat-form-field-appearance-outline .mat-form-field-outline-end{border-radius:0 5px 5px 0;border-left-style:none;flex-grow:1}[dir=rtl] .mat-form-field-appearance-outline .mat-form-field-outline-end{border-left-style:solid;border-right-style:none;border-radius:5px 0 0 5px}.mat-form-field-appearance-outline .mat-form-field-outline-gap{border-radius:.000001px;border:1px solid currentColor;border-left-style:none;border-right-style:none}.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-outline-gap{border-top-color:transparent}.mat-form-field-appearance-outline .mat-form-field-outline-thick{opacity:0}.mat-form-field-appearance-outline .mat-form-field-outline-thick .mat-form-field-outline-end,.mat-form-field-appearance-outline .mat-form-field-outline-thick .mat-form-field-outline-gap,.mat-form-field-appearance-outline .mat-form-field-outline-thick .mat-form-field-outline-start{border-width:2px;transition:border-color .3s cubic-bezier(.25,.8,.25,1)}.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline,.mat-form-field-appearance-outline.mat-form-field-invalid .mat-form-field-outline{opacity:0;transition:opacity .1s cubic-bezier(.25,.8,.25,1)}.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick,.mat-form-field-appearance-outline.mat-form-field-invalid .mat-form-field-outline-thick{opacity:1}.mat-form-field-appearance-outline:not(.mat-form-field-disabled) .mat-form-field-flex:hover .mat-form-field-outline{opacity:0;transition:opacity .6s cubic-bezier(.25,.8,.25,1)}.mat-form-field-appearance-outline:not(.mat-form-field-disabled) .mat-form-field-flex:hover .mat-form-field-outline-thick{opacity:1}.mat-form-field-appearance-outline .mat-form-field-subscript-wrapper{padding:0 1em}.mat-form-field-appearance-outline._mat-animation-noopable .mat-form-field-outline,.mat-form-field-appearance-outline._mat-animation-noopable .mat-form-field-outline-end,.mat-form-field-appearance-outline._mat-animation-noopable .mat-form-field-outline-gap,.mat-form-field-appearance-outline._mat-animation-noopable .mat-form-field-outline-start,.mat-form-field-appearance-outline._mat-animation-noopable:not(.mat-form-field-disabled) .mat-form-field-flex:hover~.mat-form-field-outline{transition:none} .mat-form-field-appearance-standard .mat-form-field-flex{padding-top:.75em}.mat-form-field-appearance-standard .mat-form-field-underline{height:1px}@media (-ms-high-contrast:active){.mat-form-field-appearance-standard .mat-form-field-underline{height:0;border-top:solid 1px}}.mat-form-field-appearance-standard .mat-form-field-ripple{bottom:0;height:2px}@media (-ms-high-contrast:active){.mat-form-field-appearance-standard .mat-form-field-ripple{height:0;border-top:2px}}.mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-position:0;background-color:transparent}@media (-ms-high-contrast:active){.mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{border-top-style:dotted;border-top-width:2px}}.mat-form-field-appearance-standard:not(.mat-form-field-disabled) .mat-form-field-flex:hover~.mat-form-field-underline .mat-form-field-ripple{opacity:1;transform:none;transition:opacity .6s cubic-bezier(.25,.8,.25,1)}.mat-form-field-appearance-standard._mat-animation-noopable:not(.mat-form-field-disabled) .mat-form-field-flex:hover~.mat-form-field-underline .mat-form-field-ripple{transition:none}"], animations: [matFormFieldAnimations.transitionMessages], host: { 'class': 'mat-form-field', '[class.mat-form-field-appearance-standard]': 'appearance == "standard"', '[class.mat-form-field-appearance-fill]': 'appearance == "fill"', '[class.mat-form-field-appearance-outline]': 'appearance == "outline"', '[class.mat-form-field-appearance-legacy]': 'appearance == "legacy"', '[class.mat-form-field-invalid]': '_control.errorState', '[class.mat-form-field-can-float]': '_canLabelFloat', '[class.mat-form-field-should-float]': '_shouldLabelFloat()', '[class.mat-form-field-has-label]': '_hasFloatingLabel()', '[class.mat-form-field-hide-placeholder]': '_hideControlPlaceholder()', '[class.mat-form-field-disabled]': '_control.disabled', '[class.mat-form-field-autofilled]': '_control.autofilled', '[class.mat-focused]': '_control.focused', '[class.mat-accent]': 'color == "accent"', '[class.mat-warn]': 'color == "warn"', '[class.ng-untouched]': '_shouldForward("untouched")', '[class.ng-touched]': '_shouldForward("touched")', '[class.ng-pristine]': '_shouldForward("pristine")', '[class.ng-dirty]': '_shouldForward("dirty")', '[class.ng-valid]': '_shouldForward("valid")', '[class.ng-invalid]': '_shouldForward("invalid")', '[class.ng-pending]': '_shouldForward("pending")', '[class._mat-animation-noopable]': '!_animationsEnabled', }, inputs: ['color'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, },] }, ]; /** @nocollapse */ MatFormField.ctorParameters = () => [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_LABEL_GLOBAL_OPTIONS,] }] }, { type: Directionality, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_FORM_FIELD_DEFAULT_OPTIONS,] }] }, { type: Platform }, { type: NgZone }, { type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] } ]; MatFormField.propDecorators = { appearance: [{ type: Input }], hideRequiredMarker: [{ type: Input }], hintLabel: [{ type: Input }], floatLabel: [{ type: Input }], underlineRef: [{ type: ViewChild, args: ['underline', { static: false },] }], _connectionContainerRef: [{ type: ViewChild, args: ['connectionContainer', { static: true },] }], _inputContainerRef: [{ type: ViewChild, args: ['inputContainer', { static: false },] }], _label: [{ type: ViewChild, args: ['label', { static: false },] }], _controlNonStatic: [{ type: ContentChild, args: [MatFormFieldControl, { static: false },] }], _controlStatic: [{ type: ContentChild, args: [MatFormFieldControl, { static: true },] }], _labelChildNonStatic: [{ type: ContentChild, args: [MatLabel, { static: false },] }], _labelChildStatic: [{ type: ContentChild, args: [MatLabel, { static: true },] }], _placeholderChild: [{ type: ContentChild, args: [MatPlaceholder, { static: false },] }], _errorChildren: [{ type: ContentChildren, args: [MatError,] }], _hintChildren: [{ type: ContentChildren, args: [MatHint,] }], _prefixChildren: [{ type: ContentChildren, args: [MatPrefix,] }], _suffixChildren: [{ type: ContentChildren, args: [MatSuffix,] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MatFormFieldModule { } MatFormFieldModule.decorators = [ { type: NgModule, args: [{ declarations: [ MatError, MatFormField, MatHint, MatLabel, MatPlaceholder, MatPrefix, MatSuffix, ], imports: [ CommonModule, ObserversModule, ], exports: [ MatError, MatFormField, MatHint, MatLabel, MatPlaceholder, MatPrefix, MatSuffix, ], },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { MatFormFieldModule, MatError, MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormField, MatFormFieldControl, getMatFormFieldPlaceholderConflictError, getMatFormFieldDuplicatedHintError, getMatFormFieldMissingControlError, MatHint, MatPlaceholder, MatPrefix, MatSuffix, MatLabel, matFormFieldAnimations }; //# sourceMappingURL=form-field.js.map