diff --git a/README.md b/README.md index 24e708a..79d8fc2 100644 --- a/README.md +++ b/README.md @@ -342,7 +342,7 @@ import active from 'svelte-spa-router/active' } -Say hi! +Say hi! Say hi with a default className! Say hi with all default options! ```` @@ -351,6 +351,7 @@ The `active` action accepts a dictionary `options` as argument: - `options.path`: the path that, when matched, makes the link active. In the first example above, we want the link to be active when the route is `/hello/*` (the asterisk matches anything after that). As you can see, this doesn't have to be the same as the path the link points to. When `options.path` is omitted or false-y, it defaults to the path specified in the link's `href` attribute. This parameter can also be a regular expression that will mark the link as active when it matches: for example, setting to the regular expression `/^\/*\/hi$/` will make the link active when it starts with `/` and ends with `/hi`, regardless of what's in between. - `options.className`: the name of the CSS class to add. This is optional, and it defaults to `active` if not present. +- `options.inactiveClassName`: the name of the CSS class to add when the link is _not_ active. This is optional, and it defaults to nothing if not present. As a shorthand, instead of passing a dictionary as `options`, you can pass a single string or regular expression that will be interpreted as `options.path`. diff --git a/active.d.ts b/active.d.ts index fa18a6e..798cf83 100644 --- a/active.d.ts +++ b/active.d.ts @@ -5,6 +5,9 @@ interface ActiveOptions { /** Name of the CSS class to add when the route is active; default is "active" */ className?: string + + /** Name of the CSS class to add when the route is inactive; nothing added by default */ + inactiveClassName?: string } /** diff --git a/active.js b/active.js index 46cc261..0185ee9 100644 --- a/active.js +++ b/active.js @@ -9,16 +9,21 @@ let location // Function that updates all nodes marking the active ones function checkActive(el) { - // Repeat this for each class - (el.className || '').split(' ').forEach((cls) => { + const matchesLocation = el.pattern.test(location) + toggleClasses(el, el.className, matchesLocation) + toggleClasses(el, el.inactiveClassName, !matchesLocation) +} + +function toggleClasses(el, className, shouldAdd) { + (className || '').split(' ').forEach((cls) => { if (!cls) { return } - // Remove the active class firsts + // Remove the class firsts el.node.classList.remove(cls) - // If the pattern matches, then set the active class - if (el.pattern.test(location)) { + // If the pattern doesn't match, then set the class + if (shouldAdd) { el.node.classList.add(cls) } }) @@ -88,6 +93,7 @@ export default function active(node, opts) { const el = { node, className: opts.className, + inactiveClassName: opts.inactiveClassName, pattern } nodes.push(el) diff --git a/test/app/src/App.svelte b/test/app/src/App.svelte index b4bef74..119d089 100644 --- a/test/app/src/App.svelte +++ b/test/app/src/App.svelte @@ -4,7 +4,7 @@
@@ -58,6 +58,10 @@ :global(a.active) { color: crimson; } +/* Style for "inactive" links; need to mark this :global because the router adds the class directly */ +:global(a.inactive) { + color: gray; +}