diff --git a/apps/desktop/src/components/sidebar/SidebarTreeRuntimeHost.vue b/apps/desktop/src/components/sidebar/SidebarTreeRuntimeHost.vue index ed0b505d99..7b9ca75044 100644 --- a/apps/desktop/src/components/sidebar/SidebarTreeRuntimeHost.vue +++ b/apps/desktop/src/components/sidebar/SidebarTreeRuntimeHost.vue @@ -4352,6 +4352,7 @@ function moreActionsSubmenu(children: ContextMenuItem[]): ContextMenuItem { return { label: t("common.more"), icon: ListTree, + variant: "destructive", children, }; } diff --git a/apps/desktop/src/components/ui/CustomContextMenu.vue b/apps/desktop/src/components/ui/CustomContextMenu.vue index 051187e499..16041d5ccd 100644 --- a/apps/desktop/src/components/ui/CustomContextMenu.vue +++ b/apps/desktop/src/components/ui/CustomContextMenu.vue @@ -243,6 +243,11 @@ function itemButtonClass(variant?: "default" | "destructive") { ]; } +function activeSubmenuTriggerClass(item: ContextMenuItem, index: number) { + if (activeSubIndex.value !== index) return ""; + return item.variant === "destructive" ? "bg-destructive/10 text-destructive" : "bg-accent text-accent-foreground"; +} + function itemIsDisabled(item: ContextMenuItem): boolean { return typeof item.disabled === "function" ? item.disabled() : !!item.disabled; } @@ -271,7 +276,7 @@ onBeforeUnmount(() => {
- diff --git a/apps/desktop/src/components/ui/__tests__/CustomContextMenu.spec.ts b/apps/desktop/src/components/ui/__tests__/CustomContextMenu.spec.ts index ec31f5ce38..cc8cfedc69 100644 --- a/apps/desktop/src/components/ui/__tests__/CustomContextMenu.spec.ts +++ b/apps/desktop/src/components/ui/__tests__/CustomContextMenu.spec.ts @@ -251,6 +251,50 @@ describe("CustomContextMenu lifecycle", () => { app.unmount(); }); + it("keeps a destructive submenu trigger red while expanded", async () => { + const root = defineComponent({ + setup() { + return () => + h( + CustomContextMenu, + { + items: [ + { + label: "More", + variant: "destructive", + children: [{ label: "Drop table", variant: "destructive" }], + }, + ], + }, + { + default: ({ onContextMenu }: { onContextMenu: (event: MouseEvent) => void }) => h("div", { id: "context-target", onContextmenu: onContextMenu }, "Target"), + }, + ); + }, + }); + const container = document.createElement("div"); + mountedContainers.push(container); + document.body.append(container); + const app = createApp(root); + app.mount(container); + + container.querySelector("#context-target")?.dispatchEvent(new MouseEvent("contextmenu", { bubbles: true })); + await nextTick(); + + const trigger = Array.from(document.body.querySelectorAll("button")).find((button) => button.textContent?.includes("More")); + expect(trigger?.classList.contains("text-destructive")).toBe(true); + expect(trigger?.querySelector("svg")?.classList.contains("text-destructive")).toBe(true); + + trigger?.dispatchEvent(new MouseEvent("mouseenter", { bubbles: true })); + await nextTick(); + + expect(trigger?.classList.contains("bg-destructive/10")).toBe(true); + expect(trigger?.classList.contains("text-accent-foreground")).toBe(false); + expect(document.body.textContent).toContain("Drop table"); + + app.unmount(); + }); + it("resolves lazy menu items again for every open", async () => { let copied = false; const items = vi.fn(() =>