Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/vuetify/src/components/VList/VList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export const VList = genericComponent<new <T>() => {
const { dimensionStyles } = useDimension(props)
const { elevationClasses } = useElevation(props)
const { roundedClasses } = useRounded(props)
const { open, select } = useNested(props)
const { open, select, getPath } = useNested(props)
const lineClasses = computed(() => props.lines ? `v-list--${props.lines}-line` : undefined)
const activeColor = toRef(props, 'activeColor')
const color = toRef(props, 'color')
Expand Down Expand Up @@ -258,6 +258,7 @@ export const VList = genericComponent<new <T>() => {
open,
select,
focus,
getPath,
}
},
})
Expand Down
78 changes: 78 additions & 0 deletions packages/vuetify/src/components/VList/__tests__/VList.spec.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,82 @@ describe('VList', () => {

cy.get('.v-list-item').eq(1).should('not.have.class', 'v-list-item--active')
})

it('should open selected items on mount', () => {
const items = [
{
title: 'Foo',
subtitle: 'Bar',
value: 'foo',
},
{
title: 'Group',
value: 'group',
children: [
{
title: 'Child',
subtitle: 'Subtitle',
value: 'child',
children: [
{
title: 'Another Child',
value: 'another_child',
},
],
},
],
},
]

const wrapper = mountFunction((
<CenteredGrid width="200px">
<VList items={items} selected={['another_child']} openOnMount="selected" />
</CenteredGrid>
))

wrapper.get('.v-list-item')
.should('have.length', 4)
.contains('Another Child')
.should('be.visible')
})

it('should open all items on mount', () => {
const items = [
{
title: 'Foo',
subtitle: 'Bar',
value: 'foo',
children: [
{
title: 'First',
value: 'first',
},
],
},
{
title: 'Group',
value: 'group',
children: [
{
title: 'Second',
value: 'second',
},
],
},
]

const wrapper = mountFunction((
<CenteredGrid width="200px">
<VList items={items} openOnMount="all" />
</CenteredGrid>
))

wrapper.get('.v-list-item')
.should('have.length', 4)
.contains('First')
.should('be.visible')
.get('.v-list-item')
.contains('Second')
.should('be.visible')
})
})
24 changes: 23 additions & 1 deletion packages/vuetify/src/composables/nested/nested.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useProxiedModel } from '@/composables/proxiedModel'
import { getCurrentInstance, getUid, propsFactory } from '@/util'
import { computed, inject, onBeforeUnmount, provide, ref, toRaw } from 'vue'
import { computed, inject, onBeforeUnmount, onMounted, provide, ref, toRaw } from 'vue'
import { listOpenStrategy, multipleOpenStrategy, singleOpenStrategy } from './openStrategies'
import {
classicSelectStrategy,
Expand All @@ -23,6 +23,7 @@ export interface NestedProps {
openStrategy: OpenStrategyProp | undefined
selected: unknown[] | undefined
opened: unknown[] | undefined
openOnMount?: 'selected' | 'all'
mandatory: boolean
'onUpdate:selected': ((val: unknown[]) => void) | undefined
'onUpdate:opened': ((val: unknown[]) => void) | undefined
Expand All @@ -42,6 +43,7 @@ type NestedProvide = {
open: (id: unknown, value: boolean, event?: Event) => void
select: (id: unknown, value: boolean, event?: Event) => void
openOnSelect: (id: unknown, value: boolean, event?: Event) => void
getPath: (id: unknown) => unknown[]
}
}

Expand All @@ -60,6 +62,7 @@ export const emptyNested: NestedProvide = {
opened: ref(new Set()),
selected: ref(new Map()),
selectedValues: ref([]),
getPath: () => [],
},
}

Expand All @@ -69,6 +72,9 @@ export const makeNestedProps = propsFactory({
opened: Array as PropType<unknown[]>,
selected: Array as PropType<unknown[]>,
mandatory: Boolean,
openOnMount: {
type: String as PropType<'selected' | 'all'>,
},
}, 'nested')

export const useNested = (props: NestedProps) => {
Expand Down Expand Up @@ -126,6 +132,21 @@ export const useNested = (props: NestedProps) => {
return path
}

onMounted(() => {
if (props.openOnMount === 'all') {
opened.value = new Set(children.value.keys())
} else if (props.openOnMount === 'selected') {
const newOpened = new Set(opened.value)
for (const key of selected.value.keys()) {
const path = getPath(key).slice(0, -1)
for (const parent of path) {
newOpened.add(parent)
}
}
opened.value = newOpened
}
})

const vm = getCurrentInstance('nested')

const nested: NestedProvide = {
Expand Down Expand Up @@ -206,6 +227,7 @@ export const useNested = (props: NestedProps) => {
},
children,
parents,
getPath,
},
}

Expand Down