mirror of
https://github.com/nuxt/nuxt.git
synced 2025-03-21 16:55:57 +00:00
feat(nuxt): add types for default NuxtLink
slot (#31104)
This commit is contained in:
parent
71de708a05
commit
a4e6069a4b
@ -2,17 +2,21 @@ import type {
|
|||||||
AllowedComponentProps,
|
AllowedComponentProps,
|
||||||
AnchorHTMLAttributes,
|
AnchorHTMLAttributes,
|
||||||
ComputedRef,
|
ComputedRef,
|
||||||
DefineComponent,
|
DefineSetupFnComponent,
|
||||||
InjectionKey, PropType,
|
InjectionKey,
|
||||||
|
PropType,
|
||||||
|
SlotsType,
|
||||||
|
UnwrapRef,
|
||||||
|
VNode,
|
||||||
VNodeProps,
|
VNodeProps,
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue'
|
import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue'
|
||||||
import type { RouteLocation, RouteLocationRaw, Router, RouterLink, RouterLinkProps, useLink } from 'vue-router'
|
import type { RouteLocation, RouteLocationRaw, Router, RouterLink, RouterLinkProps, UseLinkReturn, useLink } from 'vue-router'
|
||||||
import { hasProtocol, joinURL, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo'
|
import { hasProtocol, joinURL, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo'
|
||||||
import { preloadRouteComponents } from '../composables/preload'
|
import { preloadRouteComponents } from '../composables/preload'
|
||||||
import { onNuxtReady } from '../composables/ready'
|
import { onNuxtReady } from '../composables/ready'
|
||||||
import { navigateTo, resolveRouteObject, useRouter } from '../composables/router'
|
import { navigateTo, resolveRouteObject, useRouter } from '../composables/router'
|
||||||
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
|
import { type NuxtApp, useNuxtApp, useRuntimeConfig } from '../nuxt'
|
||||||
import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback'
|
import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback'
|
||||||
|
|
||||||
// @ts-expect-error virtual file
|
// @ts-expect-error virtual file
|
||||||
@ -28,7 +32,8 @@ const NuxtLinkDevKeySymbol: InjectionKey<boolean> = Symbol('nuxt-link-dev-key')
|
|||||||
* `<NuxtLink>` is a drop-in replacement for both Vue Router's `<RouterLink>` component and HTML's `<a>` tag.
|
* `<NuxtLink>` is a drop-in replacement for both Vue Router's `<RouterLink>` component and HTML's `<a>` tag.
|
||||||
* @see https://nuxt.com/docs/api/components/nuxt-link
|
* @see https://nuxt.com/docs/api/components/nuxt-link
|
||||||
*/
|
*/
|
||||||
export interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
|
export interface NuxtLinkProps<CustomProp extends boolean = false> extends Omit<RouterLinkProps, 'to'> {
|
||||||
|
custom?: CustomProp
|
||||||
/**
|
/**
|
||||||
* Route Location the link should navigate to when clicked on.
|
* Route Location the link should navigate to when clicked on.
|
||||||
*/
|
*/
|
||||||
@ -102,6 +107,24 @@ export interface NuxtLinkOptions extends
|
|||||||
prefetchOn?: Exclude<NuxtLinkProps['prefetchOn'], string>
|
prefetchOn?: Exclude<NuxtLinkProps['prefetchOn'], string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NuxtLinkDefaultSlotProps<CustomProp extends boolean = false> = CustomProp extends true
|
||||||
|
? {
|
||||||
|
href: string
|
||||||
|
navigate: () => Promise<void>
|
||||||
|
prefetch: (nuxtApp?: NuxtApp) => Promise<void>
|
||||||
|
route: (RouteLocation & { href: string }) | undefined
|
||||||
|
rel: string | null
|
||||||
|
target: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null
|
||||||
|
isExternal: boolean
|
||||||
|
isActive: false
|
||||||
|
isExactActive: false
|
||||||
|
}
|
||||||
|
: UnwrapRef<UseLinkReturn>
|
||||||
|
|
||||||
|
type NuxtLinkSlots<CustomProp extends boolean = false> = {
|
||||||
|
default?: (props: NuxtLinkDefaultSlotProps<CustomProp>) => VNode[]
|
||||||
|
}
|
||||||
|
|
||||||
/* @__NO_SIDE_EFFECTS__ */
|
/* @__NO_SIDE_EFFECTS__ */
|
||||||
export function defineNuxtLink (options: NuxtLinkOptions) {
|
export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||||
const componentName = options.componentName || 'NuxtLink'
|
const componentName = options.componentName || 'NuxtLink'
|
||||||
@ -466,14 +489,19 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
isExternal: isExternal.value || hasTarget.value,
|
isExternal: isExternal.value || hasTarget.value,
|
||||||
isActive: false,
|
isActive: false,
|
||||||
isExactActive: false,
|
isExactActive: false,
|
||||||
})
|
} satisfies NuxtLinkDefaultSlotProps<true>)
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts `""` to `null` to prevent the attribute from being added as empty (`href=""`)
|
// converts `""` to `null` to prevent the attribute from being added as empty (`href=""`)
|
||||||
return h('a', { ref: el, href: href.value || null, rel, target }, slots.default?.())
|
return h('a', { ref: el, href: href.value || null, rel, target }, slots.default?.())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}) as unknown as DefineComponent<NuxtLinkProps>
|
// }) as unknown as DefineComponent<NuxtLinkProps, object, object, ComputedOptions, MethodOptions, object, object, EmitsOptions, string, object, NuxtLinkProps, object, SlotsType<NuxtLinkSlots>>
|
||||||
|
}) as unknown as new<CustomProp extends boolean = false>(props: NuxtLinkProps<CustomProp>) => InstanceType<DefineSetupFnComponent<
|
||||||
|
NuxtLinkProps<CustomProp>,
|
||||||
|
[],
|
||||||
|
SlotsType<NuxtLinkSlots<CustomProp>>
|
||||||
|
>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineNuxtLink(nuxtLinkDefaults)
|
export default defineNuxtLink(nuxtLinkDefaults)
|
||||||
|
@ -55,8 +55,9 @@ const nuxtLink = (
|
|||||||
): { type: string, props: Record<string, unknown>, slots: unknown } => {
|
): { type: string, props: Record<string, unknown>, slots: unknown } => {
|
||||||
const component = defineNuxtLink({ componentName: 'NuxtLink', ...nuxtLinkOptions })
|
const component = defineNuxtLink({ componentName: 'NuxtLink', ...nuxtLinkOptions })
|
||||||
|
|
||||||
const [type, _props, slots] = (component.setup as unknown as (props: NuxtLinkProps, context: { slots: Record<string, () => unknown> }) =>
|
const [type, _props, slots] = (
|
||||||
() => [string, Record<string, unknown>, unknown])(props, { slots: { default: () => null } })()
|
component as unknown as { setup: (props: NuxtLinkProps, context: { slots: Record<string, () => unknown> }) => () => [string, Record<string, unknown>, unknown] }
|
||||||
|
).setup(props, { slots: { default: () => null } })()
|
||||||
|
|
||||||
return { type, props: _props, slots }
|
return { type, props: _props, slots }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user