Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/components/TopMenuSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@
{{ queuedCount }}
</span>
</Button>
<CurrentUserButton v-if="isLoggedIn" class="shrink-0" />
<LoginButton v-else-if="isDesktop" />
<CurrentUserButton
v-if="isLoggedIn && !isIntegratedTabBar"
class="shrink-0"
/>
<LoginButton v-else-if="isDesktop && !isIntegratedTabBar" />
<Button
v-if="!isRightSidePanelOpen"
v-tooltip.bottom="rightSidePanelTooltipConfig"
Expand Down Expand Up @@ -96,6 +99,7 @@ import Button from '@/components/ui/button/Button.vue'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
import { app } from '@/scripts/app'
import { useCommandStore } from '@/stores/commandStore'
Expand All @@ -107,6 +111,7 @@ import { useConflictAcknowledgment } from '@/workbench/extensions/manager/compos
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'

const settingStore = useSettingStore()
const workspaceStore = useWorkspaceStore()
const rightSidePanelStore = useRightSidePanelStore()
const managerState = useManagerState()
Expand All @@ -124,6 +129,9 @@ const { shouldShowRedDot: shouldShowConflictRedDot } =
useConflictAcknowledgment()
const isTopMenuHovered = ref(false)
const queuedCount = computed(() => queueStore.pendingTasks.length)
const isIntegratedTabBar = computed(
() => settingStore.get('Comfy.UI.TabBarLayout') === 'Integrated'
)
const queueHistoryTooltipConfig = computed(() =>
buildTooltipConfig(t('sideToolbar.queueProgressOverlay.viewJobHistory'))
)
Expand Down
134 changes: 134 additions & 0 deletions src/components/helpcenter/HelpCenterPopups.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<template>
<!-- Help Center Popup positioned within canvas area -->
<Teleport to="#graph-canvas-container">
<div
v-if="isHelpCenterVisible"
class="help-center-popup"
:class="{
'sidebar-left':
triggerLocation === 'sidebar' && sidebarLocation === 'left',
'sidebar-right':
triggerLocation === 'sidebar' && sidebarLocation === 'right',
'topbar-right': triggerLocation === 'topbar',
'small-sidebar': isSmall
}"
>
<HelpCenterMenuContent @close="closeHelpCenter" />
</div>
</Teleport>

<!-- Release Notification Toast positioned within canvas area -->
<Teleport to="#graph-canvas-container">
<ReleaseNotificationToast
:class="{
'sidebar-left': sidebarLocation === 'left',
'sidebar-right': sidebarLocation === 'right',
'small-sidebar': isSmall
}"
/>
</Teleport>

<!-- WhatsNew Popup positioned within canvas area -->
<Teleport to="#graph-canvas-container">
<WhatsNewPopup
:class="{
'sidebar-left': sidebarLocation === 'left',
'sidebar-right': sidebarLocation === 'right',
'small-sidebar': isSmall
}"
@whats-new-dismissed="handleWhatsNewDismissed"
/>
</Teleport>

<!-- Backdrop to close popup when clicking outside -->
<Teleport to="body">
<div
v-if="isHelpCenterVisible"
class="help-center-backdrop"
@click="closeHelpCenter"
/>
</Teleport>
Comment on lines +44 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Backdrop should use position: fixed instead of absolute.

The backdrop is teleported to body but uses position: absolute. If the body has any positioned ancestors or if the page is scrollable, the backdrop may not cover the entire viewport correctly. Using position: fixed ensures consistent full-viewport coverage.

🔎 Proposed fix
 .help-center-backdrop {
-  position: absolute;
+  position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   z-index: 9999;
   background: transparent;
 }

Also applies to: 74-82

🤖 Prompt for AI Agents
In @src/components/helpcenter/HelpCenterPopups.vue around lines 44 - 50, The
backdrop element rendered inside Teleport uses position: absolute which can fail
to cover the viewport; update the styling for the backdrop (the div with class
"help-center-backdrop" rendered when isHelpCenterVisible and the similar
backdrop used around lines 74-82) to use position: fixed instead of absolute so
it always spans the full viewport regardless of document flow or scrolling;
locate the CSS rules for .help-center-backdrop (and any duplicate backdrop
class/inline style in the same component) and change position to fixed, keeping
existing sizing (top/left/right/bottom or width/height) and z-index intact.

</template>

