implement gameboard v1

This commit is contained in:
seavor 2026-04-19 23:21:42 -05:00
parent b103db681b
commit 0d7336edc2
177 changed files with 16995 additions and 139 deletions

View file

@ -0,0 +1,3 @@
.player-context-menu .MuiMenuItem-root {
font-size: 13px;
}

View file

@ -0,0 +1,63 @@
import { screen, fireEvent } from '@testing-library/react';
import { renderWithProviders } from '../../../__test-utils__';
import PlayerContextMenu from './PlayerContextMenu';
const NOOP = () => {};
const DEFAULT_PROPS = {
isOpen: true,
anchorPosition: { top: 10, left: 10 },
onClose: NOOP,
onRequestCreateToken: NOOP,
onRequestViewSideboard: NOOP,
};
describe('PlayerContextMenu', () => {
it('fires onRequestCreateToken and closes when "Create token…" is clicked', () => {
const onRequestCreateToken = vi.fn();
const onClose = vi.fn();
renderWithProviders(
<PlayerContextMenu
{...DEFAULT_PROPS}
onClose={onClose}
onRequestCreateToken={onRequestCreateToken}
/>,
);
fireEvent.click(screen.getByRole('menuitem', { name: /create token/i }));
expect(onRequestCreateToken).toHaveBeenCalled();
expect(onClose).toHaveBeenCalled();
});
it('fires onRequestViewSideboard and closes when "View sideboard…" is clicked', () => {
const onRequestViewSideboard = vi.fn();
const onClose = vi.fn();
renderWithProviders(
<PlayerContextMenu
{...DEFAULT_PROPS}
onClose={onClose}
onRequestViewSideboard={onRequestViewSideboard}
/>,
);
fireEvent.click(screen.getByRole('menuitem', { name: /view sideboard/i }));
expect(onRequestViewSideboard).toHaveBeenCalled();
expect(onClose).toHaveBeenCalled();
});
it('does not render menu items when closed', () => {
renderWithProviders(
<PlayerContextMenu
{...DEFAULT_PROPS}
isOpen={false}
anchorPosition={null}
/>,
);
expect(screen.queryByRole('menuitem')).not.toBeInTheDocument();
});
});

View file

@ -0,0 +1,48 @@
import Divider from '@mui/material/Divider';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import './PlayerContextMenu.css';
export interface PlayerContextMenuProps {
isOpen: boolean;
anchorPosition: { top: number; left: number } | null;
onClose: () => void;
onRequestCreateToken: () => void;
onRequestViewSideboard: () => void;
}
function PlayerContextMenu({
isOpen,
anchorPosition,
onClose,
onRequestCreateToken,
onRequestViewSideboard,
}: PlayerContextMenuProps) {
const handleCreateToken = () => {
onRequestCreateToken();
onClose();
};
const handleViewSideboard = () => {
onRequestViewSideboard();
onClose();
};
return (
<Menu
open={isOpen}
onClose={onClose}
anchorReference="anchorPosition"
anchorPosition={anchorPosition ?? undefined}
data-testid="player-context-menu"
className="player-context-menu"
>
<MenuItem onClick={handleCreateToken}>Create token</MenuItem>
<Divider />
<MenuItem onClick={handleViewSideboard}>View sideboard</MenuItem>
</Menu>
);
}
export default PlayerContextMenu;