fix(sidebar): highlight destructive more menus
This commit is contained in:
3 files changed
+52
-2
No files matched your search
@@ -4352,6 +4352,7 @@ function moreActionsSubmenu(children: ContextMenuItem[]): ContextMenuItem {
|
||||
return {
|
||||
label: t("common.more"),
|
||||
icon: ListTree,
|
||||
variant: "destructive",
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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(() => {
|
||||
<div v-if="item.separator" class="-mx-1 my-1 flex items-center px-1">
|
||||
<div class="h-px flex-1 bg-border/70" />
|
||||
</div>
|
||||
<button v-else :disabled="itemIsDisabled(item)" :class="[...itemButtonClass(item.variant), activeSubIndex === index ? 'bg-accent text-accent-foreground' : '']" @click="handleItemClick(item)" @mouseenter="(e) => onItemMouseEnter(index, e)" @mouseleave="onItemMouseLeave">
|
||||
<button v-else :disabled="itemIsDisabled(item)" :class="[...itemButtonClass(item.variant), activeSubmenuTriggerClass(item, index)]" @click="handleItemClick(item)" @mouseenter="(e) => onItemMouseEnter(index, e)" @mouseleave="onItemMouseLeave">
|
||||
<span class="flex size-4 shrink-0 items-center justify-center">
|
||||
<Check v-if="item.checked" class="size-4 text-primary" />
|
||||
<component :is="item.icon" v-else-if="item.icon" :class="['size-4', item.iconClass]" />
|
||||
@@ -280,7 +285,7 @@ onBeforeUnmount(() => {
|
||||
<span v-if="item.shortcut" class="ml-8 inline-flex shrink-0 items-center gap-1 text-muted-foreground">
|
||||
<kbd v-for="key in shortcutKeys(item.shortcut)" :key="key" class="min-w-4 rounded border border-border/70 bg-muted/60 px-1 py-0.5 text-center font-mono text-[10px] leading-none text-muted-foreground shadow-xs">{{ key }}</kbd>
|
||||
</span>
|
||||
<ChevronRight v-if="item.children?.length" class="ml-auto size-4 text-muted-foreground/80" />
|
||||
<ChevronRight v-if="item.children?.length" :class="['ml-auto size-4', item.variant === 'destructive' ? 'text-destructive' : 'text-muted-foreground/80']" />
|
||||
</button>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -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(() =>
|
||||
|
||||
Reference in new issue
Block a user