feat(sidebar): support hierarchical batch connection moves
This commit is contained in:
10 files changed
+105
-38
No files matched your search
@@ -282,7 +282,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), activeSubmenuTriggerClass(item, index)]" @click="handleItemClick(item)" @mouseenter="(e) => onItemMouseEnter(index, e)" @mouseleave="onItemMouseLeave">
|
||||
<button v-else :disabled="itemIsDisabled(item)" :title="item.title" :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]" />
|
||||
@@ -313,7 +313,7 @@ onBeforeUnmount(() => {
|
||||
<div v-if="child.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(child)" :class="itemButtonClass(child.variant)" @click="handleSubItemClick(child)">
|
||||
<button v-else :disabled="itemIsDisabled(child)" :title="child.title" :class="itemButtonClass(child.variant)" :style="{ paddingInlineStart: `${0.5 + (child.indentLevel ?? 0) * 0.75}rem` }" @click="handleSubItemClick(child)">
|
||||
<span class="flex size-4 shrink-0 items-center justify-center">
|
||||
<Check v-if="child.checked" class="size-4 text-primary" />
|
||||
<component :is="child.icon" v-else-if="child.icon" :class="['size-4', child.iconClass]" />
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface LightDropdownItem {
|
||||
leadingText?: string;
|
||||
disabled?: boolean;
|
||||
separatorBefore?: boolean;
|
||||
indentLevel?: number;
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -83,13 +84,20 @@ const menuStyle = computed(() => ({
|
||||
left: `${x.value}px`,
|
||||
top: `${y.value}px`,
|
||||
minWidth: props.matchTriggerWidth ? `${minWidth.value}px` : undefined,
|
||||
maxHeight: "min(420px, calc(100vh - 16px))",
|
||||
}));
|
||||
|
||||
function onScroll(event: Event) {
|
||||
const target = event.target;
|
||||
if (target instanceof Node && menuRef.value?.contains(target)) return;
|
||||
close();
|
||||
}
|
||||
|
||||
function close() {
|
||||
open.value = false;
|
||||
document.removeEventListener("pointerdown", onOutsidePointerDown, true);
|
||||
document.removeEventListener("keydown", onKeydown);
|
||||
window.removeEventListener("scroll", close, true);
|
||||
window.removeEventListener("scroll", onScroll, true);
|
||||
window.removeEventListener("resize", close);
|
||||
}
|
||||
|
||||
@@ -123,7 +131,7 @@ function openMenu() {
|
||||
nextTick(fitPositionToViewport);
|
||||
document.addEventListener("pointerdown", onOutsidePointerDown, true);
|
||||
document.addEventListener("keydown", onKeydown);
|
||||
window.addEventListener("scroll", close, true);
|
||||
window.addEventListener("scroll", onScroll, true);
|
||||
window.addEventListener("resize", close);
|
||||
}
|
||||
|
||||
@@ -169,7 +177,7 @@ onBeforeUnmount(close);
|
||||
<ChevronDown v-if="showChevron" class="h-3 w-3 opacity-50" />
|
||||
</button>
|
||||
<Teleport to="body">
|
||||
<div v-if="open" ref="menuRef" class="fixed z-50 min-w-32 rounded-md p-1 cn-menu-translucent text-popover-foreground" :class="contentClass" :style="menuStyle" role="menu">
|
||||
<div v-if="open" ref="menuRef" class="fixed z-50 min-w-32 overflow-x-hidden overflow-y-auto rounded-md p-1 cn-menu-translucent text-popover-foreground" :class="contentClass" :style="menuStyle" role="menu">
|
||||
<div v-if="label" :class="labelClass">{{ label }}</div>
|
||||
<div v-if="label" class="bg-border -mx-1 my-1 h-px" />
|
||||
<template v-for="item in items" :key="item.value">
|
||||
@@ -180,6 +188,7 @@ onBeforeUnmount(close);
|
||||
:class="[itemClass, highlightSelected && isItemSelected(item) ? selectedItemClass : '']"
|
||||
:disabled="item.disabled"
|
||||
:title="item.title"
|
||||
:style="{ paddingInlineStart: `${0.375 + (item.indentLevel ?? 0) * 0.75}rem` }"
|
||||
role="menuitem"
|
||||
@click="selectItem(item)"
|
||||
>
|
||||
|
||||
@@ -7,6 +7,8 @@ export interface ContextMenuItem {
|
||||
separator?: boolean;
|
||||
icon?: Component;
|
||||
iconClass?: string;
|
||||
title?: string;
|
||||
indentLevel?: number;
|
||||
checked?: boolean;
|
||||
// Raw shortcut syntax such as `Mod+C` or `Shift+Alt+U`; display formatting stays in this component.
|
||||
shortcut?: string;
|
||||
|
||||
Reference in new issue
Block a user