Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(material-experimental/mdc-form-field): notched-outline should include prefixes and suffixes #18381

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/dev-app/mdc-input/mdc-input-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ <h4>Text</h4>
<span matSuffix>.00</span>
</mat-form-field>

<h4>Text (always outline)</h4>
<mat-form-field appearance="outline" class="demo-text-align-end">
<mat-label>Amount</mat-label>
<input matInput>
<span matPrefix>$&nbsp;</span>
<span matSuffix>.00</span>
</mat-form-field>

<h4>Icons</h4>
<mat-form-field [appearance]="prefixSuffixAppearance">
<mat-label>Amount</mat-label>
Expand Down Expand Up @@ -640,14 +648,31 @@ <h3>&lt;textarea&gt; with bindable autosize </h3>
<mat-label>Tab 1 input</mat-label>
<input matInput value="test">
</mat-form-field>

<mat-form-field appearance="outline" class="demo-text-align-end">
<mat-label>Amount</mat-label>
<input matInput>
<span matPrefix>$&nbsp;</span>
<span matSuffix>.00</span>
</mat-form-field>
</mat-tab>
<mat-tab label="Tab 2">
<mat-form-field appearance="outline">
<mat-label>Tab 2 input</mat-label>
<input matInput value="test">
</mat-form-field>

<mat-form-field appearance="outline" class="demo-text-align-end">
<mat-label>Amount</mat-label>
<input matInput>
<span matPrefix>$&nbsp;</span>
<span matPrefix *ngIf="showSecondPrefix">!&nbsp;</span>
<span matSuffix>.00</span>
</mat-form-field>
</mat-tab>
</mat-tab-group>

<button (click)="showSecondPrefix = !showSecondPrefix">Toggle second prefix.</button>
</mat-card-content>
</mat-card>

