Skip to content

Commit 971b0fd

Browse files
committed
fix: basic UI implementation
1 parent 6004593 commit 971b0fd

File tree

5 files changed

+69
-11
lines changed

5 files changed

+69
-11
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
import { css, cx } from '@leafygreen-ui/emotion';
3+
import { Menu, MenuItem, MenuSeparator } from './leafygreen';
4+
import type { ContextMenuItem } from '@mongodb-js/compass-context-menu';
5+
import { useContextMenu } from '@mongodb-js/compass-context-menu';
6+
7+
const menuStyle = css({
8+
position: 'fixed',
9+
zIndex: 9999,
10+
});
11+
12+
export type ContextMenuProps = {
13+
items: ContextMenuItem[];
14+
className?: string;
15+
'data-testid'?: string;
16+
};
17+
18+
export function ContextMenu({
19+
items,
20+
className,
21+
'data-testid': dataTestId,
22+
}: ContextMenuProps) {
23+
return (
24+
<Menu className={cx(menuStyle, className)} data-testid={dataTestId}>
25+
{items.map((item, idx) => {
26+
const { label, onAction } = item;
27+
const isLastItem = idx === items.length - 1;
28+
29+
return (
30+
<>
31+
{!isLastItem && <MenuSeparator />}
32+
<MenuItem
33+
key={`${label}-${idx}`}
34+
data-testid={`context-menu-item-${label}`}
35+
onClick={(evt: React.MouseEvent) => {
36+
evt.stopPropagation();
37+
onAction?.(evt);
38+
}}
39+
>
40+
{label}
41+
</MenuItem>
42+
</>
43+
);
44+
})}
45+
</Menu>
46+
);
47+
}
48+
49+
export function useContextMenuItems(
50+
items: ContextMenuItem[]
51+
): React.RefCallback<HTMLElement> {
52+
const contextMenu = useContextMenu({ Menu: ContextMenu });
53+
return contextMenu.registerItems(items);
54+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { useContextMenu } from './use-context-menu';
2+
export type { ContextMenuItem } from './types';

packages/compass-context-menu/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type ContextMenuContext = {
1515
close(): void;
1616
};
1717

18-
export type MenuItem = {
18+
export type ContextMenuItem = {
1919
label: string;
2020
onAction: (event: React.KeyboardEvent | React.MouseEvent) => void;
2121
};

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { expect } from 'chai';
44
import sinon from 'sinon';
55
import { useContextMenu } from './use-context-menu';
66
import { ContextMenuProvider } from './context-menu-provider';
7-
import type { MenuItem } from './types';
7+
import type { ContextMenuItem } from './types';
88

99
describe('useContextMenu', function () {
10-
const TestMenu: React.FC<{ items: MenuItem[] }> = ({ items }) => (
10+
const TestMenu: React.FC<{ items: ContextMenuItem[] }> = ({ items }) => (
1111
<div data-testid="test-menu">
1212
{items.map((item, idx) => (
1313
<div
@@ -36,7 +36,7 @@ describe('useContextMenu', function () {
3636
onAction?: (id) => void;
3737
}) => {
3838
const contextMenu = useContextMenu({ Menu: TestMenu });
39-
const items: MenuItem[] = [
39+
const items: ContextMenuItem[] = [
4040
{
4141
label: 'Test Item',
4242
onAction: () => onAction?.(1),
@@ -64,7 +64,7 @@ describe('useContextMenu', function () {
6464
children?: React.ReactNode;
6565
}) => {
6666
const contextMenu = useContextMenu({ Menu: TestMenu });
67-
const parentItems: MenuItem[] = [
67+
const parentItems: ContextMenuItem[] = [
6868
{
6969
label: 'Parent Item 1',
7070
onAction: () => onAction?.(1),
@@ -90,7 +90,7 @@ describe('useContextMenu', function () {
9090
onAction?: (id: number) => void;
9191
}) => {
9292
const contextMenu = useContextMenu({ Menu: TestMenu });
93-
const childItems: MenuItem[] = [
93+
const childItems: ContextMenuItem[] = [
9494
{
9595
label: 'Child Item 1',
9696
onAction: () => onAction?.(1),

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React, { useContext, useMemo, useRef } from 'react';
22
import { Context } from './context-menu-provider';
33
import { appendContextMenuContent } from './context-menu-content';
4-
import type { MenuItem } from './types';
4+
import type { ContextMenuItem } from './types';
55

6-
export type ContextMenuMethods<T extends MenuItem> = {
6+
export type ContextMenuMethods<T extends ContextMenuItem> = {
77
/**
88
* Close the context menu.
99
*/
@@ -12,10 +12,10 @@ export type ContextMenuMethods<T extends MenuItem> = {
1212
* Register the menu items for the context menu.
1313
* @returns a callback ref to be passed onto the element responsible for triggering the menu.
1414
*/
15-
registerItems: (items: T[]) => (trigger: HTMLElement | null) => void;
15+
registerItems: (items: T[]) => React.RefCallback<HTMLElement>;
1616
};
1717

18-
export function useContextMenu<T extends MenuItem>({
18+
export function useContextMenu<T extends ContextMenuItem>({
1919
Menu,
2020
}: {
2121
Menu: React.ComponentType<{
@@ -33,7 +33,9 @@ export function useContextMenu<T extends MenuItem>({
3333
throw new Error('useContextMenu called outside of the provider');
3434
}
3535

36-
const register = (content: React.ComponentType) => {
36+
const register = (
37+
content: React.ComponentType
38+
): React.RefCallback<HTMLElement> => {
3739
function listener(event: MouseEvent) {
3840
appendContextMenuContent(event, content);
3941
}

0 commit comments

Comments
 (0)