Skip to content

Commit

Permalink
fix(material/form-field): outline gap not recalculated when switching…
Browse files Browse the repository at this point in the history
… to empty label (#23949)

We had a condition where `updateOutlineGap` wouldn't do anything if the label is empty. The problem is that the label could start off with content and then switch to being empty.

These changes set the gap labels to zero width if the gap element is empty.

Fixes #23943.

(cherry picked from commit d3123f9)
  • Loading branch information
crisbeto authored and andrewseguin committed Jan 18, 2022
1 parent 439ad2c commit 805eee8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
1 change: 1 addition & 0 deletions scripts/check-mdc-tests-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const config = {
'should update the outline gap if the direction changes',
'should update the outline gap correctly if the direction changes multiple times',
'should calculate the outline gaps inside the shadow DOM',
'should recalculate the outline gap when the label changes to empty after init',
'should be legacy appearance if no default options provided',
'should be legacy appearance if empty default options provided',
],
Expand Down
27 changes: 16 additions & 11 deletions src/material/form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -549,20 +549,26 @@ export class MatFormField
*/
updateOutlineGap() {
const labelEl = this._label ? this._label.nativeElement : null;
const container = this._connectionContainerRef.nativeElement;
const outlineStartSelector = '.mat-form-field-outline-start';
const outlineGapSelector = '.mat-form-field-outline-gap';

if (
this.appearance !== 'outline' ||
!labelEl ||
!labelEl.children.length ||
!labelEl.textContent!.trim()
) {
// getBoundingClientRect isn't available on the server.
if (this.appearance !== 'outline' || !this._platform.isBrowser) {
return;
}

if (!this._platform.isBrowser) {
// getBoundingClientRect isn't available on the server.
// If there is no content, set the gap elements to zero.
if (!labelEl || !labelEl.children.length || !labelEl.textContent!.trim()) {
const gapElements = container.querySelectorAll(
`${outlineStartSelector}, ${outlineGapSelector}`,
);
for (let i = 0; i < gapElements.length; i++) {
gapElements[i].style.width = '0';
}
return;
}

// If the element is not present in the DOM, the outline gap will need to be calculated
// the next time it is checked and in the DOM.
if (!this._isAttachedToDOM()) {
Expand All @@ -573,9 +579,8 @@ export class MatFormField
let startWidth = 0;
let gapWidth = 0;

const container = this._connectionContainerRef.nativeElement;
const startEls = container.querySelectorAll('.mat-form-field-outline-start');
const gapEls = container.querySelectorAll('.mat-form-field-outline-gap');
const startEls = container.querySelectorAll(outlineStartSelector);
const gapEls = container.querySelectorAll(outlineGapSelector);

if (this._label && this._label.nativeElement.children.length) {
const containerRect = container.getBoundingClientRect();
Expand Down
28 changes: 28 additions & 0 deletions src/material/input/input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,34 @@ describe('MatInput with appearance', () => {
expect(parseInt(outlineStart.style.width || '0')).toBeGreaterThan(0);
expect(parseInt(outlineGap.style.width || '0')).toBeGreaterThan(0);
}));

it('should recalculate the outline gap when the label changes to empty after init', fakeAsync(() => {
fixture.destroy();
TestBed.resetTestingModule();

const outlineFixture = createComponent(MatInputWithAppearanceAndLabel);

outlineFixture.componentInstance.appearance = 'outline';
outlineFixture.detectChanges();
flush();
outlineFixture.detectChanges();

const wrapperElement = outlineFixture.nativeElement;
const outlineStart = wrapperElement.querySelector('.mat-form-field-outline-start');
const outlineGap = wrapperElement.querySelector('.mat-form-field-outline-gap');

expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0);
expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0);

outlineFixture.componentInstance.labelContent = '';
outlineFixture.detectChanges();

outlineFixture.componentInstance.formField.updateOutlineGap();
outlineFixture.detectChanges();

expect(parseInt(outlineStart.style.width)).toBe(0);
expect(parseInt(outlineGap.style.width)).toBe(0);
}));
});

describe('MatFormField default options', () => {
Expand Down

0 comments on commit 805eee8

Please sign in to comment.