mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-26 17:54:14 +00:00
Floating Menus - UI rework (#5980)
## Summary
Enhancing and further modernizing the UI, giving users more usable area
whilst keeping farmiliar positioning and feel of elements.
## Changes
- **What**: Significant restructure of the UI elements, changing
elements from large blocks to floating elements, updating:
- Side toolbar menu (floating style, supports small/normal mode,
combines to scroll on height overflow)
- Bottom tabs panel (floating style, tabs redesigned)
- Action bar (support for docking/undocking menu)
- Added login/user menu button to top right
- Restyled breadcrumbs (still collapse when overflows)
- Add litegraph support for fps info position (so it isn't covered by
the sidebar)
- **Breaking**:
- Removed various elements and added new ones, I have tested custom
sidebars, custom actions, etc but if scripts are inserting elements into
"other" elements they may have been (re)moved.
- Remove support for bottom menu
- Remove support for 2nd-row tabs
## Screenshots
<img width="1116" height="907" alt="ui"
src="https://github.com/user-attachments/assets/b040a215-67d3-4c88-8c4d-f402a16a34f6"
/>
https://github.com/user-attachments/assets/571dbda5-01ec-47e8-b235-ee1b88c93dd0
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5980-Floating-Menus-UI-rework-2866d73d3650810aac60cc1afe979b60)
by [Unito](https://www.unito.io)
---------
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -2,28 +2,46 @@
|
||||
<!-- Load splitter overlay only after comfyApp is ready. -->
|
||||
<!-- If load immediately, the top-level splitter stateKey won't be correctly
|
||||
synced with the stateStorage (localStorage). -->
|
||||
<LiteGraphCanvasSplitterOverlay v-if="comfyAppReady && betaMenuEnabled">
|
||||
<template v-if="!workspaceStore.focusMode" #side-bar-panel>
|
||||
<LiteGraphCanvasSplitterOverlay v-if="comfyAppReady">
|
||||
<template v-if="showUI && workflowTabsPosition === 'Topbar'" #workflow-tabs>
|
||||
<div
|
||||
class="workflow-tabs-container pointer-events-auto relative h-9.5 w-full"
|
||||
>
|
||||
<!-- Native drag area for Electron -->
|
||||
<div
|
||||
v-if="isNativeWindow() && workflowTabsPosition !== 'Topbar'"
|
||||
class="app-drag fixed top-0 left-0 z-10 h-[var(--comfy-topbar-height)] w-full"
|
||||
/>
|
||||
<div class="flex">
|
||||
<WorkflowTabs />
|
||||
<TopbarBadges />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="showUI" #side-toolbar>
|
||||
<SideToolbar />
|
||||
</template>
|
||||
<template v-if="!workspaceStore.focusMode" #bottom-panel>
|
||||
<template v-if="showUI" #side-bar-panel>
|
||||
<div
|
||||
class="sidebar-content-container h-full w-full overflow-x-hidden overflow-y-auto"
|
||||
>
|
||||
<ExtensionSlot v-if="activeSidebarTab" :extension="activeSidebarTab" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="showUI" #topmenu>
|
||||
<TopMenuSection />
|
||||
</template>
|
||||
<template v-if="showUI" #bottom-panel>
|
||||
<BottomPanel />
|
||||
</template>
|
||||
<template #graph-canvas-panel>
|
||||
<div class="pointer-events-auto absolute top-0 left-0 w-auto max-w-full">
|
||||
<SecondRowWorkflowTabs
|
||||
v-if="workflowTabsPosition === 'Topbar (2nd-row)'"
|
||||
/>
|
||||
</div>
|
||||
<GraphCanvasMenu v-if="canvasMenuEnabled" class="pointer-events-auto" />
|
||||
|
||||
<MiniMap
|
||||
v-if="comfyAppReady && minimapEnabled"
|
||||
v-if="comfyAppReady && minimapEnabled && showUI"
|
||||
class="pointer-events-auto"
|
||||
/>
|
||||
</template>
|
||||
</LiteGraphCanvasSplitterOverlay>
|
||||
<GraphCanvasMenu v-if="!betaMenuEnabled && canvasMenuEnabled" />
|
||||
<canvas
|
||||
id="graph-canvas"
|
||||
ref="canvasRef"
|
||||
@@ -81,7 +99,9 @@ import {
|
||||
} from 'vue'
|
||||
|
||||
import LiteGraphCanvasSplitterOverlay from '@/components/LiteGraphCanvasSplitterOverlay.vue'
|
||||
import TopMenuSection from '@/components/TopMenuSection.vue'
|
||||
import BottomPanel from '@/components/bottomPanel/BottomPanel.vue'
|
||||
import ExtensionSlot from '@/components/common/ExtensionSlot.vue'
|
||||
import DomWidgets from '@/components/graph/DomWidgets.vue'
|
||||
import GraphCanvasMenu from '@/components/graph/GraphCanvasMenu.vue'
|
||||
import NodeTooltip from '@/components/graph/NodeTooltip.vue'
|
||||
@@ -90,7 +110,8 @@ import TitleEditor from '@/components/graph/TitleEditor.vue'
|
||||
import NodeOptions from '@/components/graph/selectionToolbox/NodeOptions.vue'
|
||||
import NodeSearchboxPopover from '@/components/searchbox/NodeSearchBoxPopover.vue'
|
||||
import SideToolbar from '@/components/sidebar/SideToolbar.vue'
|
||||
import SecondRowWorkflowTabs from '@/components/topbar/SecondRowWorkflowTabs.vue'
|
||||
import TopbarBadges from '@/components/topbar/TopbarBadges.vue'
|
||||
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
|
||||
import { useChainCallback } from '@/composables/functional/useChainCallback'
|
||||
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { useViewportCulling } from '@/composables/graph/useViewportCulling'
|
||||
@@ -129,6 +150,7 @@ import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { isNativeWindow } from '@/utils/envUtil'
|
||||
|
||||
const emit = defineEmits<{
|
||||
ready: []
|
||||
@@ -160,6 +182,12 @@ const tooltipEnabled = computed(() => settingStore.get('Comfy.EnableTooltips'))
|
||||
const selectionToolboxEnabled = computed(() =>
|
||||
settingStore.get('Comfy.Canvas.SelectionToolbox')
|
||||
)
|
||||
const activeSidebarTab = computed(() => {
|
||||
return workspaceStore.sidebarTab.activeSidebarTab
|
||||
})
|
||||
const showUI = computed(
|
||||
() => !workspaceStore.focusMode && betaMenuEnabled.value
|
||||
)
|
||||
|
||||
const minimapEnabled = computed(() => settingStore.get('Comfy.Minimap.Visible'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user