mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-12 00:20:15 +00:00
## Summary Fixes the case where a value is updated in the graph but the result doesn't reflect on the widget representation on the relevant node. ## Changes - **What**: Uses vanilla Vue utilities instead of a special utility - **What**: Fewer places where state could be desynced. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6741-Fix-WIP-Simplify-the-widget-state-logic-2af6d73d36508160b729db50608a2ea9) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
110 lines
3.0 KiB
Vue
110 lines
3.0 KiB
Vue
<template>
|
|
<WidgetLayoutField :widget="widget">
|
|
<div :class="cn(WidgetInputBaseClass, 'flex items-center gap-2 pl-3 pr-2')">
|
|
<Slider
|
|
:model-value="[modelValue]"
|
|
v-bind="filteredProps"
|
|
class="flex-grow text-xs"
|
|
:step="stepValue"
|
|
:aria-label="widget.name"
|
|
@update:model-value="updateLocalValue"
|
|
/>
|
|
<InputNumber
|
|
:key="timesEmptied"
|
|
:model-value="modelValue"
|
|
v-bind="filteredProps"
|
|
:step="stepValue"
|
|
:min-fraction-digits="precision"
|
|
:max-fraction-digits="precision"
|
|
:aria-label="widget.name"
|
|
size="small"
|
|
pt:pc-input-text:root="min-w-[4ch] bg-transparent border-none text-center truncate"
|
|
class="w-16"
|
|
:pt="sliderNumberPt"
|
|
@update:model-value="handleNumberInputUpdate"
|
|
/>
|
|
</div>
|
|
</WidgetLayoutField>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import InputNumber from 'primevue/inputnumber'
|
|
import { computed, ref } from 'vue'
|
|
|
|
import Slider from '@/components/ui/slider/Slider.vue'
|
|
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
|
import { cn } from '@/utils/tailwindUtil'
|
|
import {
|
|
STANDARD_EXCLUDED_PROPS,
|
|
filterWidgetProps
|
|
} from '@/utils/widgetPropFilter'
|
|
|
|
import { useNumberWidgetButtonPt } from '../composables/useNumberWidgetButtonPt'
|
|
import { WidgetInputBaseClass } from './layout'
|
|
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
|
|
|
|
const { widget } = defineProps<{
|
|
widget: SimplifiedWidget<number>
|
|
}>()
|
|
|
|
const modelValue = defineModel<number>({ default: 0 })
|
|
|
|
const timesEmptied = ref(0)
|
|
|
|
const updateLocalValue = (newValue: number[] | undefined): void => {
|
|
if (newValue?.length) modelValue.value = newValue[0]
|
|
}
|
|
|
|
const handleNumberInputUpdate = (newValue: number | undefined) => {
|
|
if (newValue) {
|
|
updateLocalValue([newValue])
|
|
return
|
|
}
|
|
timesEmptied.value += 1
|
|
}
|
|
|
|
const filteredProps = computed(() =>
|
|
filterWidgetProps(widget.options, STANDARD_EXCLUDED_PROPS)
|
|
)
|
|
|
|
// Get the precision value for proper number formatting
|
|
const precision = computed(() => {
|
|
const p = widget.options?.precision
|
|
// Treat negative or non-numeric precision as undefined
|
|
return typeof p === 'number' && p >= 0 ? p : undefined
|
|
})
|
|
|
|
// Calculate the step value based on precision or widget options
|
|
const stepValue = computed(() => {
|
|
// Use step2 (correct input spec value) instead of step (legacy 10x value)
|
|
if (widget.options?.step2 !== undefined) {
|
|
return widget.options.step2
|
|
}
|
|
|
|
// Otherwise, derive from precision
|
|
if (precision.value === undefined) {
|
|
return undefined
|
|
}
|
|
|
|
if (precision.value === 0) {
|
|
return 1
|
|
}
|
|
|
|
// For precision > 0, step = 1 / (10^precision)
|
|
// precision 1 → 0.1, precision 2 → 0.01, etc.
|
|
return 1 / Math.pow(10, precision.value)
|
|
})
|
|
|
|
const sliderNumberPt = useNumberWidgetButtonPt({
|
|
roundedLeft: true,
|
|
roundedRight: true
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
:deep(.p-inputnumber-button.p-disabled .pi),
|
|
:deep(.p-inputnumber-button.p-disabled .p-icon) {
|
|
color: var(--color-node-icon-disabled) !important;
|
|
}
|
|
</style>
|