Skip to content

Commit

Permalink
fix(nested): correct prop types (#19758)
Browse files Browse the repository at this point in the history
  • Loading branch information
KaelWD authored May 7, 2024
1 parent 6c78760 commit 0db4297
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 38 deletions.
3 changes: 3 additions & 0 deletions packages/api-generator/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ function count (arr: string[], needle: string) {
// Types that are displayed as links
const allowedRefs = [
'Anchor',
'ActiveStrategy',
'DataIteratorItem',
'DataTableHeader',
'DataTableItem',
Expand All @@ -319,9 +320,11 @@ const allowedRefs = [
'ListItem',
'LocationStrategyFn',
'OpenSelectStrategyFn',
'OpenStrategy',
'OpenStrategyFn',
'ScrollStrategyFn',
'SelectItemKey',
'SelectStrategy',
'SelectStrategyFn',
'SortItem',
'SubmitEventPromise',
Expand Down
14 changes: 7 additions & 7 deletions packages/vuetify/src/components/VList/VList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ export const VList = genericComponent<new <
itemValue?: SelectItemKey<ItemType<T>>
itemChildren?: SelectItemKey<ItemType<T>>
itemProps?: SelectItemKey<ItemType<T>>
selected?: readonly S[]
'onUpdate:selected'?: (value: S[]) => void
opened?: readonly O[]
'onUpdate:opened'?: (value: O[]) => void
selected?: S
'onUpdate:selected'?: (value: S) => void
opened?: O
'onUpdate:opened'?: (value: O) => void
},
slots: VListChildrenSlots<ItemType<T>>
) => GenericProps<typeof props, typeof slots>>()({
Expand All @@ -140,9 +140,9 @@ export const VList = genericComponent<new <
props: makeVListProps(),

emits: {
'update:selected': (value: unknown[]) => true,
'update:activated': (value: unknown[]) => true,
'update:opened': (value: unknown[]) => true,
'update:selected': (value: unknown) => true,
'update:activated': (value: unknown) => true,
'update:opened': (value: unknown) => true,
'click:open': (value: { id: unknown, value: boolean, path: unknown[] }) => true,
'click:activate': (value: { id: unknown, value: boolean, path: unknown[] }) => true,
'click:select': (value: { id: unknown, value: boolean, path: unknown[] }) => true,
Expand Down
30 changes: 18 additions & 12 deletions packages/vuetify/src/composables/nested/activeStrategies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable sonarjs/no-identical-functions */
// Utilities
import { toRaw } from 'vue'
import { wrapInArray } from '@/util'

export type ActiveStrategyFn = (data: {
id: unknown
Expand All @@ -12,7 +13,7 @@ export type ActiveStrategyFn = (data: {
}) => Set<unknown>

export type ActiveStrategyTransformInFn = (
v: readonly unknown[] | undefined,
v: unknown | undefined,
children: Map<unknown, unknown[]>,
parents: Map<unknown, unknown>,
) => Set<unknown>
Expand All @@ -21,7 +22,7 @@ export type ActiveStrategyTransformOutFn = (
v: Set<unknown>,
children: Map<unknown, unknown[]>,
parents: Map<unknown, unknown>,
) => unknown[]
) => unknown

export type ActiveStrategy = {
activate: ActiveStrategyFn
Expand Down Expand Up @@ -49,14 +50,16 @@ export const independentActiveStrategy = (mandatory?: boolean): ActiveStrategy =
in: (v, children, parents) => {
let set = new Set()

for (const id of (v || [])) {
set = strategy.activate({
id,
value: true,
activated: new Set(set),
children,
parents,
})
if (v != null) {
for (const id of wrapInArray(v)) {
set = strategy.activate({
id,
value: true,
activated: new Set(set),
children,
parents,
})
}
}

return set
Expand All @@ -81,8 +84,11 @@ export const independentSingleActiveStrategy = (mandatory?: boolean): ActiveStra
in: (v, children, parents) => {
let set = new Set()

if (v?.length) {
set = parentStrategy.in(v.slice(0, 1), children, parents)
if (v != null) {
const arr = wrapInArray(v)
if (arr.length) {
set = parentStrategy.in(arr.slice(0, 1), children, parents)
}
}

return set
Expand Down
50 changes: 34 additions & 16 deletions packages/vuetify/src/composables/nested/nested.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { useProxiedModel } from '@/composables/proxiedModel'
import { computed, inject, onBeforeUnmount, provide, ref, shallowRef, toRaw, toRef } from 'vue'
import {
independentActiveStrategy,
independentSingleActiveStrategy, leafActiveStrategy,
independentSingleActiveStrategy,
leafActiveStrategy,
leafSingleActiveStrategy,
} from './activeStrategies'
import { listOpenStrategy, multipleOpenStrategy, singleOpenStrategy } from './openStrategies'
Expand All @@ -20,26 +21,41 @@ import { getCurrentInstance, getUid, propsFactory } from '@/util'

// Types
import type { InjectionKey, PropType, Ref } from 'vue'
import type { ActiveStrategy } from './activeStrategies'
import type { OpenStrategy } from './openStrategies'
import type { SelectStrategyFn } from './selectStrategies'
import type { SelectStrategy } from './selectStrategies'
import type { EventProp } from '@/util'

export type SelectStrategy = 'single-leaf' | 'leaf' | 'independent' | 'single-independent' | 'classic' | SelectStrategyFn
export type ActiveStrategyProp =
| 'single-leaf'
| 'leaf'
| 'independent'
| 'single-independent'
| ActiveStrategy
| ((mandatory: boolean) => ActiveStrategy)
export type SelectStrategyProp =
| 'single-leaf'
| 'leaf'
| 'independent'
| 'single-independent'
| 'classic'
| SelectStrategy
| ((mandatory: boolean) => SelectStrategy)
export type OpenStrategyProp = 'single' | 'multiple' | 'list' | OpenStrategy

export interface NestedProps {
activatable: boolean
selectable: boolean
activeStrategy: SelectStrategy | undefined
selectStrategy: SelectStrategy | undefined
activeStrategy: ActiveStrategyProp | undefined
selectStrategy: SelectStrategyProp | undefined
openStrategy: OpenStrategyProp | undefined
activated: readonly unknown[] | undefined
selected: readonly unknown[] | undefined
opened: readonly unknown[] | undefined
activated: any
selected: any
opened: any
mandatory: boolean
'onUpdate:activated': EventProp<[unknown[]]> | undefined
'onUpdate:selected': EventProp<[unknown[]]> | undefined
'onUpdate:opened': EventProp<[unknown[]]> | undefined
'onUpdate:activated': EventProp<[any]> | undefined
'onUpdate:selected': EventProp<[any]> | undefined
'onUpdate:opened': EventProp<[any]> | undefined
}

type NestedProvide = {
Expand Down Expand Up @@ -88,12 +104,12 @@ export const emptyNested: NestedProvide = {
export const makeNestedProps = propsFactory({
activatable: Boolean,
selectable: Boolean,
activeStrategy: [String, Function] as PropType<SelectStrategy>,
selectStrategy: [String, Function] as PropType<SelectStrategy>,
activeStrategy: [String, Function, Object] as PropType<ActiveStrategyProp>,
selectStrategy: [String, Function, Object] as PropType<SelectStrategyProp>,
openStrategy: [String, Object] as PropType<OpenStrategyProp>,
opened: Array as PropType<readonly unknown[]>,
activated: Array as PropType<readonly unknown[]>,
selected: Array as PropType<readonly unknown[]>,
opened: null,
activated: null,
selected: null,
mandatory: Boolean,
}, 'nested')

Expand All @@ -106,6 +122,7 @@ export const useNested = (props: NestedProps) => {

const activeStrategy = computed(() => {
if (typeof props.activeStrategy === 'object') return props.activeStrategy
if (typeof props.activeStrategy === 'function') return props.activeStrategy(props.mandatory)

switch (props.activeStrategy) {
case 'leaf': return leafActiveStrategy(props.mandatory)
Expand All @@ -118,6 +135,7 @@ export const useNested = (props: NestedProps) => {

const selectStrategy = computed(() => {
if (typeof props.selectStrategy === 'object') return props.selectStrategy
if (typeof props.selectStrategy === 'function') return props.selectStrategy(props.mandatory)

switch (props.selectStrategy) {
case 'single-leaf': return leafSingleSelectStrategy(props.mandatory)
Expand Down
6 changes: 3 additions & 3 deletions packages/vuetify/src/labs/VTreeview/VTreeview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export const VTreeview = genericComponent<new <T>(
props: makeVTreeviewProps(),

emits: {
'update:opened': (val: unknown[]) => true,
'update:activated': (val: unknown[]) => true,
'update:selected': (val: unknown[]) => true,
'update:opened': (val: unknown) => true,
'update:activated': (val: unknown) => true,
'update:selected': (val: unknown) => true,
'click:open': (value: { id: unknown, value: boolean, path: unknown[] }) => true,
'click:select': (value: { id: unknown, value: boolean, path: unknown[] }) => true,
},
Expand Down

0 comments on commit 0db4297

Please sign in to comment.