diff --git a/packages/components/src/components/tooltip/tooltip.e2e.ts b/packages/components/src/components/tooltip/tooltip.e2e.ts new file mode 100644 index 0000000000..be464c555b --- /dev/null +++ b/packages/components/src/components/tooltip/tooltip.e2e.ts @@ -0,0 +1,51 @@ +/** + * @license + * Scale https://github.com/telekom/scale + * + * Copyright (c) 2021 Egor Kirpichev and contributors, Deutsche Telekom AG + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +import { newE2EPage } from '@stencil/core/testing'; + +describe('scale-tooltip', () => { + it('keeps a bottom tooltip horizontally centered on an icon trigger near the viewport edge', async () => { + const page = await newE2EPage(); + await page.setViewport({ width: 320, height: 240 }); + await page.setContent(` +
+ + + +
+ `); + await page.waitForChanges(); + await page.evaluate( + () => new Promise((resolve) => setTimeout(resolve, 100)) + ); + + const geometry = await page.evaluate(() => { + const trigger = document.querySelector('#trigger'); + const tooltip = document + .querySelector('scale-tooltip') + .shadowRoot.querySelector('[part="tooltip"]'); + const triggerRect = trigger.getBoundingClientRect(); + const tooltipRect = tooltip.getBoundingClientRect(); + + return { + gap: Math.round(tooltipRect.top - triggerRect.bottom), + centerDelta: Math.round( + tooltipRect.left + + tooltipRect.width / 2 - + (triggerRect.left + triggerRect.width / 2) + ), + }; + }); + + expect(geometry.gap).toBe(10); + expect(Math.abs(geometry.centerDelta)).toBeLessThanOrEqual(1); + }); +}); diff --git a/packages/components/src/components/tooltip/tooltip.tsx b/packages/components/src/components/tooltip/tooltip.tsx index 5e17228c4e..53498ec9c3 100644 --- a/packages/components/src/components/tooltip/tooltip.tsx +++ b/packages/components/src/components/tooltip/tooltip.tsx @@ -165,7 +165,7 @@ export class Tooltip { offset(this.distance), ...(this.flip ? [flip()] : []), arrow({ element: this.arrowEl, padding: this.arrowPadding }), - shift({ crossAxis: true }), + shift({ mainAxis: false }), ], platform: { ...platform, diff --git a/packages/components/src/html/bills-data-grid.html b/packages/components/src/html/bills-data-grid.html new file mode 100644 index 0000000000..d398445dcd --- /dev/null +++ b/packages/components/src/html/bills-data-grid.html @@ -0,0 +1,493 @@ + + + + + + + Bills data-grid – Tooltip placement reproduction (Issue #2289) + + + + + + + + + +
+ +
+

bills (10)

+ + Mehr + + +
+ + +
+ +
+ + + +
+
Monatliche Rechnung
+
23.06.2023
+
+
+
56,99 €
+
+ + + +
+ +
+ + + + + + +
+
Monatliche Rechnung
+
23.06.2023
+
+
+
56,99 €
+
+ + +
+ +
+ + + +
+
Monatliche Rechnung
+
23.06.2023
+
+
+
56,99 €
+
+ + +
+ +
+ + + +
+
Monatliche Rechnung
+
23.06.2023
+
+
+
56,99 €
+
+ + +
+ Issue #2289 – tooltip placement: + The pre-opened tooltip on row 2 uses + placement="bottom" with a + single-element icon trigger + (<scale-icon-process-sepa-transaction>).
+ For a single inline element the tooltip anchor is correct because + getBoundingClientRect() returns one box.
+ The bug manifests when the trigger is a + multiline inline text span: the tooltip uses the full + combined box instead of the line box under the cursor. See + bills-data-grid-multiline-repro.html (vanilla example) for + the failing case. +
+
+ +
+

Tooltip placement – single icon trigger

+ +

+ This example keeps the trigger as a single SEPA icon near the viewport + edge. Before the fix, shift({ crossAxis: true }) moved the + tooltip horizontally so it appeared beside the icon instead of pointing + at it. +

+ + + + + + + + + + + + + +
+ Live geometry (updates on hover): + + +
+
+
+ + + +