mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-10 23:50:00 +00:00
## Summary Refactors the error and subgraph node footer UI by extracting a dedicated `NodeFooter` component and replacing the CSS `outline` approach with a layered border overlay for selection/executing state indicators. ## Changes - **What**: Extracted `NodeFooter.vue` from `LGraphNode.vue` to encapsulate the footer tab logic (subgraph enter, error, advanced inputs). Replaced CSS `outline` with an absolutely-positioned border overlay div for selection and executing state. Added a separate root border overlay div for the node body border. Removed unused `isTransparent` function from `colorUtil.ts`. - **Dependencies**: None ## Review Focus - The layered overlay approach (`absolute -inset-[3px] border-3`) for selection/executing outlines vs the previous `outline-3` approach — ensures the outline renders outside the node bounds correctly including the footer area - `NodeFooter` handles 4 cases: subgraph+error (dual tabs), error only, subgraph only, advanced inputs — verify edge cases render correctly - Resize handle bottom offset adjustments for nodes with footers (`hasFooter`) ## Screenshots <img width="1142" height="603" alt="image" src="https://github.com/user-attachments/assets/e0d401f0-8516-4f5f-ab77-48a79530f4bd" /> <img width="1175" height="577" alt="image" src="https://github.com/user-attachments/assets/bcf08fff-728a-491c-add9-5b96d2f3bfce" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9360-style-Update-error-subgraph-node-footer-design-with-layered-overlay-approach-3186d73d365081b2ac31f166f4d1944a) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: GitHub Action <action@github.com>
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import {
|
|
comfyExpect as expect,
|
|
comfyPageFixture as test
|
|
} from '../../../fixtures/ComfyPage'
|
|
|
|
const BYPASS_HOTKEY = 'Control+b'
|
|
const BYPASS_CLASS = /before:bg-bypass\/60/
|
|
|
|
test.describe('Vue Node Bypass', () => {
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
|
|
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
|
|
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', false)
|
|
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true)
|
|
await comfyPage.vueNodes.waitForNodes()
|
|
})
|
|
|
|
test(
|
|
'should allow toggling bypass on a selected node with hotkey',
|
|
{ tag: '@screenshot' },
|
|
async ({ comfyPage }) => {
|
|
await comfyPage.page.getByText('Load Checkpoint').click()
|
|
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
|
|
|
|
const checkpointNode = comfyPage.page
|
|
.locator('[data-node-id]')
|
|
.filter({ hasText: 'Load Checkpoint' })
|
|
.getByTestId('node-inner-wrapper')
|
|
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
|
|
await comfyPage.nextFrame()
|
|
await expect(comfyPage.canvas).toHaveScreenshot(
|
|
'vue-node-bypassed-state.png'
|
|
)
|
|
|
|
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
|
|
await expect(checkpointNode).not.toHaveClass(BYPASS_CLASS)
|
|
}
|
|
)
|
|
|
|
test('should allow toggling bypass on multiple selected nodes with hotkey', async ({
|
|
comfyPage
|
|
}) => {
|
|
await comfyPage.page.getByText('Load Checkpoint').click()
|
|
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })
|
|
|
|
const checkpointNode = comfyPage.page
|
|
.locator('[data-node-id]')
|
|
.filter({ hasText: 'Load Checkpoint' })
|
|
.getByTestId('node-inner-wrapper')
|
|
const ksamplerNode = comfyPage.page
|
|
.locator('[data-node-id]')
|
|
.filter({ hasText: 'KSampler' })
|
|
.getByTestId('node-inner-wrapper')
|
|
|
|
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
|
|
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
|
|
await expect(ksamplerNode).toHaveClass(BYPASS_CLASS)
|
|
|
|
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
|
|
await expect(checkpointNode).not.toHaveClass(BYPASS_CLASS)
|
|
await expect(ksamplerNode).not.toHaveClass(BYPASS_CLASS)
|
|
})
|
|
})
|