a11y: Fix missing buttons for explorer folders

This commit is contained in:
Jairus Joer 2025-10-24 15:26:31 +02:00
parent 52460f376f
commit d98e769dbc
3 changed files with 59 additions and 47 deletions

View File

@ -103,11 +103,10 @@ export default ((userOpts?: Partial<Options>) => {
data-mobile={false} data-mobile={false}
aria-expanded={true} aria-expanded={true}
> >
<h2>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h2>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="14" width="12"
height="14" height="12"
viewBox="5 8 14 8" viewBox="5 8 14 8"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -118,6 +117,7 @@ export default ((userOpts?: Partial<Options>) => {
> >
<polyline points="6 9 12 15 18 9"></polyline> <polyline points="6 9 12 15 18 9"></polyline>
</svg> </svg>
<h2>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h2>
</button> </button>
<div id={id} class="explorer-content" aria-expanded={false} role="group"> <div id={id} class="explorer-content" aria-expanded={false} role="group">
<OverflowList class="explorer-ul" /> <OverflowList class="explorer-ul" />
@ -130,6 +130,7 @@ export default ((userOpts?: Partial<Options>) => {
<template id="template-folder"> <template id="template-folder">
<li> <li>
<div class="folder-container"> <div class="folder-container">
<button class="folder-expand">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="12" width="12"
@ -144,6 +145,7 @@ export default ((userOpts?: Partial<Options>) => {
> >
<polyline points="6 9 12 15 18 9"></polyline> <polyline points="6 9 12 15 18 9"></polyline>
</svg> </svg>
</button>
<div> <div>
<button class="folder-button"> <button class="folder-button">
<span class="folder-title"></span> <span class="folder-title"></span>

View File

@ -43,11 +43,11 @@ function toggleFolder(evt: MouseEvent) {
if (!target) return if (!target) return
// Check if target was svg icon or button // Check if target was svg icon or button
const isSvg = target.nodeName === "svg" const isFolderExpand = target.classList.contains("folder-expand")
// corresponding <ul> element relative to clicked button/folder // corresponding <ul> element relative to clicked button/folder
const folderContainer = ( const folderContainer = (
isSvg isFolderExpand
? // svg -> div.folder-container ? // svg -> div.folder-container
target.parentElement target.parentElement
: // button.folder-button -> div -> div.folder-container : // button.folder-button -> div -> div.folder-container
@ -248,12 +248,12 @@ async function setupExplorer(currentSlug: FullSlug) {
} }
} }
const folderIcons = explorer.getElementsByClassName( const folderExpands = explorer.getElementsByClassName(
"folder-icon", "folder-expand",
) as HTMLCollectionOf<HTMLElement> ) as HTMLCollectionOf<HTMLElement>
for (const icon of folderIcons) { for (const expand of folderExpands) {
icon.addEventListener("click", toggleFolder) expand.addEventListener("click", toggleFolder)
window.addCleanup(() => icon.removeEventListener("click", toggleFolder)) window.addCleanup(() => expand.removeEventListener("click", toggleFolder))
} }
} }
} }

View File

@ -30,18 +30,19 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: hidden; overflow-y: hidden;
min-height: 1.2rem;
flex: 0 1 auto; flex: 0 1 auto;
&.collapsed { &.collapsed {
flex: 0 1 1.2rem; & .explorer-content {
display: none;
}
& .fold { & .fold {
transform: rotateZ(-90deg); transform: rotateZ(-90deg);
} }
} }
& .fold { & .fold {
margin-left: 0.5rem; margin-inline: 0.375rem;
transition: transform 0.3s ease; transition: transform 0.3s ease;
opacity: 0.8; opacity: 0.8;
} }
@ -120,7 +121,12 @@ button.desktop-explorer {
padding: 0; padding: 0;
overscroll-behavior: contain; overscroll-behavior: contain;
& li > a { & li {
&:not(:has(.folder-container)) {
padding-left: 0.375rem;
}
& > a {
color: var(--dark); color: var(--dark);
opacity: 0.75; opacity: 0.75;
pointer-events: all; pointer-events: all;
@ -131,6 +137,7 @@ button.desktop-explorer {
} }
} }
} }
}
.folder-outer { .folder-outer {
display: grid; display: grid;
@ -144,9 +151,9 @@ button.desktop-explorer {
.folder-outer > ul { .folder-outer > ul {
overflow: hidden; overflow: hidden;
margin-left: 6px; margin-left: 0.6875rem;
padding-left: 0.8rem; padding-left: 0.375rem;
border-left: 1px solid var(--lightgray); border-left: 0.0625rem solid var(--lightgray);
} }
} }
@ -193,21 +200,24 @@ button.desktop-explorer {
} }
} }
.folder-icon { .folder-expand {
margin-right: 5px; background: unset;
border: unset;
color: var(--secondary); color: var(--secondary);
cursor: pointer; cursor: pointer;
height: 1.5rem;
padding: 0.375rem;
transition: transform 0.3s ease; transition: transform 0.3s ease;
backface-visibility: visible; width: 1.5rem;
flex-shrink: 0;
}
li:has(> .folder-outer:not(.open)) > .folder-container > svg { &:hover,
transform: rotate(-90deg); &:focus {
}
.folder-icon:hover {
color: var(--tertiary); color: var(--tertiary);
}
}
li:has(> .folder-outer:not(.open)) .folder-icon {
transform: rotate(-90deg);
} }
.explorer { .explorer {