mirror of
https://github.com/versia-pub/frontend.git
synced 2025-12-06 16:38:20 +01:00
feat: ♿ Improve accessibility everywhere
This commit is contained in:
parent
192c7f83c3
commit
6e2401b67d
|
|
@ -22,6 +22,8 @@
|
||||||
- [x] Note editing
|
- [x] Note editing
|
||||||
- [x] Alt text support everywhere
|
- [x] Alt text support everywhere
|
||||||
- [x] Media uploads
|
- [x] Media uploads
|
||||||
|
- [x] WCAG 2.2 AAA compliance
|
||||||
|
- Testing is automated and may not catch all issues, please report any accessibility issues you find.
|
||||||
- [ ] Settings
|
- [ ] Settings
|
||||||
- [ ] Profile editing
|
- [ ] Profile editing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ButtonsBase :loading="loading" class="bg-pink-500 hover:bg-pink-400">
|
<ButtonsBase :loading="loading" class="bg-pink-600 hover:bg-pink-500">
|
||||||
<slot />
|
<slot />
|
||||||
</ButtonsBase>
|
</ButtonsBase>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
<div class="sm:flex sm:items-center sm:justify-between gap-3">
|
<div class="sm:flex sm:items-center sm:justify-between gap-3">
|
||||||
<div class="sm:flex sm:space-x-5 grow">
|
<div class="sm:flex sm:space-x-5 grow">
|
||||||
<AvatarsCentered :src="identity.account.avatar"
|
<AvatarsCentered :src="identity.account.avatar"
|
||||||
class="mx-auto shrink-0 size-20 rounded overflow-hidden ring-1 ring-white/10" />
|
class="mx-auto shrink-0 size-20 rounded overflow-hidden ring-1 ring-white/10"
|
||||||
|
:alt="'Your avatar'" />
|
||||||
<div
|
<div
|
||||||
class="mt-4 text-center flex flex-col justify-center sm:mt-0 sm:text-left bg-dark-800 py-2 px-4 rounded grow ring-1 ring-white/10">
|
class="mt-4 text-center flex flex-col justify-center sm:mt-0 sm:text-left bg-dark-800 py-2 px-4 rounded grow ring-1 ring-white/10">
|
||||||
<p class="text-sm font-medium text-gray-300">Welcome back,</p>
|
<p class="text-sm font-medium text-gray-300">Welcome back,</p>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<aside v-bind="$props" role="complementary"
|
<aside v-bind="$props" role="complementary" :aria-expanded="open ? 'true' : 'false'"
|
||||||
:class="['flex max-h-dvh overflow-hidden duration-200', open ? enterClass : leaveClass, direction === 'left' ? 'flex-row' : 'flex-row-reverse']">
|
:class="['flex max-h-dvh overflow-hidden duration-200', open ? enterClass : leaveClass, direction === 'left' ? 'flex-row' : 'flex-row-reverse']">
|
||||||
<OverlayScrollbarsComponent :defer="true"
|
<OverlayScrollbarsComponent :defer="true"
|
||||||
class="bg-dark-900 ring-1 ring-white/10 h-full overflow-y-auto w-full">
|
class="bg-dark-900 ring-1 ring-white/10 h-full overflow-y-auto w-full">
|
||||||
<slot />
|
<slot />
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
<button @click="open = !open"
|
<button @click="open = !open" aria-label="Toggle sidebar"
|
||||||
class="h-full bg-dark-700 hover:bg-dark-400 hover:cursor-pointer duration-200 py-4 px-0.5 flex items-center justify-center w-4 shrink-0">
|
class="h-full bg-dark-700 hover:bg-dark-400 hover:cursor-pointer duration-200 py-4 px-0.5 flex items-center justify-center w-4 shrink-0">
|
||||||
<iconify-icon icon="tabler:chevron-right"
|
<iconify-icon icon="tabler:chevron-right"
|
||||||
:class="['text-gray-200 duration-200', direction === 'left' ? open ? 'rotate-180' : 'rotate-0' : open ? 'rotate-0' : 'rotate-180']"
|
:class="['text-gray-200 duration-200', direction === 'left' ? open ? 'rotate-180' : 'rotate-0' : open ? 'rotate-0' : 'rotate-180']"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<aside
|
<aside
|
||||||
class="fixed h-dvh z-10 md:flex hidden flex-col p-4 bg-dark-800 gap-10 max-w-20 hover:max-w-72 duration-200 group ring-1 ring-dark-500"
|
class="fixed h-dvh z-10 md:flex hidden flex-col p-4 bg-dark-800 gap-10 max-w-20 hover:max-w-72 duration-200 group ring-1 ring-dark-500"
|
||||||
role="complementary">
|
aria-label="Navigation" role="complementary">
|
||||||
<NuxtLink href="/">
|
<NuxtLink href="/">
|
||||||
<img crossorigin="anonymous" class="size-11 rounded ring-1 ring-white/10 hover:scale-105 duration-200"
|
<img crossorigin="anonymous" class="size-11 rounded ring-1 ring-white/10 hover:scale-105 duration-200"
|
||||||
src="/logo.webp" alt="Lysand logo" />
|
src="/logo.webp" alt="Lysand logo" />
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div tabindex="0" aria-label="Open attachment in lightbox"
|
<div class="aspect-video relative">
|
||||||
class="aspect-video w-full rounded ring-white/5 shadow overflow-hidden ring-1 hover:ring-2 duration-100 relative">
|
<div tabindex="0" aria-label="Open attachment in lightbox" role="button"
|
||||||
<img v-if="attachment.type === 'image'" tabindex="-1"
|
class="w-full h-full rounded ring-white/5 shadow overflow-hidden ring-1 hover:ring-2 duration-100 relative">
|
||||||
class="object-cover w-full h-full rounded duration-150 hover:scale-[102%] ease-in-out" :src="attachment.url"
|
<img v-if="attachment.type === 'image'"
|
||||||
:alt="attachment.description ?? undefined" @click="openLightbox" @keydown="openLightbox" />
|
class="object-cover w-full h-full rounded duration-150 hover:scale-[102%] ease-in-out"
|
||||||
|
:src="attachment.url" :alt="attachment.description ?? undefined" @click="openLightbox"
|
||||||
|
@keydown="openLightbox" />
|
||||||
<video v-else-if="attachment.type === 'video'" class="object-contain w-full h-full rounded aspect-video"
|
<video v-else-if="attachment.type === 'video'" class="object-contain w-full h-full rounded aspect-video"
|
||||||
controls :alt="attachment.description ?? undefined" :src="attachment.url">
|
controls :alt="attachment.description ?? undefined" :src="attachment.url">
|
||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
|
|
@ -17,6 +19,7 @@
|
||||||
formatBytes(Number(attachment.meta?.length)) }}</p>
|
formatBytes(Number(attachment.meta?.length)) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
<!-- Alt text viewer -->
|
<!-- Alt text viewer -->
|
||||||
<Popover.Root :positioning="{
|
<Popover.Root :positioning="{
|
||||||
strategy: 'fixed',
|
strategy: 'fixed',
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<NuxtLink :href="accountUrl" class="shrink-0">
|
<NuxtLink :href="accountUrl" class="shrink-0">
|
||||||
<AvatarsCentered :src="note?.account.avatar" :alt="`${note?.account.acct}'s avatar`"
|
<AvatarsCentered :src="note?.account.avatar" :alt="`${note?.account.acct}'s avatar`"
|
||||||
class="size-6 rounded ring-1 ring-white/5" />
|
class="size-6 rounded ring-1 ring-white/5" />
|
||||||
|
<span class="sr-only">Account profile</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<div class="flex flex-col items-start justify-around ml-4 grow overflow-hidden">
|
<div class="flex flex-col items-start justify-around ml-4 grow overflow-hidden">
|
||||||
<div class="flex flex-row text-sm items-center justify-between w-full">
|
<div class="flex flex-row text-sm items-center justify-between w-full">
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
note?.account.display_name }}
|
note?.account.display_name }}
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink :href="noteUrl" class="text-gray-400 ml-2 line-clamp-1 break-all shrink-0">
|
<NuxtLink :href="noteUrl" class="text-gray-300 ml-2 line-clamp-1 break-all shrink-0">
|
||||||
<Skeleton :enabled="!note" :min-width="50" :max-width="100" shape="rect">
|
<Skeleton :enabled="!note" :min-width="50" :max-width="100" shape="rect">
|
||||||
{{ timeAgo }}
|
{{ timeAgo }}
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
|
|
@ -24,6 +25,7 @@
|
||||||
<NuxtLink :href="accountUrl" class="shrink-0">
|
<NuxtLink :href="accountUrl" class="shrink-0">
|
||||||
<AvatarsCentered :src="note?.account.avatar" :alt="`${note?.account.acct}'s avatar`"
|
<AvatarsCentered :src="note?.account.avatar" :alt="`${note?.account.acct}'s avatar`"
|
||||||
class="h-12 w-12 rounded ring-1 ring-white/5" />
|
class="h-12 w-12 rounded ring-1 ring-white/5" />
|
||||||
|
<span class="sr-only">Account profile</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<div class="flex flex-col items-start justify-around ml-4 grow overflow-hidden">
|
<div class="flex flex-col items-start justify-around ml-4 grow overflow-hidden">
|
||||||
<div class="flex flex-row items-center justify-between w-full">
|
<div class="flex flex-row items-center justify-between w-full">
|
||||||
|
|
@ -33,14 +35,14 @@
|
||||||
note?.account.display_name }}
|
note?.account.display_name }}
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink :href="noteUrl" class="text-gray-400 text-sm ml-2 line-clamp-1 break-all shrink-0"
|
<NuxtLink :href="noteUrl" class="text-gray-300 text-sm ml-2 line-clamp-1 break-all shrink-0"
|
||||||
:alt="fullTime" :title="fullTime">
|
:alt="fullTime" :title="fullTime">
|
||||||
<Skeleton :enabled="!note" :min-width="50" :max-width="100" shape="rect">
|
<Skeleton :enabled="!note" :min-width="50" :max-width="100" shape="rect">
|
||||||
{{ timeAgo }}
|
{{ timeAgo }}
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-gray-400 text-sm line-clamp-1 break-all w-full group">
|
<span class="text-gray-300 text-sm line-clamp-1 break-all w-full group">
|
||||||
<Skeleton :enabled="!note" :min-width="130" :max-width="250" shape="rect">
|
<Skeleton :enabled="!note" :min-width="130" :max-width="250" shape="rect">
|
||||||
<span class="group-hover:hidden">
|
<span class="group-hover:hidden">
|
||||||
@{{
|
@{{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<article
|
||||||
class="first:rounded-t last:rounded-b ring-1 relative ring-white/5 p-6 flex flex-col bg-dark-800 hover:bg-dark-700 duration-200">
|
class="first:rounded-t last:rounded-b ring-1 relative ring-white/5 p-6 flex flex-col bg-dark-800 hover:bg-dark-700 duration-200">
|
||||||
<!-- Overlay that blocks clicks for disabled notes -->
|
<!-- Overlay that blocks clicks for disabled notes -->
|
||||||
<div v-if="disabled" class="absolute z-10 inset-0 hover:cursor-not-allowed">
|
<div v-if="disabled" class="absolute z-10 inset-0 hover:cursor-not-allowed">
|
||||||
|
|
@ -144,7 +144,7 @@
|
||||||
</DropdownsAdaptiveDropdown>
|
</DropdownsAdaptiveDropdown>
|
||||||
</div>
|
</div>
|
||||||
</Skeleton>
|
</Skeleton>
|
||||||
</div>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
<LazySidebarsNavigation />
|
<LazySidebarsNavigation />
|
||||||
<div class="relative md:pl-20 min-h-dvh flex flex-row overflow-hidden justify-center xl:justify-between">
|
<div class="relative md:pl-20 min-h-dvh flex flex-row overflow-hidden justify-center xl:justify-between">
|
||||||
<OverlayScrollbarsComponent :defer="true" class="w-full max-h-dvh overflow-y-auto">
|
<OverlayScrollbarsComponent :defer="true" class="w-full max-h-dvh overflow-y-auto" :element="'main'">
|
||||||
<slot />
|
<slot />
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="from-dark-600 to-dark-900 bg-gradient-to-tl min-h-dvh pb-20 md:pb-0">
|
<main class="from-dark-600 to-dark-900 bg-gradient-to-tl min-h-dvh pb-20 md:pb-0">
|
||||||
<LazySidebarsNavigation />
|
<LazySidebarsNavigation />
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue