mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
* WIP
* WIP: UI design for right click menu
* feat: add composable for node customization and information handling
* fix: correct v-show directive in MaskEditorButton and enhance MoreOptions functionality
* feat: add selection and subgraph operations composables for enhanced graph management
* fix: update computed properties to use 'void' for non-reactive calls and add MenuOptionItem component
* feat: add composables for More Options menu and submenu positioning logic
* feat: refactor MoreOptions component to use MenuOptionItem for menu rendering and streamline submenu handling
* feat: implement SubmenuPopover component for enhanced submenu functionality and selection handling
* feat: add 'More Options' label and enhance shape options in localization file
* refactor: simplify shape name handling by removing Pascal case conversion and using localized names
* refactor: enhance submenu handling by dynamically setting refs and improving key assignment
* feat: implement useNodeArrangement composable for node alignment and distribution functionality
* feat: enhance useMoreOptionsMenu with image node operations and alignment options
* feat: localize context menu options and enhance submenu handling
* refactor: improve type safety for title assignment in selection operations and enhance color option retrieval in node customization
* fix: adjust component order in SelectionToolbox for improved layout
* feat: update FrameNodes button visibility and tooltip, and add localization for frameNodes
* feat: enhance button visibility logic in SelectionToolbox based on selection types
* refactor: reorganize properties panel option in More Options menu for single nodes
* remove excessive logging and alerts
* fix component tests
* ad browser tests
* feat: enhance popover behavior in MoreOptions component to manage visibility state during selection overlay changes
* refactor: update visibility logic for buttons in SelectionToolbox and ExecuteButton components
* refactor: remove duplicate shape option and clean up shapeOptions array
* refactor: update help toggle logic in InfoButton and useMoreOptionsMenu to manage sidebar and help state
* refactor: streamline node info handling and integrate output node filtering in useNodeInfo and useMoreOptionsMenu
* Added useSelectionState composable consolidating all selection-derived state and the node help toggle
* Updated toolbox buttons (InfoButton, BookmarkButton, BypassButton, MaskEditorButton, ConvertToSubgraphButton, PinButton, DeleteButton, ColorPickerButton, ExecuteButton, FrameNodes, Load3DViewerButton) to remove duplicated selection logic and use useSelectionState
* Introduced HideReason ('manual' | 'drag') to differentiate drag-induced hides from manual/outside hides in MoreOptions
* refactor: enhance popover visibility handling during drag events using canvas state
* fix: update shape option name from 'default' to 'box' and add localization for 'box'
* refactor: streamline BypassButton logic and enhance MoreOptions menu with state bumping
* refactor: remove toast notifications from subgraph operations for cleaner logic
* refactor: ensure menu options re-compute when selection flags change
* feat: Enhance MoreOptions behavior with drag-and-drop support
* fix: Update mask icon class for consistent styling in MaskEditorButton
* refactor: Standardize icon sizes and classes across selection toolbox buttons
* refactor: Update layout and styling in SelectionToolbox and MoreOptions components
* refactor: Improve selection toolbox behavior with more options state management
* Refactor: Remove unused imports and conditionally add subgraph option in menu
* Enhance popover behavior: add show/hide event handlers and improve positioning logic
* Cleanup: Remove debug comments from popover functions for clarity
* Refactor: Clean up FrameNodes component and add MenuOptionBadge for better option display
* Cleanup: Remove debug comments from useSelectionToolboxPosition for clarity
* Add useFrameNodes composable for grouping selected nodes
* Refactor: Update shape options in useNodeCustomization and localize frame nodes label
* fix tests
* Cleanup: Remove packageManager entry from package.json
* Refactor: Replace ILucide icons with named imports from lucide-vue-next
* Refactor: Update shape selection and improve color picker behavior in selection toolbox
* Update test expectations [skip ci]
* feat: Enhance More Options Menu for group node management and update localization strings
* refactor: Comment out PublishButton
* refactor: Comment out test for bookmark button visibility in SelectionToolbox
* refactor: Update class names for dark theme compatibility in ExecuteButton and MenuOptionItem components
* refactor: Modularize menu options by creating dedicated composables for group, image, node, and selection operations
* refactor: Update selectors in tests to match design changes
* refactor: Update help button selector in Node Help tests
* refactor: Update getGroupColorOptions to accept groupContext and bump parameters
* Update test expectations [skip ci]
* refactor: Center KSampler node before interaction in More Options submenu tests
* refactor: Adjust KSampler node positioning and simplify button click in More Options submenu tests
* refactor: Rename comfyPageFixture import for clarity
* refactor: use gap-1 instead of the explicit gap-[4px]
* refactor: Replace app.canvas with canvasStore.getCanvas for state management
* refactor: Simplify prop access by removing 'props.' prefix in MenuOptionItem component
* refactor: Remove explicit type annotation for item in buildSelectionSignature function
* refactor: Replace Lucide icons with string-based icon references in menu options
* refactor: Remove export from interface declarations for improved clarity
* refactor: Simplify class binding in BypassButton component for improved readability
* refactor: Update button class for consistent sizing in ExecuteButton component
* refactor: Update help button locator class for consistency in Node Help tests
* fix node help test
* refactor: Remove unused imports and simplify visibility conditions in selection toolbox components
* feat: Add 3D node selection logic and cleanup on unmount for selection toolbox
* refactor: Update help button locator to use consistent data-testid in Node Help tests
* fix: Correct help button locator syntax in Node Help tests
* refactor: Change resetMoreOptionsState to an internal function in useSelectionToolboxPosition
* test: Add Load3D node visibility logic for ColorPickerButton and remove redundant test case
* fix: Increase tooltip show delay for ColorPickerButton
* fix: Update selectedOutputNodes computation to filter by isLGraphNode
* fix: Remove unused nodeDef reference from InfoButton and submenu trigger from MenuOptionItem
* fix: Update showInfoButton logic to depend on nodeDef value
* refactor: Remove deprecated getBasicNodeOptions function for cleaner code
* refactor: Replace useNodeInfo with useSelectedNodeActions
* refactor: Integrate useNodeDefStore for improved node definition handling in SelectionToolbox and InfoButton tests
* refactor: Introduce useCanvasRefresh composable for consistent canvas refresh logic across node operations
* refactor: Remove irrelevant append-to attribute from Popover
* refactor: Use storeToRefs for selectedItems in useSelectionState and add tests for selection logic
* refactor: Update ExecuteButton to use hasOutputNodesSelected for visibility and remove unnecessary computed property
* refactor: move display of execution button tests to selectionToolbox
---------
Co-authored-by: github-actions <github-actions@github.com>
164 lines
4.5 KiB
TypeScript
164 lines
4.5 KiB
TypeScript
import { nextTick } from 'vue'
|
|
|
|
import type { MenuOption } from './useMoreOptionsMenu'
|
|
|
|
/**
|
|
* Composable for handling submenu positioning logic
|
|
*/
|
|
export function useSubmenuPositioning() {
|
|
/**
|
|
* Toggle submenu visibility with proper positioning
|
|
* @param option - Menu option with submenu
|
|
* @param event - Click event
|
|
* @param submenu - PrimeVue Popover reference
|
|
* @param currentSubmenu - Currently open submenu name
|
|
* @param menuOptionsWithSubmenu - All menu options with submenus
|
|
* @param submenuRefs - References to all submenu popovers
|
|
*/
|
|
const toggleSubmenu = async (
|
|
option: MenuOption,
|
|
event: Event,
|
|
submenu: any, // Component instance with show/hide methods
|
|
currentSubmenu: { value: string | null },
|
|
menuOptionsWithSubmenu: MenuOption[],
|
|
submenuRefs: Record<string, any> // Component instances
|
|
): Promise<void> => {
|
|
if (!option.label || !option.hasSubmenu) return
|
|
|
|
// Check if this submenu is currently open
|
|
const isCurrentlyOpen = currentSubmenu.value === option.label
|
|
|
|
// Hide all submenus first
|
|
menuOptionsWithSubmenu.forEach((opt) => {
|
|
const sm = submenuRefs[`submenu-${opt.label}`]
|
|
if (sm) {
|
|
sm.hide()
|
|
}
|
|
})
|
|
currentSubmenu.value = null
|
|
|
|
// If it wasn't open before, show it now
|
|
if (!isCurrentlyOpen) {
|
|
currentSubmenu.value = option.label
|
|
await nextTick()
|
|
|
|
const menuItem = event.currentTarget as HTMLElement
|
|
const menuItemRect = menuItem.getBoundingClientRect()
|
|
|
|
// Find the parent popover content element that contains this menu item
|
|
const mainPopoverContent = menuItem.closest(
|
|
'[data-pc-section="content"]'
|
|
) as HTMLElement
|
|
|
|
if (mainPopoverContent) {
|
|
const mainPopoverRect = mainPopoverContent.getBoundingClientRect()
|
|
|
|
// Create a temporary positioned element as the target
|
|
const tempTarget = createPositionedTarget(
|
|
mainPopoverRect.right + 8,
|
|
menuItemRect.top,
|
|
`submenu-target-${option.label}`
|
|
)
|
|
|
|
// Create event using the temp target
|
|
const tempEvent = createMouseEvent(
|
|
mainPopoverRect.right + 8,
|
|
menuItemRect.top
|
|
)
|
|
|
|
// Show submenu relative to temp target
|
|
submenu.show(tempEvent, tempTarget)
|
|
|
|
// Clean up temp target after a delay
|
|
cleanupTempTarget(tempTarget, 100)
|
|
} else {
|
|
// Fallback: position to the right of the menu item
|
|
const tempTarget = createPositionedTarget(
|
|
menuItemRect.right + 8,
|
|
menuItemRect.top,
|
|
`submenu-fallback-target-${option.label}`
|
|
)
|
|
|
|
// Create event using the temp target
|
|
const tempEvent = createMouseEvent(
|
|
menuItemRect.right + 8,
|
|
menuItemRect.top
|
|
)
|
|
|
|
// Show submenu relative to temp target
|
|
submenu.show(tempEvent, tempTarget)
|
|
|
|
// Clean up temp target after a delay
|
|
cleanupTempTarget(tempTarget, 100)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a temporary positioned DOM element for submenu targeting
|
|
*/
|
|
const createPositionedTarget = (
|
|
left: number,
|
|
top: number,
|
|
id: string
|
|
): HTMLElement => {
|
|
const tempTarget = document.createElement('div')
|
|
tempTarget.style.position = 'absolute'
|
|
tempTarget.style.left = `${left}px`
|
|
tempTarget.style.top = `${top}px`
|
|
tempTarget.style.width = '1px'
|
|
tempTarget.style.height = '1px'
|
|
tempTarget.style.pointerEvents = 'none'
|
|
tempTarget.style.visibility = 'hidden'
|
|
tempTarget.id = id
|
|
|
|
document.body.appendChild(tempTarget)
|
|
return tempTarget
|
|
}
|
|
|
|
/**
|
|
* Create a mouse event with specific coordinates
|
|
*/
|
|
const createMouseEvent = (clientX: number, clientY: number): MouseEvent => {
|
|
return new MouseEvent('click', {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
clientX,
|
|
clientY
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Clean up temporary target element after delay
|
|
*/
|
|
const cleanupTempTarget = (target: HTMLElement, delay: number): void => {
|
|
setTimeout(() => {
|
|
if (target.parentNode) {
|
|
target.parentNode.removeChild(target)
|
|
}
|
|
}, delay)
|
|
}
|
|
|
|
/**
|
|
* Hide all submenus
|
|
*/
|
|
const hideAllSubmenus = (
|
|
menuOptionsWithSubmenu: MenuOption[],
|
|
submenuRefs: Record<string, any>, // Component instances
|
|
currentSubmenu: { value: string | null }
|
|
): void => {
|
|
menuOptionsWithSubmenu.forEach((option) => {
|
|
const submenu = submenuRefs[`submenu-${option.label}`]
|
|
if (submenu) {
|
|
submenu.hide()
|
|
}
|
|
})
|
|
currentSubmenu.value = null
|
|
}
|
|
|
|
return {
|
|
toggleSubmenu,
|
|
hideAllSubmenus
|
|
}
|
|
}
|