From 005ceb9f81643fbb6c5b79f84e9a947b57c94348 Mon Sep 17 00:00:00 2001 From: Kharazian Date: Sat, 26 Aug 2023 17:05:08 -0400 Subject: [PATCH 1/3] fix(material/autocomplete): prevent autocomplete overlap with outlined label when overlay above Fixes by preventing Autocomplete overlap with outlined form-field label when overlay is positioned above. Implemente a function to calculate the necessary vertical offset for outlined appearance, ensuring label legibility. Fixes #27476 --- src/material/autocomplete/autocomplete-trigger.ts | 15 +++++++++++++-- src/material/form-field/form-field.ts | 10 ++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index 486c7a60728a..ecd5ccbf0256 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -924,9 +924,20 @@ export class MatAutocompleteTrigger // the opposite end has rounded corners. We apply a CSS class to swap the // border-radius based on the overlay position. const panelClass = this._aboveClass; + + // Calculate vertical overlay offset with outline, or set to 0. + const offsetY = this._formField?._getOverlayOffsetOutlined() || 0; + const abovePositions: ConnectedPosition[] = [ - {originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', panelClass}, - {originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', panelClass}, + { + originX: 'start', + originY: 'top', + overlayX: 'start', + overlayY: 'bottom', + panelClass, + offsetY, + }, + {originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', panelClass, offsetY}, ]; let positions: ConnectedPosition[]; diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index cc16af869f0c..79922b1e94e4 100644 --- a/src/material/form-field/form-field.ts +++ b/src/material/form-field/form-field.ts @@ -609,6 +609,16 @@ export class MatFormField return this.appearance === 'outline'; } + /** + * Calculate the vertical offset for the overlay when the input field has an outline appearance. + * In the outline appearance, the overlay should have extra space to display the label correctly. + * This function calculates the vertical offset needed. + */ + _getOverlayOffsetOutlined() { + const outlineHeight = this._floatingLabel?.element.getBoundingClientRect().height || 0; + return this._hasOutline() ? -outlineHeight / 2 : 0; + } + /** * Whether the label should display in the infix. Labels in the outline appearance are * displayed as part of the notched-outline and are horizontally offset to account for From f88a792f4df1699f4348aed1561bf0eabff4c2da Mon Sep 17 00:00:00 2001 From: Kharazian Date: Sun, 27 Aug 2023 11:31:58 -0400 Subject: [PATCH 2/3] fix(material/autocomplete): enhanced offset determination by considering parent form field Fixes #27476 --- src/material/autocomplete/autocomplete-trigger.ts | 9 +++++++-- src/material/form-field/form-field.ts | 10 ---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index ecd5ccbf0256..87ee44eb1973 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -925,8 +925,13 @@ export class MatAutocompleteTrigger // border-radius based on the overlay position. const panelClass = this._aboveClass; - // Calculate vertical overlay offset with outline, or set to 0. - const offsetY = this._formField?._getOverlayOffsetOutlined() || 0; + /** + * Calculate the vertical offset for the overlay when the input field has an outline appearance. + * In the outline appearance, the overlay should have extra space to display the label correctly. + */ + const outlineHeight = + this._formField?._floatingLabel?.element.getBoundingClientRect().height || 0; + const offsetY = this._formField?._hasOutline() ? -outlineHeight / 2 : 0; const abovePositions: ConnectedPosition[] = [ { diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index 79922b1e94e4..cc16af869f0c 100644 --- a/src/material/form-field/form-field.ts +++ b/src/material/form-field/form-field.ts @@ -609,16 +609,6 @@ export class MatFormField return this.appearance === 'outline'; } - /** - * Calculate the vertical offset for the overlay when the input field has an outline appearance. - * In the outline appearance, the overlay should have extra space to display the label correctly. - * This function calculates the vertical offset needed. - */ - _getOverlayOffsetOutlined() { - const outlineHeight = this._floatingLabel?.element.getBoundingClientRect().height || 0; - return this._hasOutline() ? -outlineHeight / 2 : 0; - } - /** * Whether the label should display in the infix. Labels in the outline appearance are * displayed as part of the notched-outline and are horizontally offset to account for From 1490253dcafa5357b02101c7b5312205e737152a Mon Sep 17 00:00:00 2001 From: Kharazian Date: Wed, 30 Aug 2023 22:29:05 -0400 Subject: [PATCH 3/3] fix(material/autocomplete): optimized performance by first checking the outline appearance Fixes #27476 --- src/material/autocomplete/autocomplete-trigger.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index 87ee44eb1973..2a769d81b521 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -925,13 +925,12 @@ export class MatAutocompleteTrigger // border-radius based on the overlay position. const panelClass = this._aboveClass; - /** - * Calculate the vertical offset for the overlay when the input field has an outline appearance. - * In the outline appearance, the overlay should have extra space to display the label correctly. - */ - const outlineHeight = - this._formField?._floatingLabel?.element.getBoundingClientRect().height || 0; - const offsetY = this._formField?._hasOutline() ? -outlineHeight / 2 : 0; + // Calculate the vertical offset for the overlay when the input field has an outline appearance. + // In the outline appearance, the overlay should have extra space to display the label correctly. + let offsetY = 0; + if (this._formField?._hasOutline()) { + offsetY = -(this._formField?._floatingLabel?.element.getBoundingClientRect().height || 0) / 2; + } const abovePositions: ConnectedPosition[] = [ {