mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-28 18:22:40 +00:00
rework minimap, toolbox, and menu designs with unified theming (#6038)
## Summary This PR redesigns the graph canvas interface components including minimap, toolbox, and menu systems with updated spacing, colors, and interaction patterns - using the design tokens directly from Figma, which can be used elsewhere going forward. There are some other changes to the designs, outlined [here](https://www.notion.so/comfy-org/Update-Minimap-Menu-v2-2886d73d365080e88e12f8df027019c0): - [x] Update/standardize the padding between viewport and toolbox - [x] Update toolbox component’s style to match the other floating menus style (border radius, height, padding and follow theme colors) - [x] Expose the minimap button - [x] Remove the focus button and delete it’s keybinding - [x] Group the hand and the default cursor buttons https://github.com/user-attachments/assets/92542e60-c32d-4a21-a6f6-e72837a70b17 ## Review Focus New CSS variables for cross-component theming consistency and CanvasModeSelector component extraction for improved code organization. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6038-rework-minimap-toolbox-and-menu-designs-with-unified-theming-28b6d73d36508191a0c6cf8036d965c4) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
126
src/components/graph/CanvasModeSelector.vue
Normal file
126
src/components/graph/CanvasModeSelector.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<Button
|
||||
ref="buttonRef"
|
||||
severity="secondary"
|
||||
class="group h-8 rounded-none! bg-interface-panel-surface p-0 transition-none! hover:rounded-lg! hover:bg-button-hover-surface!"
|
||||
:style="buttonStyles"
|
||||
@click="toggle"
|
||||
>
|
||||
<template #default>
|
||||
<div class="flex items-center gap-1 pr-0.5">
|
||||
<div
|
||||
class="rounded-lg bg-button-active-surface p-2 group-hover:bg-button-hover-surface"
|
||||
>
|
||||
<i :class="currentModeIcon" class="block h-4 w-4" />
|
||||
</div>
|
||||
<i class="icon-[lucide--chevron-down] block h-4 w-4 pr-1.5" />
|
||||
</div>
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
<Popover
|
||||
ref="popover"
|
||||
:auto-z-index="true"
|
||||
:base-z-index="1000"
|
||||
:dismissable="true"
|
||||
:close-on-escape="true"
|
||||
unstyled
|
||||
:pt="popoverPt"
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div
|
||||
class="flex cursor-pointer items-center justify-between px-3 py-2 text-sm hover:bg-node-component-surface-hovered"
|
||||
@click="setMode('select')"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="icon-[lucide--mouse-pointer-2] h-4 w-4" />
|
||||
<span>{{ $t('graphCanvasMenu.select') }}</span>
|
||||
</div>
|
||||
<span class="text-[9px] text-text-primary">{{
|
||||
unlockCommandText
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex cursor-pointer items-center justify-between rounded px-3 py-2 text-sm hover:bg-node-component-surface-hovered"
|
||||
@click="setMode('hand')"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="icon-[lucide--hand] h-4 w-4" />
|
||||
<span>{{ $t('graphCanvasMenu.hand') }}</span>
|
||||
</div>
|
||||
<span class="text-[9px] text-text-primary">{{ lockCommandText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Button from 'primevue/button'
|
||||
import Popover from 'primevue/popover'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
|
||||
interface Props {
|
||||
buttonStyles?: Record<string, string>
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
const buttonRef = ref<InstanceType<typeof Button>>()
|
||||
const popover = ref<InstanceType<typeof Popover>>()
|
||||
const commandStore = useCommandStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
|
||||
const isCanvasReadOnly = computed(() => canvasStore.canvas?.read_only ?? false)
|
||||
|
||||
const currentModeIcon = computed(() =>
|
||||
isCanvasReadOnly.value
|
||||
? 'icon-[lucide--hand]'
|
||||
: 'icon-[lucide--mouse-pointer-2]'
|
||||
)
|
||||
|
||||
const unlockCommandText = computed(() =>
|
||||
commandStore
|
||||
.formatKeySequence(commandStore.getCommand('Comfy.Canvas.Unlock'))
|
||||
.toUpperCase()
|
||||
)
|
||||
|
||||
const lockCommandText = computed(() =>
|
||||
commandStore
|
||||
.formatKeySequence(commandStore.getCommand('Comfy.Canvas.Lock'))
|
||||
.toUpperCase()
|
||||
)
|
||||
|
||||
const toggle = (event: Event) => {
|
||||
const el = (buttonRef.value as any)?.$el || buttonRef.value
|
||||
popover.value?.toggle(event, el)
|
||||
}
|
||||
|
||||
const setMode = (mode: 'select' | 'hand') => {
|
||||
if (mode === 'select' && isCanvasReadOnly.value) {
|
||||
void commandStore.execute('Comfy.Canvas.Unlock')
|
||||
} else if (mode === 'hand' && !isCanvasReadOnly.value) {
|
||||
void commandStore.execute('Comfy.Canvas.Lock')
|
||||
}
|
||||
popover.value?.hide()
|
||||
}
|
||||
|
||||
const popoverPt = computed(() => ({
|
||||
root: {
|
||||
class: 'absolute z-50 -translate-y-2'
|
||||
},
|
||||
content: {
|
||||
class: [
|
||||
'mb-2 text-text-primary',
|
||||
'shadow-lg border border-node-border',
|
||||
'bg-nav-background',
|
||||
'rounded-lg',
|
||||
'p-2 px-3',
|
||||
'min-w-39',
|
||||
'select-none'
|
||||
]
|
||||
}
|
||||
}))
|
||||
</script>
|
||||
Reference in New Issue
Block a user