From 3dc7686f7a1e5fad2d8086683eb0e91de5da0fd8 Mon Sep 17 00:00:00 2001 From: bymyself Date: Wed, 2 Jul 2025 04:30:59 -0700 Subject: [PATCH] [feat] Add widget renderer composable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Map LiteGraph widget types to Vue components - Support text, combo, number, boolean widget types - Check if widgets should render as Vue components - Proper TypeScript interfaces instead of any 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/composables/graph/useWidgetRenderer.ts | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/composables/graph/useWidgetRenderer.ts diff --git a/src/composables/graph/useWidgetRenderer.ts b/src/composables/graph/useWidgetRenderer.ts new file mode 100644 index 000000000..fc4831cf6 --- /dev/null +++ b/src/composables/graph/useWidgetRenderer.ts @@ -0,0 +1,92 @@ +/** + * Widget renderer composable for Vue node system + * Maps LiteGraph widget types to Vue components + */ +import { + WidgetType, + widgetTypeToComponent +} from '@/components/graph/vueWidgets/widgetRegistry' + +export const useWidgetRenderer = () => { + /** + * Map LiteGraph widget types to Vue widget component names + */ + const getWidgetComponent = (widgetType: string): string => { + // Map common LiteGraph widget types to our registry enum keys + const typeToEnum: Record = { + // Number inputs + number: WidgetType.NUMBER, + slider: WidgetType.SLIDER, + INT: WidgetType.INT, + FLOAT: WidgetType.FLOAT, + + // Text inputs + text: WidgetType.STRING, + string: WidgetType.STRING, + STRING: WidgetType.STRING, + + // Selection + combo: WidgetType.COMBO, + COMBO: WidgetType.COMBO, + + // Boolean + toggle: WidgetType.TOGGLESWITCH, + boolean: WidgetType.BOOLEAN, + BOOLEAN: WidgetType.BOOLEAN, + + // Multiline text + multiline: WidgetType.TEXTAREA, + textarea: WidgetType.TEXTAREA, + + // Advanced widgets + color: WidgetType.COLOR, + COLOR: WidgetType.COLOR, + image: WidgetType.IMAGE, + IMAGE: WidgetType.IMAGE, + file: WidgetType.FILEUPLOAD, + FILEUPLOAD: WidgetType.FILEUPLOAD + } + + // Get mapped enum key + const enumKey = typeToEnum[widgetType] + + // Check if we have a component for this type + if (enumKey && widgetTypeToComponent[enumKey]) { + return enumKey + } + + // Log unmapped widget types for debugging + if (process.env.NODE_ENV === 'development') { + console.warn( + `[useWidgetRenderer] Unknown widget type: ${widgetType}, falling back to WidgetInputText` + ) + } + + return WidgetType.STRING // Return enum key for WidgetInputText + } + + /** + * Check if a widget should be rendered as Vue component + */ + const shouldRenderAsVue = (widget: { + type?: string + options?: Record + }): boolean => { + // Skip widgets that are marked as canvas-only + if (widget.options?.canvasOnly) return false + + // Skip widgets without a type + if (!widget.type) return false + + // Get the component type for this widget + const enumKey = getWidgetComponent(widget.type) + + // If we have a component in our registry, render it as Vue + return widgetTypeToComponent[enumKey] !== undefined + } + + return { + getWidgetComponent, + shouldRenderAsVue + } +}