Skip to content

Commit 20fb229

Browse files
fix(Truncate): remove resize observer (#12055)
* chore(release): releasing packages [ci skip] - @patternfly/[email protected] - @patternfly/[email protected] - @patternfly/[email protected] - @patternfly/[email protected] - [email protected] - @patternfly/[email protected] - @patternfly/[email protected] * check truncated before showing tooltip Signed-off-by: gitdallas <[email protected]> * cypress fix Signed-off-by: gitdallas <[email protected]> * truncate to false initially for better tabindex Signed-off-by: gitdallas <[email protected]> * bring back resizeObserver with debounce so tabIndex updates Signed-off-by: gitdallas <[email protected]> * start from main and add debounce Signed-off-by: gitdallas <[email protected]> * cleanup Signed-off-by: gitdallas <[email protected]> * add clipboardcopy truncate integration test Signed-off-by: gitdallas <[email protected]> --------- Signed-off-by: gitdallas <[email protected]> Co-authored-by: patternfly-build <[email protected]>
1 parent 9127294 commit 20fb229

File tree

4 files changed

+61
-16
lines changed

4 files changed

+61
-16
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { render, screen } from '@testing-library/react';
2+
import userEvent from '@testing-library/user-event';
3+
import { ClipboardCopy, ClipboardCopyVariant } from '../ClipboardCopy';
4+
5+
// This test file uses the real Truncate component for integration testing, instead of a mock
6+
7+
test('Tooltip appears on keyboard focus when using inline-compact variant with truncation', async () => {
8+
const user = userEvent.setup();
9+
const longText = 'This is a very long piece of content that should be truncated when the container is too small';
10+
11+
render(
12+
<ClipboardCopy
13+
variant={ClipboardCopyVariant.inlineCompact}
14+
truncation={{ maxCharsDisplayed: 20 }}
15+
data-testid="clipboard-copy"
16+
>
17+
{longText}
18+
</ClipboardCopy>
19+
);
20+
21+
expect(screen.queryByText(longText)).not.toBeInTheDocument();
22+
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
23+
24+
await user.tab();
25+
26+
const clipboardCopy = screen.getByTestId('clipboard-copy');
27+
expect(clipboardCopy).toHaveFocus();
28+
29+
const tooltip = screen.getByRole('tooltip');
30+
expect(tooltip).toBeInTheDocument();
31+
expect(tooltip).toHaveTextContent(longText);
32+
});

packages/react-core/src/components/Truncate/Truncate.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { css } from '@patternfly/react-styles';
44
import { Tooltip, TooltipPosition, TooltipProps } from '../Tooltip';
55
import { getReferenceElement } from '../../helpers';
66
import { getResizeObserver } from '../../helpers/resizeObserver';
7+
import { debounce } from '../../helpers/util';
78

89
export enum TruncatePosition {
910
start = 'start',
@@ -130,12 +131,12 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
130131
const totalTextWidth = calculateTotalTextWidth(textElement, trailingNumChars, content);
131132
const textWidth = position === 'middle' ? totalTextWidth : textElement.scrollWidth;
132133

133-
const handleResize = () => {
134+
const debouncedHandleResize = debounce(() => {
134135
const parentWidth = getActualWidth(parentElement);
135136
setIsTruncated(textWidth >= parentWidth);
136-
};
137+
}, 500);
137138

138-
const observer = getResizeObserver(parentElement, handleResize);
139+
const observer = getResizeObserver(parentElement, debouncedHandleResize);
139140

140141
return () => {
141142
observer();
@@ -147,7 +148,7 @@ const TruncateBase: React.FunctionComponent<TruncateProps> = ({
147148
if (shouldRenderByMaxChars) {
148149
setIsTruncated(content.length > maxCharsDisplayed);
149150
}
150-
}, [shouldRenderByMaxChars]);
151+
}, [shouldRenderByMaxChars, content.length, maxCharsDisplayed]);
151152

152153
useEffect(() => {
153154
setShouldRenderByMaxChars(maxCharsDisplayed > 0);

packages/react-core/src/components/Truncate/__tests__/Truncate.test.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { render, screen, within } from '@testing-library/react';
2-
import { Truncate, TruncatePosition } from '../Truncate';
1+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
2+
import { Truncate } from '../Truncate';
33
import styles from '@patternfly/react-styles/css/components/Truncate/truncate';
44
import '@testing-library/jest-dom';
55

66
jest.mock('../../Tooltip', () => ({
77
Tooltip: ({ content, position, children, triggerRef, ...props }) => (
88
<div data-testid="Tooltip-mock" {...props}>
9-
<div data-testid="Tooltip-mock-content-container">Test {content}</div>
9+
<div>Test {content}</div>
1010
<p>{`position: ${position}`}</p>
1111
{children}
1212
</div>
@@ -242,3 +242,21 @@ describe('Truncation with maxCharsDisplayed', () => {
242242
expect(asFragment()).toMatchSnapshot();
243243
});
244244
});
245+
246+
test('Tooltip appears on keyboard focus when external triggerRef is provided (ClipboardCopy regression test)', () => {
247+
const mockTriggerRef = { current: document.createElement('div') };
248+
249+
render(
250+
<Truncate
251+
content="This is a very long piece of content that should be truncated when the container is too small"
252+
tooltipProps={{ triggerRef: mockTriggerRef }}
253+
/>
254+
);
255+
256+
// Simulate keyboard focus on the external trigger element
257+
fireEvent.focus(mockTriggerRef.current);
258+
259+
// The tooltip should be present and visible
260+
const tooltip = screen.getByTestId('Tooltip-mock');
261+
expect(tooltip).toBeInTheDocument();
262+
});

packages/react-core/src/components/Truncate/__tests__/__snapshots__/Truncate.test.tsx.snap

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ exports[`Truncation with maxCharsDisplayed Matches snapshot with default positio
55
<div
66
data-testid="Tooltip-mock"
77
>
8-
<div
9-
data-testid="Tooltip-mock-content-container"
10-
>
8+
<div>
119
Test Test truncation content
1210
</div>
1311
<p>
@@ -43,9 +41,7 @@ exports[`renders default truncation 1`] = `
4341
<div
4442
data-testid="Tooltip-mock"
4543
>
46-
<div
47-
data-testid="Tooltip-mock-content-container"
48-
>
44+
<div>
4945
Test Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
5046
</div>
5147
<p>
@@ -70,9 +66,7 @@ exports[`renders start truncation with &lrm; at start and end 1`] = `
7066
<div
7167
data-testid="Tooltip-mock"
7268
>
73-
<div
74-
data-testid="Tooltip-mock-content-container"
75-
>
69+
<div>
7670
Test Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.
7771
</div>
7872
<p>

0 commit comments

Comments
 (0)