Skip to content

Commit 6ec0ee5

Browse files
authored
feat(link): add aria-current to active links (close #2116) (#3073)
* feat(core): add aria-current to active links (close #2116) * feat(core): update aria-current to exact active route * feat(core): add ariaCurrentValue prop and add test * feat(core): type modification * feat(core): update aria-current typing to string
1 parent d3edd63 commit 6ec0ee5

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

docs/api/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ If you add a `target="_blank"` to your `a` element, you must omit the `@click="n
163163

164164
Configure the active CSS class applied when the link is active with exact match. Note the default value can also be configured globally via the `linkExactActiveClass` router constructor option.
165165

166+
### aria-current-value
167+
168+
- type: `'page' | 'step' | 'location' | 'date' | 'time'`
169+
- default: `"page"`
170+
171+
Configure the value of `aria-current` when the link is active with exact match. It must be one of the [allowed values for aria-current](https://www.w3.org/TR/wai-aria-1.2/#aria-current) in the ARIA spec. In most cases, the default of `page` should be the best fit.
172+
166173
## `<router-view>`
167174

168175
The `<router-view>` component is a functional component that renders the matched component for the given path. Components rendered in `<router-view>` can also contain their own `<router-view>`, which will render components for nested paths.

src/components/link.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export default {
2727
replace: Boolean,
2828
activeClass: String,
2929
exactActiveClass: String,
30+
ariaCurrentValue: {
31+
type: String,
32+
default: 'page'
33+
},
3034
event: {
3135
type: eventTypes,
3236
default: 'click'
@@ -67,6 +71,8 @@ export default {
6771
? classes[exactActiveClass]
6872
: isIncludedRoute(current, compareTarget)
6973

74+
const ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null
75+
7076
const handler = e => {
7177
if (guardEvent(e)) {
7278
if (this.replace) {
@@ -117,7 +123,7 @@ export default {
117123

118124
if (this.tag === 'a') {
119125
data.on = on
120-
data.attrs = { href }
126+
data.attrs = { href, 'aria-current': ariaCurrentValue }
121127
} else {
122128
// find the first <a> child and apply listener and href
123129
const a = findAnchor(this.$slots.default)
@@ -145,6 +151,7 @@ export default {
145151

146152
const aAttrs = (a.data.attrs = extend({}, a.data.attrs))
147153
aAttrs.href = href
154+
aAttrs['aria-current'] = ariaCurrentValue
148155
} else {
149156
// doesn't have <a> child, apply listener to self
150157
data.on = on

test/e2e/specs/active-links.js

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = {
3131
.assert.attributeContains('li:nth-child(18) a', 'href', '/active-links/redirect-image')
3232
.assert.attributeContains('li:nth-child(19) a', 'href', '/active-links/redirect-image')
3333
.assert.containsText('.view', 'Home')
34+
.assert.not.attributeEquals(`li:nth-child(3) a`, 'aria-current', 'page')
3435

3536
assertActiveLinks(1, [1, 2], null, [1, 2])
3637
assertActiveLinks(2, [1, 2], null, [1, 2])
@@ -70,12 +71,14 @@ module.exports = {
7071
browser.assert
7172
.cssClassPresent(`li:nth-child(${i}) a`, 'router-link-exact-active')
7273
.assert.cssClassPresent(`li:nth-child(${i}) a`, 'router-link-active')
74+
.assert.attributeEquals(`li:nth-child(${i}) a`, 'aria-current', 'page')
7375
})
7476
exactActiveLI &&
7577
exactActiveLI.forEach(i => {
7678
browser.assert
7779
.cssClassPresent(`li:nth-child(${i})`, 'router-link-exact-active')
7880
.assert.cssClassPresent(`li:nth-child(${i})`, 'router-link-active')
81+
.assert.attributeEquals(`li:nth-child(${i}) a`, 'aria-current', 'page')
7982
})
8083
}
8184
}

0 commit comments

Comments
 (0)