mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-21 14:59:39 +00:00
Fix: Vue node/widget positioning and scroll issue (#5441)
* [feat] Refactor overlay compatibility into reusable composable - Create useTransformCompatOverlayProps composable for centralized overlay prop management - Update Select, MultiSelect, TreeSelect, and FileUpload components to use composable - Provides appendTo='self' for transform inheritance in CSS-transformed parents - Enables easy future additions of other transform compatibility props - Fix duplicate v-bind attributes by combining props into single computed object * fix: Keep the canvas container from being scrolled by children * types: Align the appendTo type with primevue internals * Update test expectations [skip ci] --------- Co-authored-by: bymyself <cbyrne@comfy.org> Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
:model-value="selectedFile?.name"
|
||||
:options="[selectedFile?.name || '']"
|
||||
:disabled="true"
|
||||
v-bind="transformCompatProps"
|
||||
class="min-w-[8em] max-w-[20em] text-xs"
|
||||
size="small"
|
||||
:pt="{
|
||||
@@ -88,6 +89,7 @@
|
||||
:model-value="selectedFile?.name"
|
||||
:options="[selectedFile?.name || '']"
|
||||
:disabled="true"
|
||||
v-bind="transformCompatProps"
|
||||
class="min-w-[8em] max-w-[20em] text-xs"
|
||||
size="small"
|
||||
:pt="{
|
||||
@@ -182,6 +184,7 @@ import Select from 'primevue/select'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import { useWidgetValue } from '@/composables/graph/useWidgetValue'
|
||||
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -201,6 +204,9 @@ const { localValue, onChange } = useWidgetValue({
|
||||
emit
|
||||
})
|
||||
|
||||
// Transform compatibility props for overlay positioning
|
||||
const transformCompatProps = useTransformCompatOverlayProps()
|
||||
|
||||
const fileInputRef = ref<HTMLInputElement | null>(null)
|
||||
|
||||
// Since we only support single file, get the first file
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<WidgetLayoutField :widget="widget">
|
||||
<MultiSelect
|
||||
v-model="localValue"
|
||||
v-bind="filteredProps"
|
||||
v-bind="combinedProps"
|
||||
:disabled="readonly"
|
||||
:class="cn(WidgetInputBaseClass, 'w-full text-xs')"
|
||||
class="w-full text-xs"
|
||||
size="small"
|
||||
display="chip"
|
||||
:pt="{
|
||||
@@ -20,14 +20,13 @@ import MultiSelect from 'primevue/multiselect'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useWidgetValue } from '@/composables/graph/useWidgetValue'
|
||||
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
import {
|
||||
PANEL_EXCLUDED_PROPS,
|
||||
filterWidgetProps
|
||||
} from '@/utils/widgetPropFilter'
|
||||
|
||||
import { WidgetInputBaseClass } from './layout'
|
||||
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -48,24 +47,17 @@ const { localValue, onChange } = useWidgetValue({
|
||||
emit
|
||||
})
|
||||
|
||||
// Transform compatibility props for overlay positioning
|
||||
const transformCompatProps = useTransformCompatOverlayProps()
|
||||
|
||||
// MultiSelect specific excluded props include overlay styles
|
||||
const MULTISELECT_EXCLUDED_PROPS = [
|
||||
...PANEL_EXCLUDED_PROPS,
|
||||
'overlayStyle'
|
||||
] as const
|
||||
|
||||
const filteredProps = computed(() => {
|
||||
const filtered = filterWidgetProps(
|
||||
props.widget.options,
|
||||
MULTISELECT_EXCLUDED_PROPS
|
||||
)
|
||||
|
||||
// Ensure options array is available for MultiSelect
|
||||
const values = props.widget.options?.values
|
||||
if (values && Array.isArray(values)) {
|
||||
filtered.options = values
|
||||
}
|
||||
|
||||
return filtered
|
||||
})
|
||||
const combinedProps = computed(() => ({
|
||||
...filterWidgetProps(props.widget.options, MULTISELECT_EXCLUDED_PROPS),
|
||||
...transformCompatProps.value
|
||||
}))
|
||||
</script>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<Select
|
||||
v-model="localValue"
|
||||
:options="selectOptions"
|
||||
v-bind="filteredProps"
|
||||
v-bind="combinedProps"
|
||||
:disabled="readonly"
|
||||
:class="cn(WidgetInputBaseClass, 'w-full text-xs')"
|
||||
class="w-full text-xs bg-[#F9F8F4] dark-theme:bg-[#0E0E12] border-[#E1DED5] dark-theme:border-[#15161C] !rounded-lg"
|
||||
size="small"
|
||||
:pt="{
|
||||
option: 'text-xs'
|
||||
@@ -20,14 +20,13 @@ import Select from 'primevue/select'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useWidgetValue } from '@/composables/graph/useWidgetValue'
|
||||
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
import {
|
||||
PANEL_EXCLUDED_PROPS,
|
||||
filterWidgetProps
|
||||
} from '@/utils/widgetPropFilter'
|
||||
|
||||
import { WidgetInputBaseClass } from './layout'
|
||||
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -48,9 +47,13 @@ const { localValue, onChange } = useWidgetValue({
|
||||
emit
|
||||
})
|
||||
|
||||
const filteredProps = computed(() =>
|
||||
filterWidgetProps(props.widget.options, PANEL_EXCLUDED_PROPS)
|
||||
)
|
||||
// Transform compatibility props for overlay positioning
|
||||
const transformCompatProps = useTransformCompatOverlayProps()
|
||||
|
||||
const combinedProps = computed(() => ({
|
||||
...filterWidgetProps(props.widget.options, PANEL_EXCLUDED_PROPS),
|
||||
...transformCompatProps.value
|
||||
}))
|
||||
|
||||
// Extract select options from widget options
|
||||
const selectOptions = computed(() => {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<WidgetLayoutField :widget="widget">
|
||||
<TreeSelect
|
||||
v-model="localValue"
|
||||
v-bind="filteredProps"
|
||||
v-bind="combinedProps"
|
||||
:disabled="readonly"
|
||||
:class="cn(WidgetInputBaseClass, 'w-full text-xs')"
|
||||
class="w-full text-xs"
|
||||
size="small"
|
||||
@update:model-value="onChange"
|
||||
/>
|
||||
@@ -16,14 +16,13 @@ import TreeSelect from 'primevue/treeselect'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useWidgetValue } from '@/composables/graph/useWidgetValue'
|
||||
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
import {
|
||||
PANEL_EXCLUDED_PROPS,
|
||||
filterWidgetProps
|
||||
} from '@/utils/widgetPropFilter'
|
||||
|
||||
import { WidgetInputBaseClass } from './layout'
|
||||
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -44,6 +43,9 @@ const { localValue, onChange } = useWidgetValue({
|
||||
emit
|
||||
})
|
||||
|
||||
// Transform compatibility props for overlay positioning
|
||||
const transformCompatProps = useTransformCompatOverlayProps()
|
||||
|
||||
// TreeSelect specific excluded props
|
||||
const TREE_SELECT_EXCLUDED_PROPS = [
|
||||
...PANEL_EXCLUDED_PROPS,
|
||||
@@ -51,7 +53,8 @@ const TREE_SELECT_EXCLUDED_PROPS = [
|
||||
'inputStyle'
|
||||
] as const
|
||||
|
||||
const filteredProps = computed(() =>
|
||||
filterWidgetProps(props.widget.options, TREE_SELECT_EXCLUDED_PROPS)
|
||||
)
|
||||
const combinedProps = computed(() => ({
|
||||
...filterWidgetProps(props.widget.options, TREE_SELECT_EXCLUDED_PROPS),
|
||||
...transformCompatProps.value
|
||||
}))
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user