Expand Down
1 change: 1 addition & 0 deletions src/dev-app/mdc-input/mdc-input-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class MdcInputDemo {
prefixSuffixAppearance: MatFormFieldAppearance = 'fill';
placeholderTestControl = new FormControl('', Validators.required);
options: string[] = ['One', 'Two', 'Three'];
showSecondPrefix = false;

name: string;
errorMessageExample1: string;
Expand Down
1 change: 1 addition & 0 deletions src/material-experimental/mdc-form-field/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ng_module(
assets = [":form_field_scss"] + glob(["**/*.html"]),
module_name = "@angular/material-experimental/mdc-form-field",
deps = [
"//src/cdk/bidi",
"//src/cdk/observers",
"//src/cdk/platform",
"//src/material/core",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import '@material/notched-outline/variables.import';
@import '@material/textfield/variables.import';
@import 'form-field-sizing';

// Mixin that can be included to override the default MDC text-field
Expand Down Expand Up @@ -29,36 +31,32 @@
// spacing as we support arbitrary form-field controls which aren't necessarily matching
// the "mdc-text-field__input" class. Note: We need the first selector to overwrite the
// default no-label MDC padding styles which are set with a very high specificity.
.mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea)
.mdc-text-field--no-label:not(.mdc-text-field--textarea)
.mat-mdc-input-element.mdc-text-field__input,
.mat-mdc-input-element {
.mat-mdc-text-field-wrapper .mat-mdc-input-element {
padding: 0;
}

// MDC changes the vertical spacing of the input if there is no label. Since we moved
// the spacing of the input to the parent infix container (to support custom controls),
// we need to replicate these styles for the infix container. The goal is that the input
// placeholder vertically aligns with floating labels of other filled inputs. Note that
// outline appearance currently still relies on the input spacing due to a notched-outline
// limitation. TODO: https://github.com/material-components/material-components-web/issues/5326
.mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea)
.mat-mdc-form-field-infix {
padding-top: $mat-form-field-no-label-padding-top;
padding-bottom: $mat-form-field-no-label-padding-bottom;
}

// MDC adds vertical spacing to inputs. We removed this spacing and intend to add it
// to the infix container. This is necessary to ensure that custom form-field controls
// also have the proper Material Design spacing to the label and bottom-line. Note that
// outline appearance currently still relies on the input spacing due to a notched-outline
// limitation. TODO: https://github.com/material-components/material-components-web/issues/5326
.mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-form-field-infix {
// also have the proper Material Design spacing to the label and bottom-line.
.mat-mdc-text-field-wrapper .mat-mdc-form-field-infix {
// Apply the default text-field input padding to the infix container. We removed the
// padding from the input elements in order to support arbitrary form-field controls.
padding-top: $mat-form-field-with-label-input-padding-top;
padding-bottom: $mat-form-field-with-label-input-padding-bottom;
}

// MDC changes the vertical spacing of the input if there is no label, or in the outline
// appearance. This is because the input should vertically align with other inputs which use
// a floating label. To achieve this, we add custom vertical spacing to the infix container
// that differs from the vertical spacing for text-field's with a floating label.
.mdc-text-field--no-label:not(.mdc-text-field--textarea) .mat-mdc-form-field-infix,
.mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix {
padding-top: $mat-form-field-no-label-padding-top;
padding-bottom: $mat-form-field-no-label-padding-bottom;
}

// Root element of the mdc-text-field. As explained in the height overwrites above, MDC
// sets a default height on the text-field root element. This is not desired since we
// want the element to be able to expand as needed.
Expand All @@ -79,22 +77,33 @@
opacity: 1;
}

// The additional nesting is a temporary until the notched-outline is decoupled from the
// floating label. See https://github.com/material-components/material-components-web/issues/5326
// TODO(devversion): Remove this workaround/nesting once the feature is available.
.mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) {
// We removed the horizontal inset on input elements, but need to re-add the spacing to
// the actual form-field flex container that contains the prefixes, suffixes and infix.
.mat-mdc-form-field-flex {
padding: 0 $mdc-text-field-input-padding;
}
// We removed the horizontal inset on input elements, but need to re-add the spacing to
// the actual form-field flex container that contains the prefixes, suffixes and infix.
.mat-mdc-text-field-wrapper .mat-mdc-form-field-flex {
padding: 0 $mdc-text-field-input-padding;
}

// Since we moved the horizontal spacing from the input to the form-field flex container
// and the MDC floating label tries to account for the horizontal spacing, we need to reset
// the shifting since there is no padding the label needs to account for. Note that we do not
// want do this for labels in the notched-outline since MDC keeps those labels relative to
// the notched outline container, and already applies a specific horizontal spacing which
// we do not want to overwrite.
.mat-mdc-form-field-infix .mdc-floating-label {
left: 0;
right: 0;
}

// Since we moved the horizontal spacing from the input to the form-field flex container
// and the MDC floating label tries to account for the horizontal spacing, we need to reset
// the shifting since there is no padding the label needs to account for.
.mdc-floating-label {
left: 0;
}
// For the outline appearance, we re-create the active floating label transform. This is
// necessary because the transform for docked floating labels can be updated to account for
// the width of prefix container. We need to re-create these styles with `!important` because
// the horizontal adjustment for the label is applied through inline styles, and we want to
// make sure that the label can still float as expected. It should be okay using `!important`
// because it's unlikely that developers commonly overwrite the floating label transform.
.mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-floating-label--float-above {
// This transform has been extracted from the MDC text-field styles. We can't access it
// through a variable because MDC generates this label transform through a mixin.
transform: translateY(-$mdc-text-field-outlined-label-position-y) scale(0.75) !important;
}

// MDC sets the input elements in outline appearance to "display: flex". There seems to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,4 @@
.mat-mdc-text-field-wrapper .mdc-floating-label {
top: $mat-form-field-baseline;
}

// In the outline appearance, the textarea needs slightly reduced top spacing because
// the label overflows the outline by 50%. Additionally, horizontal spacing needs to be
// added since the outline is part of the "infix" and we need to account for the outline.
// TODO(devversion): horizontal spacing and extra specificity can be removed once the
// following feature is available: material-components-web#5326.
.mat-mdc-form-field > .mat-mdc-text-field-wrapper.mdc-text-field--outlined
.mat-mdc-form-field-infix .mat-mdc-textarea-input {
margin-top: $mat-form-field-outline-top-spacing;
padding: {
left: $mdc-text-field-input-padding;
right: $mdc-text-field-input-padding;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {MDCFloatingLabel} from '@material/floating-label';
},
})
export class MatFormFieldFloatingLabel extends MDCFloatingLabel implements OnDestroy {

@Input()
get floating() { return this._floating; }
set floating(shouldFloat: boolean) {
Expand All @@ -35,11 +34,16 @@ export class MatFormFieldFloatingLabel extends MDCFloatingLabel implements OnDes
}
private _floating = false;

constructor(elementRef: ElementRef) {
super(elementRef.nativeElement);
constructor(private _elementRef: ElementRef) {
super(_elementRef.nativeElement);
}

ngOnDestroy() {
this.destroy();
}

/** Gets the HTML element for the floating label. */
get element(): HTMLElement {
return this._elementRef.nativeElement;
}
}
16 changes: 8 additions & 8 deletions src/material-experimental/mdc-form-field/form-field.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@
[class.mdc-text-field--invalid]="_control.errorState"
(click)="_control.onContainerClick && _control.onContainerClick($event)">
<div class="mat-mdc-form-field-flex">
<div class="mat-mdc-form-field-prefix" *ngIf="_prefixChildren.length">
<div matFormFieldNotchedOutline *ngIf="_hasOutline()">
<ng-template [ngIf]="!_forceDisplayInfixLabel()">
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
</ng-template>
</div>

<div class="mat-mdc-form-field-prefix" *ngIf="_prefixChildren.length" #prefixContainer>
<ng-content select="[matPrefix]"></ng-content>
</div>

<div class="mat-mdc-form-field-infix">
<!-- For non outline appearance. -->
<ng-template [ngIf]="!_hasOutline()">
<ng-template [ngIf]="!_hasOutline() || _forceDisplayInfixLabel()">
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
</ng-template>

<!-- For outline appearance where MDC expects the label to be wrapped. -->
<div matFormFieldNotchedOutline *ngIf="_hasOutline()">
<ng-template [ngTemplateOutlet]="labelTemplate"></ng-template>
</div>

<ng-content></ng-content>
</div>

Expand Down
Loading