Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions landing/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,31 @@

const toggle = document.querySelector('[data-menu-toggle]');
const links = document.querySelector('[data-nav-links]');
const isIndonesian = document.documentElement.lang === 'id';
const menuLabel = isIndonesian
? { open: 'Buka navigasi', close: 'Tutup navigasi' }
: { open: 'Open navigation', close: 'Close navigation' };
links?.setAttribute('aria-label', isIndonesian ? 'Navigasi utama' : 'Primary navigation');
toggle?.setAttribute('aria-label', menuLabel.open);

const closeMenu = () => {
if (!toggle || !links) return;
links.classList.remove('open');
toggle.setAttribute('aria-expanded', 'false');
toggle.setAttribute('aria-label', 'Open navigation');
toggle.setAttribute('aria-label', menuLabel.open);
};

if (toggle && links) {
toggle.addEventListener('click', () => {
const isOpen = links.classList.toggle('open');
toggle.setAttribute('aria-expanded', String(isOpen));
toggle.setAttribute('aria-label', isOpen ? 'Close navigation' : 'Open navigation');
toggle.setAttribute('aria-label', isOpen ? menuLabel.close : menuLabel.open);
});

links.addEventListener('click', event => {
if (event.target instanceof HTMLAnchorElement) closeMenu();
// Localized link labels contain spans; taps on their text must also close the menu.
const target = event.target instanceof Element ? event.target.closest('a[href]') : null;
if (target instanceof HTMLAnchorElement && links.contains(target)) closeMenu();
});

document.addEventListener('keydown', event => {
Expand Down
25 changes: 15 additions & 10 deletions landing/partials/header.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
<a class="skip-link" href="#main">Skip to content</a>
<a class="skip-link" href="#main"><span data-lang="en">Skip to content</span><span data-lang="id">Langsung ke konten</span></a>
<header class="site-header">
<div class="container nav-shell">
<a class="brand" href="./" aria-label="ARSAS home">
<span class="brand-mark"><img src="assets/app-icon.png" width="535" height="535" alt="" decoding="async" /></span>
<span>ARSAS <small>IEC 61850 tester</small></span>
</a>
<button class="menu-toggle" type="button" aria-label="Open navigation" aria-expanded="false" data-menu-toggle>
<button class="menu-toggle" type="button" aria-label="Open navigation" aria-expanded="false" aria-controls="arsas-primary-nav" data-menu-toggle>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</button>
<nav class="nav-links" aria-label="Primary navigation" data-nav-links>
<a href="./" data-nav-page="overview">Overview</a>
<a href="learning-center.html" data-nav-page="learn">Learn</a>
<a href="features.html" data-nav-page="capabilities">Product</a>
<a href="solutions.html" data-nav-page="solutions">Solutions</a>
<a href="guides.html" data-nav-page="guides">Guides</a>
<a class="language-link" href="id.html" lang="id" hreflang="id" aria-label="Buka ARSAS dalam Bahasa Indonesia">ID</a>
<a class="nav-cta" href="download.html" data-nav-page="download" aria-label="Download ARSAS stable version v{{STABLE_VERSION}}">Download v{{STABLE_VERSION}}</a>
<nav class="nav-links" id="arsas-primary-nav" aria-label="Primary navigation" data-nav-links>
<a href="./" data-nav-page="overview" data-lang="en">Overview</a>
<a href="id.html" data-nav-page="overview" data-lang="id">Beranda</a>
<a href="learning-center.html" data-nav-page="learn" data-lang="en">Learn</a>
<a href="pusat-belajar-iec61850.html" data-nav-page="learn" data-lang="id">Belajar</a>
<a href="features.html" data-nav-page="capabilities"><span data-lang="en">Product</span><span data-lang="id">Produk</span></a>
<a href="solutions.html" data-nav-page="solutions"><span data-lang="en">Solutions</span><span data-lang="id">Solusi</span></a>
<a href="guides.html" data-nav-page="guides" data-lang="en">Guides</a>
<a href="panduan.html" data-nav-page="guides" data-lang="id">Panduan</a>
<a class="language-link" href="id.html" lang="id" hreflang="id" aria-label="Buka ARSAS dalam Bahasa Indonesia" data-lang="en">ID</a>
<a class="language-link" href="./" lang="en" hreflang="en" aria-label="Open ARSAS in English" data-lang="id">EN</a>
<a class="nav-cta" href="download.html" data-nav-page="download" aria-label="Download ARSAS stable version v{{STABLE_VERSION}}" data-lang="en">Download v{{STABLE_VERSION}}</a>
<a class="nav-cta" href="unduh.html" data-nav-page="download" aria-label="Unduh ARSAS versi stabil v{{STABLE_VERSION}}" data-lang="id">Unduh v{{STABLE_VERSION}}</a>
</nav>
</div>
</header>
22 changes: 22 additions & 0 deletions tests/ARSAS.Tests/WebsiteHeroLocalizationRegressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,28 @@ public void GuidedDemo_UsesActualV1642CapturesWithOriginalPngLinks(string path)
}
}

[Fact]
public void PublicNavigation_UsesLocaleSpecificDestinationsAndAccessibleMenuLabels()
{
var header = Read("landing/partials/header.html");
var css = Read("landing/audit.css");
var app = Read("landing/app.js");

Assert.Contains("Langsung ke konten", header, StringComparison.Ordinal);
Assert.Contains("href=\"id.html\" data-nav-page=\"overview\" data-lang=\"id\"", header, StringComparison.Ordinal);
Assert.Contains("href=\"pusat-belajar-iec61850.html\" data-nav-page=\"learn\" data-lang=\"id\"", header, StringComparison.Ordinal);
Assert.Contains("href=\"panduan.html\" data-nav-page=\"guides\" data-lang=\"id\"", header, StringComparison.Ordinal);
Assert.Contains("href=\"unduh.html\" data-nav-page=\"download\"", header, StringComparison.Ordinal);
Assert.Contains("href=\"./\" lang=\"en\" hreflang=\"en\"", header, StringComparison.Ordinal);
Assert.Contains("aria-controls=\"arsas-primary-nav\"", header, StringComparison.Ordinal);
Assert.Contains("[data-lang=\"id\"] { display: none; }", css, StringComparison.Ordinal);
Assert.Contains("html[lang=\"id\"] [data-lang=\"en\"] { display: none; }", css, StringComparison.Ordinal);
Assert.Contains("Buka navigasi", app, StringComparison.Ordinal);
Assert.Contains("Tutup navigasi", app, StringComparison.Ordinal);
Assert.Contains("Navigasi utama", app, StringComparison.Ordinal);
Assert.Contains("menuLabel.close : menuLabel.open", app, StringComparison.Ordinal);
}

[Fact]
public void CssArchitecture_ReplacesPhaseOverridesWithSemanticScopedLayers()
{
Expand Down
Loading