Files
ComfyUI-Lora-Manager/vue-widgets
Will Miao cde6151c71 fix: make sliders compatible with Vue DOM render mode
Add data-capture-wheel attribute to SingleSlider and DualRangeSlider
components to prevent wheel events from being intercepted by the canvas
in ComfyUI's new Vue DOM render mode. This allows mouse wheel to work
for adjusting slider values while still enabling workflow zoom on
non-interactive widget areas.

Also update event handling to use pointer events with proper stop
propagation and pointer capture for reliable drag operations in both
rendering modes.

Update development guide with Section 8 documenting Vue DOM render mode
event handling patterns and best practices.
2026-01-15 07:03:05 +08:00
..

Vue Widgets for ComfyUI LoRA Manager

This directory contains the source code for Vue 3 + PrimeVue custom widgets for ComfyUI LoRA Manager.

Structure

vue-widgets/
├── src/                    # TypeScript/Vue source code
│   ├── main.ts            # Main entry point that registers extensions
│   └── components/        # Vue components
│       └── DemoWidget.vue # Example demo widget
├── package.json           # Dependencies and build scripts
├── vite.config.mts        # Vite build configuration
├── tsconfig.json          # TypeScript configuration
└── README.md             # This file

Development

Install Dependencies

cd vue-widgets
npm install

Build for Production

npm run build

This compiles the TypeScript/Vue code and outputs to ../web/comfyui/vue-widgets/.

Development Mode (Watch)

npm run dev

This builds the widgets in watch mode, automatically rebuilding when files change.

Type Checking

npm run typecheck

Creating a New Widget

1. Create the Python Node

Create a new node file in /py/nodes/your_node.py:

class YourCustomNode:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "your_widget_name": ("YOUR_WIDGET_TYPE", {}),
            }
        }

    RETURN_TYPES = ("STRING",)
    FUNCTION = "process"
    CATEGORY = "loramanager"

    def process(self, your_widget_name):
        # Process widget data
        return (str(your_widget_name),)

NODE_CLASS_MAPPINGS = {
    "YourCustomNode": YourCustomNode
}

2. Create the Vue Component

Create a new component in src/components/YourWidget.vue:

<template>
  <div class="your-widget-container">
    <!-- Your UI here using PrimeVue components -->
    <Button label="Click me" @click="handleClick" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import Button from 'primevue/button'

const props = defineProps<{
  widget: { serializeValue?: (node: unknown, index: number) => Promise<unknown> }
  node: { id: number }
}>()

onMounted(() => {
  // Serialize widget data when workflow is saved
  props.widget.serializeValue = async () => {
    return { /* your data */ }
  }
})
</script>

<style scoped>
/* Your styles */
</style>

3. Register the Widget

In src/main.ts, add your widget registration:

import YourWidget from '@/components/YourWidget.vue'

// In getCustomWidgets()
YOUR_WIDGET_TYPE(node) {
  return createVueWidget(node, YourWidget, 'your-widget-name')
}

// In nodeCreated()
if (node.constructor?.comfyClass !== 'YourCustomNode') return

4. Register the Node

Add your node to __init__.py:

from .py.nodes.your_node import YourCustomNode

NODE_CLASS_MAPPINGS = {
    # ...
    "YourCustomNode": YourCustomNode
}

5. Build and Test

npm run build

Then restart ComfyUI and test your new widget!

Available PrimeVue Components

This project uses PrimeVue 4.x. Popular components include:

  • Button - Buttons with icons and variants
  • InputText - Text input fields
  • InputNumber - Number input with increment/decrement
  • Dropdown - Select dropdowns
  • Card - Card containers
  • DataTable - Data tables with sorting/filtering
  • Dialog - Modal dialogs
  • Tree - Tree view components
  • And many more! See PrimeVue Docs

Notes

  • Build output goes to ../web/comfyui/vue-widgets/ (gitignored)
  • The widget type name in Python (e.g., "YOUR_WIDGET_TYPE") must match the key in getCustomWidgets()
  • Widget data is serialized when the workflow is saved/executed via serializeValue()
  • ComfyUI's app.js is marked as external and not bundled