Skip to content

Commit d3123f9

Browse files
authored
fix(material/form-field): outline gap not recalculated when switching 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.
1 parent 350ab4d commit d3123f9

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

scripts/check-mdc-tests-config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export const config = {
8181
'should update the outline gap if the direction changes',
8282
'should update the outline gap correctly if the direction changes multiple times',
8383
'should calculate the outline gaps inside the shadow DOM',
84+
'should recalculate the outline gap when the label changes to empty after init',
8485
'should be legacy appearance if no default options provided',
8586
'should be legacy appearance if empty default options provided',
8687
],

src/material/form-field/form-field.ts

+16-11
Original file line numberDiff line numberDiff line change
@@ -549,20 +549,26 @@ export class MatFormField
549549
*/
550550
updateOutlineGap() {
551551
const labelEl = this._label ? this._label.nativeElement : null;
552+
const container = this._connectionContainerRef.nativeElement;
553+
const outlineStartSelector = '.mat-form-field-outline-start';
554+
const outlineGapSelector = '.mat-form-field-outline-gap';
552555

553-
if (
554-
this.appearance !== 'outline' ||
555-
!labelEl ||
556-
!labelEl.children.length ||
557-
!labelEl.textContent!.trim()
558-
) {
556+
// getBoundingClientRect isn't available on the server.
557+
if (this.appearance !== 'outline' || !this._platform.isBrowser) {
559558
return;
560559
}
561560

562-
if (!this._platform.isBrowser) {
563-
// getBoundingClientRect isn't available on the server.
561+
// If there is no content, set the gap elements to zero.
562+
if (!labelEl || !labelEl.children.length || !labelEl.textContent!.trim()) {
563+
const gapElements = container.querySelectorAll(
564+
`${outlineStartSelector}, ${outlineGapSelector}`,
565+
);
566+
for (let i = 0; i < gapElements.length; i++) {
567+
gapElements[i].style.width = '0';
568+
}
564569
return;
565570
}
571+
566572
// If the element is not present in the DOM, the outline gap will need to be calculated
567573
// the next time it is checked and in the DOM.
568574
if (!this._isAttachedToDOM()) {
@@ -573,9 +579,8 @@ export class MatFormField
573579
let startWidth = 0;
574580
let gapWidth = 0;
575581

576-
const container = this._connectionContainerRef.nativeElement;
577-
const startEls = container.querySelectorAll('.mat-form-field-outline-start');
578-
const gapEls = container.querySelectorAll('.mat-form-field-outline-gap');
582+
const startEls = container.querySelectorAll(outlineStartSelector);
583+
const gapEls = container.querySelectorAll(outlineGapSelector);
579584

580585
if (this._label && this._label.nativeElement.children.length) {
581586
const containerRect = container.getBoundingClientRect();

src/material/input/input.spec.ts

+28
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,34 @@ describe('MatInput with appearance', () => {
17611761
expect(parseInt(outlineStart.style.width || '0')).toBeGreaterThan(0);
17621762
expect(parseInt(outlineGap.style.width || '0')).toBeGreaterThan(0);
17631763
}));
1764+
1765+
it('should recalculate the outline gap when the label changes to empty after init', fakeAsync(() => {
1766+
fixture.destroy();
1767+
TestBed.resetTestingModule();
1768+
1769+
const outlineFixture = createComponent(MatInputWithAppearanceAndLabel);
1770+
1771+
outlineFixture.componentInstance.appearance = 'outline';
1772+
outlineFixture.detectChanges();
1773+
flush();
1774+
outlineFixture.detectChanges();
1775+
1776+
const wrapperElement = outlineFixture.nativeElement;
1777+
const outlineStart = wrapperElement.querySelector('.mat-form-field-outline-start');
1778+
const outlineGap = wrapperElement.querySelector('.mat-form-field-outline-gap');
1779+
1780+
expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0);
1781+
expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0);
1782+
1783+
outlineFixture.componentInstance.labelContent = '';
1784+
outlineFixture.detectChanges();
1785+
1786+
outlineFixture.componentInstance.formField.updateOutlineGap();
1787+
outlineFixture.detectChanges();
1788+
1789+
expect(parseInt(outlineStart.style.width)).toBe(0);
1790+
expect(parseInt(outlineGap.style.width)).toBe(0);
1791+
}));
17641792
});
17651793

17661794
describe('MatFormField default options', () => {

0 commit comments

Comments
 (0)