Skip to content

Commit 15a591b

Browse files
committed
correctly position and size the gap
1 parent 9c25f9a commit 15a591b

File tree

3 files changed

+80
-24
lines changed

3 files changed

+80
-24
lines changed

src/lib/form-field/form-field-outline.scss

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,41 @@ $mat-form-field-outline-subscript-padding:
4040
left: 0;
4141
right: 0;
4242
pointer-events: none;
43+
}
4344

44-
&::before,
45-
&::after {
46-
content: '';
47-
width: $mat-form-field-outline-side-padding;
48-
border: $mat-form-field-outline-width solid currentColor;
49-
flex-grow: 1;
50-
}
45+
.mat-form-field-outline-start,
46+
.mat-form-field-outline-end {
47+
border: $mat-form-field-outline-width solid currentColor;
48+
min-width: $mat-form-field-outline-border-radius;
49+
}
5150

52-
&::before {
53-
border-radius: $mat-form-field-outline-border-radius 0 0
54-
$mat-form-field-outline-border-radius;
55-
border-right: none;
56-
}
51+
.mat-form-field-outline-start {
52+
border-radius: $mat-form-field-outline-border-radius 0 0 $mat-form-field-outline-border-radius;
53+
border-right-style: none;
5754

58-
&::after {
55+
[dir="rtl"] & {
56+
border-right-style: solid;
57+
border-left-style: none;
5958
border-radius: 0 $mat-form-field-outline-border-radius $mat-form-field-outline-border-radius
6059
0;
61-
border-left: none;
60+
}
61+
}
62+
63+
.mat-form-field-outline-end {
64+
border-radius: 0 $mat-form-field-outline-border-radius $mat-form-field-outline-border-radius 0;
65+
border-left-style: none;
66+
flex-grow: 1;
67+
68+
[dir="rtl"] & {
69+
border-left-style: solid;
70+
border-right-style: none;
71+
border-radius: $mat-form-field-outline-border-radius 0 0
72+
$mat-form-field-outline-border-radius;
6273
}
6374
}
6475

6576
.mat-form-field-outline-gap {
6677
border-bottom: $mat-form-field-outline-width solid currentColor;
67-
width: 100px; // TODO(mmalerba): set size dynamically.
6878

6979
&::before {
7080
content: '';
@@ -85,8 +95,8 @@ $mat-form-field-outline-subscript-padding:
8595
.mat-form-field-outline-thick {
8696
opacity: 0;
8797

88-
&::before,
89-
&::after,
98+
.mat-form-field-outline-start,
99+
.mat-form-field-outline-end,
90100
.mat-form-field-outline-gap,
91101
.mat-form-field-outline-gap::before {
92102
border-width: $mat-form-field-outline-thick-width;

src/lib/form-field/form-field.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,14 @@
6464
<!-- Outline used for outline appearance. -->
6565
<ng-container *ngIf="appearance == 'outline'">
6666
<div class="mat-form-field-outline">
67-
<div class="mat-form-field-outline-gap"></div>
67+
<div class="mat-form-field-outline-start" [style.width.px]="_outlineGapStart"></div>
68+
<div class="mat-form-field-outline-gap" [style.width.px]="_outlineGapWidth"></div>
69+
<div class="mat-form-field-outline-end"></div>
6870
</div>
6971
<div class="mat-form-field-outline mat-form-field-outline-thick">
70-
<div class="mat-form-field-outline-gap"></div>
72+
<div class="mat-form-field-outline-start" [style.width.px]="_outlineGapStart"></div>
73+
<div class="mat-form-field-outline-gap" [style.width.px]="_outlineGapWidth"></div>
74+
<div class="mat-form-field-outline-end"></div>
7175
</div>
7276
</ng-container>
7377

src/lib/form-field/form-field.ts

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ import {MatLabel} from './label';
4848
import {MatPlaceholder} from './placeholder';
4949
import {MatPrefix} from './prefix';
5050
import {MatSuffix} from './suffix';
51+
import {Directionality} from '@angular/cdk/bidi';
52+
53+
54+
let nextUniqueId = 0;
55+
const floatingLabelScale = 0.75;
56+
const outlineGapPadding = 5;
5157

5258

5359
// Boilerplate for applying mixins to MatFormField.
@@ -56,10 +62,8 @@ export class MatFormFieldBase {
5662
constructor(public _elementRef: ElementRef) { }
5763
}
5864

59-
export const _MatFormFieldMixinBase = mixinColor(MatFormFieldBase, 'primary');
60-
6165

62-
let nextUniqueId = 0;
66+
export const _MatFormFieldMixinBase = mixinColor(MatFormFieldBase, 'primary');
6367

6468

6569
export type MatFormFieldAppearance = 'legacy' | 'standard' | 'fill' | 'outline';
@@ -118,7 +122,7 @@ export class MatFormField extends _MatFormFieldMixinBase
118122
private _labelOptions: LabelOptions;
119123

120124
/** The form-field appearance style. */
121-
@Input() appearance: MatFormFieldAppearance = 'outline';
125+
@Input() appearance: MatFormFieldAppearance = 'legacy';
122126

123127
/**
124128
* @deprecated Use `color` instead.
@@ -191,6 +195,10 @@ export class MatFormField extends _MatFormFieldMixinBase
191195
}
192196
private _floatLabel: FloatLabelType;
193197

198+
_outlineGapWidth = 0;
199+
200+
_outlineGapStart = 0;
201+
194202
/** @deletion-target 7.0.0 */
195203
@ViewChild('underline') underlineRef: ElementRef;
196204

@@ -208,7 +216,8 @@ export class MatFormField extends _MatFormFieldMixinBase
208216
constructor(
209217
public _elementRef: ElementRef,
210218
private _changeDetectorRef: ChangeDetectorRef,
211-
@Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) labelOptions: LabelOptions) {
219+
@Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) labelOptions: LabelOptions,
220+
@Optional() private _dir: Directionality) {
212221
super(_elementRef);
213222

214223
this._labelOptions = labelOptions ? labelOptions : {};
@@ -255,6 +264,11 @@ export class MatFormField extends _MatFormFieldMixinBase
255264
this._syncDescribedByIds();
256265
this._changeDetectorRef.markForCheck();
257266
});
267+
268+
Promise.resolve().then(() => {
269+
this._updateOutlineGap();
270+
this._changeDetectorRef.detectChanges();
271+
});
258272
}
259273

260274
ngAfterContentChecked() {
@@ -394,4 +408,32 @@ export class MatFormField extends _MatFormFieldMixinBase
394408
throw getMatFormFieldMissingControlError();
395409
}
396410
}
411+
412+
/**
413+
* Updates the width and position of the gap in the outline. Only relevant for the outline
414+
* appearance.
415+
*/
416+
private _updateOutlineGap() {
417+
if (this.appearance === 'outline' && this._label && this._label.nativeElement.children.length) {
418+
const containerStart = this._getStartEnd(
419+
this._connectionContainerRef.nativeElement.getBoundingClientRect());
420+
const labelStart = this._getStartEnd(
421+
this._label.nativeElement.children[0].getBoundingClientRect());
422+
let labelWidth = 0;
423+
for (const child of this._label.nativeElement.children) {
424+
labelWidth += child.offsetWidth;
425+
}
426+
this._outlineGapStart = labelStart - containerStart - outlineGapPadding;
427+
this._outlineGapWidth = labelWidth * floatingLabelScale + outlineGapPadding * 2;
428+
} else {
429+
this._outlineGapStart = 0;
430+
this._outlineGapWidth = 0;
431+
}
432+
this._changeDetectorRef.markForCheck();
433+
}
434+
435+
/** Gets the start end of the rect considering the current directionality. */
436+
private _getStartEnd(rect: ClientRect): number {
437+
return this._dir && this._dir.value === 'rtl' ? rect.right : rect.left;
438+
}
397439
}

0 commit comments

Comments
 (0)