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:
parent
c3e1597972
commit
31a655ae7f
|
@ -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)
|
||||||
},
|
},
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -713,7 +713,7 @@ htmx.on('closeModal', () => {
|
||||||
|
|
||||||
htmx.on(document, 'alpine:init', () => {
|
htmx.on(document, 'alpine:init', () => {
|
||||||
document.body.classList.remove('filters-visible');
|
document.body.classList.remove('filters-visible');
|
||||||
|
|
||||||
Alpine.data('snackbar', () => ({
|
Alpine.data('snackbar', () => ({
|
||||||
show: false, toast: "", toasts: [], timeoutId: null, init() {
|
show: false, toast: "", toasts: [], timeoutId: null, init() {
|
||||||
htmx.on('htmx:error', (error) => {
|
htmx.on('htmx:error', (error) => {
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue