Skip to content

Commit 147f0a7

Browse files
webJoseCopilot
andauthored
refactor(Link): Use isRouteActive() and take style calculation to a s… (#91)
* refactor(Link): Use isRouteActive() and take style calculation to a separate, importable function * Update src/lib/utils.ts Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent bcfc463 commit 147f0a7

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed

src/lib/Link/Link.svelte

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import { location } from '$lib/core/Location.js';
55
import { resolveHashValue } from '$lib/core/resolveHashValue.js';
66
import { getLinkContext, type ILinkContext } from '$lib/LinkContext/LinkContext.svelte';
7+
import { isRouteActive } from '$lib/public-utils.js';
78
import { getRouterContext } from '$lib/Router/Router.svelte';
89
import type { ActiveState, Hash, RouteStatus } from '$lib/types.js';
9-
import { assertAllowedRoutingMode } from '$lib/utils.js';
10+
import { assertAllowedRoutingMode, joinStyles } from '$lib/utils.js';
1011
import { type Snippet } from 'svelte';
1112
import type { HTMLAnchorAttributes } from 'svelte/elements';
1213
@@ -92,7 +93,7 @@
9293
const calcReplace = $derived(replace ?? linkContext?.replace ?? false);
9394
const calcPreserveQuery = $derived(preserveQuery ?? linkContext?.preserveQuery ?? false);
9495
const calcPrependBasePath = $derived(prependBasePath ?? linkContext?.prependBasePath ?? false);
95-
const isActive = $derived(!!router?.routeStatus[activeState?.key ?? '']?.match);
96+
const isActive = $derived(isRouteActive(router, activeState?.key));
9697
const calcHref = $derived(
9798
calculateHref(
9899
{
@@ -111,29 +112,12 @@
111112
const newState = calculateState(resolvedHash, typeof state === 'function' ? state() : state);
112113
location.goTo(calcHref, { state: newState, replace: calcReplace });
113114
}
114-
115-
function styleString() {
116-
let baseStyle = style ? style.trim() : '';
117-
if (baseStyle && !baseStyle.endsWith(';')) {
118-
baseStyle += ';';
119-
}
120-
if (!activeState?.style) {
121-
return baseStyle || undefined;
122-
}
123-
if (typeof activeState.style === 'string') {
124-
return baseStyle ? `${baseStyle} ${activeState.style}` : activeState.style;
125-
}
126-
const calculatedStyle = Object.entries(activeState.style)
127-
.map(([key, value]) => `${key}: ${value}`)
128-
.join('; ');
129-
return baseStyle ? `${baseStyle} ${calculatedStyle}` : calculatedStyle;
130-
}
131115
</script>
132116

133117
<a
134118
href={calcHref}
135119
class={[cssClass, (isActive && activeState?.class) || undefined]}
136-
style={isActive ? styleString() : style}
120+
style={isActive ? joinStyles(style, activeState?.style) : style}
137121
aria-current={isActive ? (activeState?.ariaCurrent ?? 'page') : undefined}
138122
onclick={handleClick}
139123
{...restProps}

src/lib/utils.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import type { Hash } from "./types.js";
2-
import { routingOptions } from "./core/options.js";
1+
import type { ActiveState, Hash } from "./types.js";
2+
import { routingOptions } from "./core/options.js";
3+
import type { HTMLAnchorAttributes } from "svelte/elements";
34

45
/**
56
* Asserts that the specified routing mode is allowed by the current routing options.
@@ -18,3 +19,29 @@ export function assertAllowedRoutingMode(hash: Hash) {
1819
throw new Error("Multi-hash routing has been disallowed by a library extension.");
1920
}
2021
}
22+
23+
/**
24+
* Joins two style definitions into a single style definition.
25+
*
26+
* @param startingStyle The base style definition.
27+
* @param addedStyle The style definition to add to the base style definition.
28+
* @returns The combined style definition, or `undefined` if both inputs are empty or `undefined`.
29+
*/
30+
export function joinStyles(
31+
startingStyle: HTMLAnchorAttributes["style"],
32+
addedStyle: ActiveState["style"],
33+
): string | undefined {
34+
let baseStyle = startingStyle ? startingStyle.trim() : '';
35+
if (baseStyle && !baseStyle.endsWith(';')) {
36+
baseStyle += ';';
37+
}
38+
if (!addedStyle) {
39+
return baseStyle || undefined;
40+
}
41+
if (typeof addedStyle === 'string') {
42+
return baseStyle ? `${baseStyle} ${addedStyle}` : addedStyle;
43+
}
44+
const calculatedStyle = Object.entries(addedStyle)
45+
.reduce((acc, [key, value]) => acc + `${key}: ${value}; `, '');
46+
return baseStyle ? `${baseStyle} ${calculatedStyle}` : calculatedStyle;
47+
}

0 commit comments

Comments
 (0)