diff --git a/src/lib/Link/Link.svelte b/src/lib/Link/Link.svelte index 274d164..65dc68f 100644 --- a/src/lib/Link/Link.svelte +++ b/src/lib/Link/Link.svelte @@ -7,7 +7,7 @@ import { isRouteActive } from '$lib/public-utils.js'; import { getRouterContext } from '$lib/Router/Router.svelte'; import type { Hash, RouteStatus } from '$lib/types.js'; - import { assertAllowedRoutingMode, joinStyles } from '$lib/utils.js'; + import { assertAllowedRoutingMode, expandAriaAttributes, joinStyles } from '$lib/utils.js'; import { type Snippet } from 'svelte'; import type { AriaAttributes, HTMLAnchorAttributes } from 'svelte/elements'; @@ -101,15 +101,14 @@ return result; }); const calcActiveStateAria = $derived.by(() => { - const result = {} as AriaAttributes; - for (let [k, v] of Object.entries({ - ...linkContext?.activeState?.aria, - ...activeState?.aria - })) { - // @ts-expect-error TS7053 - Since k is typed as string, the relationship can't be established. - result[`aria-${k}`] = v; + if (!linkContext?.activeStateAria && !activeState?.aria) { + return { 'aria-current': 'page' } as AriaAttributes; } - return result; + const localAria = expandAriaAttributes(activeState?.aria); + return { + ...linkContext?.activeStateAria, + ...localAria + }; }); const isActive = $derived(isRouteActive(router, activeFor)); const calcHref = $derived(href === '' ? location.url.href : calculateHref( diff --git a/src/lib/Link/Link.svelte.test.ts b/src/lib/Link/Link.svelte.test.ts index 39954ee..4631533 100644 --- a/src/lib/Link/Link.svelte.test.ts +++ b/src/lib/Link/Link.svelte.test.ts @@ -311,6 +311,65 @@ function activeStateTests(setup: ReturnType) { expect(anchor?.getAttribute('aria-current')).toBe('page'); }); + test("Should apply aria-current with value 'page' when route is active and no aria object is provided.", () => { + // Arrange. + const { hash, router, context } = setup; + const href = "/test/path"; + const activeKey = "test-route"; + // Mock active route status + if (router) { + Object.defineProperty(router, 'routeStatus', { + value: { [activeKey]: { match: true } }, + configurable: true + }); + } + + // Act. + const { container } = render(Link, { + props: { + hash, + href, + activeFor: activeKey, + children: content + }, + context + }); + const anchor = container.querySelector('a'); + + // Assert. + expect(anchor?.getAttribute('aria-current')).toBe('page'); + }); + + test("Should not apply aria-current when route is active and activeState.aria is set to an empty object.", () => { + // Arrange. + const { hash, router, context } = setup; + const href = "/test/path"; + const activeKey = "test-route"; + // Mock active route status + if (router) { + Object.defineProperty(router, 'routeStatus', { + value: { [activeKey]: { match: true } }, + configurable: true + }); + } + + // Act. + const { container } = render(Link, { + props: { + hash, + href, + activeFor: activeKey, + activeState: { aria: {} }, + children: content + }, + context + }); + const anchor = container.querySelector('a'); + + // Assert. + expect(anchor?.getAttribute('aria-current')).toBeNull(); + }); + test("Should not apply active styles when route is not active.", async () => { // Arrange. const { hash, router, context } = setup; diff --git a/src/lib/LinkContext/LinkContext.svelte b/src/lib/LinkContext/LinkContext.svelte index c00fa0f..b7e22b1 100644 --- a/src/lib/LinkContext/LinkContext.svelte +++ b/src/lib/LinkContext/LinkContext.svelte @@ -1,6 +1,8 @@