feat(web, a11y): focus management for modals and popups (#8298)

* feat(web, a11y): focus management for modals and popups

* feat: hide asset options dropdown on escape key
This commit is contained in:
Ben Basten 2024-03-27 20:55:27 +00:00 committed by GitHub
parent 9fe80c25eb
commit e1c2135850
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 459 additions and 359 deletions

View file

@ -11,6 +11,7 @@
import { notificationController, NotificationType } from '../notification/notification';
import UserAvatar from '../user-avatar.svelte';
import AvatarSelector from './avatar-selector.svelte';
import FocusTrap from '$lib/components/shared-components/focus-trap.svelte';
let isShowSelectAvatar = false;
@ -46,19 +47,20 @@
};
</script>
<div
in:fade={{ duration: 100 }}
out:fade={{ duration: 100 }}
id="account-info-panel"
class="absolute right-[25px] top-[75px] z-[100] w-[360px] rounded-3xl bg-gray-200 shadow-lg dark:border dark:border-immich-dark-gray dark:bg-immich-dark-gray"
>
<FocusTrap>
<div
class="mx-4 mt-4 flex flex-col items-center justify-center gap-4 rounded-3xl bg-white p-4 dark:bg-immich-dark-primary/10"
in:fade={{ duration: 100 }}
out:fade={{ duration: 100 }}
id="account-info-panel"
class="absolute right-[25px] top-[75px] z-[100] w-[360px] rounded-3xl bg-gray-200 shadow-lg dark:border dark:border-immich-dark-gray dark:bg-immich-dark-gray"
>
<div class="relative">
{#key $user}
<UserAvatar user={$user} size="xl" />
<div
class="mx-4 mt-4 flex flex-col items-center justify-center gap-4 rounded-3xl bg-white p-4 dark:bg-immich-dark-primary/10"
>
<div class="relative">
{#key $user}
<UserAvatar user={$user} size="xl" />
{/key}
<div
class="absolute z-10 bottom-0 right-0 rounded-full w-6 h-6 border dark:border-immich-dark-primary bg-immich-primary"
>
@ -69,35 +71,35 @@
<Icon path={mdiPencil} />
</button>
</div>
{/key}
</div>
<div>
<p class="text-center text-lg font-medium text-immich-primary dark:text-immich-dark-primary">
{$user.name}
</p>
<p class="text-sm text-gray-500 dark:text-immich-dark-fg">{$user.email}</p>
</div>
<div>
<p class="text-center text-lg font-medium text-immich-primary dark:text-immich-dark-primary">
{$user.name}
</p>
<p class="text-sm text-gray-500 dark:text-immich-dark-fg">{$user.email}</p>
</div>
<a href={AppRoute.USER_SETTINGS} on:click={() => dispatch('close')}>
<Button color="dark-gray" size="sm" shadow={false} border>
<div class="flex place-content-center place-items-center gap-2 px-2">
<Icon path={mdiCog} size="18" />
Account Settings
</div>
</Button>
</a>
</div>
<a href={AppRoute.USER_SETTINGS} on:click={() => dispatch('close')}>
<Button color="dark-gray" size="sm" shadow={false} border>
<div class="flex place-content-center place-items-center gap-2 px-2">
<Icon path={mdiCog} size="18" />
Account Settings
</div>
</Button>
</a>
<div class="mb-4 flex flex-col">
<button
class="flex w-full place-content-center place-items-center gap-2 py-3 font-medium text-gray-500 hover:bg-immich-primary/10 dark:text-gray-300"
on:click={() => dispatch('logout')}
>
<Icon path={mdiLogout} size={24} />
Sign Out</button
>
</div>
</div>
<div class="mb-4 flex flex-col">
<button
class="flex w-full place-content-center place-items-center gap-2 py-3 font-medium text-gray-500 hover:bg-immich-primary/10 dark:text-gray-300"
on:click={() => dispatch('logout')}
>
<Icon path={mdiLogout} size={24} />
Sign Out</button
>
</div>
</div>
</FocusTrap>
{#if isShowSelectAvatar}
<AvatarSelector
user={$user}