diff --git a/modules/react/tooltip/lib/OverflowTooltip.tsx b/modules/react/tooltip/lib/OverflowTooltip.tsx
index 9784d12352..3eb39992ec 100644
--- a/modules/react/tooltip/lib/OverflowTooltip.tsx
+++ b/modules/react/tooltip/lib/OverflowTooltip.tsx
@@ -55,6 +55,11 @@ export const findEllipsisElement = (element: Element): Element | null => {
}
};
+const getInnerText = (element: Element): string => {
+ const ownerWindow = element.ownerDocument?.defaultView;
+ return ownerWindow && element instanceof ownerWindow.HTMLElement ? element.innerText : '';
+};
+
const isOverflowed = (element: Element) => {
const overflowElement = findEllipsisElement(element) || findOverflowElement(element);
@@ -134,14 +139,14 @@ export const OverflowTooltip = ({
const onMouseEnter = (event: React.MouseEvent) => {
const target = event.currentTarget;
- setTitleText(target instanceof HTMLElement ? target.innerText : '');
+ setTitleText(getInnerText(target));
if (isOverflowed(target)) {
targetProps.onMouseEnter(event as React.MouseEvent);
}
};
const onFocus = (event: React.FocusEvent) => {
const target = event.currentTarget;
- setTitleText(target instanceof HTMLElement ? target.innerText : '');
+ setTitleText(getInnerText(target));
if (isOverflowed(target)) {
targetProps.onFocus(event as React.FocusEvent);
}
diff --git a/modules/react/tooltip/spec/OverflowTooltip.spec.tsx b/modules/react/tooltip/spec/OverflowTooltip.spec.tsx
index f618884c0c..d0af9a9366 100644
--- a/modules/react/tooltip/spec/OverflowTooltip.spec.tsx
+++ b/modules/react/tooltip/spec/OverflowTooltip.spec.tsx
@@ -1,4 +1,4 @@
-import {fireEvent, render, screen} from '@testing-library/react';
+import {fireEvent, render, screen, within} from '@testing-library/react';
import {act} from 'react-dom/test-utils';
import {OverflowTooltip, findEllipsisElement, findOverflowElement} from '..';
@@ -29,6 +29,7 @@ describe('OverflowTooltip', () => {
const markAsOverflowed = (target: HTMLElement) => {
Object.defineProperty(target, 'scrollWidth', {configurable: true, value: 200});
Object.defineProperty(target, 'clientWidth', {configurable: true, value: 100});
+ Object.defineProperty(target, 'innerText', {configurable: true, value: target.textContent});
};
it('should render the tooltip after the delay when "showDelay" is passed', () => {
@@ -54,6 +55,57 @@ describe('OverflowTooltip', () => {
expect(screen.getByRole('tooltip')).toBeInTheDocument();
});
+ it('should show the target text in the tooltip when the target is overflowed', () => {
+ render(
+
+ Overflowed Text
+
+ );
+
+ const target = screen.getByText('Overflowed Text');
+ markAsOverflowed(target);
+
+ fireEvent.mouseEnter(target);
+
+ act(() => {
+ vi.advanceTimersByTime(500);
+ });
+ expect(screen.getByRole('tooltip')).toHaveTextContent('Overflowed Text');
+ });
+
+ it('should show the target text when the target is in a different window realm', () => {
+ const testWindow = document.createElement('iframe');
+ document.body.appendChild(testWindow);
+
+ const containerBody = testWindow.contentDocument?.body;
+ if (!containerBody) {
+ throw new Error('iframe contentDocument not available');
+ }
+
+ const {unmount} = render(
+
+ Overflowed Text
+ ,
+ {container: containerBody}
+ );
+
+ try {
+ const target = within(containerBody).getByText('Overflowed Text');
+ markAsOverflowed(target);
+
+ fireEvent.mouseEnter(target);
+
+ act(() => {
+ vi.advanceTimersByTime(500);
+ });
+ // Use textContent directly: toHaveTextContent() uses instanceof Node and fails across window realms
+ expect(within(containerBody).getByRole('tooltip').textContent).toBe('Overflowed Text');
+ } finally {
+ unmount();
+ testWindow.remove();
+ }
+ });
+
it('should hide the tooltip after the delay when "hideDelay" is passed', () => {
render(