mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
[Refactor] useStringWidget composable (#2503)
This commit is contained in:
90
src/composables/widgets/useStringWidget.ts
Normal file
90
src/composables/widgets/useStringWidget.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import type { IWidget, LGraphNode } from '@comfyorg/litegraph'
|
||||||
|
|
||||||
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
|
import type { ComfyApp } from '@/types'
|
||||||
|
import type { InputSpec } from '@/types/apiTypes'
|
||||||
|
|
||||||
|
function addMultilineWidget(
|
||||||
|
node: LGraphNode,
|
||||||
|
name: string,
|
||||||
|
opts: { defaultVal: string; placeholder?: string },
|
||||||
|
app: ComfyApp
|
||||||
|
) {
|
||||||
|
const inputEl = document.createElement('textarea')
|
||||||
|
inputEl.className = 'comfy-multiline-input'
|
||||||
|
inputEl.value = opts.defaultVal
|
||||||
|
inputEl.placeholder = opts.placeholder || name
|
||||||
|
if (app.vueAppReady) {
|
||||||
|
inputEl.spellcheck = useSettingStore().get(
|
||||||
|
'Comfy.TextareaWidget.Spellcheck'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = node.addDOMWidget(name, 'customtext', inputEl, {
|
||||||
|
getValue(): string {
|
||||||
|
return inputEl.value
|
||||||
|
},
|
||||||
|
setValue(v: string) {
|
||||||
|
inputEl.value = v
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
widget.inputEl = inputEl
|
||||||
|
|
||||||
|
inputEl.addEventListener('input', () => {
|
||||||
|
widget.callback?.(widget.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
inputEl.addEventListener('pointerdown', (event: PointerEvent) => {
|
||||||
|
if (event.button === 1) {
|
||||||
|
app.canvas.processMouseDown(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
inputEl.addEventListener('pointermove', (event: PointerEvent) => {
|
||||||
|
if ((event.buttons & 4) === 4) {
|
||||||
|
app.canvas.processMouseMove(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
inputEl.addEventListener('pointerup', (event: PointerEvent) => {
|
||||||
|
if (event.button === 1) {
|
||||||
|
app.canvas.processMouseUp(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { minWidth: 400, minHeight: 200, widget }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useStringWidget = () => {
|
||||||
|
const widgetConstructor = (
|
||||||
|
node: LGraphNode,
|
||||||
|
inputName: string,
|
||||||
|
inputData: InputSpec,
|
||||||
|
app: ComfyApp
|
||||||
|
) => {
|
||||||
|
const defaultVal = inputData[1].default || ''
|
||||||
|
const multiline = !!inputData[1].multiline
|
||||||
|
|
||||||
|
let res: { widget: IWidget }
|
||||||
|
if (multiline) {
|
||||||
|
res = addMultilineWidget(
|
||||||
|
node,
|
||||||
|
inputName,
|
||||||
|
{ defaultVal, ...inputData[1] },
|
||||||
|
app
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
widget: node.addWidget('text', inputName, defaultVal, () => {}, {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputData[1].dynamicPrompts != undefined)
|
||||||
|
res.widget.dynamicPrompts = inputData[1].dynamicPrompts
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
return widgetConstructor
|
||||||
|
}
|
||||||
@@ -10,8 +10,7 @@ useExtensionService().registerExtension({
|
|||||||
if (node.widgets) {
|
if (node.widgets) {
|
||||||
// Locate dynamic prompt text widgets
|
// Locate dynamic prompt text widgets
|
||||||
// Include any widgets with dynamicPrompts set to true, and customtext
|
// Include any widgets with dynamicPrompts set to true, and customtext
|
||||||
// @ts-expect-error dynamicPrompts is not typed
|
const widgets = node.widgets.filter((w) => w.dynamicPrompts)
|
||||||
const widgets = node.widgets.filter((n) => n.dynamicPrompts)
|
|
||||||
for (const widget of widgets) {
|
for (const widget of widgets) {
|
||||||
// Override the serialization of the value to resolve dynamic prompts for all widgets supporting it in this node
|
// Override the serialization of the value to resolve dynamic prompts for all widgets supporting it in this node
|
||||||
// @ts-expect-error hacky override
|
// @ts-expect-error hacky override
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import TiptapStarterKit from '@tiptap/starter-kit'
|
|||||||
import { Markdown as TiptapMarkdown } from 'tiptap-markdown'
|
import { Markdown as TiptapMarkdown } from 'tiptap-markdown'
|
||||||
|
|
||||||
import { useRemoteWidget } from '@/composables/widgets/useRemoteWidget'
|
import { useRemoteWidget } from '@/composables/widgets/useRemoteWidget'
|
||||||
|
import { useStringWidget } from '@/composables/widgets/useStringWidget'
|
||||||
import { useSettingStore } from '@/stores/settingStore'
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
import { useToastStore } from '@/stores/toastStore'
|
import { useToastStore } from '@/stores/toastStore'
|
||||||
import { useWidgetStore } from '@/stores/widgetStore'
|
import { useWidgetStore } from '@/stores/widgetStore'
|
||||||
@@ -335,52 +336,6 @@ function createIntWidget(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMultilineWidget(node, name: string, opts, app: ComfyApp) {
|
|
||||||
const inputEl = document.createElement('textarea')
|
|
||||||
inputEl.className = 'comfy-multiline-input'
|
|
||||||
inputEl.value = opts.defaultVal
|
|
||||||
inputEl.placeholder = opts.placeholder || name
|
|
||||||
if (app.vueAppReady) {
|
|
||||||
inputEl.spellcheck = useSettingStore().get(
|
|
||||||
'Comfy.TextareaWidget.Spellcheck'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const widget = node.addDOMWidget(name, 'customtext', inputEl, {
|
|
||||||
getValue() {
|
|
||||||
return inputEl.value
|
|
||||||
},
|
|
||||||
setValue(v) {
|
|
||||||
inputEl.value = v
|
|
||||||
}
|
|
||||||
})
|
|
||||||
widget.inputEl = inputEl
|
|
||||||
|
|
||||||
inputEl.addEventListener('input', () => {
|
|
||||||
widget.callback?.(widget.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
inputEl.addEventListener('pointerdown', (event: PointerEvent) => {
|
|
||||||
if (event.button === 1) {
|
|
||||||
app.canvas.processMouseDown(event)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
inputEl.addEventListener('pointermove', (event: PointerEvent) => {
|
|
||||||
if ((event.buttons & 4) === 4) {
|
|
||||||
app.canvas.processMouseMove(event)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
inputEl.addEventListener('pointerup', (event: PointerEvent) => {
|
|
||||||
if (event.button === 1) {
|
|
||||||
app.canvas.processMouseUp(event)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return { minWidth: 400, minHeight: 200, widget }
|
|
||||||
}
|
|
||||||
|
|
||||||
function addMarkdownWidget(node, name: string, opts, app: ComfyApp) {
|
function addMarkdownWidget(node, name: string, opts, app: ComfyApp) {
|
||||||
TiptapMarkdown.configure({
|
TiptapMarkdown.configure({
|
||||||
html: false,
|
html: false,
|
||||||
@@ -528,29 +483,7 @@ export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
|
|||||||
widget: node.addWidget('toggle', inputName, defaultVal, () => {}, options)
|
widget: node.addWidget('toggle', inputName, defaultVal, () => {}, options)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
STRING(node, inputName, inputData: InputSpec, app) {
|
STRING: useStringWidget(),
|
||||||
const defaultVal = inputData[1].default || ''
|
|
||||||
const multiline = !!inputData[1].multiline
|
|
||||||
|
|
||||||
let res
|
|
||||||
if (multiline) {
|
|
||||||
res = addMultilineWidget(
|
|
||||||
node,
|
|
||||||
inputName,
|
|
||||||
{ defaultVal, ...inputData[1] },
|
|
||||||
app
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
res = {
|
|
||||||
widget: node.addWidget('text', inputName, defaultVal, () => {}, {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inputData[1].dynamicPrompts != undefined)
|
|
||||||
res.widget.dynamicPrompts = inputData[1].dynamicPrompts
|
|
||||||
|
|
||||||
return res
|
|
||||||
},
|
|
||||||
MARKDOWN(node, inputName, inputData: InputSpec, app) {
|
MARKDOWN(node, inputName, inputData: InputSpec, app) {
|
||||||
const defaultVal = inputData[1].default || ''
|
const defaultVal = inputData[1].default || ''
|
||||||
|
|
||||||
|
|||||||
6
src/types/litegraph-augmentation.d.ts
vendored
6
src/types/litegraph-augmentation.d.ts
vendored
@@ -17,6 +17,12 @@ declare module '@comfyorg/litegraph/dist/types/widgets' {
|
|||||||
onRemove?: () => void
|
onRemove?: () => void
|
||||||
beforeQueued?: () => unknown
|
beforeQueued?: () => unknown
|
||||||
serializeValue?: (node: LGraphNode, index: number) => Promise<unknown>
|
serializeValue?: (node: LGraphNode, index: number) => Promise<unknown>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the widget supports dynamic prompts, this will be set to true.
|
||||||
|
* See extensions/core/dynamicPrompts.ts
|
||||||
|
*/
|
||||||
|
dynamicPrompts?: boolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user