diff --git a/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.test.ts b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.test.ts
new file mode 100644
index 0000000000..50765a9846
--- /dev/null
+++ b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.test.ts
@@ -0,0 +1,115 @@
+import { flushPromises, mount } from '@vue/test-utils'
+import PrimeVue from 'primevue/config'
+import { createI18n } from 'vue-i18n'
+import { describe, expect, it, vi } from 'vitest'
+import { defineComponent, h } from 'vue'
+
+import FormDropdown from './FormDropdown.vue'
+import type { FormDropdownItem } from './types'
+
+function createItem(id: string, name: string): FormDropdownItem {
+ return { id, preview_url: '', name, label: name }
+}
+
+const i18n = createI18n({ legacy: false, locale: 'en', messages: { en: {} } })
+
+vi.mock('@/platform/updates/common/toastStore', () => ({
+ useToastStore: () => ({
+ addAlert: vi.fn()
+ })
+}))
+
+const MockFormDropdownMenu = defineComponent({
+ name: 'FormDropdownMenu',
+ props: {
+ items: { type: Array as () => FormDropdownItem[], default: () => [] },
+ isSelected: { type: Function, default: undefined },
+ filterOptions: { type: Array, default: () => [] },
+ sortOptions: { type: Array, default: () => [] },
+ maxSelectable: { type: Number, default: 1 },
+ disabled: { type: Boolean, default: false },
+ showOwnershipFilter: { type: Boolean, default: false },
+ ownershipOptions: { type: Array, default: () => [] },
+ showBaseModelFilter: { type: Boolean, default: false },
+ baseModelOptions: { type: Array, default: () => [] }
+ },
+ setup() {
+ return () => h('div', { class: 'mock-menu' })
+ }
+})
+
+function mountDropdown(items: FormDropdownItem[]) {
+ return mount(FormDropdown, {
+ props: { items },
+ global: {
+ plugins: [PrimeVue, i18n],
+ stubs: {
+ FormDropdownInput: true,
+ Popover: { template: '
' },
+ FormDropdownMenu: MockFormDropdownMenu
+ }
+ }
+ })
+}
+
+function getMenuItems(
+ wrapper: ReturnType
+): FormDropdownItem[] {
+ return wrapper
+ .findComponent(MockFormDropdownMenu)
+ .props('items') as FormDropdownItem[]
+}
+
+describe('FormDropdown', () => {
+ describe('filteredItems updates when items prop changes', () => {
+ it('updates displayed items when items prop changes', async () => {
+ const wrapper = mountDropdown([
+ createItem('input-0', 'video1.mp4'),
+ createItem('input-1', 'video2.mp4')
+ ])
+ await flushPromises()
+
+ expect(getMenuItems(wrapper)).toHaveLength(2)
+
+ await wrapper.setProps({
+ items: [
+ createItem('output-0', 'rendered1.mp4'),
+ createItem('output-1', 'rendered2.mp4')
+ ]
+ })
+ await flushPromises()
+
+ const menuItems = getMenuItems(wrapper)
+ expect(menuItems).toHaveLength(2)
+ expect(menuItems[0].name).toBe('rendered1.mp4')
+ })
+
+ it('updates when items change but IDs stay the same', async () => {
+ const wrapper = mountDropdown([createItem('1', 'alpha')])
+ await flushPromises()
+
+ await wrapper.setProps({ items: [createItem('1', 'beta')] })
+ await flushPromises()
+
+ expect(getMenuItems(wrapper)[0].name).toBe('beta')
+ })
+
+ it('updates when switching between empty and non-empty items', async () => {
+ const wrapper = mountDropdown([])
+ await flushPromises()
+
+ expect(getMenuItems(wrapper)).toHaveLength(0)
+
+ await wrapper.setProps({ items: [createItem('1', 'video.mp4')] })
+ await flushPromises()
+
+ expect(getMenuItems(wrapper)).toHaveLength(1)
+ expect(getMenuItems(wrapper)[0].name).toBe('video.mp4')
+
+ await wrapper.setProps({ items: [] })
+ await flushPromises()
+
+ expect(getMenuItems(wrapper)).toHaveLength(0)
+ })
+ })
+})
diff --git a/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
index 12c30a1ab8..a9574e566f 100644
--- a/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
+++ b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue
@@ -1,4 +1,5 @@
@@ -233,11 +226,9 @@ async function customSearcher(
:show-base-model-filter
:base-model-options
:disabled
- :searcher="customSearcher"
:items="sortedItems"
:is-selected="internalIsSelected"
:max-selectable
- :update-key="itemsKey"
@close="closeDropdown"
@item-click="handleSelection"
/>
diff --git a/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
index 8d12c47e7a..ae571d2021 100644
--- a/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
+++ b/src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
@@ -1,5 +1,5 @@