mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(form-field): update label gap for outline style (#12555)
This commit is contained in:
@@ -18,6 +18,7 @@ ng_module(
|
||||
deps = [
|
||||
"//src/lib/core",
|
||||
"//src/cdk/coercion",
|
||||
"//src/cdk/observers",
|
||||
"//src/cdk/platform",
|
||||
],
|
||||
tsconfig = "//src/lib:tsconfig-build.json",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {ObserversModule} from '@angular/cdk/observers';
|
||||
import {MatError} from './error';
|
||||
import {MatFormField} from './form-field';
|
||||
import {MatHint} from './hint';
|
||||
@@ -27,7 +28,10 @@ import {MatSuffix} from './suffix';
|
||||
MatPrefix,
|
||||
MatSuffix,
|
||||
],
|
||||
imports: [CommonModule],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ObserversModule,
|
||||
],
|
||||
exports: [
|
||||
MatError,
|
||||
MatFormField,
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
<!-- Outline used for outline appearance. -->
|
||||
<ng-container *ngIf="appearance == 'outline'">
|
||||
<div class="mat-form-field-outline">
|
||||
<div class="mat-form-field-outline-start" [style.width.px]="_outlineGapStart"></div>
|
||||
<div class="mat-form-field-outline-gap" [style.width.px]="_outlineGapWidth"></div>
|
||||
<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" [style.width.px]="_outlineGapStart"></div>
|
||||
<div class="mat-form-field-outline-gap" [style.width.px]="_outlineGapWidth"></div>
|
||||
<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>
|
||||
@@ -27,6 +27,7 @@
|
||||
<!-- We add aria-owns as a workaround for an issue in JAWS & NVDA where the label isn't
|
||||
read if it comes before the control in the DOM. -->
|
||||
<label class="mat-form-field-label"
|
||||
(cdkObserveContent)="updateOutlineGap()"
|
||||
[id]="_labelId"
|
||||
[attr.for]="_control.id"
|
||||
[attr.aria-owns]="_control.id"
|
||||
|
||||
@@ -148,12 +148,18 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
return this._appearance || this._defaultOptions && this._defaultOptions.appearance || 'legacy';
|
||||
}
|
||||
set appearance(value: MatFormFieldAppearance) {
|
||||
// If we're switching to `outline` from another appearance, we have to recalculate the gap.
|
||||
if (value !== this._appearance && value === 'outline') {
|
||||
this._initialGapCalculated = false;
|
||||
}
|
||||
|
||||
const oldValue = this._appearance;
|
||||
this._appearance = value;
|
||||
if (this._appearance === 'outline' && oldValue !== value) {
|
||||
// @breaking-change 7.0.0 Remove this check and else block once _ngZone is required.
|
||||
if (this._ngZone) {
|
||||
this._ngZone!.onStable.pipe(take(1)).subscribe(() => {
|
||||
this._ngZone!.runOutsideAngular(() => this.updateOutlineGap());
|
||||
});
|
||||
} else {
|
||||
Promise.resolve().then(() => this.updateOutlineGap());
|
||||
}
|
||||
}
|
||||
}
|
||||
_appearance: MatFormFieldAppearance;
|
||||
|
||||
@@ -217,17 +223,13 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
/** Whether the Angular animations are enabled. */
|
||||
_animationsEnabled: boolean;
|
||||
|
||||
_outlineGapWidth = 0;
|
||||
_outlineGapStart = 0;
|
||||
_initialGapCalculated = false;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @breaking-change 7.0.0
|
||||
*/
|
||||
@ViewChild('underline') underlineRef: ElementRef;
|
||||
|
||||
@ViewChild('connectionContainer') _connectionContainerRef: ElementRef;
|
||||
@ViewChild('connectionContainer') _connectionContainerRef: ElementRef<HTMLElement>;
|
||||
@ViewChild('inputContainer') _inputContainerRef: ElementRef;
|
||||
@ViewChild('label') private _label: ElementRef;
|
||||
@ContentChild(MatFormFieldControl) _control: MatFormFieldControl<any>;
|
||||
@@ -298,20 +300,6 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
|
||||
ngAfterContentChecked() {
|
||||
this._validateControlChild();
|
||||
|
||||
if (!this._initialGapCalculated) {
|
||||
// @breaking-change 7.0.0 Remove this check and else block once _ngZone is required.
|
||||
if (this._ngZone) {
|
||||
// It's important that we run this outside the `_ngZone`, because the `Promise.resolve`
|
||||
// can kick us into an infinite change detection loop, if the `_initialGapCalculated`
|
||||
// wasn't flipped on for some reason.
|
||||
this._ngZone.runOutsideAngular(() => {
|
||||
Promise.resolve().then(() => this.updateOutlineGap());
|
||||
});
|
||||
} else {
|
||||
Promise.resolve().then(() => this.updateOutlineGap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
@@ -422,9 +410,9 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
let ids: string[] = [];
|
||||
|
||||
if (this._getDisplayedMessages() === 'hint') {
|
||||
let startHint = this._hintChildren ?
|
||||
const startHint = this._hintChildren ?
|
||||
this._hintChildren.find(hint => hint.align === 'start') : null;
|
||||
let endHint = this._hintChildren ?
|
||||
const endHint = this._hintChildren ?
|
||||
this._hintChildren.find(hint => hint.align === 'end') : null;
|
||||
|
||||
if (startHint) {
|
||||
@@ -456,10 +444,19 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
* appearance.
|
||||
*/
|
||||
updateOutlineGap() {
|
||||
if (this.appearance === 'outline' && this._label && this._label.nativeElement.children.length) {
|
||||
if (this.appearance !== 'outline') {
|
||||
return;
|
||||
}
|
||||
|
||||
let startWidth = 0;
|
||||
let gapWidth = 0;
|
||||
const startEls = this._connectionContainerRef.nativeElement.querySelectorAll<HTMLElement>(
|
||||
'.mat-form-field-outline-start');
|
||||
const gapEls = this._connectionContainerRef.nativeElement.querySelectorAll<HTMLElement>(
|
||||
'.mat-form-field-outline-gap');
|
||||
if (this._label && this._label.nativeElement.children.length) {
|
||||
if (this._platform && !this._platform.isBrowser) {
|
||||
// getBoundingClientRect isn't available on the server.
|
||||
this._initialGapCalculated = true;
|
||||
return;
|
||||
}
|
||||
if (!document.documentElement.contains(this._elementRef.nativeElement)) {
|
||||
@@ -474,14 +471,16 @@ export class MatFormField extends _MatFormFieldMixinBase
|
||||
for (const child of this._label.nativeElement.children) {
|
||||
labelWidth += child.offsetWidth;
|
||||
}
|
||||
this._outlineGapStart = labelStart - containerStart - outlineGapPadding;
|
||||
this._outlineGapWidth = labelWidth * floatingLabelScale + outlineGapPadding * 2;
|
||||
} else {
|
||||
this._outlineGapStart = 0;
|
||||
this._outlineGapWidth = 0;
|
||||
startWidth = labelStart - containerStart - outlineGapPadding;
|
||||
gapWidth = labelWidth * floatingLabelScale + outlineGapPadding * 2;
|
||||
}
|
||||
|
||||
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._initialGapCalculated = true;
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/** Gets the start end of the rect considering the current directionality. */
|
||||
|
||||
Reference in New Issue
Block a user