Compare commits

...

2 Commits

Author SHA1 Message Date
Glary-Bot
227a80a17a fix: apply scrollbar-gutter to the actual scroll container
Move scrollbar-gutter: stable from panel components to the parent
scroll container in NodeLibrarySidebarTabV2 where overflow-y-auto
actually triggers. Panel root divs lack height constraints from
TabPanel, so their overflow-y-auto never activates.

Also strengthen E2E tests: use clientWidth (excludes scrollbar) for
the overlap assertion and add click-based behavioral assertions.
2026-04-19 10:07:01 +00:00
Glary-Bot
28a95902cd fix: reserve scrollbar space in node library panels to prevent bookmark icon overlap
Add scrollbar-gutter: stable to AllNodesPanel, BlueprintsPanel,
EssentialNodesPanel, and CustomNodesPanel scroll containers. This
reserves space for the scrollbar before it appears so bookmark icons
at the right edge of tree rows are never overlapped.

Matches the existing pattern in VirtualGrid.vue.
2026-04-19 09:53:38 +00:00
2 changed files with 94 additions and 1 deletions

View File

@@ -120,4 +120,95 @@ test.describe('Node library sidebar V2', () => {
await expect(options.first()).toBeVisible()
await expect.poll(() => options.count()).toBeGreaterThanOrEqual(2)
})
test.describe('Bookmark button scrollbar overlap', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [])
})
test('Bookmark button is not clipped by the scroll container', async ({
comfyPage
}) => {
const tab = comfyPage.menu.nodeLibraryTabV2
await tab.expandFolder('sampling')
const node = tab.getNode('KSampler (Advanced)')
await expect(node).toBeVisible()
// Hover required: bookmark button uses opacity-0 → group-hover:opacity-100
await node.hover()
const bookmarkButton = node.getByRole('button', { name: 'Bookmark' })
await expect(bookmarkButton).toBeVisible()
// clientWidth excludes the scrollbar, so checking against it proves the
// button sits inside the usable content area, not under the scrollbar.
await expect
.poll(async () => {
const buttonBox = await bookmarkButton.boundingBox()
if (!buttonBox) return false
const scrollContainerRect = await comfyPage.page.evaluate(() => {
const el = document.querySelector('.sidebar-content-container')
if (!el) return null
return {
left: el.getBoundingClientRect().left,
clientWidth: el.clientWidth
}
})
if (!scrollContainerRect) return false
const contentRight =
scrollContainerRect.left + scrollContainerRect.clientWidth
return buttonBox.x + buttonBox.width <= contentRight
})
.toBe(true)
})
test('Bookmark button click toggles bookmark state', async ({
comfyPage
}) => {
const tab = comfyPage.menu.nodeLibraryTabV2
await tab.expandFolder('sampling')
const node = tab.getNode('KSampler (Advanced)')
await expect(node).toBeVisible()
await node.hover()
const bookmarkButton = node.getByRole('button', { name: 'Bookmark' })
await bookmarkButton.click()
await expect
.poll(() =>
comfyPage.settings.getSetting<string[]>(
'Comfy.NodeLibrary.Bookmarks.V2'
)
)
.toContain('KSamplerAdvanced')
})
test('Bookmark button is clickable after search populates many results', async ({
comfyPage
}) => {
const tab = comfyPage.menu.nodeLibraryTabV2
await tab.searchInput.fill('e')
await tab.searchInput.press('Enter')
const firstResult = tab.sidebarContent.getByRole('treeitem').first()
await expect(firstResult).toBeVisible()
await firstResult.hover()
const bookmarkButton = firstResult.getByRole('button', {
name: 'Bookmark'
})
await bookmarkButton.click()
await expect
.poll(() =>
comfyPage.settings.getSetting<string[]>(
'Comfy.NodeLibrary.Bookmarks.V2'
)
)
.not.toEqual([])
})
})
})

View File

@@ -117,7 +117,9 @@
<template #body>
<NodeDragPreview />
<div class="flex h-full flex-col">
<div class="min-h-0 flex-1 overflow-y-auto py-2">
<div
class="min-h-0 flex-1 overflow-y-auto py-2 [scrollbar-gutter:stable]"
>
<TabPanel
v-if="flags.nodeLibraryEssentialsEnabled"
:model-value="selectedTab"