From 2235db5fac20440cdfe3d9c03e182cd12d182ed6 Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Sat, 1 Feb 2025 00:25:09 +0800 Subject: [PATCH 1/4] fix(nested): prevent parent node activate firing for singleLeaf --- packages/vuetify/src/composables/nested/nested.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vuetify/src/composables/nested/nested.ts b/packages/vuetify/src/composables/nested/nested.ts index b3ede9a3b84..3b4b6b761c7 100644 --- a/packages/vuetify/src/composables/nested/nested.ts +++ b/packages/vuetify/src/composables/nested/nested.ts @@ -303,13 +303,13 @@ export const useNested = (props: NestedProps) => { const newActivated = activeStrategy.value.activate({ id, value, - activated: new Set(activated.value), + activated: activated.value, children: children.value, parents: parents.value, event, }) - newActivated && (activated.value = newActivated) + newActivated && newActivated.size && activated.value !== newActivated && (activated.value = newActivated) }, children, parents, From 0734fad32687ccdcd1dff43aa49b42a5e6fff663 Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Fri, 7 Feb 2025 17:49:01 +0800 Subject: [PATCH 2/4] chore: refactor solution --- packages/vuetify/src/composables/nested/nested.ts | 6 +++--- packages/vuetify/src/util/helpers.ts | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/vuetify/src/composables/nested/nested.ts b/packages/vuetify/src/composables/nested/nested.ts index 3b4b6b761c7..c34f9fa60d9 100644 --- a/packages/vuetify/src/composables/nested/nested.ts +++ b/packages/vuetify/src/composables/nested/nested.ts @@ -27,7 +27,7 @@ import { leafSelectStrategy, leafSingleSelectStrategy, } from './selectStrategies' -import { consoleError, getCurrentInstance, getUid, propsFactory } from '@/util' +import { arrayDiff, consoleError, getCurrentInstance, getUid, propsFactory } from '@/util' // Types import type { InjectionKey, PropType, Ref } from 'vue' @@ -303,13 +303,13 @@ export const useNested = (props: NestedProps) => { const newActivated = activeStrategy.value.activate({ id, value, - activated: activated.value, + activated: new Set(activated.value), children: children.value, parents: parents.value, event, }) - newActivated && newActivated.size && activated.value !== newActivated && (activated.value = newActivated) + newActivated && arrayDiff(activated.value, newActivated).length && (activated.value = newActivated) }, children, parents, diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index 19a08a709e9..42336771a5b 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -378,11 +378,14 @@ export function filterInputAttrs (attrs: Record) { /** * Returns the set difference of B and A, i.e. the set of elements in B but not in A + * A and B can be sets, but the function always returns the result as an array. */ -export function arrayDiff (a: any[], b: any[]): any[] { +export function arrayDiff (a: any[] | Set, b: any[] | Set): any[] { const diff: any[] = [] - for (let i = 0; i < b.length; i++) { - if (!a.includes(b[i])) diff.push(b[i]) + const aArr: any[] = a instanceof Set ? Array.from(a) : a + const bArr: any[] = b instanceof Set ? Array.from(b) : b + for (let i = 0; i < bArr.length; i++) { + if (!aArr.includes(bArr[i])) diff.push(bArr[i]) } return diff } From 9fccf797981843fff58950fe3e0f6fe26cd914b2 Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Sun, 9 Feb 2025 16:01:38 +0800 Subject: [PATCH 3/4] refactor: use symmetricDifference --- packages/vuetify/src/composables/nested/nested.ts | 4 ++-- packages/vuetify/src/util/helpers.ts | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/vuetify/src/composables/nested/nested.ts b/packages/vuetify/src/composables/nested/nested.ts index c34f9fa60d9..7a5527707b3 100644 --- a/packages/vuetify/src/composables/nested/nested.ts +++ b/packages/vuetify/src/composables/nested/nested.ts @@ -27,7 +27,7 @@ import { leafSelectStrategy, leafSingleSelectStrategy, } from './selectStrategies' -import { arrayDiff, consoleError, getCurrentInstance, getUid, propsFactory } from '@/util' +import { consoleError, getCurrentInstance, getUid, propsFactory } from '@/util' // Types import type { InjectionKey, PropType, Ref } from 'vue' @@ -309,7 +309,7 @@ export const useNested = (props: NestedProps) => { event, }) - newActivated && arrayDiff(activated.value, newActivated).length && (activated.value = newActivated) + newActivated && newActivated.symmetricDifference(activated.value).size && (activated.value = newActivated) }, children, parents, diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index 42336771a5b..19a08a709e9 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -378,14 +378,11 @@ export function filterInputAttrs (attrs: Record) { /** * Returns the set difference of B and A, i.e. the set of elements in B but not in A - * A and B can be sets, but the function always returns the result as an array. */ -export function arrayDiff (a: any[] | Set, b: any[] | Set): any[] { +export function arrayDiff (a: any[], b: any[]): any[] { const diff: any[] = [] - const aArr: any[] = a instanceof Set ? Array.from(a) : a - const bArr: any[] = b instanceof Set ? Array.from(b) : b - for (let i = 0; i < bArr.length; i++) { - if (!aArr.includes(bArr[i])) diff.push(bArr[i]) + for (let i = 0; i < b.length; i++) { + if (!a.includes(b[i])) diff.push(b[i]) } return diff } From 15c1be70cd4ef9bd36bc76e5c74494a878010a53 Mon Sep 17 00:00:00 2001 From: Kael Date: Tue, 11 Feb 2025 19:34:01 +1100 Subject: [PATCH 4/4] early return from same value check --- .../vuetify/src/composables/nested/nested.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/vuetify/src/composables/nested/nested.ts b/packages/vuetify/src/composables/nested/nested.ts index 7a5527707b3..08ddd9c6318 100644 --- a/packages/vuetify/src/composables/nested/nested.ts +++ b/packages/vuetify/src/composables/nested/nested.ts @@ -309,7 +309,22 @@ export const useNested = (props: NestedProps) => { event, }) - newActivated && newActivated.symmetricDifference(activated.value).size && (activated.value = newActivated) + if (newActivated.size !== activated.value.size) { + activated.value = newActivated + } else { + for (const value of newActivated) { + if (!activated.value.has(value)) { + activated.value = newActivated + return + } + } + for (const value of activated.value) { + if (!newActivated.has(value)) { + activated.value = newActivated + return + } + } + } }, children, parents,