Skip to content

Commit 1907437

Browse files
committed
feat(Link)!: Allow any aria- attribute in ActiveState
1 parent 17df387 commit 1907437

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

src/lib/Link/Link.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@
118118
href={calcHref}
119119
class={[cssClass, (isActive && activeState?.class) || undefined]}
120120
style={isActive ? joinStyles(style, activeState?.style) : style}
121-
aria-current={isActive ? (activeState?.ariaCurrent ?? 'page') : undefined}
122121
onclick={handleClick}
122+
{...(isActive ? activeState?.aria : undefined)}
123123
{...restProps}
124124
>
125125
{@render children?.(location.getState(resolvedHash), router?.routeStatus)}

src/lib/Link/Link.svelte.test.ts

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,44 @@ function activeStateTests(setup: ReturnType<typeof createRouterTestSetup>) {
233233
expect(anchor?.getAttribute('style')).toContain('color: red');
234234
});
235235

236-
test("Should set aria-current when route is active.", async () => {
236+
test("Should set any aria- attributes from activeState when route is active.", () => {
237+
// Arrange.
238+
const { hash, router, context } = setup;
239+
const href = "/test/path";
240+
const activeKey = "test-route";
241+
242+
// Mock active route status
243+
if (router) {
244+
Object.defineProperty(router, 'routeStatus', {
245+
value: { [activeKey]: { match: false } },
246+
configurable: true
247+
});
248+
}
249+
250+
// Act.
251+
const { container } = render(Link, {
252+
props: {
253+
hash,
254+
href,
255+
activeState: {
256+
key: activeKey,
257+
aria: {
258+
'aria-selected': 'true',
259+
'aria-current': 'page'
260+
}
261+
},
262+
children: content
263+
},
264+
context
265+
});
266+
const anchor = container.querySelector('a');
267+
268+
// Assert.
269+
expect(anchor?.getAttribute('aria-selected')).toBeNull();
270+
expect(anchor?.getAttribute('aria-current')).toBeNull();
271+
});
272+
273+
test("Should not set any aria- attributes when route is not active.", async () => {
237274
// Arrange.
238275
const { hash, router, context } = setup;
239276
const href = "/test/path";
@@ -252,14 +289,21 @@ function activeStateTests(setup: ReturnType<typeof createRouterTestSetup>) {
252289
props: {
253290
hash,
254291
href,
255-
activeState: { key: activeKey, ariaCurrent: "page" },
292+
activeState: {
293+
key: activeKey,
294+
aria: {
295+
'aria-selected': 'true',
296+
'aria-current': 'page'
297+
}
298+
},
256299
children: content
257300
},
258301
context
259302
});
260303
const anchor = container.querySelector('a');
261304

262305
// Assert.
306+
expect(anchor?.getAttribute('aria-selected')).toBe('true');
263307
expect(anchor?.getAttribute('aria-current')).toBe('page');
264308
});
265309

@@ -678,15 +722,15 @@ describe("Routing Mode Assertions", () => {
678722
])("Should throw error when $description and hash=$hash .", ({ options, hash }) => {
679723
// Arrange
680724
setRoutingOptions(options);
681-
725+
682726
// Act & Assert
683727
expect(() => {
684-
render(Link, {
685-
props: {
686-
href: "/test",
687-
hash,
688-
children: content
689-
},
728+
render(Link, {
729+
props: {
730+
href: "/test",
731+
hash,
732+
children: content
733+
},
690734
});
691735
}).toThrow();
692736
});

src/lib/types.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ClassValue, HTMLAnchorAttributes } from "svelte/elements";
1+
import type { AriaAttributes, ClassValue, HTMLAnchorAttributes } from "svelte/elements";
22

33
/**
44
* Defines the data type of all `hash` properties found in almost all of the library's components.
@@ -318,13 +318,22 @@ export type ActiveState = {
318318
*/
319319
style?: HTMLAnchorAttributes['style'] | Record<string, string>;
320320
/**
321-
* Sets the value of the `aria-current` attribute when the link is active.
321+
* Sets additional ARIA attributes when the link is active.
322322
*
323-
* The possible values are defined by the HTML specification.
323+
* ### aria-selected
324+
* Use it for `gridcell`, `option`, `row`, `tab`, and `treeitem` roles to indicate the current item in a
325+
* selection.
324326
*
325-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#values)
327+
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-selected)
328+
*
329+
* ### aria-current
330+
* Use it for `article`, `cell`, `columnheader`, `document`, `feed`, `listitem`, `math`, `rowheader`,
331+
* `section`, `table`, and `treeitem` roles to indicate the current item within a container or set of related
332+
* items.
333+
*
334+
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
326335
*/
327-
ariaCurrent?: HTMLAnchorAttributes['aria-current'];
336+
aria?: AriaAttributes;
328337
}
329338

330339
/**

0 commit comments

Comments
 (0)