Skip to content

Commit

Permalink
fix(material-experimental/mdc-form-field): Properly handle when defau…
Browse files Browse the repository at this point in the history
…lts setting is 'dynamic' and the subscriptSizing input is not present. (angular#24263)
  • Loading branch information
kseamon authored and zarend committed Jan 26, 2022
1 parent 43db844 commit 89f548f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/material-experimental/mdc-form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ 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. */
/** Default way that the subscript element height is set. */
const DEFAULT_SUBSCRIPT_SIZING: SubscriptSizing = 'fixed';

/**
Expand Down Expand Up @@ -225,7 +225,7 @@ export class MatFormField
set subscriptSizing(value: SubscriptSizing) {
this._subscriptSizing = value || this._defaults?.subscriptSizing || DEFAULT_SUBSCRIPT_SIZING;
}
private _subscriptSizing: SubscriptSizing = DEFAULT_SUBSCRIPT_SIZING;
private _subscriptSizing: SubscriptSizing | null = null;

/** Text for the form field hint. */
@Input()
Expand Down
21 changes: 20 additions & 1 deletion src/material-experimental/mdc-input/input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1430,7 +1430,7 @@ describe('MatFormField default options', () => {
);
});

it('changes the default value of subscriptSizing', () => {
it('changes the default value of subscriptSizing (undefined input)', () => {
const fixture = createComponent(MatInputWithSubscriptSizing, [
{
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
Expand All @@ -1448,6 +1448,25 @@ describe('MatFormField default options', () => {
.classList.contains('mat-mdc-form-field-subscript-dynamic-size'),
).toBe(true);
});

it('changes the default value of subscriptSizing (no input)', () => {
const fixture = createComponent(MatInputWithAppearance, [
{
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
useValue: {
subscriptSizing: 'dynamic',
},
},
]);

fixture.detectChanges();
expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic');
expect(
fixture.nativeElement
.querySelector('.mat-mdc-form-field-subscript-wrapper')
.classList.contains('mat-mdc-form-field-subscript-dynamic-size'),
).toBe(true);
});
});

function configureTestingModule(
Expand Down
28 changes: 26 additions & 2 deletions src/material/datepicker/calendar-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
OnChanges,
SimpleChanges,
OnDestroy,
AfterViewChecked
} from '@angular/core';
import {take} from 'rxjs/operators';

Expand Down Expand Up @@ -67,13 +68,18 @@ export interface MatCalendarUserEvent<D> {
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatCalendarBody implements OnChanges, OnDestroy {
export class MatCalendarBody implements OnChanges, OnDestroy, AfterViewChecked {
/**
* Used to skip the next focus event when rendering the preview range.
* We need a flag like this, because some browsers fire focus events asynchronously.
*/
private _skipNextFocus: boolean;

/**
* Used to schedule focusing the active cell after change detection has run.
*/
private _focusActiveCellAfterViewChecked = false;

/** The label for the table. (e.g. "Jan 2017"). */
@Input() label: string;

Expand All @@ -96,7 +102,13 @@ export class MatCalendarBody implements OnChanges, OnDestroy {
@Input() numCols: number = 7;

/** The cell number of the active cell in the table. */
@Input() activeCell: number = 0;
@Input() get activeCell(): number {
return this._activeCell;
}
set activeCell(activeCell: number) {
this._activeCell = activeCell;
}
private _activeCell: number = 0;

/** Whether a range is being selected. */
@Input() isRange: boolean = false;
Expand Down Expand Up @@ -183,6 +195,13 @@ export class MatCalendarBody implements OnChanges, OnDestroy {
element.removeEventListener('blur', this._leaveHandler, true);
}

ngAfterViewChecked() {
if (this._focusActiveCellAfterViewChecked) {
this._focusActiveCell();
this._focusActiveCellAfterViewChecked = false;
}
}

/** Returns whether a cell is active. */
_isActiveCell(rowIndex: number, colIndex: number): boolean {
let cellNumber = rowIndex * this.numCols + colIndex;
Expand Down Expand Up @@ -214,6 +233,11 @@ export class MatCalendarBody implements OnChanges, OnDestroy {
});
}

/** Focuses the active cell after change detection has run and the microtask queue is empty. */
_scheduleFocusActiveCell() {
this._focusActiveCellAfterViewChecked = true;
}

/** Gets whether a value is the start of the main range. */
_isRangeStart(value: number) {
return isStart(value, this.startValue, this.endValue);
Expand Down
6 changes: 5 additions & 1 deletion src/material/datepicker/month-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
this.activeDateChange.emit(this.activeDate);
}

this._focusActiveCell();
this._scheduleFocusActiveCell();
// Prevent unexpected default actions such as form submission.
event.preventDefault();
}
Expand Down Expand Up @@ -376,6 +376,10 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
this._matCalendarBody._focusActiveCell(movePreview);
}

_scheduleFocusActiveCell() {
this._matCalendarBody._scheduleFocusActiveCell();
}

/** Called when the user has activated a new cell and the preview needs to be updated. */
_previewChanged({event, value: cell}: MatCalendarUserEvent<MatCalendarCell<D> | null>) {
if (this._rangeStrategy) {
Expand Down

0 comments on commit 89f548f

Please sign in to comment.