Files
ComfyUI-Lora-Manager/vue-widgets
Will Miao f28c32f2b1 feat(lora-cycler): increase repeat input width for better usability
The width of the repeat input field in the LoRA cycler settings view has been increased from 40px to 50px. This change improves usability by providing more space for user input, making the control easier to interact with and reducing visual crowding.
2026-02-03 09:40:55 +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