Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions src/runtime/components/Link.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,64 @@
<script lang="ts">
import type { AppConfig } from '@nuxt/schema'
import type { NuxtLinkProps } from '#app'
import type { RouterLinkProps, RouteLocationRaw } from 'vue-router'
import theme from '#build/ui/link'
import type { ButtonHTMLAttributes, AnchorHTMLAttributes } from '../types/html'
import type { ComponentConfig } from '../types/tv'
type Link = ComponentConfig<typeof theme, AppConfig, 'link'>
export interface LinkProps extends Omit<NuxtLinkProps, 'custom'>, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
/**
* Route Location the link should navigate to when clicked on.
*/
to?: RouteLocationRaw
/**
* An alias for `to`. If used with `to`, `href` will be ignored
*/
href?: NuxtLinkProps['to']
/**
* Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases
*/
external?: boolean
/**
* Where to display the linked URL, as the name for a browsing context.
*/
target?: '_blank' | '_parent' | '_self' | '_top' | (string & {}) | null
/**
* A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links.
*/
rel?: 'noopener' | 'noreferrer' | 'nofollow' | 'sponsored' | 'ugc' | (string & {}) | null
/**
* If set to true, no rel attribute will be added to the link
*/
noRel?: boolean
/**
* A class to apply to links that have been prefetched.
*/
prefetchedClass?: string
/**
* When enabled will prefetch middleware, layouts and payloads of links in the viewport.
*/
prefetch?: boolean
/**
* Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility.
*/
prefetchOn?: 'visibility' | 'interaction' | Partial<{
visibility: boolean
interaction: boolean
}>
/**
* Escape hatch to disable `prefetch` attribute.
*/
noPrefetch?: boolean
/**
* An option to either add or remove trailing slashes in the `href` for this specific link.
* Overrides the global `trailingSlash` option if provided.
*/
trailingSlash?: 'append' | 'remove'
}
export interface LinkProps extends NuxtLinkProps, /** @vue-ignore */ Omit<ButtonHTMLAttributes, 'type' | 'disabled'>, /** @vue-ignore */ Omit<AnchorHTMLAttributes, 'href' | 'target' | 'rel' | 'type'> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The activeClass property is missing from the LinkProps interface definition, even though it's used throughout the component code. This will cause TypeScript errors when accessing props.activeClass.

View Details
πŸ“ Patch Details
diff --git a/src/runtime/components/Link.vue b/src/runtime/components/Link.vue
index a07f8f44..ca09cecd 100644
--- a/src/runtime/components/Link.vue
+++ b/src/runtime/components/Link.vue
@@ -78,6 +78,8 @@ export interface LinkProps extends NuxtLinkProps, /** @vue-ignore */ Omit<Button
   exactQuery?: boolean | 'partial'
   /** Will only be active if the current route hash is an exact match. */
   exactHash?: boolean
+  /** The class to apply when the link is active. */
+  activeClass?: string
   /** The class to apply when the link is inactive. */
   inactiveClass?: string
   custom?: boolean
diff --git a/src/runtime/vue/components/Link.vue b/src/runtime/vue/components/Link.vue
index e454893a..9c3d2acf 100644
--- a/src/runtime/vue/components/Link.vue
+++ b/src/runtime/vue/components/Link.vue
@@ -47,6 +47,8 @@ export interface LinkProps extends Partial<Omit<RouterLinkProps, 'custom'>>, /**
   exactQuery?: boolean | 'partial'
   /** Will only be active if the current route hash is an exact match. */
   exactHash?: boolean
+  /** The class to apply when the link is active. */
+  activeClass?: string
   /** The class to apply when the link is inactive. */
   inactiveClass?: string
   custom?: boolean

Analysis

Missing activeClass property in LinkProps interfaces

What fails: TypeScript error TS2551 when accessing props.activeClass in components that use it but don't define it in the interface. The LinkProps interface in src/runtime/components/Link.vue and src/runtime/vue/components/Link.vue was missing the activeClass?: string property despite the code accessing it on lines 126/128 and 165/167 respectively.

How to reproduce:

# Run TypeScript compiler on Link components
npx tsc src/runtime/components/Link.vue --noEmit
npx tsc src/runtime/vue/components/Link.vue --noEmit
# Would show: Property 'activeClass' does not exist on type 'LinkProps'

Result: TypeScript compiler would report errors when accessing props.activeClass on these components, even though the property is used in the template code via reactiveOmit (line 119/71) and in the ui computed property (lines 126/100) and resolveLinkClass function (lines 165/176).

Expected: The LinkProps interface should include activeClass?: string to match the code's usage and be consistent with src/runtime/inertia/components/Link.vue which already has this property defined.

Fix applied: Added activeClass?: string property to the LinkProps interface in both:

  • src/runtime/components/Link.vue (line 82)
  • src/runtime/vue/components/Link.vue (line 51)

This makes all three Link components consistent and resolves the TypeScript type error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

activeClass lives inside RouterLinkProps

/**
* The element or component this component should render as when not a link.
* @defaultValue 'button'
Expand Down
Loading