diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png index 45c01962d..bfa8676ee 100644 Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png index f43d02474..7da6db5ad 100644 Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png index 3d7fd1919..fff14d6b2 100644 Binary files a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png index 4e3021151..730f96c39 100644 Binary files a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png and b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png index 04e22226f..caaed368a 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png index 5522930b4..44900b718 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png index a016491af..2a3051d82 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png index e7dea316e..24182c58b 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png index 5303ad2a2..a419f5d45 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png index 29dd6136a..f11e37f4e 100644 Binary files a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png and b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png differ diff --git a/src/composables/graph/useWidgetValue.ts b/src/composables/graph/useWidgetValue.ts deleted file mode 100644 index 20e018881..000000000 --- a/src/composables/graph/useWidgetValue.ts +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Composable for managing widget value synchronization between Vue and LiteGraph - * Provides consistent pattern for immediate UI updates and LiteGraph callbacks - */ -import { computed, toValue, ref, watch } from 'vue' -import type { Ref } from 'vue' - -import type { SimplifiedWidget, WidgetValue } from '@/types/simplifiedWidget' -import type { MaybeRefOrGetter } from '@vueuse/core' - -interface UseWidgetValueOptions { - /** The widget configuration from LiteGraph */ - widget: SimplifiedWidget - /** The current value from parent component (can be a value or a getter function) */ - modelValue: MaybeRefOrGetter - /** Default value if modelValue is null/undefined */ - defaultValue: T - /** Emit function from component setup */ - emit: (event: 'update:modelValue', value: T) => void - /** Optional value transformer before sending to LiteGraph */ - transform?: (value: U) => T -} - -interface UseWidgetValueReturn { - /** Local value for immediate UI updates */ - localValue: Ref - /** Handler for user interactions */ - onChange: (newValue: U) => void -} - -/** - * Manages widget value synchronization with LiteGraph - * - * @example - * ```vue - * const { localValue, onChange } = useWidgetValue({ - * widget: props.widget, - * modelValue: props.modelValue, - * defaultValue: '' - * }) - * ``` - */ -export function useWidgetValue({ - widget, - modelValue, - defaultValue, - emit, - transform -}: UseWidgetValueOptions): UseWidgetValueReturn { - // Ref for immediate UI feedback before value flows back through modelValue - const newProcessedValue = ref(null) - - // Computed that prefers the immediately processed value, then falls back to modelValue - const localValue = computed( - () => newProcessedValue.value ?? toValue(modelValue) ?? defaultValue - ) - - // Clear newProcessedValue when modelValue updates (allowing external changes to flow through) - watch( - () => toValue(modelValue), - () => { - newProcessedValue.value = null - } - ) - - // Handle user changes - const onChange = (newValue: U) => { - // Handle different PrimeVue component signatures - let processedValue: T - if (transform) { - processedValue = transform(newValue) - } else { - // Ensure type safety - only cast when types are compatible - if ( - typeof newValue === typeof defaultValue || - newValue === null || - newValue === undefined - ) { - processedValue = (newValue ?? defaultValue) as T - } else { - console.warn( - `useWidgetValue: Type mismatch for widget ${widget.name}. Expected ${typeof defaultValue}, got ${typeof newValue}` - ) - processedValue = defaultValue - } - } - - // Set for immediate UI feedback - newProcessedValue.value = processedValue - - // Emit to parent component - emit('update:modelValue', processedValue) - } - - return { - localValue: localValue as Ref, - onChange - } -} - -/** - * Type-specific helper for string widgets - */ -export function useStringWidgetValue( - widget: SimplifiedWidget, - modelValue: string | (() => string), - emit: (event: 'update:modelValue', value: string) => void -) { - return useWidgetValue({ - widget, - modelValue, - defaultValue: '', - emit, - transform: (value: string | undefined) => String(value || '') // Handle undefined from PrimeVue - }) -} - -/** - * Type-specific helper for number widgets - */ -export function useNumberWidgetValue( - widget: SimplifiedWidget, - modelValue: number | (() => number), - emit: (event: 'update:modelValue', value: number) => void -) { - return useWidgetValue({ - widget, - modelValue, - defaultValue: 0, - emit, - transform: (value: number | number[]) => { - // Handle PrimeVue Slider which can emit number | number[] - if (Array.isArray(value)) { - return value.length > 0 ? (value[0] ?? 0) : 0 - } - return Number(value) || 0 - } - }) -} - -/** - * Type-specific helper for boolean widgets - */ -export function useBooleanWidgetValue( - widget: SimplifiedWidget, - modelValue: boolean | (() => boolean), - emit: (event: 'update:modelValue', value: boolean) => void -) { - return useWidgetValue({ - widget, - modelValue, - defaultValue: false, - emit, - transform: (value: boolean) => Boolean(value) - }) -} diff --git a/src/extensions/core/previewAny.ts b/src/extensions/core/previewAny.ts index 5266f9af9..3de4ca2f3 100644 --- a/src/extensions/core/previewAny.ts +++ b/src/extensions/core/previewAny.ts @@ -22,9 +22,12 @@ useExtensionService().registerExtension({ 'preview', ['STRING', { multiline: true }], app - ).widget as DOMWidget + ).widget as DOMWidget + + showValueWidget.options.read_only = true showValueWidget.element.readOnly = true + showValueWidget.element.disabled = true showValueWidget.serialize = false } diff --git a/src/renderer/extensions/vueNodes/components/LGraphNode.vue b/src/renderer/extensions/vueNodes/components/LGraphNode.vue index d88aab4b6..8b3fd2697 100644 --- a/src/renderer/extensions/vueNodes/components/LGraphNode.vue +++ b/src/renderer/extensions/vueNodes/components/LGraphNode.vue @@ -8,7 +8,7 @@ :data-node-id="nodeData.id" :class=" cn( - 'bg-component-node-background lg-node absolute', + 'bg-component-node-background lg-node absolute pb-1', 'contain-style contain-layout min-w-[225px] min-h-(--node-height) w-(--node-width)', 'rounded-2xl touch-none flex flex-col', diff --git a/src/renderer/extensions/vueNodes/components/NodeWidgets.vue b/src/renderer/extensions/vueNodes/components/NodeWidgets.vue index 864e9d93b..10a06ff15 100644 --- a/src/renderer/extensions/vueNodes/components/NodeWidgets.vue +++ b/src/renderer/extensions/vueNodes/components/NodeWidgets.vue @@ -59,10 +59,11 @@ diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue index b4a11de65..a08087db0 100644 --- a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue +++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue @@ -2,7 +2,6 @@ import InputNumber from 'primevue/inputnumber' import { computed } from 'vue' -import { useNumberWidgetValue } from '@/composables/graph/useWidgetValue' import type { SimplifiedWidget } from '@/types/simplifiedWidget' import { cn } from '@/utils/tailwindUtil' import { @@ -15,18 +14,9 @@ import WidgetLayoutField from './layout/WidgetLayoutField.vue' const props = defineProps<{ widget: SimplifiedWidget - modelValue: number }>() -const emit = defineEmits<{ - 'update:modelValue': [value: number] -}>() - -const { localValue, onChange } = useNumberWidgetValue( - props.widget, - props.modelValue, - emit -) +const modelValue = defineModel({ default: 0 }) const filteredProps = computed(() => filterWidgetProps(props.widget.options, INPUT_EXCLUDED_PROPS) @@ -65,7 +55,7 @@ const useGrouping = computed(() => { // Check if increment/decrement buttons should be disabled due to precision limits const buttonsDisabled = computed(() => { - const currentValue = localValue.value ?? 0 + const currentValue = modelValue.value ?? 0 return ( !Number.isFinite(currentValue) || Math.abs(currentValue) > Number.MAX_SAFE_INTEGER @@ -83,7 +73,7 @@ const buttonTooltip = computed(() => {