Skip to content

Commit 3be92fa

Browse files
authored
Merge pull request #1733 from guilherme-gm/fix-rightpanel
fix(cv-header): fix crash when focusing out of right panels
2 parents 1c05423 + 6eb9603 commit 3be92fa

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

src/components/CvUIShell/CvHeader.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,10 @@ function onCvPanelFocusout(payload) {
192192
item => item.ariaControls === srcComponent.id
193193
);
194194
if (
195-
srcComponent.el !== srcEvent.relatedTarget &&
196-
!srcComponent.el.contains(srcEvent.relatedTarget) &&
195+
srcComponent.el.value !== srcEvent.relatedTarget &&
196+
!srcComponent.el.value.contains(srcEvent.relatedTarget) &&
197197
found &&
198-
found.el !== srcEvent.relatedTarget
198+
found.el.value !== srcEvent.relatedTarget
199199
) {
200200
onCvPanelControlToggle(found, false);
201201
}

src/components/CvUIShell/__tests__/CvHeader.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import CvSideNavItems from '../CvSideNavItems.vue';
99
import CvSideNavMenu from '../CvSideNavMenu.vue';
1010
import CvSideNavMenuItem from '../CvSideNavMenuItem.vue';
1111
import CvSideNavLink from '../CvSideNavLink.vue';
12+
import PanelFocusTestComponent from './PanelFocusTestComponent.vue';
13+
import { nextTick } from 'vue';
1214

1315
const globalHeader = {
1416
components: { CvHeaderGlobalAction },
@@ -101,6 +103,52 @@ describe('CvHeader', () => {
101103
expect(onResize.mock.calls.length).toBe(2);
102104
});
103105

106+
it('should allow user to focus between elements in the right panel', async () => {
107+
const user = userEvent.setup();
108+
const component = render(PanelFocusTestComponent);
109+
110+
const testPanel = await component.findByTestId('links-panel');
111+
expect(testPanel.getAttribute('aria-hidden')).toBe('true'); // panel is closed
112+
113+
const actionButton = await component.findByTestId('action-button');
114+
await user.click(actionButton);
115+
116+
expect(testPanel.getAttribute('aria-hidden')).toBe('false'); // panel is open
117+
118+
const link1 = await component.findByTestId('link-1');
119+
const link2 = await component.findByTestId('link-2');
120+
121+
link1.focus();
122+
expect(testPanel.getAttribute('aria-hidden')).toBe('false');
123+
124+
link2.focus();
125+
expect(testPanel.getAttribute('aria-hidden')).toBe('false');
126+
});
127+
128+
it('should close the right panel when focusing out of its elements', async () => {
129+
const user = userEvent.setup();
130+
const component = render(PanelFocusTestComponent);
131+
132+
const testPanel = await component.findByTestId('links-panel');
133+
expect(testPanel.getAttribute('aria-hidden')).toBe('true'); // panel is closed
134+
135+
const actionButton = await component.findByTestId('action-button');
136+
await user.click(actionButton);
137+
138+
expect(testPanel.getAttribute('aria-hidden')).toBe('false'); // panel is open
139+
140+
const link1 = await component.findByTestId('link-1');
141+
link1.focus();
142+
expect(testPanel.getAttribute('aria-hidden')).toBe('false');
143+
144+
const outerInput = await component.findByTestId('outer-input');
145+
outerInput.focus();
146+
147+
await nextTick();
148+
149+
expect(testPanel.getAttribute('aria-hidden')).toBe('true'); // panel is closed
150+
});
151+
104152
it('CvHeader - side nav rail', async () => {
105153
const result = render(CvHeader, {
106154
slots: {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<script setup>
2+
import CvHeader from '../CvHeader.vue';
3+
import CvHeaderGlobalAction from '../CvHeaderGlobalAction.vue';
4+
import CvHeaderPanel from '../CvHeaderPanel.vue';
5+
import CvSwitcher from '../CvSwitcher.vue';
6+
import CvSwitcherItem from '../CvSwitcherItem.vue';
7+
import CvSwitcherItemLink from '../CvSwitcherItemLink.vue';
8+
</script>
9+
10+
<template>
11+
<cv-header>
12+
<template #header-global>
13+
<cv-header-global-action
14+
data-testid="action-button"
15+
aria-label="List links"
16+
aria-controls="links-panel"
17+
label="Links"
18+
>
19+
Links
20+
</cv-header-global-action>
21+
</template>
22+
<template #right-panels>
23+
<cv-header-panel id="links-panel" data-testid="links-panel">
24+
<cv-switcher>
25+
<cv-switcher-item>
26+
<cv-switcher-item-link
27+
href="javascript:void(0)"
28+
data-testid="link-1"
29+
selected
30+
>
31+
Selected app
32+
</cv-switcher-item-link>
33+
</cv-switcher-item>
34+
<cv-switcher-item>
35+
<cv-switcher-item-link
36+
href="javascript:void(0)"
37+
data-testid="link-2"
38+
>
39+
Other app
40+
</cv-switcher-item-link>
41+
</cv-switcher-item>
42+
</cv-switcher>
43+
</cv-header-panel>
44+
</template>
45+
</cv-header>
46+
<input type="text" data-testid="outer-input" />
47+
</template>

0 commit comments

Comments
 (0)