Implement profile menu with <details>

It works better than with the weird hover behaviour i could do in CSS,
and it already has most of the aria roles needed.

The only tricky part is to allow closing it by clicking anywhere else,
that is done by “extending” the <summary> to the whole screen, with a
lower z-index than the menu but higher than the rest of controls, that
way we force people to click on that summary.
This commit is contained in:
jordi fita mas 2023-01-23 18:52:18 +01:00
parent c7e34cc488
commit 22509dd683
4 changed files with 53 additions and 46 deletions

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-01-23 00:41+0100\n"
"POT-Creation-Date: 2023-01-23 18:50+0100\n"
"PO-Revision-Date: 2023-01-18 17:08+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n"
@ -81,11 +81,11 @@ msgctxt "action"
msgid "Save changes"
msgstr "Desa canvis"
#: web/template/app.html:16
#: web/template/app.html:20
msgid "Account"
msgstr "Compte"
#: web/template/app.html:19
#: web/template/app.html:27
msgctxt "action"
msgid "Logout"
msgstr "Surt"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-01-23 00:41+0100\n"
"POT-Creation-Date: 2023-01-23 18:50+0100\n"
"PO-Revision-Date: 2023-01-18 17:45+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
@ -81,11 +81,11 @@ msgctxt "action"
msgid "Save changes"
msgstr "Guardar cambios"
#: web/template/app.html:16
#: web/template/app.html:20
msgid "Account"
msgstr "Cuenta"
#: web/template/app.html:19
#: web/template/app.html:27
msgctxt "action"
msgid "Logout"
msgstr "Salir"

View File

@ -279,11 +279,13 @@ input[type="text"], input[type="password"], input[type="email"], select {
transition: 0.2s;
}
.relative {
/* Profile Menu */
#profilemenu {
position: relative;
}
#profilebutton {
#profilemenu summary {
width: 7rem;
height: 7rem;
margin: 1rem 0;
@ -292,45 +294,41 @@ input[type="text"], input[type="password"], input[type="email"], select {
align-items: center;
border-radius: 50%;
border: none;
list-style: none;
}
#profilebutton, #profilemenu button {
#profilemenu summary::-webkit-details-marker {
display: none;
}
#profilemenu summary, #profilemenu button {
cursor: pointer;
}
#profilemenu {
#profilemenu summary, #profilemenu ul {
background-color: var(--numerus--background-color);
}
#profilemenu[open] summary::before {
background-color: var(--numerus--header--background-color);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
content: "";
cursor: default;
z-index: 10;
mix-blend-mode: multiply;
}
#profilemenu ul {
list-style: none;
position: absolute;
right: -1.875em;
top: 100%;
padding: 1rem 2rem;
background-color: var(--numerus--color--white);
display: none;
opacity: 0;
z-index: 10;
}
header div:hover #profilemenu {
opacity: 1;
display: initial;
}
header .overlay {
background-color: var(--numerus--header--background-color);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
display: none;
pointer-events: none;
mix-blend-mode: multiply;
}
header div:hover + .overlay {
display: block;
opacity: 1;
z-index: 20;
}
#profilemenu li + li {
@ -351,12 +349,12 @@ header div:hover + .overlay {
text-transform: initial;
}
#profilemenu i[class^='ri-'] {
#profilemenu li i[class^='ri-'] {
margin-right: 2rem;
color: var(--numerus--color--dark-gray);
}
#profilemenu button:hover, #profilemenu a:hover {
#profilemenu summary:hover, #profilemenu summary:focus, #profilemenu button:hover, #profilemenu a:hover {
background-color: var(--numerus--color--light-gray);
}

View File

@ -9,18 +9,27 @@
<body>
<header>
<h1><img src="/static/numerus.svg" alt="Numerus" width="261" height="33"></h1>
<div class="relative">
<button id="profilebutton" aria-controls="profilemenu" aria-haspopup="true"><i class="ri-eye-close-line ri-3x"></i></button>
<ul id="profilemenu" role="menu" aria-labelledby="profilebutton">
<details id="profilemenu">
<summary>
<i class="ri-eye-close-line ri-3x"></i>
</summary>
<ul role="menu">
<li role="presentation">
<a role="menuitem" href="/profile"><i class="ri-account-circle-line"></i> {{( gettext "Account" )}}</a>
<a role="menuitem" href="/profile">
<i class="ri-account-circle-line"></i>
{{( gettext "Account" )}}
</a>
</li>
<li role="presentation">
<form method="POST" action="/logout"><button type="submit" role="menuitem"><i class="ri-logout-circle-line"></i> {{( pgettext "Logout" "action" )}}</button></form>
<form method="POST" action="/logout">
<button type="submit" role="menuitem">
<i class="ri-logout-circle-line"></i>
{{( pgettext "Logout" "action" )}}
</button>
</form>
</li>
</ul>
</div>
<div class="overlay"></div>
</details>
</header>
<main>
{{- template "content" . }}