Skip to content

Commit

Permalink
feat(material-experimental/mdc-form-field): separate out text and icon
Browse files Browse the repository at this point in the history
prefixes/suffixes
  • Loading branch information
mmalerba committed Feb 24, 2021
1 parent f94181a commit d88e750
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 32 deletions.
56 changes: 38 additions & 18 deletions src/dev-app/mdc-input/mdc-input-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,32 +124,50 @@ <h4>Text</h4>
<mat-form-field [appearance]="prefixSuffixAppearance" class="demo-text-align-end">
<mat-label>Amount</mat-label>
<input matInput>
<span matPrefix *ngIf="showPrefix">$&nbsp;</span>
<span matSuffix>.00</span>
<span matTextPrefix *ngIf="showPrefix">$</span>
<span matTextSuffix>.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>
<span matTextPrefix>$</span>
<span matTextSuffix>.00</span>
</mat-form-field>

<h4>Icons</h4>
<mat-form-field [appearance]="prefixSuffixAppearance">
<mat-label>Amount</mat-label>
<input matInput>
<mat-icon matPrefix *ngIf="showPrefix">calendar_today</mat-icon>
<mat-icon matSuffix>mode_edit</mat-icon>
<mat-icon matIconPrefix *ngIf="showPrefix">calendar_today</mat-icon>
<mat-icon matIconSuffix>mode_edit</mat-icon>
</mat-form-field>

<h4>Icon buttons</h4>
<mat-form-field [appearance]="prefixSuffixAppearance">
<mat-label>Amount</mat-label>
<input matInput>
<button mat-icon-button matPrefix *ngIf="showPrefix"><mat-icon>calendar_today</mat-icon></button>
<button mat-icon-button matSuffix><mat-icon>mode_edit</mat-icon></button>
<button mat-icon-button matIconPrefix *ngIf="showPrefix">
<mat-icon>calendar_today</mat-icon>
</button>
<button mat-icon-button matIconSuffix>
<mat-icon>mode_edit</mat-icon>
</button>
</mat-form-field>

<h4>Text & Icons</h4>
<mat-form-field [appearance]="prefixSuffixAppearance">
<mat-label>Amount</mat-label>
<input matInput>
<span matTextPrefix>$</span>
<span matTextSuffix>.00</span>
<button mat-icon-button matIconPrefix *ngIf="showPrefix">
<mat-icon>calendar_today</mat-icon>
</button>
<button mat-icon-button matIconSuffix>
<mat-icon>mode_edit</mat-icon>
</button>
</mat-form-field>

<p>
Expand Down Expand Up @@ -371,20 +389,22 @@ <h4>Textarea</h4>
<mat-form-field>
<mat-label>Prefixed</mat-label>
<input matInput value="example">
<div matPrefix>Example:&nbsp;</div>
<span matTextPrefix>Example:&nbsp;</span>
</mat-form-field>
<mat-form-field class="demo-text-align-end">
<mat-label>Suffixed</mat-label>
<input matInput value="123">
<span matSuffix>.00 €</span>
<span matTextSuffix>.00 €</span>
</mat-form-field>
<br/>
Both:
<mat-form-field class="demo-text-align-end">
<mat-label>Email address</mat-label>
<input matInput #email="matInput" value="angular-core">
<span matPrefix><mat-icon [class.primary]="email.focused">email</mat-icon>&nbsp;</span>
<span matSuffix [class.primary]="email.focused">&nbsp;@gmail.com</span>
<span matIconPrefix>
<mat-icon [class.primary]="email.focused">email</mat-icon>&nbsp;
</span>
<span matTextSuffix [class.primary]="email.focused">&nbsp;@gmail.com</span>
</mat-form-field>
</p>