<script setup lang="ts">
import { useHelpCenter } from '@/composables/useHelpCenter'
import ReleaseNotificationToast from '@/platform/updates/components/ReleaseNotificationToast.vue'
import WhatsNewPopup from '@/platform/updates/components/WhatsNewPopup.vue'

import HelpCenterMenuContent from './HelpCenterMenuContent.vue'

const { isSmall = false } = defineProps<{
isSmall?: boolean
}>()

const {
isHelpCenterVisible,
triggerLocation,
sidebarLocation,
closeHelpCenter,
handleWhatsNewDismissed
} = useHelpCenter()
</script>

<style scoped>
.help-center-backdrop {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
background: transparent;
}

.help-center-popup {
position: absolute;
bottom: 1rem;
z-index: 10000;
animation: slideInUp 0.2s ease-out;
pointer-events: auto;
}

.help-center-popup.sidebar-left {
left: 1rem;
}

.help-center-popup.sidebar-left.small-sidebar {
left: 1rem;
}

.help-center-popup.sidebar-right {
right: 1rem;
}

.help-center-popup.topbar-right {
top: 2rem;
right: 1rem;
bottom: auto;
animation: slideInDown 0.2s ease-out;
}

@keyframes slideInDown {
from {
opacity: 0;
transform: translateY(-20px);
}

to {
opacity: 1;
transform: translateY(0);
}
}

@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(20px);
}

to {
opacity: 1;
transform: translateY(0);
}
}
</style>
Comment on lines +73 to +134
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider migrating custom CSS to Tailwind utilities.

Per coding guidelines, Vue components should "Use Tailwind CSS only for styling (no custom CSS)" and "Use the correct tokens from style.css in the design system package."

The current implementation uses:

  • Hardcoded z-index values (9999, 10000)
  • Custom keyframe animations
  • Multiple positioning classes

While animations may require CSS, the positioning and z-index could leverage Tailwind utilities or design system tokens. If Tailwind's animation utilities don't suffice, consider extracting the keyframes to a shared CSS file or using @apply in a design system context.

🤖 Prompt for AI Agents
In @src/components/helpcenter/HelpCenterPopups.vue around lines 73 - 134,
Replace hardcoded CSS in HelpCenterPopups.vue by switching positioning and
z-index to Tailwind/design tokens and moving animations to shared CSS: update
usages of .help-center-backdrop and .help-center-popup (including variants
.sidebar-left, .sidebar-right, .topbar-right, .small-sidebar) to use Tailwind
utility classes for absolute positioning, spacing and z-index tokens instead of
9999/10000; if Tailwind's built-in animations cover the behavior, replace the
local @keyframes slideInUp and slideInDown with Tailwind animation classes,
otherwise move these keyframes into the shared design-system CSS (or an
@apply-enabled file) and reference them via a named utility or class so the
component contains only utility classes.

7 changes: 6 additions & 1 deletion src/components/sidebar/SideToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@
v-if="userStore.isMultiUserServer"
:is-small="isSmall"
/>
<SidebarHelpCenterIcon :is-small="isSmall" />
<SidebarHelpCenterIcon v-if="!isIntegratedTabBar" :is-small="isSmall" />
<SidebarBottomPanelToggleButton :is-small="isSmall" />
<SidebarShortcutsToggleButton :is-small="isSmall" />
<SidebarSettingsButton :is-small="isSmall" />
</div>
</div>
<HelpCenterPopups :is-small="isSmall" />
</nav>
</template>

Expand All @@ -54,6 +55,7 @@ import { useResizeObserver } from '@vueuse/core'
import { debounce } from 'es-toolkit/compat'
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'

import HelpCenterPopups from '@/components/helpcenter/HelpCenterPopups.vue'
import ComfyMenuButton from '@/components/sidebar/ComfyMenuButton.vue'
import SidebarBottomPanelToggleButton from '@/components/sidebar/SidebarBottomPanelToggleButton.vue'
import SidebarSettingsButton from '@/components/sidebar/SidebarSettingsButton.vue'
Expand Down Expand Up @@ -89,6 +91,9 @@ const sidebarLocation = computed<'left' | 'right'>(() =>
settingStore.get('Comfy.Sidebar.Location')
)
const sidebarStyle = computed(() => settingStore.get('Comfy.Sidebar.Style'))
const isIntegratedTabBar = computed(
() => settingStore.get('Comfy.UI.TabBarLayout') === 'Integrated'
)
const isConnected = computed(
() =>
selectedTab.value ||
Expand Down
Loading
Loading