feat(web, a11y): add labels! (#8354)

* feat(web, a11y): add labels!

* fix: move required prop to the top of the list
This commit is contained in:
Ben Basten 2024-03-29 12:48:07 +00:00 committed by GitHub
parent 6f677b4fae
commit fcc3b81745
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 63 additions and 26 deletions

View File

@ -61,7 +61,7 @@
<div class="flex items-center"> <div class="flex items-center">
<h1 class="px-4 w-full self-center font-medium text-immich-primary dark:text-immich-dark-primary">Options</h1> <h1 class="px-4 w-full self-center font-medium text-immich-primary dark:text-immich-dark-primary">Options</h1>
<div> <div>
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton icon={mdiClose} title="Close" on:click={() => dispatch('close')} />
</div> </div>
</div> </div>

View File

@ -97,6 +97,7 @@
{#if isOwned} {#if isOwned}
<div> <div>
<CircleIconButton <CircleIconButton
title="Options"
on:click={(event) => showContextMenu(event, user)} on:click={(event) => showContextMenu(event, user)}
icon={mdiDotsVertical} icon={mdiDotsVertical}
backgroundColor="transparent" backgroundColor="transparent"

View File

@ -305,7 +305,13 @@
</div> </div>
{:else if message} {:else if message}
<div class="flex items-end w-fit ml-0"> <div class="flex items-end w-fit ml-0">
<CircleIconButton size="15" icon={mdiSend} iconColor={'dark'} hoverColor={'rgb(173,203,250)'} /> <CircleIconButton
title="Send message"
size="15"
icon={mdiSend}
iconColor={'dark'}
hoverColor={'rgb(173,203,250)'}
/>
</div> </div>
{/if} {/if}
</form> </form>

View File

@ -102,7 +102,7 @@
class="z-[1001] flex h-16 place-items-center justify-between bg-gradient-to-b from-black/40 px-3 transition-transform duration-200" class="z-[1001] flex h-16 place-items-center justify-between bg-gradient-to-b from-black/40 px-3 transition-transform duration-200"
> >
<div class="text-white"> <div class="text-white">
<CircleIconButton isOpacity={true} icon={mdiArrowLeft} on:click={() => dispatch('back')} /> <CircleIconButton isOpacity={true} icon={mdiArrowLeft} title="Go back" on:click={() => dispatch('back')} />
</div> </div>
<div class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white"> <div class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white">
{#if showShareButton} {#if showShareButton}

View File

@ -39,7 +39,13 @@
</div> </div>
</div> </div>
<div class="absolute right-2"> <div class="absolute right-2">
<CircleIconButton on:click={() => abort(downloadKey, download)} size="20" icon={mdiClose} forceDark /> <CircleIconButton
title="Close"
on:click={() => abort(downloadKey, download)}
size="20"
icon={mdiClose}
forceDark
/>
</div> </div>
</div> </div>
{/each} {/each}

View File

@ -2,11 +2,11 @@
import Icon from '$lib/components/elements/icon.svelte'; import Icon from '$lib/components/elements/icon.svelte';
export let icon: string; export let icon: string;
export let title: string;
export let backgroundColor = ''; export let backgroundColor = '';
export let hoverColor = '#e2e7e9'; export let hoverColor = '#e2e7e9';
export let padding = '3'; export let padding = '3';
export let size = '24'; export let size = '24';
export let title = '';
export let isOpacity = false; export let isOpacity = false;
export let forceDark = false; export let forceDark = false;
export let hideMobile = false; export let hideMobile = false;
@ -27,7 +27,7 @@
{hideMobile && 'hidden sm:flex'}" {hideMobile && 'hidden sm:flex'}"
on:click on:click
> >
<Icon path={icon} {size} color={iconColor} /> <Icon path={icon} {size} ariaLabel={title} color={iconColor} />
<slot /> <slot />
</button> </button>

View File

@ -135,7 +135,12 @@
</div> </div>
{#if selectedPeople.length === 1} {#if selectedPeople.length === 1}
<div class="absolute bottom-2"> <div class="absolute bottom-2">
<CircleIconButton icon={mdiSwapHorizontal} size="24" on:click={handleSwapPeople} /> <CircleIconButton
title="Swap merge direction"
icon={mdiSwapHorizontal}
size="24"
on:click={handleSwapPeople}
/>
</div> </div>
{/if} {/if}
</div> </div>

View File

@ -40,7 +40,7 @@
Merge People - {title} Merge People - {title}
</h1> </h1>
<div class="p-2"> <div class="p-2">
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton title="Close" icon={mdiClose} on:click={() => dispatch('close')} />
</div> </div>
</div> </div>
@ -57,6 +57,7 @@
</div> </div>
<div class="mx-0.5 flex md:mx-2"> <div class="mx-0.5 flex md:mx-2">
<CircleIconButton <CircleIconButton
title="Swap merge direction"
icon={mdiMerge} icon={mdiMerge}
on:click={() => ([personMerge1, personMerge2] = [personMerge2, personMerge1])} on:click={() => ([personMerge1, personMerge2] = [personMerge2, personMerge1])}
/> />

View File

@ -29,7 +29,7 @@
class="fixed top-0 z-10 flex h-16 w-full items-center justify-between border-b bg-white p-1 dark:border-immich-dark-gray dark:bg-black dark:text-immich-dark-fg md:p-8" class="fixed top-0 z-10 flex h-16 w-full items-center justify-between border-b bg-white p-1 dark:border-immich-dark-gray dark:bg-black dark:text-immich-dark-fg md:p-8"
> >
<div class="flex items-center"> <div class="flex items-center">
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton title="Close" icon={mdiClose} on:click={() => dispatch('close')} />
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center">
<p class="ml-2">Show & hide people</p> <p class="ml-2">Show & hide people</p>
<p class="text-sm text-gray-400 dark:text-gray-600">({countTotalPeople.toLocaleString($locale)})</p> <p class="text-sm text-gray-400 dark:text-gray-600">({countTotalPeople.toLocaleString($locale)})</p>

View File

@ -96,7 +96,7 @@
class="relative max-h-screen w-[500px] max-w-[95vw] overflow-y-auto rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg" class="relative max-h-screen w-[500px] max-w-[95vw] overflow-y-auto rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
> >
<div class="absolute top-0 right-0 px-2 py-2 h-fit"> <div class="absolute top-0 right-0 px-2 py-2 h-fit">
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton title="Close" icon={mdiClose} on:click={() => dispatch('close')} />
</div> </div>
<div <div

View File

@ -108,7 +108,12 @@
{#if canGoForward} {#if canGoForward}
<div class="flex place-content-center place-items-center gap-2 overflow-hidden"> <div class="flex place-content-center place-items-center gap-2 overflow-hidden">
<CircleIconButton icon={paused ? mdiPlay : mdiPause} forceDark on:click={() => (paused = !paused)} /> <CircleIconButton
title={paused ? 'Play memories' : 'Pause memories'}
icon={paused ? mdiPlay : mdiPause}
forceDark
on:click={() => (paused = !paused)}
/>
{#each currentMemory.assets as _, index} {#each currentMemory.assets as _, index}
<button <button
@ -144,7 +149,7 @@
class:opacity-100={galleryInView} class:opacity-100={galleryInView}
> >
<button on:click={() => memoryWrapper.scrollIntoView({ behavior: 'smooth' })} disabled={!galleryInView}> <button on:click={() => memoryWrapper.scrollIntoView({ behavior: 'smooth' })} disabled={!galleryInView}>
<CircleIconButton icon={mdiChevronUp} backgroundColor="white" forceDark /> <CircleIconButton title="Hide gallery" icon={mdiChevronUp} backgroundColor="white" forceDark />
</button> </button>
</div> </div>
{/if} {/if}
@ -204,13 +209,23 @@
<!-- CONTROL BUTTONS --> <!-- CONTROL BUTTONS -->
{#if canGoBack} {#if canGoBack}
<div class="absolute top-1/2 left-0 ml-4"> <div class="absolute top-1/2 left-0 ml-4">
<CircleIconButton icon={mdiChevronLeft} backgroundColor="#202123" on:click={toPrevious} /> <CircleIconButton
title="Previous memory"
icon={mdiChevronLeft}
backgroundColor="#202123"
on:click={toPrevious}
/>
</div> </div>
{/if} {/if}
{#if canGoForward} {#if canGoForward}
<div class="absolute top-1/2 right-0 mr-4"> <div class="absolute top-1/2 right-0 mr-4">
<CircleIconButton icon={mdiChevronRight} backgroundColor="#202123" on:click={toNext} /> <CircleIconButton
title="Next memory"
icon={mdiChevronRight}
backgroundColor="#202123"
on:click={toNext}
/>
</div> </div>
{/if} {/if}
@ -271,7 +286,7 @@
class:opacity-100={!galleryInView} class:opacity-100={!galleryInView}
> >
<button on:click={() => memoryGallery.scrollIntoView({ behavior: 'smooth' })}> <button on:click={() => memoryGallery.scrollIntoView({ behavior: 'smooth' })}>
<CircleIconButton icon={mdiChevronDown} backgroundColor="white" forceDark /> <CircleIconButton title="Show gallery" icon={mdiChevronDown} backgroundColor="white" forceDark />
</button> </button>
</div> </div>

View File

@ -56,7 +56,7 @@
</slot> </slot>
</div> </div>
<CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} /> <CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} title="Close" />
</div> </div>
<div> <div>

View File

@ -14,7 +14,7 @@
{#if text} {#if text}
{#if icon} {#if icon}
<p class="flex gap-2"> <p class="flex gap-2">
<Icon path={icon} size="18" /> <Icon path={icon} ariaHidden={true} size="18" />
{text} {text}
</p> </p>
{:else} {:else}

View File

@ -58,6 +58,7 @@
<div class="flex place-items-center gap-6 justify-self-start dark:text-immich-dark-fg"> <div class="flex place-items-center gap-6 justify-self-start dark:text-immich-dark-fg">
{#if showBackButton} {#if showBackButton}
<CircleIconButton <CircleIconButton
title="Close"
on:click={handleClose} on:click={handleClose}
icon={backIcon} icon={backIcon}
backgroundColor={'transparent'} backgroundColor={'transparent'}

View File

@ -25,14 +25,14 @@
SELECT AVATAR COLOR SELECT AVATAR COLOR
</h1> </h1>
<div> <div>
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton icon={mdiClose} title="Close" on:click={() => dispatch('close')} />
</div> </div>
</div> </div>
<div class="flex items-center justify-center p-4 mt-4"> <div class="flex items-center justify-center p-4 mt-4">
<div class="grid grid-cols-2 md:grid-cols-5 gap-4"> <div class="grid grid-cols-2 md:grid-cols-5 gap-4">
{#each colors as color} {#each colors as color}
<button on:click={() => dispatch('choose', color)}> <button on:click={() => dispatch('choose', color)}>
<UserAvatar {user} {color} size="xl" showProfileImage={false} /> <UserAvatar label={color} {user} {color} size="xl" showProfileImage={false} />
</button> </button>
{/each} {/each}
</div> </div>

View File

@ -44,7 +44,7 @@
<div class="relative px-4 pt-4"> <div class="relative px-4 pt-4">
<h1 class="px-4 py-4 font-medium text-immich-primary dark:text-immich-dark-primary">Keyboard Shortcuts</h1> <h1 class="px-4 py-4 font-medium text-immich-primary dark:text-immich-dark-primary">Keyboard Shortcuts</h1>
<div class="absolute inset-y-0 right-0 px-4 py-4"> <div class="absolute inset-y-0 right-0 px-4 py-4">
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} /> <CircleIconButton title="Close" icon={mdiClose} on:click={() => dispatch('close')} />
</div> </div>
</div> </div>

View File

@ -22,6 +22,7 @@
export let interactive = false; export let interactive = false;
export let showTitle = true; export let showTitle = true;
export let showProfileImage = true; export let showProfileImage = true;
export let label: string | undefined = undefined;
let img: HTMLImageElement; let img: HTMLImageElement;
let showFallback = true; let showFallback = true;
@ -61,7 +62,7 @@
$: colorClass = colorClasses[color]; $: colorClass = colorClasses[color];
$: sizeClass = sizeClasses[size]; $: sizeClass = sizeClasses[size];
$: title = `${user.name} (${user.email})`; $: title = label ?? `${user.name} (${user.email})`;
$: interactiveClass = interactive $: interactiveClass = interactive
? 'border-2 border-immich-primary hover:border-immich-dark-primary dark:hover:border-immich-primary dark:border-immich-dark-primary transition-colors' ? 'border-2 border-immich-primary hover:border-immich-dark-primary dark:hover:border-immich-primary dark:border-immich-dark-primary transition-colors'
: ''; : '';

View File

@ -168,9 +168,9 @@
<div class="flex flex-auto flex-col place-content-center place-items-end text-right"> <div class="flex flex-auto flex-col place-content-center place-items-end text-right">
<div class="flex"> <div class="flex">
<CircleIconButton icon={mdiDelete} on:click={() => dispatch('delete')} /> <CircleIconButton title="Delete link" icon={mdiDelete} on:click={() => dispatch('delete')} />
<CircleIconButton icon={mdiCircleEditOutline} on:click={() => dispatch('edit')} /> <CircleIconButton title="Edit link" icon={mdiCircleEditOutline} on:click={() => dispatch('edit')} />
<CircleIconButton icon={mdiContentCopy} on:click={() => dispatch('copy')} /> <CircleIconButton title="Copy link" icon={mdiContentCopy} on:click={() => dispatch('copy')} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -545,6 +545,7 @@
<!-- link --> <!-- link -->
{#if album.hasSharedLink && isOwned} {#if album.hasSharedLink && isOwned}
<CircleIconButton <CircleIconButton
title="Create link to share "
backgroundColor="#d3d3d3" backgroundColor="#d3d3d3"
forceDark forceDark
size="20" size="20"

View File

@ -266,7 +266,7 @@
title={orphan.pathValue} title={orphan.pathValue}
> >
<td on:click={() => copyToClipboard(orphan.pathValue)}> <td on:click={() => copyToClipboard(orphan.pathValue)}>
<CircleIconButton icon={mdiContentCopy} size="18" /> <CircleIconButton title="Copy file path" icon={mdiContentCopy} size="18" />
</td> </td>
<td class="truncate text-sm font-mono text-left" title={orphan.pathValue}> <td class="truncate text-sm font-mono text-left" title={orphan.pathValue}>
{orphan.pathValue} {orphan.pathValue}
@ -306,7 +306,7 @@
title={extra.filename} title={extra.filename}
> >
<td on:click={() => copyToClipboard(extra.filename)}> <td on:click={() => copyToClipboard(extra.filename)}>
<CircleIconButton icon={mdiContentCopy} size="18" /> <CircleIconButton title="Copy file path" icon={mdiContentCopy} size="18" />
</td> </td>
<td class="w-full text-md text-ellipsis flex justify-between pr-5"> <td class="w-full text-md text-ellipsis flex justify-between pr-5">
<span class="text-ellipsis grow truncate font-mono text-sm pr-5" title={extra.filename} <span class="text-ellipsis grow truncate font-mono text-sm pr-5" title={extra.filename}