ui/menu: add simple context menu

This commit is contained in:
Johannes Kirschbauer
2025-08-29 18:42:18 +02:00
parent c260a97cc1
commit 25fdabee29
2 changed files with 94 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
.list {
display: flex;
width: 113px;
padding: 8px;
flex-direction: column;
align-items: flex-start;
border-radius: 5px;
border: 1px solid var(--clr-border-def-2, #d8e8eb);
background: var(--clr-bg-def-1, #fff);
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.24);
}
.item {
max-height: 28px;
height: 28px;
padding: 4px 8px;
cursor: pointer;
display: flex;
align-items: center;
align-self: stretch;
gap: 4px;
&:hover {
@apply bg-def-3;
border-radius: 2px;
}
&[aria-disabled="true"] {
cursor: not-allowed;
pointer-events: none;
}
}

View File

@@ -0,0 +1,61 @@
import { onCleanup, onMount } from "solid-js";
import styles from "./ContextMenu.module.css";
import { Typography } from "../Typography/Typography";
export const Menu = (props: {
x: number;
y: number;
onSelect: (option: "move") => void;
close: () => void;
intersect: string[];
}) => {
let ref: HTMLUListElement;
const handleClickOutside = (e: MouseEvent) => {
if (!ref.contains(e.target as Node)) {
props.close();
}
};
onMount(() => {
document.addEventListener("mousedown", handleClickOutside);
});
onCleanup(() =>
document.removeEventListener("mousedown", handleClickOutside),
);
const currentMachine = () => props.intersect.at(0) || null;
return (
<ul
ref={(el) => (ref = el)}
style={{
position: "absolute",
top: `${props.y}px`,
left: `${props.x}px`,
"z-index": 1000,
"pointer-events": "auto",
}}
class={styles.list}
>
<li
class={styles.item}
aria-disabled={!currentMachine()}
onClick={() => {
console.log("Move clicked", currentMachine());
props.onSelect("move");
props.close();
}}
>
<Typography
hierarchy="label"
size="s"
weight="bold"
color={currentMachine() ? "primary" : "quaternary"}
>
Move
</Typography>
</li>
</ul>
);
};