fix(diagram): keep the shape menu from blocking the editor (#595)
The shape-library trigger opened its menu on every pointerenter. When the editor replaced the note list under a pointer that did not move, or when the pointer only passed over the toolbar, the menu opened by itself and stayed open. For mind maps and flowcharts that menu was modal, so the back-to-list button could not be pressed until the menu was closed. On touch screens pointerenter fires right before the pointerdown that toggles the menu, so a tap could open it and close it again. - Open the menu on hover only for mouse pointers. - Make the mind-map and flowchart insert menu non-modal, as the architecture library already is.
This commit is contained in:
1 parent
d96b8f6e69
commit
c2ff5ca1b6
3 files changed
+18
-3
No files matched your search
@@ -275,12 +275,19 @@ describe("diagram editor canvas surface", () => {
|
||||
test("reuses the architecture shape-library trigger across every diagram kind", () => {
|
||||
expect(toolbarSource).toContain("export const DiagramToolbarAddTrigger");
|
||||
expect(toolbarSource).toContain("<DropdownMenuTrigger asChild>");
|
||||
expect(toolbarSource).toContain('<Button size="sm" variant="soft" onPointerEnter={onPointerEnter}>');
|
||||
expect(toolbarSource).toContain('if (event.pointerType === "mouse") onPointerEnter(event);');
|
||||
expect(toolbarSource).toContain('<Boxes className="h-4 w-4" />');
|
||||
expect(toolbarSource).toContain('{t("diagram.componentLibrary")}');
|
||||
expect(source.match(/<DiagramToolbarAddTrigger onPointerEnter=/g)).toHaveLength(2);
|
||||
});
|
||||
|
||||
test("keeps a shape menu opened by hover from blocking the rest of the editor", () => {
|
||||
// Touch fires pointerenter right before the pointerdown that toggles the
|
||||
// menu, and a modal menu hides the back button while it is open.
|
||||
expect(toolbarSource).not.toContain("onPointerEnter={onPointerEnter}");
|
||||
expect(source.match(/<DropdownMenu modal=\{false\} open=\{open\}/g)).toHaveLength(2);
|
||||
});
|
||||
|
||||
test("exposes connection handles on flowcharts and architecture components with safe connection rules", () => {
|
||||
expect(source).toContain("const hasPorts = isConnectableDiagram(kind) && node.shape !== \"boundary\"");
|
||||
expect(source).toContain("const FLOW_PORT_HIT_RADIUS = 14");
|
||||
|
||||
@@ -686,7 +686,7 @@ const DiagramInsertMenu = ({
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||
<DropdownMenu modal={false} open={open} onOpenChange={setOpen}>
|
||||
<DiagramToolbarAddTrigger onPointerEnter={() => setOpen(true)} />
|
||||
<DropdownMenuContent align="start">
|
||||
{items.map((item) => {
|
||||
|
||||
@@ -174,7 +174,15 @@ export const DiagramToolbarAddTrigger = ({
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="sm" variant="soft" onPointerEnter={onPointerEnter}>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="soft"
|
||||
// Hover opening is for mice. A touch fires pointerenter right before the
|
||||
// pointerdown that toggles the menu, which would close it again.
|
||||
onPointerEnter={(event) => {
|
||||
if (event.pointerType === "mouse") onPointerEnter(event);
|
||||
}}
|
||||
>
|
||||
<Boxes className="h-4 w-4" />
|
||||
{t("diagram.componentLibrary")}
|
||||
<ChevronDown className="h-3.5 w-3.5 text-slate-400" />
|
||||
|
||||
Reference in new issue
Block a user