Expand Down Expand Up @@ -679,8 +699,8 @@ <h3>&lt;textarea&gt; with bindable autosize </h3>
<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>
<span matTextPrefix>$&nbsp;</span>
<span matTextSuffix>.00</span>
</mat-form-field>
</mat-tab>
<mat-tab label="Tab 2">
Expand All @@ -692,9 +712,9 @@ <h3>&lt;textarea&gt; with bindable autosize </h3>
<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>
<span matTextPrefix>$&nbsp;</span>
<span matTextPrefix *ngIf="showSecondPrefix">!&nbsp;</span>
<span matTextSuffix>.00</span>
</mat-form-field>
</mat-tab>
</mat-tab-group>
Expand Down Expand Up @@ -724,7 +744,7 @@ <h4>Custom control</h4>
<mat-form-field appearance="outline">
<mat-label>Phone number</mat-label>
<example-tel-input required></example-tel-input>
<mat-icon matSuffix>phone</mat-icon>
<mat-icon matIconSuffix>phone</mat-icon>
<mat-hint>Include area code</mat-hint>
</mat-form-field>
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
// the correct level.
.mat-mdc-input-element,
.mat-mdc-form-field label,
.mat-mdc-form-field-prefix,
.mat-mdc-form-field-suffix {
.mat-mdc-form-field-text-prefix,
.mat-mdc-form-field-text-suffix {
@include mdc-typography(body1, $query: mdc-helpers.$mat-typography-styles-query);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const MAT_PREFIX = new InjectionToken<MatPrefix>('MatPrefix');

/** Prefix to be placed in front of the form field. */
@Directive({
selector: '[matPrefix]',
/** @breaking-change 13.0.0 remove [matPrefix] */
selector: '[matPrefix], [matIconPrefix], [matTextPrefix]',
providers: [{provide: MAT_PREFIX, useExisting: MatPrefix}],
})
export class MatPrefix {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const MAT_SUFFIX = new InjectionToken<MatSuffix>('MatSuffix');

/** Suffix to be placed at the end of the form field. */
@Directive({
selector: '[matSuffix]',
/** @breaking-change 13.0.0 remove [matSuffix] */
selector: '[matSuffix], [matIconSuffix], [matTextSuffix]',
providers: [{provide: MAT_SUFFIX, useExisting: MatSuffix}],
})
export class MatSuffix {}
14 changes: 10 additions & 4 deletions src/material-experimental/mdc-form-field/form-field.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@
</ng-template>
</div>

<div class="mat-mdc-form-field-prefix" *ngIf="_prefixChildren.length" #prefixContainer>
<ng-content select="[matPrefix]"></ng-content>
<div class="mat-mdc-form-field-icon-prefix" *ngIf="_prefixChildren.length" #iconPrefixContainer>
<ng-content select="[matPrefix], [matIconPrefix]"></ng-content>
</div>
<div class="mat-mdc-form-field-text-prefix" *ngIf="_prefixChildren.length" #textPrefixContainer>
<ng-content select="[matTextPrefix]"></ng-content>
</div>

<div class="mat-mdc-form-field-infix">
Expand All @@ -56,8 +59,11 @@
<ng-content></ng-content>
</div>

<div class="mat-mdc-form-field-suffix" *ngIf="_suffixChildren.length">
<ng-content select="[matSuffix]"></ng-content>
<div class="mat-mdc-form-field-text-suffix" *ngIf="_suffixChildren.length">
<ng-content select="[matTextSuffix]"></ng-content>
</div>
<div class="mat-mdc-form-field-icon-suffix" *ngIf="_suffixChildren.length">
<ng-content select="[matSuffix], [matIconSuffix]"></ng-content>
</div>
</div>

Expand Down
5 changes: 5 additions & 0 deletions src/material-experimental/mdc-form-field/form-field.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
width: 100%;
}

.mat-mdc-form-field-icon-prefix,
.mat-mdc-form-field-icon-suffix {
align-self: center;
}

// Infix that contains the projected content (usually an input or a textarea). We ensure
// that the projected form-field control and content can stretch as needed, but we also
// apply a default infix width to make the form-field's look natural.
Expand Down
13 changes: 9 additions & 4 deletions src/material-experimental/mdc-form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ const FLOATING_LABEL_DEFAULT_DOCKED_TRANSFORM = `translateY(-50%)`;
export class MatFormField implements AfterViewInit, OnDestroy, AfterContentChecked,
AfterContentInit {
@ViewChild('textField') _textField: ElementRef<HTMLElement>;
@ViewChild('prefixContainer') _prefixContainer: ElementRef<HTMLElement>;
@ViewChild('iconPrefixContainer') _iconPrefixContainer: ElementRef<HTMLElement>;
@ViewChild('textPrefixContainer') _textPrefixContainer: ElementRef<HTMLElement>;
@ViewChild(MatFormFieldFloatingLabel) _floatingLabel: MatFormFieldFloatingLabel|undefined;
@ViewChild(MatFormFieldNotchedOutline) _notchedOutline: MatFormFieldNotchedOutline|undefined;
@ViewChild(MatFormFieldLineRipple) _lineRipple: MatFormFieldLineRipple|undefined;
Expand Down Expand Up @@ -654,7 +655,7 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
const floatingLabel = this._floatingLabel.element;
// If no prefix is displayed, reset the outline label offset from potential
// previous label offset updates.
if (!this._prefixContainer) {
if (!(this._iconPrefixContainer || this._textPrefixContainer)) {
floatingLabel.style.transform = '';
return;
}
Expand All @@ -664,11 +665,15 @@ export class MatFormField implements AfterViewInit, OnDestroy, AfterContentCheck
this._needsOutlineLabelOffsetUpdateOnStable = true;
return;
}
const prefixContainer = this._prefixContainer.nativeElement as HTMLElement;
const iconPrefixContainer = this._iconPrefixContainer.nativeElement as HTMLElement;
const textPrefixContainer = this._textPrefixContainer.nativeElement as HTMLElement;
// If the directionality is RTL, the x-axis transform needs to be inverted. This
// is because `transformX` does not change based on the page directionality.
const labelHorizontalOffset =
(this._dir.value === 'rtl' ? -1 : 1) * prefixContainer.getBoundingClientRect().width;
(this._dir.value === 'rtl' ? -1 : 1) * (
iconPrefixContainer.getBoundingClientRect().width +
textPrefixContainer.getBoundingClientRect().width
);

// Update the transform the floating label to account for the prefix container. Note
// that we do not want to overwrite the default transform for docked floating labels.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class MatFormFieldHarness extends _MatFormFieldHarnessBase<FormFieldContr
async (harness, hasErrors) => await harness.hasErrors() === hasErrors);
}

protected _prefixContainer = this.locatorForOptional('.mat-mdc-form-field-prefix');
protected _suffixContainer = this.locatorForOptional('.mat-mdc-form-field-suffix');
protected _prefixContainer = this.locatorForOptional('.mat-mdc-form-field-text-prefix');
protected _suffixContainer = this.locatorForOptional('.mat-mdc-form-field-text-suffix');
protected _label = this.locatorForOptional('.mdc-floating-label');
protected _errors = this.locatorForAll('.mat-mdc-form-field-error');
protected _hints = this.locatorForAll('.mat-mdc-form-field-hint');
Expand Down

0 comments on commit d88e750

Please sign in to comment.