fix(NavigationMenu): improve generic types (#2482)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Yasser Lahbibi
2024-10-29 19:21:35 +01:00
committed by GitHub
parent 03dd1eba7e
commit fc2015bb0e
7 changed files with 71 additions and 24 deletions

View File

@@ -6,7 +6,7 @@ import type { AppConfig } from '@nuxt/schema'
import _appConfig from '#build/app.config'
import theme from '#build/ui/navigation-menu'
import type { AvatarProps, BadgeProps, LinkProps } from '../types'
import type { DynamicSlots, PartialString } from '../types/utils'
import type { DynamicSlots, MaybeArrayOfArray, MaybeArrayOfArrayItem, PartialString } from '../types/utils'
const appConfig = _appConfig as AppConfig & { ui: { navigationMenu: Partial<typeof theme> } }
@@ -45,7 +45,7 @@ export interface NavigationMenuProps<T> extends Pick<NavigationMenuRootProps, 'd
* @defaultValue appConfig.ui.icons.chevronDown
*/
trailingIcon?: string
items?: T[] | T[][]
items?: T
color?: NavigationMenuVariants['color']
variant?: NavigationMenuVariants['variant']
/**
@@ -85,10 +85,10 @@ export type NavigationMenuSlots<T extends { slot?: string }> = {
</script>
<script setup lang="ts" generic="T extends NavigationMenuItem">
import { computed, toRef } from 'vue'
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<NavigationMenuItem>">
import { computed, reactive, toRef } from 'vue'
import { NavigationMenuRoot, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport, useForwardPropsEmits } from 'radix-vue'
import { reactivePick, createReusableTemplate } from '@vueuse/core'
import { createReusableTemplate } from '@vueuse/core'
import { get } from '../utils'
import { pickLinkProps } from '../utils/link'
import ULinkBase from './LinkBase.vue'
@@ -98,7 +98,7 @@ import UIcon from './Icon.vue'
import UBadge from './Badge.vue'
import UCollapsible from './Collapsible.vue'
const props = withDefaults(defineProps<NavigationMenuProps<T>>(), {
const props = withDefaults(defineProps<NavigationMenuProps<I>>(), {
orientation: 'horizontal',
delayDuration: 0,
labelKey: 'label'
@@ -106,7 +106,15 @@ const props = withDefaults(defineProps<NavigationMenuProps<T>>(), {
const emits = defineEmits<NavigationMenuEmits>()
const slots = defineSlots<NavigationMenuSlots<T>>()
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'delayDuration', 'skipDelayDuration', 'orientation'), emits)
const rootProps = useForwardPropsEmits(reactive({
as: props.as,
modelValue: props.modelValue,
defaultValue: props.defaultValue,
delayDuration: props.delayDuration,
skipDelayDuration: props.skipDelayDuration,
orientation: props.orientation
}), emits)
const contentProps = toRef(() => props.content)
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: NavigationMenuItem, active?: boolean, index: number }>()
@@ -174,7 +182,7 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
@select="item.onSelect"
>
<ULinkBase v-bind="slotProps" :class="ui.link({ class: [props.ui?.link, item.class], active, disabled: !!item.disabled })">
<ReuseItemTemplate :item="item" :active="active" :index="index" />
<ReuseItemTemplate :item="(item as T)" :active="active" :index="index" />
</ULinkBase>
</component>
@@ -210,7 +218,7 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
<ULink v-slot="{ active: childActive, ...childSlotProps }" v-bind="pickLinkProps(childItem)" custom>
<NavigationMenuLink as-child :active="childActive" @select="childItem.onSelect">
<ULinkBase v-bind="childSlotProps" :class="ui.link({ class: [props.ui?.link, childItem.class], active: childActive, disabled: !!childItem.disabled })">
<ReuseItemTemplate :item="childItem" :active="childActive" :index="childIndex" />
<ReuseItemTemplate :item="(childItem as T)" :active="childActive" :index="childIndex" />
</ULinkBase>
</NavigationMenuLink>
</ULink>