</template>
<script lang="ts" setup>
-import { defineComponent, inject, computed, ref } from 'vue'
+import { inject, computed, ref } from 'vue'
import { scrollWaiter } from './scrollWaiter'
import { useLink, useRoute, RouterLink } from 'vue-router'
import AppLink from './AppLink.vue'
() => '/users/' + String((Number(route.params.id) || 0) + 1)
)
-currentLocation,
- nextUserLink,
- state,
- flushWaiter,
- setupWaiter,
- viewName,
- function toggleViewName() {
- viewName.value = viewName.value === 'default' ? 'other' : 'default'
- }
+function toggleViewName() {
+ viewName.value = viewName.value === 'default' ? 'other' : 'default'
+}
</script>
RendererNode,
// @ts-ignore
ComponentOptionsMixin,
+ MaybeRef,
} from 'vue'
import { isSameRouteLocationParams, isSameRouteRecord } from './location'
import { routerKey, routeLocationKey } from './injectionSymbols'
import { NavigationFailure } from './errors'
import { isArray, isBrowser, noop } from './utils'
import { warn } from './warning'
-import { isRouteLocation, type VueUseOptions } from './types'
+import { isRouteLocation } from './types'
import {
RouteLocation,
+ RouteLocationAsPath,
+ RouteLocationAsRelativeTyped,
+ RouteLocationAsString,
RouteLocationRaw,
RouteLocationResolved,
+ RouteMap,
} from './typed-routes'
export interface RouterLinkOptions {
| 'false'
}
+/**
+ * Context passed from router-link components to devtools.
+ * @internal
+ */
export interface UseLinkDevtoolsContext {
route: RouteLocationResolved
isActive: boolean
error: string | null
}
-export type UseLinkOptions = VueUseOptions<RouterLinkOptions>
+/**
+ * Options passed to {@link useLink}.
+ */
+export interface UseLinkOptions<Name extends keyof RouteMap = keyof RouteMap> {
+ to: MaybeRef<
+ | RouteLocationAsString
+ | RouteLocationAsRelativeTyped<RouteMap, Name>
+ | RouteLocationAsPath
+ | RouteLocationRaw
+ >
+ replace?: MaybeRef<boolean | undefined>
+}
+
+/**
+ * Return type of {@link useLink}.
+ * @internal
+ */
+export interface UseLinkReturn<Name extends keyof RouteMap = keyof RouteMap> {
+ route: ComputedRef<RouteLocationResolved<Name>>
+ href: ComputedRef<string>
+ isActive: ComputedRef<boolean>
+ isExactActive: ComputedRef<boolean>
+ navigate(e?: MouseEvent): Promise<void | NavigationFailure>
+}
// TODO: we could allow currentRoute as a prop to expose `isActive` and
// `isExactActive` behavior should go through an RFC
-export function useLink(props: UseLinkOptions) {
+/**
+ * Returns the internal behavior of a {@link RouterLink} without the rendering part.
+ *
+ * @param props - a `to` location and an optional `replace` flag
+ */
+export function useLink<Name extends keyof RouteMap = keyof RouteMap>(
+ props: UseLinkOptions<Name>
+): UseLinkReturn<Name> {
const router = inject(routerKey)!
const currentRoute = inject(routeLocationKey)!
isActive,
isExactActive,
navigate,
- }: UnwrapRef<ReturnType<typeof useLink>>) => VNode[]
+ }: // TODO: How do we add the name generic
+ UnwrapRef<UseLinkReturn>) => VNode[]
}
}
// route location
RouteLocationRaw,
RouteLocation,
+ RouteLocationGeneric,
RouteLocationTyped,
RouteLocationTypedList,
- RouteLocationGeneric,
// RouteLocationNormalized
RouteLocationNormalizedGeneric,
RouteLocationNormalizedLoadedTypedList,
// RouteLocationResolved
- RouteLocationResolved,
RouteLocationResolvedGeneric,
+ RouteLocationResolved,
RouteLocationResolvedTyped,
RouteLocationResolvedTypedList,
// relative
- RouteLocationAsRelative,
RouteLocationAsRelativeGeneric,
+ RouteLocationAsRelative,
RouteLocationAsRelativeTyped,
RouteLocationAsRelativeTypedList,
// string
+ RouteLocationAsStringTyped,
RouteLocationAsString,
+ RouteLocationAsStringTypedList,
// as path
RouteLocationAsPathGeneric,
+ RouteLocationAsPath,
RouteLocationAsPathTyped,
RouteLocationAsPathTypedList,
NavigationGuardWithThis,
NavigationHookAfter,
RouteLocationResolved,
+ RouteLocationAsRelative,
+ RouteLocationAsPath,
+ RouteLocationAsString,
} from './typed-routes'
import { RouterHistory, HistoryState, NavigationType } from './history/common'
import {
} from './injectionSymbols'
import { addDevtools } from './devtools'
import { _LiteralUnion } from './types/utils'
-import {
- RouteLocationAsPathTyped,
- RouteLocationAsRelativeTyped,
- RouteLocationAsString,
-} from './typed-routes/route-location'
+import { RouteLocationAsRelativeTyped } from './typed-routes/route-location'
import { RouteMap } from './typed-routes/route-map'
/**
* @param currentLocation - Optional current location to resolve against
*/
resolve<Name extends keyof RouteMap = keyof RouteMap>(
- to:
- | RouteLocationAsString<RouteMap>
- | RouteLocationAsRelativeTyped<RouteMap, Name>
- | RouteLocationAsPathTyped<RouteMap, Name>,
+ to: RouteLocationAsRelativeTyped<RouteMap, Name>,
+ // NOTE: This version doesn't work probably because it infers the type too early
+ // | RouteLocationAsRelative<Name>
currentLocation?: RouteLocationNormalizedLoaded
): RouteLocationResolved<Name>
+ resolve(
+ // not having the overload produces errors in RouterLink calls to router.resolve()
+ to: RouteLocationAsString | RouteLocationAsRelative | RouteLocationAsPath,
+ currentLocation?: RouteLocationNormalizedLoaded
+ ): RouteLocationResolved
/**
* Programmatically navigate to a new URL by pushing an entry in the history
/**
* Helper to generate a type safe version of the {@link RouteLocation} type.
- * @internal
*/
export interface RouteLocationTyped<
RouteMap extends RouteMapGeneric,
/**
* Helper to generate a type safe version of the {@link RouteLocationNormalized} type.
- * @internal
*/
export interface RouteLocationNormalizedTyped<
RouteMap extends RouteMapGeneric = RouteMapGeneric,
/**
* Helper to generate a type safe version of the {@link RouteLocationNormalizedLoaded} type.
- * @internal
*/
export interface RouteLocationNormalizedLoadedTyped<
RouteMap extends RouteMapGeneric = RouteMapGeneric,
/**
* Helper to generate a type safe version of the {@link RouteLocationAsRelative} type.
- * @internal
*/
export interface RouteLocationAsRelativeTyped<
RouteMap extends RouteMapGeneric = RouteMapGeneric,
/**
* Helper to generate a type safe version of the {@link RouteLocationAsPath} type.
- * @internal
*/
export interface RouteLocationAsPathTyped<
RouteMap extends RouteMapGeneric = RouteMapGeneric,
}
/**
- * Type safe version to auto complete the path of a route.
+ * List of all possible {@link RouteLocationAsPath} indexed by the route name.
* @internal
*/
export type RouteLocationAsPathTypedList<
RouteMap extends RouteMapGeneric = RouteMapGeneric
> = { [N in keyof RouteMap]: RouteLocationAsPathTyped<RouteMap, N> }
+/**
+ * Helper to generate a type safe version of the {@link RouteLocationAsString} type.
+ */
+export type RouteLocationAsStringTyped<
+ RouteMap extends RouteMapGeneric = RouteMapGeneric,
+ Name extends keyof RouteMap = keyof RouteMap
+> = RouteMap[Name]['path']
+
+/**
+ * List of all possible {@link RouteLocationAsString} indexed by the route name.
+ * @internal
+ */
+export type RouteLocationAsStringTypedList<
+ RouteMap extends RouteMapGeneric = RouteMapGeneric
+> = { [N in keyof RouteMap]: RouteLocationAsStringTyped<RouteMap, N> }
+
/**
* Generic version of {@link RouteLocationResolved}. It is used when no {@link RouteMap} is provided.
*/
/**
* Helper to generate a type safe version of the {@link RouteLocationResolved} type.
- * @internal
*/
export interface RouteLocationResolvedTyped<
RouteMap extends RouteMapGeneric,
: RouteLocationResolvedTypedList<RouteMap>[Name]
/**
- * Same as {@link RouteLocationAsPathTyped} but as a string literal.
- * @internal
+ * Same as {@link RouteLocationAsPath} but as a string literal.
*/
export type RouteLocationAsString<
- RouteMap extends RouteMapGeneric = RouteMapGeneric
+ Name extends keyof RouteMap = keyof RouteMap
> = RouteMapGeneric extends RouteMap
? string
- : _LiteralUnion<RouteMap[keyof RouteMap]['path'], string>
+ : _LiteralUnion<RouteLocationAsStringTypedList<RouteMap>[Name], string>
+
+/**
+ * Route location as an object with a `path` property.
+ */
+export type RouteLocationAsPath<Name extends keyof RouteMap = keyof RouteMap> =
+ RouteMapGeneric extends RouteMap
+ ? RouteLocationAsPathGeneric
+ : RouteLocationAsPathTypedList<RouteMap>[Name]
/**
* Route location that can be passed to `router.push()` and other user-facing APIs.
export type RouteLocationRaw<Name extends keyof RouteMap = keyof RouteMap> =
RouteMapGeneric extends RouteMap
?
- | RouteLocationAsString
+ | RouteLocationAsStringTyped
| RouteLocationAsRelativeGeneric
| RouteLocationAsPathGeneric
:
- | RouteLocationAsString<RouteMap>
+ | RouteLocationAsStringTyped<RouteMap>
| RouteLocationAsRelativeTypedList<RouteMap>[Name]
| RouteLocationAsPathTypedList<RouteMap>[Name]