Add aria-current attribute to links in the top menu

This is mainly to be able to stylize them using CSS; the current style
i set i just a placeholder to check that it works as expected.

Most of these links needs to check for the URI’s prefix, because they
are links to a whole section, but the first link must check for the
exact match, otherwise it would match every other URI, as all of them
start with /company/{uuid}.

The server does not return the markup for the top navigation when usin
HTMx, though, hence i have to change the current class using JavaScript.

I am not sure if the correct value for aria-current is “page” when the
link is not for the actual page the user is currently in, like when is
in the new quote page, but it seems to be the most appropriate value
from the enumeration given in the specifications, except, perhaps, for
the “location” value, but i was unable to find any example of that value
anywhere.

Part of #89.
This commit is contained in:
jordi fita mas 2023-11-13 14:42:27 +01:00
parent c3e1597972
commit 31a655ae7f
4 changed files with 33 additions and 8 deletions

View File

@ -10,6 +10,7 @@ import (
"math" "math"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"time" "time"
) )
@ -30,6 +31,12 @@ func mustRenderTemplate(wr io.Writer, r *http.Request, layout string, filename s
"currentLocale": func() string { "currentLocale": func() string {
return locale.Language.String() return locale.Language.String()
}, },
"requestURIMatches": func(uri string) bool {
return r.RequestURI == uri
},
"requestURIHasPrefix": func(uri string) bool {
return strings.HasPrefix(r.RequestURI, uri)
},
"companyURI": func(uri string) string { "companyURI": func(uri string) string {
return companyURI(company, uri) return companyURI(company, uri)
}, },

View File

@ -562,10 +562,12 @@ ul[role="menu"].action-menu li i[class^='ri-'] {
text-decoration: underline; text-decoration: underline;
} }
body > nav a[aria-current] {
background-color: yellow;
}
/* menu tauler final */ /* menu tauler final */
main > nav { main > nav {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -753,3 +753,19 @@ htmx.on(document, 'alpine:init', () => {
}, },
})); }));
}); });
function updateCurrentMenuItem() {
const path = window.location.pathname;
const items = document.querySelectorAll('body > nav a');
items.forEach((item, i) => {
const matches = path === item.pathname;
if (matches || (i !== 0 && path.startsWith(item.pathname))) {
item.setAttribute('aria-current', 'page');
} else {
item.removeAttribute('aria-current');
}
});
}
htmx.on('htmx:pushedIntoHistory', updateCurrentMenuItem);
htmx.on('htmx:replacedInHistory', updateCurrentMenuItem);

View File

@ -50,12 +50,12 @@
</header> </header>
<nav aria-label="{{( pgettext "Main" "title" )}}" data-hx-target="main" data-hx-boost="true"> <nav aria-label="{{( pgettext "Main" "title" )}}" data-hx-target="main" data-hx-boost="true">
<ul> <ul>
<li><a href="{{ companyURI "/" }}">{{( pgettext "Dashboard" "nav" )}}</a></li> <li><a{{if requestURIMatches (companyURI "/") }} aria-current="page"{{ end }} href="{{ companyURI "/" }}">{{( pgettext "Dashboard" "nav" )}}</a></li>
<li><a href="{{ companyURI "/quotes" }}">{{( pgettext "Quotations" "nav" )}}</a></li> <li><a{{if requestURIHasPrefix (companyURI "/quotes") }} aria-current="page"{{ end }} href="{{ companyURI "/quotes" }}">{{( pgettext "Quotations" "nav" )}}</a></li>
<li><a href="{{ companyURI "/invoices" }}">{{( pgettext "Invoices" "nav" )}}</a></li> <li><a{{if requestURIHasPrefix (companyURI "/invoices") }} aria-current="page"{{ end }} href="{{ companyURI "/invoices" }}">{{( pgettext "Invoices" "nav" )}}</a></li>
<li><a href="{{ companyURI "/expenses" }}">{{( pgettext "Expenses" "nav" )}}</a></li> <li><a{{if requestURIHasPrefix (companyURI "/expenses") }} aria-current="page"{{ end }} href="{{ companyURI "/expenses" }}">{{( pgettext "Expenses" "nav" )}}</a></li>
<li><a href="{{ companyURI "/products" }}">{{( pgettext "Products" "nav" )}}</a></li> <li><a{{if requestURIHasPrefix (companyURI "/products") }} aria-current="page"{{ end }} href="{{ companyURI "/products" }}">{{( pgettext "Products" "nav" )}}</a></li>
<li><a href="{{ companyURI "/contacts" }}">{{( pgettext "Contacts" "nav" )}}</a></li> <li><a{{if requestURIHasPrefix (companyURI "/contacts") }} aria-current="page"{{ end }} href="{{ companyURI "/contacts" }}">{{( pgettext "Contacts" "nav" )}}</a></li>
</ul> </ul>
</nav> </nav>
<main> <main>