This is an automated email from the ASF dual-hosted git repository.

rfellows pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 8d8aebc5be NIFI-13054: Tooltip improvements (#8657)
8d8aebc5be is described below

commit 8d8aebc5be77743c40107751014aea6a22f834df
Author: Matt Gilman <[email protected]>
AuthorDate: Thu Apr 18 16:11:05 2024 -0400

    NIFI-13054: Tooltip improvements (#8657)
    
    * NIFI-13054:
    - Using Overlay for tooltips which correctly handle z-index and improvement 
positioning logic.
    
    * NIFI-13054:
    - Removing wrapped elements that are no longer needed with the use of 
Overlay for dialog handling.
    
    This closes #8657
---
 .../flow-designer/service/canvas-utils.service.ts  | 63 ++++++++++-----
 .../flow-designer/service/canvas-view.service.ts   | 14 ++--
 .../service/manager/connection-manager.service.ts  | 23 ++----
 .../service/manager/port-manager.service.ts        | 24 ++----
 .../manager/process-group-manager.service.ts       | 23 ++----
 .../service/manager/processor-manager.service.ts   | 23 ++----
 .../remote-process-group-manager.service.ts        | 35 +++-----
 .../flow-designer/ui/canvas/canvas.component.ts    |  5 +-
 .../header/flow-status/flow-status.component.html  |  2 +-
 .../header/flow-status/flow-status.component.ts    | 14 +++-
 .../manage-remote-ports.component.html             | 28 +++----
 .../parameter-table/parameter-table.component.html | 16 ++--
 .../flow-analysis-rule-table.component.html        | 42 +++++-----
 .../parameter-providers-table.component.html       | 14 ++--
 .../reporting-task-table.component.html            | 42 +++++-----
 .../controller-service-references.component.html   | 41 +++++-----
 .../controller-service-table.component.html        | 42 +++++-----
 .../parameter-references.component.html            | 40 +++++-----
 .../property-table/property-table.component.html   | 14 ++--
 .../bulletins-tip/bulletins-tip.component.html     |  2 +-
 .../bulletins-tip/bulletins-tip.component.ts       |  2 -
 .../controller-service-api-tip.component.html      |  2 +-
 .../controller-service-api-tip.component.ts        |  2 -
 .../el-function-tip/el-function-tip.component.html |  2 +-
 .../el-function-tip/el-function-tip.component.ts   |  2 -
 .../ui/common/tooltips/nifi-tooltip.directive.ts   | 92 ++++++++++++++--------
 .../parameter-tip/parameter-tip.component.html     |  2 +-
 .../parameter-tip/parameter-tip.component.ts       |  2 -
 .../property-hint-tip.component.html               |  2 +-
 .../property-hint-tip.component.ts                 |  2 -
 .../property-tip/property-tip.component.html       |  2 +-
 .../property-tip/property-tip.component.ts         |  2 -
 .../restrictions-tip.component.html                |  2 +-
 .../restrictions-tip/restrictions-tip.component.ts |  2 -
 .../tooltips/text-tip/text-tip.component.html      |  2 +-
 .../common/tooltips/text-tip/text-tip.component.ts |  2 -
 .../unordered-list-tip.component.html              |  2 +-
 .../unordered-list-tip.component.ts                |  2 -
 .../validation-errors-tip.component.html           |  2 +-
 .../validation-errors-tip.component.ts             |  2 -
 .../src/main/nifi/src/assets/styles/_app.scss      |  2 -
 41 files changed, 296 insertions(+), 343 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts
index e57e390991..37b4e7adb8 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-utils.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { ComponentRef, DestroyRef, inject, Injectable, Type, ViewContainerRef 
} from '@angular/core';
+import { DestroyRef, inject, Injectable, Type } from '@angular/core';
 import * as d3 from 'd3';
 import { humanizer, Humanizer } from 'humanize-duration';
 import { Store } from '@ngrx/store';
@@ -40,6 +40,8 @@ import { FlowConfiguration } from 
'../../../state/flow-configuration';
 import { initialState as initialFlowConfigurationState } from 
'../../../state/flow-configuration/flow-configuration.reducer';
 import { selectFlowConfiguration } from 
'../../../state/flow-configuration/flow-configuration.selectors';
 import { VersionControlInformation } from '../state/flow';
+import { Overlay, OverlayRef } from '@angular/cdk/overlay';
+import { ComponentPortal } from '@angular/cdk/portal';
 
 @Injectable({
     providedIn: 'root'
@@ -62,7 +64,8 @@ export class CanvasUtils {
 
     constructor(
         private store: Store<CanvasState>,
-        private nifiCommon: NiFiCommon
+        private nifiCommon: NiFiCommon,
+        private overlay: Overlay
     ) {
         this.humanizeDuration = humanizer();
 
@@ -1005,42 +1008,61 @@ export class CanvasUtils {
     /**
      * Creates tooltip for the specified selection.
      *
-     * @param viewContainerRef
      * @param type
      * @param selection
      * @param tooltipData
      */
-    public canvasTooltip<C>(viewContainerRef: ViewContainerRef, type: Type<C>, 
selection: any, tooltipData: any): void {
+    public canvasTooltip<C>(type: Type<C>, selection: any, tooltipData: any): 
void {
         let closeTimer = -1;
-        let tooltipRef: ComponentRef<C> | undefined;
+        const overlay = this.overlay;
+        let overlayRef: OverlayRef | null = null;
 
         selection
             .on('mouseenter', function (this: any) {
-                const { x, y, width, height } = 
d3.select(this).node().getBoundingClientRect();
+                if (overlayRef?.hasAttached()) {
+                    return;
+                }
 
-                // clear any existing tooltips
-                viewContainerRef.clear();
+                if (!overlayRef) {
+                    const positionStrategy = overlay
+                        .position()
+                        .flexibleConnectedTo(d3.select(this).node())
+                        .withPositions([
+                            {
+                                originX: 'end',
+                                originY: 'bottom',
+                                overlayX: 'start',
+                                overlayY: 'top',
+                                offsetX: 8,
+                                offsetY: 8
+                            }
+                        ])
+                        .withPush(true);
+
+                    overlayRef = overlay.create({ positionStrategy });
+                }
 
-                // create and configure the tooltip
-                tooltipRef = viewContainerRef.createComponent(type);
-                tooltipRef.setInput('top', y + height + 8);
-                tooltipRef.setInput('left', x + width + 8);
-                tooltipRef.setInput('data', tooltipData);
+                const tooltipReference = overlayRef.attach(new 
ComponentPortal(type));
+                tooltipReference.setInput('data', tooltipData);
 
                 // register mouse events
-                
tooltipRef.location.nativeElement.addEventListener('mouseenter', () => {
+                
tooltipReference.location.nativeElement.addEventListener('mouseenter', () => {
                     if (closeTimer > 0) {
-                        clearTimeout(closeTimer);
+                        window.clearTimeout(closeTimer);
                         closeTimer = -1;
                     }
                 });
-                
tooltipRef.location.nativeElement.addEventListener('mouseleave', () => {
-                    tooltipRef?.destroy();
+                
tooltipReference.location.nativeElement.addEventListener('mouseleave', () => {
+                    overlayRef?.detach();
+                    overlayRef?.dispose();
+                    overlayRef = null;
                 });
             })
             .on('mouseleave', function () {
                 closeTimer = window.setTimeout(() => {
-                    tooltipRef?.destroy();
+                    overlayRef?.detach();
+                    overlayRef?.dispose();
+                    overlayRef = null;
                 }, 400);
             });
     }
@@ -1048,11 +1070,10 @@ export class CanvasUtils {
     /**
      * Sets the bulletin visibility and applies a tooltip if necessary.
      *
-     * @param viewContainerRef
      * @param selection
      * @param bulletins
      */
-    public bulletins(viewContainerRef: ViewContainerRef, selection: any, 
bulletins: string[]): void {
+    public bulletins(selection: any, bulletins: string[]): void {
         if (this.nifiCommon.isEmpty(bulletins)) {
             // reset the bulletin icon/background
             selection.select('text.bulletin-icon').style('visibility', 
'hidden');
@@ -1063,7 +1084,7 @@ export class CanvasUtils {
             selection.select('rect.bulletin-background').style('visibility', 
'visible');
 
             // add the tooltip
-            this.canvasTooltip(viewContainerRef, BulletinsTip, bulletinIcon, {
+            this.canvasTooltip(BulletinsTip, bulletinIcon, {
                 bulletins: bulletins
             });
         }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.ts
index 699656dd86..bb8a844836 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-view.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { Injectable, ViewContainerRef } from '@angular/core';
+import { Injectable } from '@angular/core';
 import * as d3 from 'd3';
 import * as WebFont from 'webfontloader';
 import { Store } from '@ngrx/store';
@@ -65,7 +65,7 @@ export class CanvasView {
         private connectionManager: ConnectionManager
     ) {}
 
-    public init(viewContainerRef: ViewContainerRef, svg: any, canvas: any): 
void {
+    public init(svg: any, canvas: any): void {
         WebFont.load({
             custom: {
                 families: ['Roboto', 'Roboto Slab', 'flowfont', 'FontAwesome']
@@ -92,11 +92,11 @@ export class CanvasView {
 
         this.labelManager.init();
         this.funnelManager.init();
-        this.portManager.init(viewContainerRef);
-        this.remoteProcessGroupManager.init(viewContainerRef);
-        this.processGroupManager.init(viewContainerRef);
-        this.processorManager.init(viewContainerRef);
-        this.connectionManager.init(viewContainerRef);
+        this.portManager.init();
+        this.remoteProcessGroupManager.init();
+        this.processGroupManager.init();
+        this.processorManager.init();
+        this.connectionManager.init();
 
         const self: CanvasView = this;
         let refreshed: Promise<void> | null;
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts
index 78b2bb1425..50e5f976e2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { DestroyRef, inject, Injectable, ViewContainerRef } from 
'@angular/core';
+import { DestroyRef, inject, Injectable } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { CanvasState } from '../../state';
 import { CanvasUtils } from '../canvas-utils.service';
@@ -90,8 +90,6 @@ export class ConnectionManager {
 
     private snapEnabled = true;
 
-    private viewContainerRef: ViewContainerRef | undefined;
-
     constructor(
         private store: Store<CanvasState>,
         private canvasUtils: CanvasUtils,
@@ -1732,11 +1730,9 @@ export class ConnectionManager {
                 });
 
             updated.select('g.backpressure-data-size-container').each(function 
(this: any, d: any) {
-                if (self.viewContainerRef) {
-                    self.canvasUtils.canvasTooltip(self.viewContainerRef, 
UnorderedListTip, d3.select(this), {
-                        items: self.getBackPressureSizeTip(d)
-                    });
-                }
+                self.canvasUtils.canvasTooltip(UnorderedListTip, 
d3.select(this), {
+                    items: self.getBackPressureSizeTip(d)
+                });
             });
         });
     }
@@ -1803,11 +1799,9 @@ export class ConnectionManager {
                 });
 
             updated.select('g.backpressure-object-container').each(function 
(this: any, d: any) {
-                if (self.viewContainerRef) {
-                    self.canvasUtils.canvasTooltip(self.viewContainerRef, 
UnorderedListTip, d3.select(this), {
-                        items: self.getBackPressureCountTip(d)
-                    });
-                }
+                self.canvasUtils.canvasTooltip(UnorderedListTip, 
d3.select(this), {
+                    items: self.getBackPressureCountTip(d)
+                });
             });
         });
     }
@@ -1820,9 +1814,8 @@ export class ConnectionManager {
         removed.remove();
     }
 
-    public init(viewContainerRef: ViewContainerRef): void {
+    public init(): void {
         const self: ConnectionManager = this;
-        this.viewContainerRef = viewContainerRef;
 
         this.connectionContainer = d3
             .select('#canvas')
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts
index 553c516994..a0b8520139 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/port-manager.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { DestroyRef, inject, Injectable, ViewContainerRef } from 
'@angular/core';
+import { DestroyRef, inject, Injectable } from '@angular/core';
 import { CanvasState } from '../../state';
 import { Store } from '@ngrx/store';
 import { CanvasUtils } from '../canvas-utils.service';
@@ -61,8 +61,6 @@ export class PortManager {
     private portContainer: any;
     private transitionRequired = false;
 
-    private viewContainerRef: ViewContainerRef | undefined;
-
     constructor(
         private store: Store<CanvasState>,
         private canvasUtils: CanvasUtils,
@@ -331,8 +329,8 @@ export class PortManager {
                                 ')'
                         )
                         .each(function (this: any) {
-                            if 
(!self.nifiCommon.isBlank(portData.component.comments) && 
self.viewContainerRef) {
-                                
self.canvasUtils.canvasTooltip(self.viewContainerRef, TextTip, d3.select(this), 
{
+                            if 
(!self.nifiCommon.isBlank(portData.component.comments)) {
+                                self.canvasUtils.canvasTooltip(TextTip, 
d3.select(this), {
                                     text: portData.component.comments
                                 });
                             }
@@ -421,12 +419,8 @@ export class PortManager {
             })
             .each(function (this: any, d: any) {
                 // if there are validation errors generate a tooltip
-                if (
-                    d.permissions.canRead &&
-                    !self.nifiCommon.isEmpty(d.component.validationErrors) &&
-                    self.viewContainerRef
-                ) {
-                    self.canvasUtils.canvasTooltip(self.viewContainerRef, 
ValidationErrorsTip, d3.select(this), {
+                if (d.permissions.canRead && 
!self.nifiCommon.isEmpty(d.component.validationErrors)) {
+                    self.canvasUtils.canvasTooltip(ValidationErrorsTip, 
d3.select(this), {
                         isValidating: false,
                         validationErrors: d.component.validationErrors
                     });
@@ -472,9 +466,7 @@ export class PortManager {
             // bulletins
             // ---------
 
-            if (self.viewContainerRef) {
-                self.canvasUtils.bulletins(self.viewContainerRef, port, 
d.bulletins);
-            }
+            self.canvasUtils.bulletins(port, d.bulletins);
         });
     }
 
@@ -482,9 +474,7 @@ export class PortManager {
         removed.remove();
     }
 
-    public init(viewContainerRef: ViewContainerRef): void {
-        this.viewContainerRef = viewContainerRef;
-
+    public init(): void {
         this.portContainer = 
d3.select('#canvas').append('g').attr('pointer-events', 'all').attr('class', 
'ports');
 
         this.store
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts
index 8883e49119..37b1402b09 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/process-group-manager.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { DestroyRef, inject, Injectable, ViewContainerRef } from 
'@angular/core';
+import { DestroyRef, inject, Injectable } from '@angular/core';
 import { CanvasState } from '../../state';
 import { Store } from '@ngrx/store';
 import { PositionBehavior } from '../behavior/position-behavior.service';
@@ -58,8 +58,6 @@ export class ProcessGroupManager {
     private processGroupContainer: any;
     private transitionRequired = false;
 
-    private viewContainerRef: ViewContainerRef | undefined;
-
     constructor(
         private store: Store<CanvasState>,
         private canvasUtils: CanvasUtils,
@@ -1116,8 +1114,8 @@ export class ProcessGroupManager {
                 if (processGroupData.permissions.canRead) {
                     // version control tooltip
                     versionControl.each(function (this: any) {
-                        if (self.isUnderVersionControl(processGroupData) && 
self.viewContainerRef) {
-                            
self.canvasUtils.canvasTooltip(self.viewContainerRef, VersionControlTip, 
d3.select(this), {
+                        if (self.isUnderVersionControl(processGroupData)) {
+                            self.canvasUtils.canvasTooltip(VersionControlTip, 
d3.select(this), {
                                 versionControlInformation: 
processGroupData.component.versionControlInformation
                             });
                         }
@@ -1131,11 +1129,8 @@ export class ProcessGroupManager {
                             
self.nifiCommon.isBlank(processGroupData.component.comments) ? 'hidden' : 
'visible'
                         )
                         .each(function (this: any) {
-                            if (
-                                
!self.nifiCommon.isBlank(processGroupData.component.comments) &&
-                                self.viewContainerRef
-                            ) {
-                                
self.canvasUtils.canvasTooltip(self.viewContainerRef, TextTip, d3.select(this), 
{
+                            if 
(!self.nifiCommon.isBlank(processGroupData.component.comments)) {
+                                self.canvasUtils.canvasTooltip(TextTip, 
d3.select(this), {
                                     text: processGroupData.component.comments
                                 });
                             }
@@ -1293,9 +1288,7 @@ export class ProcessGroupManager {
             // bulletins
             // ---------
 
-            if (self.viewContainerRef) {
-                self.canvasUtils.bulletins(self.viewContainerRef, 
processGroup, d.bulletins);
-            }
+            self.canvasUtils.bulletins(processGroup, d.bulletins);
         });
     }
 
@@ -1311,9 +1304,7 @@ export class ProcessGroupManager {
         return !!d.versionedFlowState;
     }
 
-    public init(viewContainerRef: ViewContainerRef): void {
-        this.viewContainerRef = viewContainerRef;
-
+    public init(): void {
         this.processGroupContainer = d3
             .select('#canvas')
             .append('g')
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts
index 3c628ebcdd..c93ab75dc7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/processor-manager.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { DestroyRef, inject, Injectable, ViewContainerRef } from 
'@angular/core';
+import { DestroyRef, inject, Injectable } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { CanvasState } from '../../state';
 import { CanvasUtils } from '../canvas-utils.service';
@@ -55,8 +55,6 @@ export class ProcessorManager {
     private processorContainer: any;
     private transitionRequired = false;
 
-    private viewContainerRef: ViewContainerRef | undefined;
-
     constructor(
         private store: Store<CanvasState>,
         private canvasUtils: CanvasUtils,
@@ -547,11 +545,8 @@ export class ProcessorManager {
                             
self.nifiCommon.isBlank(processorData.component.config.comments) ? 'hidden' : 
'visible'
                         )
                         .each(function (this: any) {
-                            if (
-                                
!self.nifiCommon.isBlank(processorData.component.config.comments) &&
-                                self.viewContainerRef
-                            ) {
-                                
self.canvasUtils.canvasTooltip(self.viewContainerRef, TextTip, d3.select(this), 
{
+                            if 
(!self.nifiCommon.isBlank(processorData.component.config.comments)) {
+                                self.canvasUtils.canvasTooltip(TextTip, 
d3.select(this), {
                                     text: 
processorData.component.config.comments
                                 });
                             }
@@ -719,8 +714,8 @@ export class ProcessorManager {
             })
             .each(function (this: any, d: any) {
                 // if there are validation errors generate a tooltip
-                if (self.needsTip(d) && self.viewContainerRef) {
-                    self.canvasUtils.canvasTooltip(self.viewContainerRef, 
ValidationErrorsTip, d3.select(this), {
+                if (self.needsTip(d)) {
+                    self.canvasUtils.canvasTooltip(ValidationErrorsTip, 
d3.select(this), {
                         isValidating: d.status.aggregateSnapshot.runStatus === 
'Validating',
                         validationErrors: d.component.validationErrors
                     });
@@ -770,9 +765,7 @@ export class ProcessorManager {
             // bulletins
             // ---------
 
-            if (self.viewContainerRef) {
-                self.canvasUtils.bulletins(self.viewContainerRef, processor, 
d.bulletins);
-            }
+            self.canvasUtils.bulletins(processor, d.bulletins);
         });
     }
 
@@ -817,9 +810,7 @@ export class ProcessorManager {
         return d.status.aggregateSnapshot.executionNode === 'PRIMARY' ? 
'visible' : 'hidden';
     }
 
-    public init(viewContainerRef: ViewContainerRef): void {
-        this.viewContainerRef = viewContainerRef;
-
+    public init(): void {
         this.processorContainer = d3
             .select('#canvas')
             .append('g')
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts
index 343628f52e..8c91b736c7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/remote-process-group-manager.service.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { DestroyRef, inject, Injectable, ViewContainerRef } from 
'@angular/core';
+import { DestroyRef, inject, Injectable } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { CanvasState } from '../../state';
 import { CanvasUtils } from '../canvas-utils.service';
@@ -55,8 +55,6 @@ export class RemoteProcessGroupManager {
     private remoteProcessGroupContainer: any;
     private transitionRequired = false;
 
-    private viewContainerRef: ViewContainerRef | undefined;
-
     constructor(
         private store: Store<CanvasState>,
         private canvasUtils: CanvasUtils,
@@ -442,13 +440,11 @@ export class RemoteProcessGroupManager {
                             return icon;
                         })
                         .each(function (this: any, d: any) {
-                            if (self.viewContainerRef) {
-                                
self.canvasUtils.canvasTooltip(self.viewContainerRef, TextTip, d3.select(this), 
{
-                                    text: d.component.targetSecure
-                                        ? 'Site-to-Site is secure.'
-                                        : 'Site-to-Site is NOT secure.'
-                                });
-                            }
+                            self.canvasUtils.canvasTooltip(TextTip, 
d3.select(this), {
+                                text: d.component.targetSecure
+                                    ? 'Site-to-Site is secure.'
+                                    : 'Site-to-Site is NOT secure.'
+                            });
                         });
 
                     // ---------------
@@ -463,11 +459,8 @@ export class RemoteProcessGroupManager {
                             
self.nifiCommon.isBlank(remoteProcessGroupData.component.comments) ? 'hidden' : 
'visible'
                         )
                         .each(function (this: any) {
-                            if (
-                                
!self.nifiCommon.isBlank(remoteProcessGroupData.component.comments) &&
-                                self.viewContainerRef
-                            ) {
-                                
self.canvasUtils.canvasTooltip(self.viewContainerRef, TextTip, d3.select(this), 
{
+                            if 
(!self.nifiCommon.isBlank(remoteProcessGroupData.component.comments)) {
+                                self.canvasUtils.canvasTooltip(TextTip, 
d3.select(this), {
                                     text: 
remoteProcessGroupData.component.comments
                                 });
                             }
@@ -621,9 +614,9 @@ export class RemoteProcessGroupManager {
             })
             .each(function (this: any, d: any) {
                 // if there are validation errors generate a tooltip
-                if (d.permissions.canRead && self.hasIssues(d) && 
self.viewContainerRef) {
+                if (d.permissions.canRead && self.hasIssues(d)) {
                     // remote process groups combine validation errors and 
authorization issues into a single listing
-                    self.canvasUtils.canvasTooltip(self.viewContainerRef, 
ValidationErrorsTip, d3.select(this), {
+                    self.canvasUtils.canvasTooltip(ValidationErrorsTip, 
d3.select(this), {
                         isValidating: false,
                         validationErrors: self.getIssues(d)
                     });
@@ -643,9 +636,7 @@ export class RemoteProcessGroupManager {
             // bulletins
             // ---------
 
-            if (self.viewContainerRef) {
-                self.canvasUtils.bulletins(self.viewContainerRef, 
remoteProcessGroup, d.bulletins);
-            }
+            self.canvasUtils.bulletins(remoteProcessGroup, d.bulletins);
         });
     }
 
@@ -668,9 +659,7 @@ export class RemoteProcessGroupManager {
         removed.remove();
     }
 
-    public init(viewContainerRef: ViewContainerRef): void {
-        this.viewContainerRef = viewContainerRef;
-
+    public init(): void {
         this.remoteProcessGroupContainer = d3
             .select('#canvas')
             .append('g')
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.ts
index d4755efb85..e238803986 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/canvas.component.ts
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import { Component, OnDestroy, OnInit, ViewContainerRef } from '@angular/core';
+import { Component, OnDestroy, OnInit } from '@angular/core';
 import { CanvasState } from '../../state';
 import { Position } from '../../state/shared';
 import { Store } from '@ngrx/store';
@@ -86,7 +86,6 @@ export class Canvas implements OnInit, OnDestroy {
     private canvasClicked = false;
 
     constructor(
-        private viewContainerRef: ViewContainerRef,
         private store: Store<CanvasState>,
         private canvasView: CanvasView,
         private storage: Storage,
@@ -287,7 +286,7 @@ export class Canvas implements OnInit, OnDestroy {
     ngOnInit(): void {
         // initialize the canvas svg
         this.createSvg();
-        this.canvasView.init(this.viewContainerRef, this.svg, this.canvas);
+        this.canvasView.init(this.svg, this.canvas);
 
         this.store.dispatch(loadFlowConfiguration());
         this.store.dispatch(loadClusterSummary());
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.html
index 6be27a229f..7baa64aae9 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.html
@@ -130,7 +130,7 @@
                     nifiTooltip
                     [tooltipComponentType]="BulletinsTip"
                     [tooltipInputData]="getBulletins()"
-                    [xOffset]="getBulletinTooltipXOffset()"
+                    [position]="getBulletinTooltipPosition()"
                     class="h-8 w-8 controller-bulletins has-bulletins">
                     <i class="fa fa-sticky-note-o"></i>
                 </button>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts
index f6b7c11b20..28fd39d02a 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/flow-status/flow-status.component.ts
@@ -24,6 +24,7 @@ import { BulletinEntity, BulletinsTipInput } from 
'../../../../../../state/share
 import { Search } from '../search/search.component';
 import { NifiTooltipDirective } from 
'../../../../../../ui/common/tooltips/nifi-tooltip.directive';
 import { ClusterSummary } from '../../../../../../state/cluster-summary';
+import { ConnectedPosition } from '@angular/cdk/overlay';
 
 @Component({
     selector: 'flow-status',
@@ -38,6 +39,7 @@ export class FlowStatus {
     @Input() clusterSummary: ClusterSummary | null = null;
     @Input() currentProcessGroupId: string = initialState.id;
     @Input() loadingStatus = false;
+
     @Input() set bulletins(bulletins: BulletinEntity[]) {
         if (bulletins) {
             this.filteredBulletins = bulletins.filter((bulletin) => 
bulletin.canRead);
@@ -129,8 +131,14 @@ export class FlowStatus {
         };
     }
 
-    getBulletinTooltipXOffset(): number {
-        // 500 bulletin tooltip width and 2 * 8 normal tooltip offset
-        return -516;
+    getBulletinTooltipPosition(): ConnectedPosition {
+        return {
+            originX: 'end',
+            originY: 'bottom',
+            overlayX: 'end',
+            overlayY: 'top',
+            offsetX: -8,
+            offsetY: 8
+        };
     }
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.html
index 8b61556009..392fbcfa98 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/manage-remote-ports/manage-remote-ports.component.html
@@ -67,24 +67,20 @@
                                         <td mat-cell *matCellDef="let item">
                                             <div class="flex items-center 
gap-x-2">
                                                 @if (hasComments(item)) {
-                                                    <div>
-                                                        <div
-                                                            class="pointer fa 
fa-comment primary-color"
-                                                            nifiTooltip
-                                                            
[delayClose]="false"
-                                                            
[tooltipComponentType]="TextTip"
-                                                            
[tooltipInputData]="getCommentsTipData(item)"></div>
-                                                    </div>
+                                                    <div
+                                                        class="pointer fa 
fa-comment primary-color"
+                                                        nifiTooltip
+                                                        [delayClose]="false"
+                                                        
[tooltipComponentType]="TextTip"
+                                                        
[tooltipInputData]="getCommentsTipData(item)"></div>
                                                 }
                                                 @if (portExists(item)) {
-                                                    <div>
-                                                        <div
-                                                            class="pointer fa 
fa-warning invalid"
-                                                            nifiTooltip
-                                                            
[delayClose]="false"
-                                                            
[tooltipComponentType]="TextTip"
-                                                            
[tooltipInputData]="getDisconnectedTipData()"></div>
-                                                    </div>
+                                                    <div
+                                                        class="pointer fa 
fa-warning invalid"
+                                                        nifiTooltip
+                                                        [delayClose]="false"
+                                                        
[tooltipComponentType]="TextTip"
+                                                        
[tooltipInputData]="getDisconnectedTipData()"></div>
                                                 }
                                             </div>
                                         </td>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
index 688c3edc00..46c598fa2e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.html
@@ -35,15 +35,13 @@
                                 <div>
                                     {{ item.entity.parameter.name }}
                                 </div>
-                                <div>
-                                    @if (hasDescription(item)) {
-                                        <div
-                                            class="fa fa-question-circle 
primary-color"
-                                            nifiTooltip
-                                            [tooltipComponentType]="TextTip"
-                                            
[tooltipInputData]="getDescriptionTipData(item)"></div>
-                                    }
-                                </div>
+                                @if (hasDescription(item)) {
+                                    <div
+                                        class="fa fa-question-circle 
primary-color"
+                                        nifiTooltip
+                                        [tooltipComponentType]="TextTip"
+                                        
[tooltipInputData]="getDescriptionTipData(item)"></div>
+                                }
                             </div>
                         </td>
                     </ng-container>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html
index c674e92801..620182b6b9 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/flow-analysis-rules/flow-analysis-rule-table/flow-analysis-rule-table.component.html
@@ -37,34 +37,28 @@
                                 title="View Documentation"></div>
                             <!-- TODO - handle read only in configure 
component? -->
                             @if (hasComments(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-comment 
primary-color"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        [tooltipComponentType]="TextTip"
-                                        
[tooltipInputData]="getCommentsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-comment primary-color"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    [tooltipComponentType]="TextTip"
+                                    
[tooltipInputData]="getCommentsTipData(item)"></div>
                             }
                             @if (hasErrors(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-warning 
has-errors"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        
[tooltipComponentType]="ValidationErrorsTip"
-                                        
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-warning has-errors"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    
[tooltipComponentType]="ValidationErrorsTip"
+                                    
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
                             }
                             @if (hasBulletins(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-sticky-note-o 
primary-color"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        [tooltipComponentType]="BulletinsTip"
-                                        
[tooltipInputData]="getBulletinsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-sticky-note-o 
primary-color"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    [tooltipComponentType]="BulletinsTip"
+                                    
[tooltipInputData]="getBulletinsTipData(item)"></div>
                             }
                         </div>
                     }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers-table/parameter-providers-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers-table/parameter-providers-table.component.html
index a7d2165844..12713e56d5 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers-table/parameter-providers-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/parameter-providers/parameter-providers-table/parameter-providers-table.component.html
@@ -43,14 +43,12 @@
 
                                     <!-- Validation Errors -->
                                     @if (hasErrors(item)) {
-                                        <div>
-                                            <div
-                                                class="pointer fa fa-warning 
has-errors"
-                                                nifiTooltip
-                                                [delayClose]="false"
-                                                
[tooltipComponentType]="ValidationErrorsTip"
-                                                
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
-                                        </div>
+                                        <div
+                                            class="pointer fa fa-warning 
has-errors"
+                                            nifiTooltip
+                                            [delayClose]="false"
+                                            
[tooltipComponentType]="ValidationErrorsTip"
+                                            
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
                                     }
                                 </div>
                             }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
index e5b2d05f44..13dbffa452 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/settings/ui/reporting-tasks/reporting-task-table/reporting-task-table.component.html
@@ -37,34 +37,28 @@
                                 title="View Documentation"></div>
                             <!-- TODO - handle read only in configure 
component? -->
                             @if (hasComments(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-comment 
primary-color"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        [tooltipComponentType]="TextTip"
-                                        
[tooltipInputData]="getCommentsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-comment primary-color"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    [tooltipComponentType]="TextTip"
+                                    
[tooltipInputData]="getCommentsTipData(item)"></div>
                             }
                             @if (hasErrors(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-warning 
has-errors"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        
[tooltipComponentType]="ValidationErrorsTip"
-                                        
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-warning has-errors"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    
[tooltipComponentType]="ValidationErrorsTip"
+                                    
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
                             }
                             @if (hasBulletins(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-sticky-note-o 
primary-color"
-                                        [delayClose]="false"
-                                        nifiTooltip
-                                        [tooltipComponentType]="BulletinsTip"
-                                        
[tooltipInputData]="getBulletinsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-sticky-note-o 
primary-color"
+                                    [delayClose]="false"
+                                    nifiTooltip
+                                    [tooltipComponentType]="BulletinsTip"
+                                    
[tooltipInputData]="getBulletinsTipData(item)"></div>
                             }
                         </div>
                     }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-references/controller-service-references.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-references/controller-service-references.component.html
index 42f6a96b6f..4c5244b40e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-references/controller-service-references.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-references/controller-service-references.component.html
@@ -88,17 +88,16 @@
                     <div class="references">
                         @for (reference of references; track reference) {
                             <div class="flex items-center gap-x-2">
-                                <div>
-                                    @if 
(isNonServiceInvalid(reference.component)) {
-                                        <div
-                                            class="invalid fa fa-warning"
-                                            nifiTooltip
-                                            
[tooltipComponentType]="ValidationErrorsTip"
-                                            
[tooltipInputData]="getValidationErrorTipData(reference.component)"></div>
-                                    } @else {
-                                        <div 
[ngClass]="getNonServiceStateIcon(reference.component)"></div>
-                                    }
-                                </div>
+                                @if (isNonServiceInvalid(reference.component)) 
{
+                                    <div
+                                        class="invalid fa fa-warning"
+                                        nifiTooltip
+                                        
[tooltipComponentType]="ValidationErrorsTip"
+                                        
[tooltipInputData]="getValidationErrorTipData(reference.component)"
+                                        [delayClose]="false"></div>
+                                } @else {
+                                    <div 
[ngClass]="getNonServiceStateIcon(reference.component)"></div>
+                                }
                                 <a 
(click)="goToReferencingComponentClicked($event, reference.component)">{{
                                     reference.component.name
                                 }}</a>
@@ -126,17 +125,15 @@
                         @for (service of references; track service) {
                             <div class="flex flex-col">
                                 <div class="flex items-center gap-x-2">
-                                    <div>
-                                        @if 
(isServiceInvalid(service.component)) {
-                                            <div
-                                                class="invalid fa fa-warning"
-                                                nifiTooltip
-                                                
[tooltipComponentType]="ValidationErrorsTip"
-                                                
[tooltipInputData]="getValidationErrorTipData(service.component)"></div>
-                                        } @else {
-                                            <div 
[ngClass]="getServiceStateIcon(service.component)"></div>
-                                        }
-                                    </div>
+                                    @if (isServiceInvalid(service.component)) {
+                                        <div
+                                            class="invalid fa fa-warning"
+                                            nifiTooltip
+                                            
[tooltipComponentType]="ValidationErrorsTip"
+                                            
[tooltipInputData]="getValidationErrorTipData(service.component)"></div>
+                                    } @else {
+                                        <div 
[ngClass]="getServiceStateIcon(service.component)"></div>
+                                    }
                                     <a
                                         
(click)="goToReferencingComponentClicked($event, service.component)"
                                         mat-dialog-close="ROUTED"
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
index 1771491070..0bfb32f119 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/controller-service/controller-service-table/controller-service-table.component.html
@@ -37,34 +37,28 @@
                                 title="View Documentation"></div>
 
                             @if (hasComments(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-comment 
primary-color"
-                                        nifiTooltip
-                                        [delayClose]="false"
-                                        [tooltipComponentType]="TextTip"
-                                        
[tooltipInputData]="getCommentsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-comment primary-color"
+                                    nifiTooltip
+                                    [delayClose]="false"
+                                    [tooltipComponentType]="TextTip"
+                                    
[tooltipInputData]="getCommentsTipData(item)"></div>
                             }
                             @if (hasErrors(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-warning 
has-errors"
-                                        nifiTooltip
-                                        [delayClose]="false"
-                                        
[tooltipComponentType]="ValidationErrorsTip"
-                                        
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-warning has-errors"
+                                    nifiTooltip
+                                    [delayClose]="false"
+                                    
[tooltipComponentType]="ValidationErrorsTip"
+                                    
[tooltipInputData]="getValidationErrorsTipData(item)"></div>
                             }
                             @if (hasBulletins(item)) {
-                                <div>
-                                    <div
-                                        class="pointer fa fa-sticky-note-o 
primary-color"
-                                        nifiTooltip
-                                        [delayClose]="false"
-                                        [tooltipComponentType]="BulletinsTip"
-                                        
[tooltipInputData]="getBulletinsTipData(item)"></div>
-                                </div>
+                                <div
+                                    class="pointer fa fa-sticky-note-o 
primary-color"
+                                    nifiTooltip
+                                    [delayClose]="false"
+                                    [tooltipComponentType]="BulletinsTip"
+                                    
[tooltipInputData]="getBulletinsTipData(item)"></div>
                             }
                         </div>
                     }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/parameter-references/parameter-references.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/parameter-references/parameter-references.component.html
index 7de673df91..3affa59d60 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/parameter-references/parameter-references.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/parameter-references/parameter-references.component.html
@@ -57,17 +57,15 @@
                     <div class="references">
                         @for (reference of references; track reference) {
                             <div class="flex items-center gap-x-2">
-                                <div>
-                                    @if 
(isNonServiceInvalid(reference.component)) {
-                                        <div
-                                            class="invalid fa fa-warning"
-                                            nifiTooltip
-                                            
[tooltipComponentType]="ValidationErrorsTip"
-                                            
[tooltipInputData]="getValidationErrorTipData(reference.component)"></div>
-                                    } @else {
-                                        <div 
[ngClass]="getNonServiceStateIcon(reference.component)"></div>
-                                    }
-                                </div>
+                                @if (isNonServiceInvalid(reference.component)) 
{
+                                    <div
+                                        class="invalid fa fa-warning"
+                                        nifiTooltip
+                                        
[tooltipComponentType]="ValidationErrorsTip"
+                                        
[tooltipInputData]="getValidationErrorTipData(reference.component)"></div>
+                                } @else {
+                                    <div 
[ngClass]="getNonServiceStateIcon(reference.component)"></div>
+                                }
                                 <a 
[routerLink]="getRouteForReference(reference.component)" 
mat-dialog-close="ROUTED">{{
                                     reference.component.name
                                 }}</a>
@@ -95,17 +93,15 @@
                         @for (service of references; track service) {
                             <div class="flex flex-col">
                                 <div class="flex items-center gap-x-2">
-                                    <div>
-                                        @if 
(isServiceInvalid(service.component)) {
-                                            <div
-                                                class="invalid fa fa-warning"
-                                                nifiTooltip
-                                                
[tooltipComponentType]="ValidationErrorsTip"
-                                                
[tooltipInputData]="getValidationErrorTipData(service.component)"></div>
-                                        } @else {
-                                            <div 
[ngClass]="getServiceStateIcon(service.component)"></div>
-                                        }
-                                    </div>
+                                    @if (isServiceInvalid(service.component)) {
+                                        <div
+                                            class="invalid fa fa-warning"
+                                            nifiTooltip
+                                            
[tooltipComponentType]="ValidationErrorsTip"
+                                            
[tooltipInputData]="getValidationErrorTipData(service.component)"></div>
+                                    } @else {
+                                        <div 
[ngClass]="getServiceStateIcon(service.component)"></div>
+                                    }
                                     <a
                                         
[routerLink]="getRouteForReference(service.component)"
                                         mat-dialog-close="ROUTED"
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
index 4dc639d049..ef73a58ed0 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/property-table/property-table.component.html
@@ -36,14 +36,12 @@
                             <div>
                                 {{ item.descriptor.displayName }}
                             </div>
-                            <div>
-                                <div
-                                    class="fa fa-question-circle primary-color"
-                                    nifiTooltip
-                                    [tooltipComponentType]="PropertyTip"
-                                    
[tooltipInputData]="getPropertyTipData(item)"
-                                    [delayClose]="false"></div>
-                            </div>
+                            <div
+                                class="fa fa-question-circle primary-color"
+                                nifiTooltip
+                                [tooltipComponentType]="PropertyTip"
+                                [tooltipInputData]="getPropertyTipData(item)"
+                                [delayClose]="false"></div>
                         </div>
                     </td>
                 </ng-container>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.html
index a01dde05cb..86bc0b7d7c 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip overflow-auto" [style.left.px]="left" [style.top.px]="top">
+<div class="tooltip overflow-auto">
     <ul class="flex flex-wrap gap-y-1">
         @for (bulletinEntity of data?.bulletins; track bulletinEntity) {
             @if (bulletinEntity.canRead) {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.ts
index e40fdf744d..a5e2636980 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/bulletins-tip/bulletins-tip.component.ts
@@ -26,7 +26,5 @@ import { BulletinsTipInput } from '../../../../state/shared';
     styleUrls: ['./bulletins-tip.component.scss']
 })
 export class BulletinsTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: BulletinsTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.html
index b85739a275..db80ca17b7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip flex flex-col gap-y-3" [style.left.px]="left" 
[style.top.px]="top">
+<div class="tooltip flex flex-col gap-y-3">
     <div>Supports Controller Services</div>
     <ul>
         @for (serviceApi of data?.controllerServiceApis; track serviceApi) {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.ts
index d6d4ef954f..68d885ad68 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/controller-service-api-tip/controller-service-api-tip.component.ts
@@ -28,7 +28,5 @@ import { ControllerServiceApi } from 
'../../controller-service/controller-servic
     styleUrls: ['./controller-service-api-tip.component.scss']
 })
 export class ControllerServiceApiTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: ControllerServiceApiTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html
index bf84151567..d956885800 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="el-function-tooltip tooltip" [style.left.px]="left" 
[style.bottom.px]="bottom">
+<div class="el-function-tooltip tooltip">
     @if (data?.elFunction; as elFunction) {
         <div class="flex flex-col gap-y-3">
             <div class="el-name">{{ elFunction.name }}</div>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts
index 17209928ad..6ce25ef196 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/el-function-tip/el-function-tip.component.ts
@@ -29,8 +29,6 @@ import { ControllerServiceApi } from 
'../../controller-service/controller-servic
     styleUrls: ['./el-function-tip.component.scss']
 })
 export class ElFunctionTip {
-    @Input() left = 0;
-    @Input() bottom = 0;
     @Input() data: ElFunctionTipInput | null = null;
 
     constructor(private nifiCommon: NiFiCommon) {}
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/nifi-tooltip.directive.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/nifi-tooltip.directive.ts
index 4341199633..44f71452a3 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/nifi-tooltip.directive.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/nifi-tooltip.directive.ts
@@ -15,63 +15,91 @@
  * limitations under the License.
  */
 
-import { ComponentRef, Directive, HostListener, Input, Type, ViewContainerRef 
} from '@angular/core';
+import { Directive, ElementRef, HostListener, Input, OnDestroy, Type } from 
'@angular/core';
+import { ConnectedPosition, Overlay, OverlayRef, PositionStrategy } from 
'@angular/cdk/overlay';
+import { ComponentPortal } from '@angular/cdk/portal';
 
 @Directive({
     selector: '[nifiTooltip]',
     standalone: true
 })
-export class NifiTooltipDirective<T> {
+export class NifiTooltipDirective<T> implements OnDestroy {
     @Input() tooltipComponentType!: Type<T>;
     @Input() tooltipInputData: any;
-    @Input() xOffset = 0; // TODO - replace pixel based offset with css 
transformY to support positioning above/below
-    @Input() yOffset = 0;
+    @Input() position: ConnectedPosition | undefined;
     @Input() delayClose = true;
 
     private closeTimer = -1;
-    private tooltipRef: ComponentRef<T> | undefined;
+    private overlayRef: OverlayRef | null = null;
 
-    constructor(private viewContainerRef: ViewContainerRef) {}
+    constructor(
+        private element: ElementRef<HTMLElement>,
+        private overlay: Overlay
+    ) {}
 
-    @HostListener('mouseenter', ['$event'])
-    mouseEnter(event: MouseEvent) {
-        if (!event.currentTarget) {
-            return;
+    @HostListener('mouseenter')
+    mouseEnter() {
+        if (!this.overlayRef?.hasAttached()) {
+            this.attach();
         }
-        const target = event.currentTarget as HTMLElement;
-        const { x, y, width, height } = target.getBoundingClientRect();
+    }
+
+    @HostListener('mouseleave')
+    mouseLeave() {
+        if (this.overlayRef?.hasAttached()) {
+            if (this.delayClose) {
+                this.closeTimer = window.setTimeout(() => {
+                    this.overlayRef?.detach();
+                    this.closeTimer = -1;
+                }, 400);
+            } else {
+                this.overlayRef?.detach();
+            }
+        }
+    }
 
-        // clear any existing tooltips
-        this.viewContainerRef.clear();
+    ngOnDestroy(): void {
+        this.overlayRef?.dispose();
+    }
+
+    private attach(): void {
+        if (!this.overlayRef) {
+            const positionStrategy = this.getPositionStrategy();
+            this.overlayRef = this.overlay.create({ positionStrategy });
+        }
 
-        // create and configure the tooltip
-        this.tooltipRef = 
this.viewContainerRef.createComponent(this.tooltipComponentType);
-        this.tooltipRef.setInput('top', y + height + 8 + this.yOffset);
-        this.tooltipRef.setInput('left', x + width + 8 + this.xOffset);
-        this.tooltipRef.setInput('data', this.tooltipInputData);
+        const tooltipReference = this.overlayRef.attach(new 
ComponentPortal(this.tooltipComponentType));
+        tooltipReference.setInput('data', this.tooltipInputData);
 
         // register mouse events
-        this.tooltipRef.location.nativeElement.addEventListener('mouseenter', 
() => {
+        tooltipReference.location.nativeElement.addEventListener('mouseenter', 
() => {
             if (this.closeTimer > 0) {
                 window.clearTimeout(this.closeTimer);
                 this.closeTimer = -1;
             }
         });
-        this.tooltipRef.location.nativeElement.addEventListener('mouseleave', 
() => {
-            this.tooltipRef?.destroy();
+        tooltipReference.location.nativeElement.addEventListener('mouseleave', 
() => {
+            this.overlayRef?.detach();
             this.closeTimer = -1;
         });
     }
 
-    @HostListener('mouseleave', ['$event'])
-    mouseLeave() {
-        if (this.delayClose) {
-            this.closeTimer = window.setTimeout(() => {
-                this.tooltipRef?.destroy();
-                this.closeTimer = -1;
-            }, 400);
-        } else {
-            this.tooltipRef?.destroy();
-        }
+    private getPositionStrategy(): PositionStrategy {
+        return this.overlay
+            .position()
+            .flexibleConnectedTo(this.element)
+            .withPositions([
+                this.position
+                    ? this.position
+                    : {
+                          originX: 'end',
+                          originY: 'bottom',
+                          overlayX: 'start',
+                          overlayY: 'top',
+                          offsetX: 8,
+                          offsetY: 8
+                      }
+            ])
+            .withPush(true);
     }
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html
index 4276b9d12a..0f8a99ae63 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.bottom.px]="bottom">
+<div class="tooltip">
     @if (data?.parameter; as parameter) {
         <div class="flex flex-col gap-y-3">
             <div class="parameter-name">{{ parameter.name }}</div>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts
index d71082a5c7..850b588bf2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/parameter-tip/parameter-tip.component.ts
@@ -29,8 +29,6 @@ import { ControllerServiceApi } from 
'../../controller-service/controller-servic
     styleUrls: ['./parameter-tip.component.scss']
 })
 export class ParameterTip {
-    @Input() left = 0;
-    @Input() bottom = 0;
     @Input() data: ParameterTipInput | null = null;
 
     constructor(private nifiCommon: NiFiCommon) {}
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html
index 09457c4e2d..9d2da78784 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.top.px]="top">
+<div class="tooltip">
     <div class="flex flex-col gap-y-3">
         <ng-container *ngTemplateOutlet="data?.supportsEl ? elSupported : 
elNotSupported"></ng-container>
         <ng-container *ngTemplateOutlet="data?.supportsParameters ? 
paramSupported : paramNotSupported"></ng-container>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts
index 47a35f5fc3..115a4e07c7 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-hint-tip/property-hint-tip.component.ts
@@ -28,7 +28,5 @@ import { ControllerServiceApi } from 
'../../controller-service/controller-servic
     styleUrls: ['./property-hint-tip.component.scss']
 })
 export class PropertyHintTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: PropertyHintTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.html
index 33e160f598..f094092019 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.top.px]="top">
+<div class="tooltip">
     <div class="flex flex-col gap-y-3">
         @if (data?.descriptor; as descriptor) {
             @if (hasDescription(descriptor)) {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.ts
index 0bec15a57c..9ada96d36f 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/property-tip/property-tip.component.ts
@@ -29,8 +29,6 @@ import { ControllerServiceApi } from 
'../../controller-service/controller-servic
     styleUrls: ['./property-tip.component.scss']
 })
 export class PropertyTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: PropertyTipInput | undefined;
 
     constructor(private nifiCommon: NiFiCommon) {}
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.html
index 8cb516c1f6..daff2876f3 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip flex flex-col gap-y-3" [style.left.px]="left" 
[style.top.px]="top">
+<div class="tooltip flex flex-col gap-y-3">
     <div>
         {{ getUsageRestriction() }}
     </div>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.ts
index f76c5e5924..1f48fc2fee 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/restrictions-tip/restrictions-tip.component.ts
@@ -28,8 +28,6 @@ import { NiFiCommon } from 
'../../../../service/nifi-common.service';
     styleUrls: ['./restrictions-tip.component.scss']
 })
 export class RestrictionsTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: RestrictionsTipInput | undefined;
 
     constructor(private nifiCommon: NiFiCommon) {}
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.html
index efba5c26d7..21b44f1685 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.html
@@ -15,4 +15,4 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.top.px]="top">{{ data?.text 
}}</div>
+<div class="tooltip">{{ data?.text }}</div>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.ts
index bfd8aaa92e..a733824320 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/text-tip/text-tip.component.ts
@@ -25,7 +25,5 @@ import { TextTipInput } from '../../../../state/shared';
     styleUrls: ['./text-tip.component.scss']
 })
 export class TextTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: TextTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.html
index e4b464ff7d..6adb8a0536 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.top.px]="top">
+<div class="tooltip">
     <ul>
         @for (item of data?.items; track item) {
             <li>{{ item }}</li>
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.ts
index 43d94f4577..985c97d33d 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/unordered-list-tip/unordered-list-tip.component.ts
@@ -26,7 +26,5 @@ import { UnorderedListTipInput } from 
'../../../../state/shared';
     styleUrls: ['./unordered-list-tip.component.scss']
 })
 export class UnorderedListTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: UnorderedListTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.html
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.html
index ce90ba4f9c..4c35bb62e8 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.html
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<div class="tooltip" [style.left.px]="left" [style.top.px]="top">
+<div class="tooltip">
     @if (data?.isValidating) {
         <span>Validating...</span>
     } @else {
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.ts
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.ts
index 6bdc246e39..7d8a6d284e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.ts
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/ui/common/tooltips/validation-errors-tip/validation-errors-tip.component.ts
@@ -26,7 +26,5 @@ import { ValidationErrorsTipInput } from 
'../../../../state/shared';
     styleUrls: ['./validation-errors-tip.component.scss']
 })
 export class ValidationErrorsTip {
-    @Input() left = 0;
-    @Input() top = 0;
     @Input() data: ValidationErrorsTipInput | undefined;
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/_app.scss
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/_app.scss
index 23c6231a7f..8ae8689fcb 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/_app.scss
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/assets/styles/_app.scss
@@ -65,7 +65,6 @@
     }
 
     .tooltip {
-        position: fixed;
         max-width: 500px;
         padding: 10px;
         border-radius: 2px;
@@ -75,7 +74,6 @@
         font-weight: 400;
         word-wrap: break-word;
         white-space: normal;
-        z-index: 1;
 
         ul {
             list-style: disc outside;


Reply via email to