Skip to content

Commit 6af9f68

Browse files
fix: popover focus management fix (#20276)
Co-authored-by: NikhilTomar-sev1 <NIKHIL.TOMAR@ibm.com>
1 parent 41da4bd commit 6af9f68

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

packages/react/src/components/Popover/__tests__/Popover-test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import React from 'react';
1010
import { Popover, PopoverContent } from '../../Popover';
1111
import userEvent from '@testing-library/user-event';
1212
import { waitForPosition } from '../../ListBox/test-helpers';
13+
import RadioButton from '../../RadioButton';
14+
import RadioButtonGroup from '../../RadioButtonGroup';
15+
import { default as Checkbox } from '../../Checkbox';
1316

1417
const prefix = 'cds';
1518

@@ -313,4 +316,42 @@ describe('Popover', () => {
313316
await userEvent.click(screen.getByTestId('inside-input'));
314317
expect(onRequestClose).not.toHaveBeenCalled();
315318
});
319+
it('should not close TabTip when interacting with form elements inside', async () => {
320+
const onRequestClose = jest.fn();
321+
render(
322+
<Popover open isTabTip onRequestClose={onRequestClose}>
323+
<button type="button">Settings</button>
324+
<PopoverContent>
325+
<RadioButtonGroup legendText="Test options">
326+
<RadioButton
327+
labelText="Option 1"
328+
value="option1"
329+
id="tabtip-radio-1"
330+
data-testid="tabtip-radio-1"
331+
/>
332+
<RadioButton
333+
labelText="Option 2"
334+
value="option2"
335+
id="tabtip-radio-2"
336+
data-testid="tabtip-radio-2"
337+
/>
338+
</RadioButtonGroup>
339+
<Checkbox
340+
labelText="Test checkbox"
341+
id="tabtip-checkbox"
342+
data-testid="tabtip-checkbox"
343+
/>
344+
</PopoverContent>
345+
</Popover>
346+
);
347+
348+
await userEvent.click(screen.getByTestId('tabtip-radio-1'));
349+
expect(onRequestClose).not.toHaveBeenCalled();
350+
351+
await userEvent.click(screen.getByTestId('tabtip-radio-2'));
352+
expect(onRequestClose).not.toHaveBeenCalled();
353+
354+
await userEvent.click(screen.getByTestId('tabtip-checkbox'));
355+
expect(onRequestClose).not.toHaveBeenCalled();
356+
});
316357
});

packages/react/src/components/Popover/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,13 @@ export const Popover: PopoverComponent & {
186186
// The `Popover` should close whenever it and its children loses focus
187187
useEvent(popover, 'focusout', (event) => {
188188
const relatedTarget = (event as FocusEvent).relatedTarget as Node | null;
189+
if (isTabTip) {
190+
if (relatedTarget && !popover.current?.contains(relatedTarget)) {
191+
onRequestClose?.();
192+
}
193+
return;
194+
}
189195

190-
// No relatedTarget, focus moved to nowhere, so close the popover
191196
if (!relatedTarget) {
192197
onRequestClose?.();
193198
return;

0 commit comments

Comments
 (0)