mirror of
https://github.com/immich-app/immich.git
synced 2024-12-29 15:11:58 +00:00
feat(web): standardize CircleIconButton colors (#9127)
* feat(web): standardize CircleIconButton colors * fix: memory lane close button color
This commit is contained in:
parent
034c928d9e
commit
19aa97da02
9 changed files with 71 additions and 93 deletions
|
@ -122,8 +122,6 @@
|
|||
title="Options"
|
||||
on:click={(event) => showContextMenu(event, user)}
|
||||
icon={mdiDotsVertical}
|
||||
backgroundColor="transparent"
|
||||
hoverColor="#e2e7e9"
|
||||
size="20"
|
||||
/>
|
||||
|
||||
|
|
|
@ -308,13 +308,7 @@
|
|||
</div>
|
||||
{:else if message}
|
||||
<div class="flex items-end w-fit ml-0">
|
||||
<CircleIconButton
|
||||
title="Send message"
|
||||
size="15"
|
||||
icon={mdiSend}
|
||||
iconColor={'dark'}
|
||||
hoverColor={'rgb(173,203,250)'}
|
||||
/>
|
||||
<CircleIconButton title="Send message" size="15" icon={mdiSend} class="dark:text-immich-dark-gray" />
|
||||
</div>
|
||||
{/if}
|
||||
</form>
|
||||
|
|
|
@ -105,12 +105,12 @@
|
|||
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} title="Go back" on:click={() => dispatch('back')} />
|
||||
<CircleIconButton color="opaque" 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}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiShareVariantOutline}
|
||||
on:click={() => dispatch('showShareModal')}
|
||||
title="Share"
|
||||
|
@ -118,7 +118,7 @@
|
|||
{/if}
|
||||
{#if asset.isOffline}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiAlertOutline}
|
||||
on:click={() => dispatch('showDetail')}
|
||||
title="Asset Offline"
|
||||
|
@ -127,14 +127,14 @@
|
|||
{#if showMotionPlayButton}
|
||||
{#if isMotionPhotoPlaying}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiMotionPauseOutline}
|
||||
title="Stop Motion Photo"
|
||||
on:click={() => dispatch('stopMotionPhoto')}
|
||||
/>
|
||||
{:else}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiPlaySpeed}
|
||||
title="Play Motion Photo"
|
||||
on:click={() => dispatch('playMotionPhoto')}
|
||||
|
@ -143,7 +143,7 @@
|
|||
{/if}
|
||||
{#if showZoomButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
hideMobile={true}
|
||||
icon={$photoZoomState && $photoZoomState.currentZoom > 1 ? mdiMagnifyMinusOutline : mdiMagnifyPlusOutline}
|
||||
title="Zoom Image"
|
||||
|
@ -155,7 +155,7 @@
|
|||
{/if}
|
||||
{#if showCopyButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiContentCopy}
|
||||
title="Copy Image"
|
||||
on:click={() => {
|
||||
|
@ -167,7 +167,7 @@
|
|||
|
||||
{#if !isOwner && showDownloadButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiFolderDownloadOutline}
|
||||
on:click={() => dispatch('download')}
|
||||
title="Download"
|
||||
|
@ -176,7 +176,7 @@
|
|||
|
||||
{#if showDetailButton}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={mdiInformationOutline}
|
||||
on:click={() => dispatch('showDetail')}
|
||||
title="Info"
|
||||
|
@ -185,7 +185,7 @@
|
|||
|
||||
{#if isOwner}
|
||||
<CircleIconButton
|
||||
isOpacity={true}
|
||||
color="opaque"
|
||||
icon={asset.isFavorite ? mdiHeart : mdiHeartOutline}
|
||||
on:click={() => dispatch('favorite')}
|
||||
title={asset.isFavorite ? 'Unfavorite' : 'Favorite'}
|
||||
|
@ -194,7 +194,7 @@
|
|||
|
||||
{#if isOwner}
|
||||
{#if !asset.isReadOnly || !asset.isExternal}
|
||||
<CircleIconButton isOpacity={true} icon={mdiDeleteOutline} on:click={() => dispatch('delete')} title="Delete" />
|
||||
<CircleIconButton color="opaque" icon={mdiDeleteOutline} on:click={() => dispatch('delete')} title="Delete" />
|
||||
{/if}
|
||||
<div
|
||||
use:clickOutside={{
|
||||
|
@ -202,7 +202,7 @@
|
|||
onEscape: () => (isShowAssetOptions = false),
|
||||
}}
|
||||
>
|
||||
<CircleIconButton isOpacity={true} icon={mdiDotsVertical} on:click={showOptionsMenu} title="More" />
|
||||
<CircleIconButton color="opaque" icon={mdiDotsVertical} on:click={showOptionsMenu} title="More" />
|
||||
{#if isShowAssetOptions}
|
||||
<ContextMenu {...contextMenuPosition} direction="left">
|
||||
{#if showSlideshow}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
on:click={() => abort(downloadKey, download)}
|
||||
size="20"
|
||||
icon={mdiClose}
|
||||
forceDark
|
||||
class="dark:text-immich-dark-gray"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
type Color = 'transparent' | 'light' | 'dark' | 'gray' | 'primary' | 'opaque';
|
||||
|
||||
export let icon: string;
|
||||
export let color: Color = 'transparent';
|
||||
export let title: string;
|
||||
export let backgroundColor = '';
|
||||
export let hoverColor = '#e2e7e9';
|
||||
export let padding = '3';
|
||||
export let size = '24';
|
||||
export let isOpacity = false;
|
||||
export let forceDark = false;
|
||||
export let hideMobile = false;
|
||||
export let iconColor = 'currentColor';
|
||||
export let buttonSize: string | undefined = undefined;
|
||||
|
||||
/**
|
||||
* Override the default styling of the button for specific use cases, such as the icon color.
|
||||
*/
|
||||
let className = '';
|
||||
export { className as class };
|
||||
|
||||
const colorClasses: Record<Color, string> = {
|
||||
transparent: 'bg-transparent hover:bg-[#d3d3d3] dark:text-immich-dark-fg',
|
||||
opaque: 'bg-transparent hover:bg-immich-bg/30 text-white hover:dark:text-white',
|
||||
light: 'bg-white hover:bg-[#d3d3d3]',
|
||||
dark: 'bg-[#202123] hover:bg-[#d3d3d3]',
|
||||
gray: 'bg-[#d3d3d3] hover:bg-[#e2e7e9] text-immich-dark-gray hover:text-black',
|
||||
primary:
|
||||
'bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 hover:dark:bg-immich-dark-primary/80 text-white dark:text-immich-dark-gray',
|
||||
};
|
||||
|
||||
$: colorClass = colorClasses[color];
|
||||
$: mobileClass = hideMobile ? 'hidden sm:flex' : '';
|
||||
</script>
|
||||
|
||||
<button
|
||||
{title}
|
||||
style:width={buttonSize ? buttonSize + 'px' : ''}
|
||||
style:height={buttonSize ? buttonSize + 'px' : ''}
|
||||
style:background-color={backgroundColor}
|
||||
style:--immich-icon-button-hover-color={hoverColor}
|
||||
class:dark:text-immich-dark-fg={!forceDark}
|
||||
class="flex place-content-center place-items-center rounded-full p-{padding} transition-all
|
||||
{isOpacity ? 'hover:bg-immich-bg/30' : 'immich-circle-icon-button hover:dark:text-immich-dark-gray'}
|
||||
{forceDark && 'hover:text-black'}
|
||||
{hideMobile && 'hidden sm:flex'}"
|
||||
class="flex place-content-center place-items-center rounded-full {colorClass} p-{padding} transition-all hover:dark:text-immich-dark-gray {className} {mobileClass}"
|
||||
on:click
|
||||
>
|
||||
<Icon path={icon} {size} ariaLabel={title} color={iconColor} />
|
||||
<Icon path={icon} {size} ariaLabel={title} color="currentColor" />
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--immich-icon-button-hover-color: #d3d3d3;
|
||||
}
|
||||
|
||||
.immich-circle-icon-button:hover {
|
||||
background-color: var(--immich-icon-button-hover-color) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -111,8 +111,8 @@
|
|||
<CircleIconButton
|
||||
title={paused ? 'Play memories' : 'Pause memories'}
|
||||
icon={paused ? mdiPlay : mdiPause}
|
||||
forceDark
|
||||
on:click={() => (paused = !paused)}
|
||||
class="hover:text-black"
|
||||
/>
|
||||
|
||||
{#each currentMemory.assets as _, index}
|
||||
|
@ -149,7 +149,7 @@
|
|||
class:opacity-100={galleryInView}
|
||||
>
|
||||
<button on:click={() => memoryWrapper.scrollIntoView({ behavior: 'smooth' })} disabled={!galleryInView}>
|
||||
<CircleIconButton title="Hide gallery" icon={mdiChevronUp} backgroundColor="white" forceDark />
|
||||
<CircleIconButton title="Hide gallery" icon={mdiChevronUp} color="light" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -209,23 +209,13 @@
|
|||
<!-- CONTROL BUTTONS -->
|
||||
{#if canGoBack}
|
||||
<div class="absolute top-1/2 left-0 ml-4">
|
||||
<CircleIconButton
|
||||
title="Previous memory"
|
||||
icon={mdiChevronLeft}
|
||||
backgroundColor="#202123"
|
||||
on:click={toPrevious}
|
||||
/>
|
||||
<CircleIconButton title="Previous memory" icon={mdiChevronLeft} color="dark" on:click={toPrevious} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if canGoForward}
|
||||
<div class="absolute top-1/2 right-0 mr-4">
|
||||
<CircleIconButton
|
||||
title="Next memory"
|
||||
icon={mdiChevronRight}
|
||||
backgroundColor="#202123"
|
||||
on:click={toNext}
|
||||
/>
|
||||
<CircleIconButton title="Next memory" icon={mdiChevronRight} color="dark" on:click={toNext} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -286,7 +276,7 @@
|
|||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<button on:click={() => memoryGallery.scrollIntoView({ behavior: 'smooth' })}>
|
||||
<CircleIconButton title="Show gallery" icon={mdiChevronDown} backgroundColor="white" forceDark />
|
||||
<CircleIconButton title="Show gallery" icon={mdiChevronDown} color="light" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
document.removeEventListener('scroll', onScroll);
|
||||
}
|
||||
});
|
||||
|
||||
$: buttonClass = forceDark ? 'hover:text-immich-dark-gray' : undefined;
|
||||
</script>
|
||||
|
||||
<div in:fly={{ y: 10, duration: 200 }} class="absolute top-0 w-full z-[100] bg-transparent">
|
||||
|
@ -57,15 +59,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'}
|
||||
hoverColor={'#e2e7e9'}
|
||||
size={'24'}
|
||||
forceDark
|
||||
/>
|
||||
<CircleIconButton title="Close" on:click={handleClose} icon={backIcon} size={'24'} class={buttonClass} />
|
||||
{/if}
|
||||
<slot name="leading" />
|
||||
</div>
|
||||
|
|
|
@ -570,9 +570,8 @@
|
|||
<!-- link -->
|
||||
{#if album.hasSharedLink && isOwned}
|
||||
<CircleIconButton
|
||||
title="Create link to share "
|
||||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
title="Create link to share"
|
||||
color="gray"
|
||||
size="20"
|
||||
icon={mdiLink}
|
||||
on:click={() => (viewMode = ViewMode.LINK_SHARING)}
|
||||
|
@ -595,8 +594,7 @@
|
|||
{#if albumHasViewers}
|
||||
<CircleIconButton
|
||||
title="View all users"
|
||||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
color="gray"
|
||||
size="20"
|
||||
icon={mdiDotsVertical}
|
||||
on:click={() => (viewMode = ViewMode.VIEW_USERS)}
|
||||
|
@ -605,8 +603,7 @@
|
|||
|
||||
{#if isOwned}
|
||||
<CircleIconButton
|
||||
backgroundColor="#d3d3d3"
|
||||
forceDark
|
||||
color="gray"
|
||||
size="20"
|
||||
icon={mdiPlus}
|
||||
on:click={() => (viewMode = ViewMode.SELECT_USERS)}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
import { DateTime } from 'luxon';
|
||||
import { onMount } from 'svelte';
|
||||
import type { PageData } from './$types';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
|
@ -221,31 +222,35 @@
|
|||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td class="w-4/12 lg:w-3/12 xl:w-2/12 text-ellipsis break-all text-sm">
|
||||
<td
|
||||
class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-4/12 lg:w-3/12 xl:w-2/12 text-ellipsis break-all text-sm"
|
||||
>
|
||||
{#if !immichUser.deletedAt}
|
||||
<button
|
||||
<CircleIconButton
|
||||
icon={mdiPencilOutline}
|
||||
title="Edit user"
|
||||
color="primary"
|
||||
size="16"
|
||||
on:click={() => editUserHandler(immichUser)}
|
||||
class="rounded-full bg-immich-primary p-2 sm:p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700 max-sm:mb-1"
|
||||
>
|
||||
<Icon path={mdiPencilOutline} size="16" />
|
||||
</button>
|
||||
/>
|
||||
{#if immichUser.id !== $user.id}
|
||||
<button
|
||||
<CircleIconButton
|
||||
icon={mdiTrashCanOutline}
|
||||
title="Delete user"
|
||||
color="primary"
|
||||
size="16"
|
||||
on:click={() => deleteUserHandler(immichUser)}
|
||||
class="rounded-full bg-immich-primary p-2 sm:p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
>
|
||||
<Icon path={mdiTrashCanOutline} size="16" />
|
||||
</button>
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if immichUser.deletedAt && immichUser.status === UserStatus.Deleted}
|
||||
<button
|
||||
<CircleIconButton
|
||||
icon={mdiDeleteRestore}
|
||||
title="Restore user - scheduled removal on {getDeleteDate(immichUser.deletedAt)}"
|
||||
color="primary"
|
||||
size="16"
|
||||
on:click={() => restoreUserHandler(immichUser)}
|
||||
class="rounded-full bg-immich-primary p-3 text-gray-100 transition-all duration-150 hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:text-gray-700"
|
||||
title="scheduled removal on {getDeleteDate(immichUser.deletedAt)}"
|
||||
>
|
||||
<Icon path={mdiDeleteRestore} size="16" />
|
||||
</button>
|
||||
/>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
Loading…
Reference in a new issue