Skip to content

Commit

Permalink
feat(material-experimental/mdc-form-field): Add option for dynamic su…
Browse files Browse the repository at this point in the history
…ffix height based on number of hints and errors.
  • Loading branch information
kseamon committed Jan 19, 2022
1 parent 9b1fd61 commit 1169d8c
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
65 changes: 65 additions & 0 deletions src/dev-app/mdc-input/mdc-input-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,71 @@ <h4>Textarea</h4>
</mat-card-content>
</mat-card>

<mat-card class="demo-card demo-basic">
<mat-toolbar color="primary">Dynamic Suffix Sizing</mat-toolbar>
<mat-card-content>
<p>
One validation
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput [(ngModel)]="fillAppearance" required>
<mat-error>This field is required</mat-error>
</mat-form-field>
</p>

<p>
One hint and one validation
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput [(ngModel)]="fillAppearance" required>
<mat-error>This field is required</mat-error>
<mat-hint>Please type something here</mat-hint>
</mat-form-field>
</p>

<p>
Multiple errors
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput [(ngModel)]="fillAppearance" required>
<mat-error>AAA</mat-error>
<mat-error>BBB</mat-error>
<mat-error>CCC</mat-error>
</mat-form-field>
</p>

<p>
Multiple hints
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput>
<mat-hint>aaa</mat-hint>
<mat-hint>bbb</mat-hint>
<mat-hint>ccc</mat-hint>
</mat-form-field>
</p>

<p>
Multiple hints with differing alignment
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput>
<mat-hint>aaa</mat-hint>
<mat-hint align="end">bbb</mat-hint>
<mat-hint align="end">ccc</mat-hint>
</mat-form-field>
</p>

<p>
No hints or errors
<mat-form-field appearance="fill" [color]="color" suffixSizing="dynamic">
<mat-label>Fill appearance</mat-label>
<input matInput>
</mat-form-field>
</p>
</mat-card-content>
</mat-card>

<mat-card class="demo-card demo-basic">
<mat-toolbar color="primary">Number Inputs</mat-toolbar>
<mat-card-content>
Expand Down
3 changes: 2 additions & 1 deletion src/material-experimental/mdc-form-field/form-field.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
</div>

<div class="mat-mdc-form-field-subscript-wrapper mat-mdc-form-field-bottom-align"
[ngSwitch]="_getDisplayedMessages()">
[ngSwitch]="_getDisplayedMessages()"
[style.height.px]="_getDynamicSuffixHeight()">
<div class="mat-mdc-form-field-error-wrapper" *ngSwitchCase="'error'"
[@transitionMessages]="_subscriptAnimationState">
<ng-content select="mat-error"></ng-content>
Expand Down
33 changes: 33 additions & 0 deletions src/material-experimental/mdc-form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export type FloatLabelType = 'always' | 'auto';
/** Possible appearance styles for the form field. */
export type MatFormFieldAppearance = 'fill' | 'outline';

/** Behaviors for how the suffix height is set. */
export type SuffixSizingBehavior = 'fixed' | 'dynamic';

/**
* Represents the default options for the form field that can be configured
* using the `MAT_FORM_FIELD_DEFAULT_OPTIONS` injection token.
Expand All @@ -69,6 +72,7 @@ export interface MatFormFieldDefaultOptions {
appearance?: MatFormFieldAppearance;
hideRequiredMarker?: boolean;
floatLabel?: FloatLabelType;
suffixSizing?: SuffixSizingBehavior;
}

/**
Expand All @@ -87,6 +91,9 @@ const DEFAULT_APPEARANCE: MatFormFieldAppearance = 'fill';
/** Default appearance used by the form-field. */
const DEFAULT_FLOAT_LABEL: FloatLabelType = 'auto';

/** Default way that the suffix element height is set. */
const DEFAULT_SUFFIX_SIZING: SuffixSizingBehavior = 'fixed';

/**
* Default transform for docked floating labels in a MDC text-field. This value has been
* extracted from the MDC text-field styles because we programmatically modify the docked
Expand All @@ -100,6 +107,11 @@ const FLOATING_LABEL_DEFAULT_DOCKED_TRANSFORM = `translateY(-50%)`;
*/
const WRAPPER_HORIZONTAL_PADDING = 16;

/** Height provided for each row of text when using dynamic suffix sizing. */
const SUFFIX_ROW_HEIGHT = 16;
/** Space added to dynamic suffix height if rows of text are present. */
const SUFFIX_ROW_SPACER = 4;

/** Container for form controls that applies Material Design styling and behavior. */
@Component({
selector: 'mat-form-field',
Expand Down Expand Up @@ -206,6 +218,15 @@ export class MatFormField
}
private _appearance: MatFormFieldAppearance = DEFAULT_APPEARANCE;

@Input()
get suffixSizing(): SuffixSizingBehavior {
return this._suffixSizing || this._defaults?.suffixSizing || DEFAULT_SUFFIX_SIZING;
}
set suffixSizing(value: SuffixSizingBehavior) {
this._suffixSizing = value || this._defaults?.suffixSizing || DEFAULT_SUFFIX_SIZING;
}
private _suffixSizing: SuffixSizingBehavior = DEFAULT_SUFFIX_SIZING;

/** Text for the form field hint. */
@Input()
get hintLabel(): string {
Expand Down Expand Up @@ -604,6 +625,18 @@ export class MatFormField
: 'hint';
}

/** Determines height of suffix when in dynamic suffix sizing mode. */
_getDynamicSuffixHeight(): number | null {
if (this.suffixSizing !== 'dynamic') return null;

const numSuffixRows =
this._getDisplayedMessages() === 'error'
? this._errorChildren.length
: Math.min(this._hintChildren.length, 1);

return numSuffixRows && numSuffixRows * SUFFIX_ROW_HEIGHT + SUFFIX_ROW_SPACER;
}

/** Refreshes the width of the outline-notch, if present. */
_refreshOutlineNotchWidth() {
if (!this._hasOutline() || !this._floatingLabel) {
Expand Down

0 comments on commit 1169d8c

Please sign in to comment.