Skip to content

Commit 7756845

Browse files
authored
fix: correct Compass Context Menu wrapper usage (#7042)
1 parent cb9d596 commit 7756845

File tree

3 files changed

+63
-7
lines changed

3 files changed

+63
-7
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import { render } from '@mongodb-js/testing-library-compass';
3+
import { expect } from 'chai';
4+
import { ContextMenuProvider } from './context-menu-provider';
5+
import type { ContextMenuWrapperProps } from './types';
6+
7+
describe('ContextMenuProvider', function () {
8+
const TestMenu: React.FC<ContextMenuWrapperProps> = () => (
9+
<div data-testid="test-menu">Test Menu</div>
10+
);
11+
12+
const TestComponent = () => (
13+
<div data-testid="test-content">Test Content</div>
14+
);
15+
16+
describe('when nested', function () {
17+
it('throws an error when providers are nested', function () {
18+
expect(() => {
19+
render(
20+
<ContextMenuProvider menuWrapper={TestMenu}>
21+
<div>
22+
<ContextMenuProvider menuWrapper={TestMenu}>
23+
<TestComponent />
24+
</ContextMenuProvider>
25+
</div>
26+
</ContextMenuProvider>
27+
);
28+
}).to.throw(
29+
'Duplicated ContextMenuProvider found. Please remove the nested provider.'
30+
);
31+
});
32+
});
33+
34+
describe('when not nested', function () {
35+
it('renders without error', function () {
36+
render(
37+
<ContextMenuProvider menuWrapper={TestMenu}>
38+
<TestComponent />
39+
</ContextMenuProvider>
40+
);
41+
42+
expect(document.querySelector('[data-testid="test-content"]')).to.exist;
43+
});
44+
});
45+
});

packages/compass-context-menu/src/context-menu-provider.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, {
44
useState,
55
useMemo,
66
createContext,
7+
useContext,
78
} from 'react';
89
import type { ContextMenuContextType, ContextMenuState } from './types';
910
import type { EnhancedMouseEvent } from './context-menu-content';
@@ -22,6 +23,16 @@ export function ContextMenuProvider({
2223
menu: ContextMenuState & { close: () => void };
2324
}>;
2425
}) {
26+
// Check if there's already a parent context menu provider
27+
const parentContext = useContext(ContextMenuContext);
28+
29+
// Prevent accidental nested providers
30+
if (parentContext) {
31+
throw new Error(
32+
'Duplicated ContextMenuProvider found. Please remove the nested provider.'
33+
);
34+
}
35+
2536
const [menu, setMenu] = useState<ContextMenuState>({
2637
isOpen: false,
2738
itemGroups: [],

packages/compass-context-menu/src/use-context-menu.spec.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ describe('useContextMenu', function () {
136136

137137
it('renders without error', function () {
138138
render(
139-
<ContextMenuProvider wrapper={TestMenu}>
139+
<ContextMenuProvider menuWrapper={TestMenu}>
140140
<TestComponent />
141141
</ContextMenuProvider>
142142
);
@@ -148,7 +148,7 @@ describe('useContextMenu', function () {
148148
const onRegister = sinon.spy();
149149

150150
render(
151-
<ContextMenuProvider wrapper={TestMenu}>
151+
<ContextMenuProvider menuWrapper={TestMenu}>
152152
<TestComponent onRegister={onRegister} />
153153
</ContextMenuProvider>
154154
);
@@ -159,7 +159,7 @@ describe('useContextMenu', function () {
159159

160160
it('shows context menu on right click', function () {
161161
render(
162-
<ContextMenuProvider wrapper={TestMenu}>
162+
<ContextMenuProvider menuWrapper={TestMenu}>
163163
<TestComponent />
164164
</ContextMenuProvider>
165165
);
@@ -174,7 +174,7 @@ describe('useContextMenu', function () {
174174
describe('with nested context menus', function () {
175175
it('shows only parent items when right clicking parent area', function () {
176176
render(
177-
<ContextMenuProvider wrapper={TestMenu}>
177+
<ContextMenuProvider menuWrapper={TestMenu}>
178178
<ParentComponent />
179179
</ContextMenuProvider>
180180
);
@@ -193,7 +193,7 @@ describe('useContextMenu', function () {
193193

194194
it('shows both parent and child items when right clicking child area', function () {
195195
render(
196-
<ContextMenuProvider wrapper={TestMenu}>
196+
<ContextMenuProvider menuWrapper={TestMenu}>
197197
<ParentComponent>
198198
<ChildComponent />
199199
</ParentComponent>
@@ -215,7 +215,7 @@ describe('useContextMenu', function () {
215215
const childOnAction = sinon.spy();
216216

217217
render(
218-
<ContextMenuProvider wrapper={TestMenu}>
218+
<ContextMenuProvider menuWrapper={TestMenu}>
219219
<ParentComponent onAction={parentOnAction}>
220220
<ChildComponent onAction={childOnAction} />
221221
</ParentComponent>
@@ -238,7 +238,7 @@ describe('useContextMenu', function () {
238238
const childOnAction = sinon.spy();
239239

240240
render(
241-
<ContextMenuProvider wrapper={TestMenu}>
241+
<ContextMenuProvider menuWrapper={TestMenu}>
242242
<ParentComponent onAction={parentOnAction}>
243243
<ChildComponent onAction={childOnAction} />
244244
</ParentComponent>

0 commit comments

Comments
 (0)