Use v2 input spec in string widgets (#2877)

This commit is contained in:
Chenlei Hu
2025-03-05 12:48:23 -05:00
committed by GitHub
parent 1882a9af6f
commit 8a479979b1
4 changed files with 48 additions and 58 deletions

View File

@@ -8,15 +8,14 @@ import TiptapTableRow from '@tiptap/extension-table-row'
import TiptapStarterKit from '@tiptap/starter-kit' import TiptapStarterKit from '@tiptap/starter-kit'
import { Markdown as TiptapMarkdown } from 'tiptap-markdown' import { Markdown as TiptapMarkdown } from 'tiptap-markdown'
import type { InputSpec } from '@/schemas/nodeDefSchema' import { type InputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import type { ComfyWidgetConstructor } from '@/scripts/widgets' import { app } from '@/scripts/app'
import type { ComfyApp } from '@/types' import { type ComfyWidgetConstructorV2 } from '@/scripts/widgets'
function addMarkdownWidget( function addMarkdownWidget(
node: LGraphNode, node: LGraphNode,
name: string, name: string,
opts: { defaultVal: string }, opts: { defaultVal: string }
app: ComfyApp
) { ) {
TiptapMarkdown.configure({ TiptapMarkdown.configure({
html: false, html: false,
@@ -52,6 +51,7 @@ function addMarkdownWidget(
} }
}) })
widget.inputEl = inputEl widget.inputEl = inputEl
widget.options.minNodeSize = [400, 200]
inputEl.addEventListener('pointerdown', (event: PointerEvent) => { inputEl.addEventListener('pointerdown', (event: PointerEvent) => {
if (event.button !== 0) { if (event.button !== 0) {
@@ -98,23 +98,17 @@ function addMarkdownWidget(
} }
}) })
return { minWidth: 400, minHeight: 200, widget } return widget
} }
export const useMarkdownWidget = () => { export const useMarkdownWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = ( const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode, node: LGraphNode,
inputName: string, inputSpec: InputSpec
inputData: InputSpec,
app: ComfyApp
) => { ) => {
const defaultVal = inputData[1]?.default || '' return addMarkdownWidget(node, inputSpec.name, {
return addMarkdownWidget( defaultVal: inputSpec.default ?? ''
node, })
inputName,
{ defaultVal, ...inputData[1] },
app
)
} }
return widgetConstructor return widgetConstructor

View File

@@ -1,25 +1,23 @@
import type { IWidget, LGraphNode } from '@comfyorg/litegraph' import type { LGraphNode } from '@comfyorg/litegraph'
import { type InputSpec, isStringInputSpec } from '@/schemas/nodeDefSchema' import {
import type { ComfyWidgetConstructor } from '@/scripts/widgets' type InputSpec,
isStringInputSpec
} from '@/schemas/nodeDef/nodeDefSchemaV2'
import { app } from '@/scripts/app'
import { type ComfyWidgetConstructorV2 } from '@/scripts/widgets'
import { useSettingStore } from '@/stores/settingStore' import { useSettingStore } from '@/stores/settingStore'
import type { ComfyApp } from '@/types'
function addMultilineWidget( function addMultilineWidget(
node: LGraphNode, node: LGraphNode,
name: string, name: string,
opts: { defaultVal: string; placeholder?: string }, opts: { defaultVal: string; placeholder?: string }
app: ComfyApp
) { ) {
const inputEl = document.createElement('textarea') const inputEl = document.createElement('textarea')
inputEl.className = 'comfy-multiline-input' inputEl.className = 'comfy-multiline-input'
inputEl.value = opts.defaultVal inputEl.value = opts.defaultVal
inputEl.placeholder = opts.placeholder || name inputEl.placeholder = opts.placeholder || name
if (app.vueAppReady) { inputEl.spellcheck = useSettingStore().get('Comfy.TextareaWidget.Spellcheck')
inputEl.spellcheck = useSettingStore().get(
'Comfy.TextareaWidget.Spellcheck'
)
}
const widget = node.addDOMWidget(name, 'customtext', inputEl, { const widget = node.addDOMWidget(name, 'customtext', inputEl, {
getValue(): string { getValue(): string {
@@ -31,6 +29,7 @@ function addMultilineWidget(
}) })
widget.inputEl = inputEl widget.inputEl = inputEl
widget.options.minNodeSize = [400, 200]
inputEl.addEventListener('input', () => { inputEl.addEventListener('input', () => {
widget.callback?.(widget.value) widget.callback?.(widget.value)
@@ -54,43 +53,33 @@ function addMultilineWidget(
} }
}) })
return { minWidth: 400, minHeight: 200, widget } return widget
} }
export const useStringWidget = () => { export const useStringWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = ( const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode, node: LGraphNode,
inputName: string, inputSpec: InputSpec
inputData: InputSpec,
app: ComfyApp
) => { ) => {
if (!isStringInputSpec(inputData)) { if (!isStringInputSpec(inputSpec)) {
throw new Error(`Invalid input data: ${inputData}`) throw new Error(`Invalid input data: ${inputSpec}`)
} }
const inputOptions = inputData[1] ?? {} const defaultVal = inputSpec.default ?? ''
const defaultVal = inputOptions.default ?? '' const multiline = inputSpec.multiline
const multiline = inputOptions.multiline
let res: { widget: IWidget } const widget = multiline
if (multiline) { ? addMultilineWidget(node, inputSpec.name, {
res = addMultilineWidget( defaultVal,
node, placeholder: inputSpec.placeholder
inputName, })
{ defaultVal, ...inputOptions }, : node.addWidget('text', inputSpec.name, defaultVal, () => {}, {})
app
) if (typeof inputSpec.dynamicPrompts === 'boolean') {
} else { widget.dynamicPrompts = inputSpec.dynamicPrompts
res = {
widget: node.addWidget('text', inputName, defaultVal, () => {}, {})
}
} }
if (typeof inputOptions.dynamicPrompts === 'boolean') { return widget
res.widget.dynamicPrompts = inputOptions.dynamicPrompts
}
return res
} }
return widgetConstructor return widgetConstructor

View File

@@ -46,8 +46,11 @@ const transformWidgetConstructorV2ToV1 = (
const inputSpec = transformInputSpecV1ToV2(inputData, { const inputSpec = transformInputSpecV1ToV2(inputData, {
name: inputName name: inputName
}) })
const widget = widgetConstructorV2(node, inputSpec)
return { return {
widget: widgetConstructorV2(node, inputSpec) widget,
minWidth: widget.options.minNodeSize?.[0],
minHeight: widget.options.minNodeSize?.[1]
} }
} }
} }
@@ -288,8 +291,8 @@ export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
INT: transformWidgetConstructorV2ToV1(useIntWidget()), INT: transformWidgetConstructorV2ToV1(useIntWidget()),
FLOAT: transformWidgetConstructorV2ToV1(useFloatWidget()), FLOAT: transformWidgetConstructorV2ToV1(useFloatWidget()),
BOOLEAN: transformWidgetConstructorV2ToV1(useBooleanWidget()), BOOLEAN: transformWidgetConstructorV2ToV1(useBooleanWidget()),
STRING: useStringWidget(), STRING: transformWidgetConstructorV2ToV1(useStringWidget()),
MARKDOWN: useMarkdownWidget(), MARKDOWN: transformWidgetConstructorV2ToV1(useMarkdownWidget()),
COMBO: useComboWidget(), COMBO: useComboWidget(),
IMAGEUPLOAD: useImageUploadWidget() IMAGEUPLOAD: useImageUploadWidget()
} }

View File

@@ -22,6 +22,10 @@ declare module '@comfyorg/litegraph/dist/types/widgets' {
* Rounding value for numeric float widgets. * Rounding value for numeric float widgets.
*/ */
round?: number round?: number
/**
* The minimum size of the node if the widget is present.
*/
minNodeSize?: Size
} }
interface IBaseWidget { interface IBaseWidget {