feat(web): make custom clickable elements keyboard accessible

The channel cards, member node badges, and member URL text are
clickable divs/spans, so keyboard users could not reach or activate
them. Add role/tabindex, Enter/Space key handling, and a
focus-visible outline (invisible to mouse users). daisyUI btn/link/
input components already ship focus-visible outlines, so only these
custom elements needed it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Louis King
2026-07-02 21:32:25 +01:00
parent 79565326e2
commit 91a3fcf237
2 changed files with 10 additions and 3 deletions
@@ -37,7 +37,9 @@ function renderChannelCard(channel, { oidcEnabled, isAdmin, onDelete, onEdit, on
? html`<div id="${qrId}" class="qr-container"></div>`
: nothing;
return html`<div class="card bg-base-100 shadow-xl cursor-pointer" @click=${() => onNavigate(channelIdx)}>
return html`<div class="card bg-base-100 shadow-xl cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" role="button" tabindex="0"
@click=${() => onNavigate(channelIdx)}
@keydown=${(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onNavigate(channelIdx); } }}>
<div class="card-body flex-row gap-4">
<div class="flex-1 min-w-0">
<h2 class="card-title flex items-center gap-2">
@@ -25,7 +25,9 @@ function renderProfileTile(profile, router) {
e.stopPropagation();
router.navigate('/nodes/' + node.public_key);
};
return html`<span class="badge badge-secondary badge-sm cursor-pointer" @click=${handleClick}>${label}</span>`;
return html`<span class="badge badge-secondary badge-sm cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" role="button" tabindex="0"
@click=${handleClick}
@keydown=${(e) => { if (e.key === 'Enter' || e.key === ' ') handleClick(e); }}>${label}</span>`;
})}</div>`
: nothing;
@@ -33,8 +35,11 @@ function renderProfileTile(profile, router) {
? html`<p class="text-sm opacity-70 mt-1 truncate">${profile.description}</p>`
: nothing;
const openUrl = (e) => { e.preventDefault(); e.stopPropagation(); window.open(profile.url, '_blank', 'noopener,noreferrer'); };
const urlLink = profile.url
? html`<span class="link link-accent text-xs mt-1 inline-block truncate cursor-pointer" @click=${(e) => { e.preventDefault(); e.stopPropagation(); window.open(profile.url, '_blank', 'noopener,noreferrer'); }}>${profile.url}</span>`
? html`<span class="link link-accent text-xs mt-1 inline-block truncate cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" role="link" tabindex="0"
@click=${openUrl}
@keydown=${(e) => { if (e.key === 'Enter') openUrl(e); }}>${profile.url}</span>`
: nothing;
return html`<a href="/profile/${profile.id}" class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">