Skip to content

Commit 304c4d6

Browse files
committed
[LG-5488] fix(code-editor): open copy button tooltip on click
CodeEditorCopyButton duplicates Code's CopyButton and needed the same openTooltip() patch, since focus no longer opens the tooltip after mouse usage. Also note LeafyGreenProvider requirement in changeset and dedupe Tooltip spec render helper.
1 parent e56eaf6 commit 304c4d6

4 files changed

Lines changed: 52 additions & 22 deletions

File tree

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
'@leafygreen-ui/tooltip': patch
33
'@leafygreen-ui/code': patch
4+
'@leafygreen-ui/code-editor': patch
45
---
56

6-
[LG-5488](https://jira.mongodb.org/browse/LG-5488): `Tooltip` no longer opens when its trigger receives focus from mouse interaction or programmatic focus (e.g. focus restored after closing a modal). It still opens when focus comes from keyboard navigation. `Code`'s copy button now explicitly opens its tooltip on click to continue showing the copied confirmation.
7+
[LG-5488](https://jira.mongodb.org/browse/LG-5488): `Tooltip` no longer opens when its trigger receives focus from mouse interaction or programmatic focus (e.g. focus restored after closing a modal). It still opens when focus comes from keyboard navigation. Keyboard detection requires the app to be wrapped in `LeafyGreenProvider`; without one, focus continues to open the tooltip as before. The copy buttons in `Code` and `CodeEditor` now explicitly open their tooltips on click to continue showing the copied confirmation.

packages/code-editor/src/CodeEditorCopyButton/CodeEditorCopyButton.spec.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import React from 'react';
2-
import { act, render, screen, waitFor } from '@testing-library/react';
2+
import {
3+
act,
4+
fireEvent,
5+
render,
6+
screen,
7+
waitFor,
8+
} from '@testing-library/react';
39
import userEvent from '@testing-library/user-event';
410

11+
import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider';
12+
513
import { CodeEditorCopyButton } from './CodeEditorCopyButton';
614
import { CopyButtonVariant } from './CodeEditorCopyButton.types';
715
import { COPIED_SUCCESS_DURATION, COPIED_TEXT, COPY_TEXT } from './constants';
@@ -109,6 +117,35 @@ describe('CodeEditorCopyButton', () => {
109117
});
110118
});
111119

120+
test('opens tooltip with copied text on keyboard activation after mouse usage', async () => {
121+
render(
122+
<LeafyGreenProvider>
123+
<CodeEditorCopyButton
124+
getContentsToCopy={mockgetContentsToCopy}
125+
onCopy={mockOnCopy}
126+
/>
127+
</LeafyGreenProvider>,
128+
);
129+
130+
const button = screen.getByRole('button', { name: COPY_TEXT });
131+
132+
// Mouse usage sets usingKeyboard to false, so the focus from
133+
// Enter activation no longer opens the tooltip — the click
134+
// handler must open it explicitly
135+
await act(async () => {
136+
fireEvent.mouseDown(document.body);
137+
});
138+
139+
await act(async () => {
140+
button.focus();
141+
await userEvent.keyboard('{Enter}');
142+
});
143+
144+
await waitFor(() => {
145+
expect(screen.getByRole('tooltip')).toHaveTextContent(COPIED_TEXT);
146+
});
147+
});
148+
112149
test('shows copied text in tooltip after successful copy', async () => {
113150
render(
114151
<CodeEditorCopyButton

packages/code-editor/src/CodeEditorCopyButton/CodeEditorCopyButton.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ export function CodeEditorCopyButton({
104104
await copyToClipboard();
105105
onCopy?.();
106106
setCopied(true);
107+
// Explicitly open the tooltip to show the copied confirmation,
108+
// since focus alone no longer opens the tooltip
109+
openTooltip();
107110

108111
setTimeout(() => {
109112
setCopied(false);

packages/tooltip/src/Tooltip/Tooltip.spec.tsx

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { createRef, ReactElement } from 'react';
22
import {
33
act,
44
render,
5+
RenderOptions,
56
screen,
67
waitFor,
78
waitForElementToBeRemoved,
@@ -66,6 +67,7 @@ function renderTooltip(
6667
{ renderMode?: 'portal'; portalClassName?: string },
6768
{ renderMode: 'inline' | 'top-layer' }
6869
> = {},
70+
options?: Pick<RenderOptions, 'wrapper'>,
6971
) {
7072
const utils = render(
7173
<>
@@ -78,6 +80,7 @@ function renderTooltip(
7880
<div>Tooltip Contents!</div>
7981
</Tooltip>
8082
</>,
83+
options,
8184
);
8285

8386
const button = utils.getByText(buttonText);
@@ -159,29 +162,15 @@ describe('packages/tooltip', () => {
159162
});
160163

161164
describe('when "triggerEvent" is "hover", focusing the trigger (LG-5488)', () => {
162-
const renderTooltipWithProvider = () => {
163-
const utils = render(
164-
<LeafyGreenProvider>
165-
<div data-testid="backdrop" />
166-
<Tooltip
167-
trigger={<button>{buttonText}</button>}
168-
data-testid={tooltipTestId}
169-
triggerEvent="hover"
170-
>
171-
<div>Tooltip Contents!</div>
172-
</Tooltip>
173-
</LeafyGreenProvider>,
165+
// LeafyGreenProvider is required for keyboard detection
166+
const renderTooltipWithProvider = () =>
167+
renderTooltip(
168+
{ triggerEvent: 'hover' },
169+
{ wrapper: LeafyGreenProvider },
174170
);
175171

176-
const button = utils.getByText(buttonText);
177-
const backdrop = utils.getByTestId('backdrop');
178-
179-
return { ...utils, button, backdrop };
180-
};
181-
182172
test('does not open the tooltip when focus follows mouse usage', async () => {
183-
const { queryByTestId, button, backdrop } =
184-
renderTooltipWithProvider();
173+
const { queryByTestId, button, backdrop } = renderTooltipWithProvider();
185174

186175
// Mouse usage sets usingKeyboard to false
187176
await userEvent.click(backdrop);

0 commit comments

Comments
 (0)