Skip to content

Commit

Permalink
Add inactiveClassName to use:active action
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Holthausen committed Dec 2, 2020
1 parent bacd869 commit 083e310
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 7 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ import active from 'svelte-spa-router/active'
}
</style>
<a href="/hello/user" use:link use:active={{path: '/hello/*', className: 'active'}}>Say hi!</a>
<a href="/hello/user" use:link use:active={{path: '/hello/*', className: 'active', inactiveClassName: 'inactive'}}>Say hi!</a>
<a href="/hello/user" use:link use:active={'/hello/*'}>Say hi with a default className!</a>
<a href="/hello/user" use:link use:active>Say hi with all default options!</a>
````
Expand All @@ -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`.

Expand Down
3 changes: 3 additions & 0 deletions active.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

/**
Expand Down
16 changes: 11 additions & 5 deletions active.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
})
Expand Down Expand Up @@ -88,6 +93,7 @@ export default function active(node, opts) {
const el = {
node,
className: opts.className,
inactiveClassName: opts.inactiveClassName,
pattern
}
nodes.push(el)
Expand Down
6 changes: 5 additions & 1 deletion test/app/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ul class="navigation-links">
<li><a href="/" use:link use:active>Home</a></li>
<li><a href="/brand" use:link><b>Brand</b></a></li>
<li><a href="/hello/svelte" use:link use:active={{path: '/hello/*', className: 'active another-class'}}>Say hi!</a></li>
<li><a href="/hello/svelte" use:link use:active={{path: '/hello/*', className: 'active another-class', inactiveClassName: 'inactive'}}>Say hi!</a></li>
<li><a href="/does/not/exist" use:link>Not found</a></li>
</ul>

Expand Down Expand Up @@ -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;
}
</style>

<script>
Expand Down
23 changes: 23 additions & 0 deletions test/cases/02-active-action.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ describe('use:active action', function() {
browser.end()
})

it('inactive class', (browser) => {
// Check if inactive class is toggled
browser
.url(browser.launchUrl + '/#/hello/world')
.waitForElementVisible('ul.navigation-links')
// There should be no inactive class when link is active
.elements('css selector', 'ul.navigation-links li a.inactive', (elements) => {
assert(elements)
assert.strictEqual(elements.value.length, 0)

browser
.url(browser.launchUrl + '/#/notfound')
.waitForElementVisible('ul.navigation-links')
// There should an inactive class when link is not active
.elements('css selector', 'ul.navigation-links li a.inactive', (elements) => {
assert(elements)
assert.strictEqual(elements.value.length, 1)

browser.end()
})
})
})

it('navigating pages', (browser) => {
browser
.url(browser.launchUrl + '/#/hello/world')
Expand Down

0 comments on commit 083e310

Please sign in to comment.