Skip to content

Commit 44002f6

Browse files
committed
Revert "fix(VCombobox): filter matching items when opening first time"
This reverts commit eeb9d14. fixes #22077
1 parent 4d4c872 commit 44002f6

File tree

2 files changed

+11
-91
lines changed

2 files changed

+11
-91
lines changed

packages/vuetify/src/components/VCombobox/VCombobox.tsx

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ export const VCombobox = genericComponent<new <
128128
const isFocused = shallowRef(false)
129129
const isPristine = shallowRef(true)
130130
const listHasFocus = shallowRef(false)
131-
const showAllItemsForNoMatch = shallowRef(false)
132131
const vMenuRef = ref<VMenu>()
133132
const vVirtualScrollRef = ref<VVirtualScroll>()
134133
const selectionIndex = shallowRef(-1)
@@ -190,27 +189,19 @@ export const VCombobox = genericComponent<new <
190189
: (props.multiple ? model.value.length : search.value.length)
191190
})
192191

193-
const { filteredItems, getMatches } = useFilter(props, items, search)
194-
195-
const hasMatchingItems = computed(() => {
196-
return props.hideSelected
197-
? filteredItems.value.some(filteredItem => !model.value.some(s => s.value === filteredItem.value))
198-
: filteredItems.value.length > 0
199-
})
192+
const { filteredItems, getMatches } = useFilter(props, items, () => isPristine.value ? '' : search.value)
200193

201194
const displayItems = computed(() => {
202195
if (props.hideSelected) {
203196
return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value))
204197
}
205-
if (filteredItems.value.length === 0 && showAllItemsForNoMatch.value) {
206-
return items.value
207-
}
208198
return filteredItems.value
209199
})
210200

211-
const menuDisabled = computed(() => {
212-
return form.isReadonly.value || form.isDisabled.value
213-
})
201+
const menuDisabled = computed(() => (
202+
(props.hideNoData && !displayItems.value.length) ||
203+
form.isReadonly.value || form.isDisabled.value
204+
))
214205
const _menu = useProxiedModel(props, 'menu')
215206
const menu = computed({
216207
get: () => _menu.value,
@@ -224,18 +215,14 @@ export const VCombobox = genericComponent<new <
224215
const { menuId, ariaExpanded, ariaControls, ariaLabel } = useMenuActivator(props, menu)
225216

226217
watch(_search, value => {
227-
showAllItemsForNoMatch.value = false
228218
if (cleared) {
229219
// wait for clear to finish, VTextField sets _search to null
230220
// then search computed triggers and updates _search to ''
231221
nextTick(() => (cleared = false))
232222
} else if (isFocused.value && !menu.value) {
233-
menu.value = hasMatchingItems.value || !props.hideNoData
234-
} else if (isFocused.value && menu.value && !hasMatchingItems.value && props.hideNoData) {
235-
menu.value = false
223+
menu.value = true
236224
}
237225

238-
isPristine.value = !value
239226
emit('update:search', value)
240227
})
241228

@@ -453,22 +440,16 @@ export const VCombobox = genericComponent<new <
453440
}
454441
})
455442

456-
watch(menu, val => {
457-
if (!props.hideSelected && val && model.value.length) {
443+
watch(menu, () => {
444+
if (!props.hideSelected && menu.value && model.value.length) {
458445
const index = displayItems.value.findIndex(
459446
item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value))
460447
)
461448
IN_BROWSER && window.requestAnimationFrame(() => {
462449
index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index)
463450
})
464451
}
465-
466-
if (val && search.value && !hasMatchingItems.value) {
467-
showAllItemsForNoMatch.value = true
468-
}
469-
470-
isPristine.value = !search.value
471-
}, { immediate: true })
452+
})
472453

473454
watch(items, (newVal, oldVal) => {
474455
if (menu.value) return
@@ -560,6 +541,7 @@ export const VCombobox = genericComponent<new <
560541
{ !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? (
561542
<VListItem key="no-data" title={ t(props.noDataText) } />
562543
))}
544+
563545
<VVirtualScroll ref={ vVirtualScrollRef } renderless items={ displayItems.value } itemKey="value">
564546
{ ({ item, index, itemRef }) => {
565547
const itemProps = mergeProps(item.props, {
@@ -715,7 +697,7 @@ export const VCombobox = genericComponent<new <
715697
'append-inner': (...args) => (
716698
<>
717699
{ slots['append-inner']?.(...args) }
718-
{ props.menuIcon ? (
700+
{ (!props.hideNoData || props.items.length) && props.menuIcon ? (
719701
<VIcon
720702
class="v-combobox__menu-icon"
721703
color={ vTextFieldRef.value?.fieldIconColor }

packages/vuetify/src/components/VCombobox/__tests__/VCombobox.spec.browser.tsx

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -238,33 +238,6 @@ describe('VCombobox', () => {
238238
await userEvent.keyboard('antonsen')
239239
await expect(screen.findByRole('option')).resolves.toHaveTextContent('Antonsen PK')
240240
})
241-
242-
// https://github.com/vuetifyjs/vuetify/pull/22045
243-
it('should keep menu open while typing', async () => {
244-
const items = ['Item 1', 'Item 1a', 'Another']
245-
246-
const { element } = render(() => (
247-
<VCombobox items={ items } multiple />
248-
))
249-
250-
const optionsPerAction = [
251-
['1', 2],
252-
['a', 1],
253-
['x', 0],
254-
['y', 0],
255-
['{Backspace}', 0],
256-
['{Backspace}', 1],
257-
['{Backspace}', 2],
258-
['{Backspace}', 3],
259-
] as const
260-
261-
await userEvent.click(element)
262-
await expect(screen.findAllByRole('option')).resolves.toHaveLength(3)
263-
for (const [text, expectedItemsCount] of optionsPerAction) {
264-
await userEvent.keyboard(text)
265-
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(expectedItemsCount)
266-
}
267-
})
268241
})
269242

270243
describe('prefilled data', () => {
@@ -798,41 +771,6 @@ describe('VCombobox', () => {
798771
expect(model.value).toEqual(expected)
799772
})
800773

801-
it('should show only matching items when reopening the menu', async () => {
802-
const { element } = render(() => (
803-
<VCombobox items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']} />
804-
))
805-
806-
await userEvent.click(element)
807-
await userEvent.keyboard('c')
808-
await expect(screen.findAllByRole('option')).resolves.toHaveLength(2)
809-
await userEvent.keyboard('al')
810-
await expect(screen.findAllByRole('option')).resolves.toHaveLength(1)
811-
await userEvent.click(document.body)
812-
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)
813-
await userEvent.click(element)
814-
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(1)
815-
})
816-
817-
it('should show only matching items when opening for the first time', async () => {
818-
const model = ref('flor')
819-
const { element } = render(() => (
820-
<VCombobox
821-
v-model={ model.value }
822-
items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}
823-
/>
824-
))
825-
826-
await userEvent.click(element)
827-
expect(screen.getAllByRole('option')).toHaveLength(1)
828-
await userEvent.click(document.body)
829-
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)
830-
831-
// expect same behavior when re-opening the menu
832-
await userEvent.click(element)
833-
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(1)
834-
})
835-
836774
describe('Showcase', () => {
837775
generate({ stories })
838776
})

0 commit comments

Comments
 (0)