|
1 | 1 | --- |
2 | 2 | import type { HTMLAttributes } from 'astro/types'; |
3 | 3 |
|
4 | | -type Props = HTMLAttributes<'a'>; |
| 4 | +/* 1️⃣ Force href to be a string so TS stops complaining */ |
| 5 | +interface Props extends Omit<HTMLAttributes<'a'>, 'href'> { |
| 6 | + href: string; |
| 7 | +} |
| 8 | +const { href, class: className, ...rest } = Astro.props as Props; |
5 | 9 |
|
6 | | -const { href, class: className, ...props } = Astro.props; |
7 | | -const pathname = Astro.url.pathname.replace(import.meta.env.BASE_URL, ''); |
8 | | -const subpath = pathname.match(/[^\/]+/g); |
9 | | -const isActive = href === pathname || href === '/' + (subpath?.[0] || ''); |
| 10 | +/* 2️⃣ Build the correct URL (adds `/spark-tuning-notes/` in prod) */ |
| 11 | +const finalHref = (Astro as any).resolve?.(href) ?? href; // e.g. "/spark-tuning-notes/blog" |
| 12 | +
|
| 13 | +/* 3️⃣ Active-link logic – compare full paths */ |
| 14 | +const current = Astro.url.pathname; // already includes base |
| 15 | +const isActive = finalHref === current || |
| 16 | + (current.startsWith(finalHref) && href !== '/'); |
| 17 | +
|
| 18 | +/* 4️⃣ Combine classes */ |
| 19 | +const classes = [className, { active: isActive }]; |
10 | 20 | --- |
11 | 21 |
|
12 | | -<a href={href} class:list={[className, { active: isActive }]} {...props}> |
13 | | - <slot /> |
| 22 | +<a href={finalHref} class:list={classes} {...rest}> |
| 23 | + <slot /> |
14 | 24 | </a> |
| 25 | + |
15 | 26 | <style> |
16 | | - a { |
17 | | - display: inline-block; |
18 | | - text-decoration: none; |
19 | | - } |
20 | | - a.active { |
21 | | - font-weight: bolder; |
22 | | - text-decoration: underline; |
23 | | - } |
| 27 | + a { display:inline-block; text-decoration:none; } |
| 28 | + a.active { font-weight:bold; text-decoration:underline; } |
24 | 29 | </style> |
0 commit comments