mirror of
https://github.com/immich-app/immich.git
synced 2024-11-24 08:52:28 +02:00
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:
parent
6f677b4fae
commit
fcc3b81745
@ -61,7 +61,7 @@
|
||||
<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>
|
||||
<div>
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
<CircleIconButton icon={mdiClose} title="Close" on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -97,6 +97,7 @@
|
||||
{#if isOwned}
|
||||
<div>
|
||||
<CircleIconButton
|
||||
title="Options"
|
||||
on:click={(event) => showContextMenu(event, user)}
|
||||
icon={mdiDotsVertical}
|
||||
backgroundColor="transparent"
|
||||
|
@ -305,7 +305,13 @@
|
||||
</div>
|
||||
{:else if message}
|
||||
<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>
|
||||
{/if}
|
||||
</form>
|
||||
|
@ -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"
|
||||
>
|
||||
<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 class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white">
|
||||
{#if showShareButton}
|
||||
|
@ -39,7 +39,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
{/each}
|
||||
|
@ -2,11 +2,11 @@
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let icon: string;
|
||||
export let title: string;
|
||||
export let backgroundColor = '';
|
||||
export let hoverColor = '#e2e7e9';
|
||||
export let padding = '3';
|
||||
export let size = '24';
|
||||
export let title = '';
|
||||
export let isOpacity = false;
|
||||
export let forceDark = false;
|
||||
export let hideMobile = false;
|
||||
@ -27,7 +27,7 @@
|
||||
{hideMobile && 'hidden sm:flex'}"
|
||||
on:click
|
||||
>
|
||||
<Icon path={icon} {size} color={iconColor} />
|
||||
<Icon path={icon} {size} ariaLabel={title} color={iconColor} />
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
|
@ -135,7 +135,12 @@
|
||||
</div>
|
||||
{#if selectedPeople.length === 1}
|
||||
<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>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -40,7 +40,7 @@
|
||||
Merge People - {title}
|
||||
</h1>
|
||||
<div class="p-2">
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
<CircleIconButton title="Close" icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -57,6 +57,7 @@
|
||||
</div>
|
||||
<div class="mx-0.5 flex md:mx-2">
|
||||
<CircleIconButton
|
||||
title="Swap merge direction"
|
||||
icon={mdiMerge}
|
||||
on:click={() => ([personMerge1, personMerge2] = [personMerge2, personMerge1])}
|
||||
/>
|
||||
|
@ -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"
|
||||
>
|
||||
<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">
|
||||
<p class="ml-2">Show & hide people</p>
|
||||
<p class="text-sm text-gray-400 dark:text-gray-600">({countTotalPeople.toLocaleString($locale)})</p>
|
||||
|
@ -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"
|
||||
>
|
||||
<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
|
||||
|
@ -108,7 +108,12 @@
|
||||
|
||||
{#if canGoForward}
|
||||
<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}
|
||||
<button
|
||||
@ -144,7 +149,7 @@
|
||||
class:opacity-100={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>
|
||||
</div>
|
||||
{/if}
|
||||
@ -204,13 +209,23 @@
|
||||
<!-- CONTROL BUTTONS -->
|
||||
{#if canGoBack}
|
||||
<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>
|
||||
{/if}
|
||||
|
||||
{#if canGoForward}
|
||||
<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>
|
||||
{/if}
|
||||
|
||||
@ -271,7 +286,7 @@
|
||||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<button on:click={() => memoryGallery.scrollIntoView({ behavior: 'smooth' })}>
|
||||
<CircleIconButton icon={mdiChevronDown} backgroundColor="white" forceDark />
|
||||
<CircleIconButton title="Show gallery" icon={mdiChevronDown} backgroundColor="white" forceDark />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} />
|
||||
<CircleIconButton on:click={() => dispatch('close')} icon={mdiClose} size={'20'} title="Close" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
{#if text}
|
||||
{#if icon}
|
||||
<p class="flex gap-2">
|
||||
<Icon path={icon} size="18" />
|
||||
<Icon path={icon} ariaHidden={true} size="18" />
|
||||
{text}
|
||||
</p>
|
||||
{:else}
|
||||
|
@ -58,6 +58,7 @@
|
||||
<div class="flex place-items-center gap-6 justify-self-start dark:text-immich-dark-fg">
|
||||
{#if showBackButton}
|
||||
<CircleIconButton
|
||||
title="Close"
|
||||
on:click={handleClose}
|
||||
icon={backIcon}
|
||||
backgroundColor={'transparent'}
|
||||
|
@ -25,14 +25,14 @@
|
||||
SELECT AVATAR COLOR
|
||||
</h1>
|
||||
<div>
|
||||
<CircleIconButton icon={mdiClose} on:click={() => dispatch('close')} />
|
||||
<CircleIconButton icon={mdiClose} title="Close" on:click={() => dispatch('close')} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center p-4 mt-4">
|
||||
<div class="grid grid-cols-2 md:grid-cols-5 gap-4">
|
||||
{#each colors as color}
|
||||
<button on:click={() => dispatch('choose', color)}>
|
||||
<UserAvatar {user} {color} size="xl" showProfileImage={false} />
|
||||
<UserAvatar label={color} {user} {color} size="xl" showProfileImage={false} />
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
export let interactive = false;
|
||||
export let showTitle = true;
|
||||
export let showProfileImage = true;
|
||||
export let label: string | undefined = undefined;
|
||||
|
||||
let img: HTMLImageElement;
|
||||
let showFallback = true;
|
||||
@ -61,7 +62,7 @@
|
||||
|
||||
$: colorClass = colorClasses[color];
|
||||
$: sizeClass = sizeClasses[size];
|
||||
$: title = `${user.name} (${user.email})`;
|
||||
$: title = label ?? `${user.name} (${user.email})`;
|
||||
$: interactiveClass = interactive
|
||||
? 'border-2 border-immich-primary hover:border-immich-dark-primary dark:hover:border-immich-primary dark:border-immich-dark-primary transition-colors'
|
||||
: '';
|
||||
|
@ -168,9 +168,9 @@
|
||||
|
||||
<div class="flex flex-auto flex-col place-content-center place-items-end text-right">
|
||||
<div class="flex">
|
||||
<CircleIconButton icon={mdiDelete} on:click={() => dispatch('delete')} />
|
||||
<CircleIconButton icon={mdiCircleEditOutline} on:click={() => dispatch('edit')} />
|
||||
<CircleIconButton icon={mdiContentCopy} on:click={() => dispatch('copy')} />
|
||||
<CircleIconButton title="Delete link" icon={mdiDelete} on:click={() => dispatch('delete')} />
|
||||
<CircleIconButton title="Edit link" icon={mdiCircleEditOutline} on:click={() => dispatch('edit')} />
|
||||
<CircleIconButton title="Copy link" icon={mdiContentCopy} on:click={() => dispatch('copy')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -545,6 +545,7 @@
|
||||
<!-- link -->
|
||||
{#if album.hasSharedLink && isOwned}
|
||||
<CircleIconButton
|
||||
title="Create link to share "
|
||||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
size="20"
|
||||
|
@ -266,7 +266,7 @@
|
||||
title={orphan.pathValue}
|
||||
>
|
||||
<td on:click={() => copyToClipboard(orphan.pathValue)}>
|
||||
<CircleIconButton icon={mdiContentCopy} size="18" />
|
||||
<CircleIconButton title="Copy file path" icon={mdiContentCopy} size="18" />
|
||||
</td>
|
||||
<td class="truncate text-sm font-mono text-left" title={orphan.pathValue}>
|
||||
{orphan.pathValue}
|
||||
@ -306,7 +306,7 @@
|
||||
title={extra.filename}
|
||||
>
|
||||
<td on:click={() => copyToClipboard(extra.filename)}>
|
||||
<CircleIconButton icon={mdiContentCopy} size="18" />
|
||||
<CircleIconButton title="Copy file path" icon={mdiContentCopy} size="18" />
|
||||
</td>
|
||||
<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}
|
||||
|
Loading…
Reference in New Issue
Block a user