Feat: Add preview as plaintext toggle for Preview As Text (#7102)

## Summary

Adds a toggle to conditionally render the text as Markdown.

## Also...

Fixes some type issues across our myriad Widget types. We should
probably clean those up.

## Example


https://github.com/user-attachments/assets/24fed943-1e79-4ea4-a962-826b06d68761



This could be a good minimal testcase for dynamic widgets @AustinMroz

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7102-WIP-Feat-Add-preview-as-plaintext-toggle-for-Preview-As-Text-2bd6d73d3650810c8b25c84866c8875c)
by [Unito](https://www.unito.io)
This commit is contained in:
Alexander Brown
2025-12-02 14:37:57 -08:00
committed by GitHub
parent e887d69cdc
commit c263111eeb
8 changed files with 107 additions and 57 deletions

View File

@@ -24,12 +24,43 @@ useExtensionService().registerExtension({
app
).widget as DOMWidget<HTMLTextAreaElement, string>
showValueWidget.options.read_only = true
const showValueWidgetPlain = ComfyWidgets['STRING'](
this,
'preview',
['STRING', { multiline: true }],
app
).widget as DOMWidget<HTMLTextAreaElement, string>
const showAsPlaintextWidget = ComfyWidgets['BOOLEAN'](
this,
'previewMode',
[
'BOOLEAN',
{ label_on: 'Markdown', label_off: 'Plaintext', default: false }
],
app
)
showAsPlaintextWidget.widget.callback = (value) => {
showValueWidget.hidden = !value
showValueWidget.options.hidden = !value
showValueWidgetPlain.hidden = value
showValueWidgetPlain.options.hidden = value
}
showValueWidget.hidden = true
showValueWidget.options.hidden = true
showValueWidget.options.read_only = true
showValueWidget.element.readOnly = true
showValueWidget.element.disabled = true
showValueWidget.serialize = false
showValueWidgetPlain.hidden = false
showValueWidgetPlain.options.hidden = false
showValueWidgetPlain.options.read_only = true
showValueWidgetPlain.element.readOnly = true
showValueWidgetPlain.element.disabled = true
showValueWidgetPlain.serialize = false
}
const onExecuted = nodeType.prototype.onExecuted
@@ -39,9 +70,10 @@ useExtensionService().registerExtension({
? void 0
: onExecuted.apply(this, [message])
const previewWidget = this.widgets?.find((w) => w.name === 'preview')
const previewWidgets =
this.widgets?.filter((w) => w.name === 'preview') ?? []
if (previewWidget) {
for (const previewWidget of previewWidgets) {
previewWidget.value = message.text[0]
}
}

View File

@@ -14,7 +14,11 @@ import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
import type { InputSpec } from '@/schemas/nodeDefSchema'
import { app } from '@/scripts/app'
import { ComfyWidgets, addValueControlWidgets } from '@/scripts/widgets'
import {
ComfyWidgets,
addValueControlWidgets,
isValidWidgetType
} from '@/scripts/widgets'
import { CONFIG, GET_CONFIG } from '@/services/litegraphService'
import { mergeInputSpec } from '@/utils/nodeDefUtil'
import { applyTextReplacements } from '@/utils/searchAndReplace'
@@ -223,8 +227,8 @@ export class PrimitiveNode extends LGraphNode {
// Store current size as addWidget resizes the node
const [oldWidth, oldHeight] = this.size
let widget: IBaseWidget | undefined
if (type in ComfyWidgets) {
let widget: IBaseWidget
if (isValidWidgetType(type)) {
widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget
} else {
// @ts-expect-error InputSpec is not typed correctly