diff --git a/packages/vuetify/src/labs/VTreeview/VTreeview.tsx b/packages/vuetify/src/labs/VTreeview/VTreeview.tsx index 172deddbc10..3ada9eb33f8 100644 --- a/packages/vuetify/src/labs/VTreeview/VTreeview.tsx +++ b/packages/vuetify/src/labs/VTreeview/VTreeview.tsx @@ -90,7 +90,11 @@ export const VTreeview = genericComponent( const getPath = vListRef.value?.getPath if (!getPath) return null return new Set(filteredItems.value.flatMap(item => { - return [...getPath(item.props.value), ...getChildren(item.props.value)] + const itemVal = props.returnObject ? item.raw : item.props.value + return [ + ...getPath(itemVal), + ...getChildren(itemVal), + ].map(toRaw) })) }) diff --git a/packages/vuetify/src/labs/VTreeview/__tests__/VTreeview.spec.cy.tsx b/packages/vuetify/src/labs/VTreeview/__tests__/VTreeview.spec.cy.tsx index 541b9f929df..a3e5aebf144 100644 --- a/packages/vuetify/src/labs/VTreeview/__tests__/VTreeview.spec.cy.tsx +++ b/packages/vuetify/src/labs/VTreeview/__tests__/VTreeview.spec.cy.tsx @@ -2,9 +2,10 @@ // Components import { VTreeview } from '../VTreeview' +import { VTextField } from '@/components/VTextField' // Utilities -import { ref } from 'vue' +import { ref, shallowRef } from 'vue' function compareItemObject (a: any, b: any) { return a.id - b.id @@ -849,6 +850,106 @@ describe('VTreeview', () => { }) }) }) + describe('search', () => { + // https://github.com/vuetifyjs/vuetify/issues/20488 + it('should filter items based on the search text and return the correct result', () => { + const items = ref([ + { + id: 1, + title: 'Vuetify Human Resources', + children: [ + { + id: 2, + title: 'Core team', + children: [ + { + id: 201, + title: 'John', + }, + { + id: 202, + title: 'Kael', + }, + { + id: 203, + title: 'Nekosaur', + }, + { + id: 204, + title: 'Jacek', + }, + { + id: 205, + title: 'Andrew', + }, + ], + }, + { + id: 3, + title: 'Administrators', + children: [ + { + id: 301, + title: 'Mike', + }, + { + id: 302, + title: 'Hunt', + }, + ], + }, + { + id: 4, + title: 'Contributors', + children: [ + { + id: 401, + title: 'Phlow', + }, + { + id: 402, + title: 'Brandon', + }, + { + id: 403, + title: 'Sean', + }, + ], + }, + ], + }, + ]) + const search = shallowRef('') + + function filterFn (value: string, search: string) { + return value.toLowerCase().includes(search.toLowerCase()) + } + cy.mount(() => ( + <> + + + + )) + .get('.v-text-field input') + .type('j') + .get('.v-treeview-item').eq(0).should('be.visible') // { id: 1, title: 'Vuetify Human Resources' } + .get('.v-treeview-item').eq(1).should('be.visible') // { id: 2, title: 'Core team' } + .get('.v-treeview-item').eq(2).should('be.visible') // { id: 201, title: 'John' } + .get('.v-treeview-item').eq(3).should('not.be.visible') + .get('.v-treeview-item').eq(4).should('not.be.visible') + .get('.v-treeview-item').eq(5).should('be.visible') // { id: 204, title: 'Jacek' } + .get('.v-treeview-item').eq(9).should('not.be.visible') + .get('.v-treeview-item').eq(13).should('not.be.visible') + }) + }) }) it('should have all items visible when open-all is applied', () => {