Skip to content

Commit 8853f4d

Browse files
jcjpJ-Sek
authored andcommitted
feat(VCombobox): add always-filter prop (#22093)
closes #22060
1 parent ab1c1c1 commit 8853f4d

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

packages/api-generator/src/locale/en/VCombobox.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"props": {
3+
"alwaysFilter": "When enabled, dropdown list will always show items matching non-empty value within the field. Recommended when the list is meant to show suggestions rather than options to choose from. For optimal UX, should be combined with `:menu-icon=\"false\"` and `hide-selected`.",
34
"autoSelectFirst": "When searching, will always highlight the first option and select it on blur. `exact` will only highlight and select exact matches.",
45
"clearOnSelect": "Reset the search text when a selection is made while using the **multiple** prop.",
56
"itemChildren": "This property currently has **no effect**.",

packages/docs/src/data/new-in.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
},
6161
"VCombobox": {
6262
"props": {
63+
"alwaysFilter": "3.10.4",
6364
"autocomplete": "3.10.0",
6465
"clearOnSelect": "3.5.0",
6566
"listProps": "3.5.0"

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type Value <T, ReturnObject extends boolean, Multiple extends boolean> =
6363
: Val<T, ReturnObject> | null
6464

6565
export const makeVComboboxProps = propsFactory({
66+
alwaysFilter: Boolean,
6667
autoSelectFirst: {
6768
type: [Boolean, String] as PropType<boolean | 'exact'>,
6869
},
@@ -189,7 +190,11 @@ export const VCombobox = genericComponent<new <
189190
: (props.multiple ? model.value.length : search.value.length)
190191
})
191192

192-
const { filteredItems, getMatches } = useFilter(props, items, () => isPristine.value ? '' : search.value)
193+
const { filteredItems, getMatches } = useFilter(
194+
props,
195+
items,
196+
() => props.alwaysFilter || !isPristine.value ? search.value : ''
197+
)
193198

194199
const displayItems = computed(() => {
195200
if (props.hideSelected) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,22 @@ describe('VCombobox', () => {
771771
expect(model.value).toEqual(expected)
772772
})
773773

774+
it('should show only matching items when reopening the menu if alwaysFilter is true', async () => {
775+
const { element } = render(() => (
776+
<VCombobox alwaysFilter items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']} />
777+
))
778+
779+
await userEvent.click(element)
780+
await userEvent.keyboard('c')
781+
await expect(screen.findAllByRole('option')).resolves.toHaveLength(2)
782+
await userEvent.keyboard('al')
783+
await expect(screen.findAllByRole('option')).resolves.toHaveLength(1)
784+
await userEvent.click(document.body)
785+
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)
786+
await userEvent.click(element)
787+
await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(1)
788+
})
789+
774790
describe('Showcase', () => {
775791
generate({ stories })
776792
})

0 commit comments

Comments
 (0)