mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
parent
7c2f7d6c51
commit
f55b3add80
242 changed files with 12794 additions and 13426 deletions
|
|
@ -1,26 +1,24 @@
|
|||
<script lang="ts" context="module">
|
||||
export type Color = 'primary' | 'secondary';
|
||||
export type Rounded = false | true | 'full';
|
||||
export type Color = 'primary' | 'secondary';
|
||||
export type Rounded = false | true | 'full';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let color: Color = 'primary';
|
||||
export let rounded: Rounded = true;
|
||||
export let color: Color = 'primary';
|
||||
export let rounded: Rounded = true;
|
||||
|
||||
const colorClasses: Record<Color, string> = {
|
||||
primary:
|
||||
'text-gray-100 dark:text-immich-dark-gray bg-immich-primary dark:bg-immich-dark-primary',
|
||||
secondary:
|
||||
'text-immich-dark-bg dark:text-immich-gray dark:bg-gray-600 bg-gray-300 dark:text-immich-gray'
|
||||
};
|
||||
const colorClasses: Record<Color, string> = {
|
||||
primary: 'text-gray-100 dark:text-immich-dark-gray bg-immich-primary dark:bg-immich-dark-primary',
|
||||
secondary: 'text-immich-dark-bg dark:text-immich-gray dark:bg-gray-600 bg-gray-300 dark:text-immich-gray',
|
||||
};
|
||||
</script>
|
||||
|
||||
<span
|
||||
class="inline-block h-min whitespace-nowrap px-4 pt-[0.55em] pb-[0.55em] text-center align-baseline text-xs leading-none {colorClasses[
|
||||
color
|
||||
]}"
|
||||
class:rounded-md={rounded === true}
|
||||
class:rounded-full={rounded === 'full'}
|
||||
class="inline-block h-min whitespace-nowrap px-4 pt-[0.55em] pb-[0.55em] text-center align-baseline text-xs leading-none {colorClasses[
|
||||
color
|
||||
]}"
|
||||
class:rounded-md={rounded === true}
|
||||
class:rounded-full={rounded === 'full'}
|
||||
>
|
||||
<slot />
|
||||
<slot />
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -1,73 +1,73 @@
|
|||
<script lang="ts" context="module">
|
||||
export type Type = 'button' | 'submit' | 'reset';
|
||||
export type Color =
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'transparent-primary'
|
||||
| 'light-red'
|
||||
| 'red'
|
||||
| 'green'
|
||||
| 'gray'
|
||||
| 'transparent-gray'
|
||||
| 'dark-gray'
|
||||
| 'overlay-primary';
|
||||
export type Size = 'icon' | 'link' | 'sm' | 'base' | 'lg';
|
||||
export type Rounded = 'lg' | '3xl' | 'full' | false;
|
||||
export type Shadow = 'md' | false;
|
||||
export type Type = 'button' | 'submit' | 'reset';
|
||||
export type Color =
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'transparent-primary'
|
||||
| 'light-red'
|
||||
| 'red'
|
||||
| 'green'
|
||||
| 'gray'
|
||||
| 'transparent-gray'
|
||||
| 'dark-gray'
|
||||
| 'overlay-primary';
|
||||
export type Size = 'icon' | 'link' | 'sm' | 'base' | 'lg';
|
||||
export type Rounded = 'lg' | '3xl' | 'full' | false;
|
||||
export type Shadow = 'md' | false;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let type: Type = 'button';
|
||||
export let color: Color = 'primary';
|
||||
export let size: Size = 'base';
|
||||
export let rounded: Rounded = '3xl';
|
||||
export let shadow: Shadow = 'md';
|
||||
export let disabled = false;
|
||||
export let fullwidth = false;
|
||||
export let border = false;
|
||||
export let title: string | undefined = '';
|
||||
export let type: Type = 'button';
|
||||
export let color: Color = 'primary';
|
||||
export let size: Size = 'base';
|
||||
export let rounded: Rounded = '3xl';
|
||||
export let shadow: Shadow = 'md';
|
||||
export let disabled = false;
|
||||
export let fullwidth = false;
|
||||
export let border = false;
|
||||
export let title: string | undefined = '';
|
||||
|
||||
const colorClasses: Record<Color, string> = {
|
||||
primary:
|
||||
'bg-immich-primary dark:bg-immich-dark-primary text-white dark:text-immich-dark-gray enabled:dark:hover:bg-immich-dark-primary/80 enabled:hover:bg-immich-primary/90',
|
||||
secondary:
|
||||
'bg-gray-500 dark:bg-gray-200 text-white dark:text-immich-dark-gray enabled:hover:bg-gray-500/90 enabled:dark:hover:bg-gray-200/90',
|
||||
'transparent-primary':
|
||||
'text-gray-500 dark:text-immich-dark-primary enabled:hover:bg-gray-100 enabled:dark:hover:bg-gray-700',
|
||||
'light-red': 'bg-[#F9DEDC] text-[#410E0B] enabled:hover:bg-red-50',
|
||||
red: 'bg-red-500 text-white enabled:hover:bg-red-400',
|
||||
green: 'bg-lime-600 text-white enabled:hover:bg-lime-500',
|
||||
gray: 'bg-gray-500 dark:bg-gray-200 enabled:hover:bg-gray-500/75 enabled:dark:hover:bg-gray-200/80 text-white dark:text-immich-dark-gray',
|
||||
'transparent-gray':
|
||||
'dark:text-immich-dark-fg enabled:hover:bg-immich-primary/5 enabled:hover:text-gray-700 enabled:hover:dark:text-immich-dark-fg enabled:dark:hover:bg-immich-dark-primary/25',
|
||||
'dark-gray':
|
||||
'dark:border-immich-dark-gray dark:bg-gray-500 enabled:dark:hover:bg-immich-dark-primary/50 enabled:hover:bg-immich-primary/10 dark:text-white',
|
||||
'overlay-primary': 'text-gray-500 enabled:hover:bg-gray-100'
|
||||
};
|
||||
const colorClasses: Record<Color, string> = {
|
||||
primary:
|
||||
'bg-immich-primary dark:bg-immich-dark-primary text-white dark:text-immich-dark-gray enabled:dark:hover:bg-immich-dark-primary/80 enabled:hover:bg-immich-primary/90',
|
||||
secondary:
|
||||
'bg-gray-500 dark:bg-gray-200 text-white dark:text-immich-dark-gray enabled:hover:bg-gray-500/90 enabled:dark:hover:bg-gray-200/90',
|
||||
'transparent-primary':
|
||||
'text-gray-500 dark:text-immich-dark-primary enabled:hover:bg-gray-100 enabled:dark:hover:bg-gray-700',
|
||||
'light-red': 'bg-[#F9DEDC] text-[#410E0B] enabled:hover:bg-red-50',
|
||||
red: 'bg-red-500 text-white enabled:hover:bg-red-400',
|
||||
green: 'bg-lime-600 text-white enabled:hover:bg-lime-500',
|
||||
gray: 'bg-gray-500 dark:bg-gray-200 enabled:hover:bg-gray-500/75 enabled:dark:hover:bg-gray-200/80 text-white dark:text-immich-dark-gray',
|
||||
'transparent-gray':
|
||||
'dark:text-immich-dark-fg enabled:hover:bg-immich-primary/5 enabled:hover:text-gray-700 enabled:hover:dark:text-immich-dark-fg enabled:dark:hover:bg-immich-dark-primary/25',
|
||||
'dark-gray':
|
||||
'dark:border-immich-dark-gray dark:bg-gray-500 enabled:dark:hover:bg-immich-dark-primary/50 enabled:hover:bg-immich-primary/10 dark:text-white',
|
||||
'overlay-primary': 'text-gray-500 enabled:hover:bg-gray-100',
|
||||
};
|
||||
|
||||
const sizeClasses: Record<Size, string> = {
|
||||
icon: 'p-2.5',
|
||||
link: 'p-2 font-medium',
|
||||
sm: 'px-4 py-2 text-sm font-medium',
|
||||
base: 'px-6 py-3 font-medium',
|
||||
lg: 'px-6 py-4 font-semibold'
|
||||
};
|
||||
const sizeClasses: Record<Size, string> = {
|
||||
icon: 'p-2.5',
|
||||
link: 'p-2 font-medium',
|
||||
sm: 'px-4 py-2 text-sm font-medium',
|
||||
base: 'px-6 py-3 font-medium',
|
||||
lg: 'px-6 py-4 font-semibold',
|
||||
};
|
||||
</script>
|
||||
|
||||
<button
|
||||
{type}
|
||||
{disabled}
|
||||
{title}
|
||||
on:click
|
||||
class="inline-flex justify-center items-center transition-colors disabled:cursor-not-allowed disabled:opacity-60 {colorClasses[
|
||||
color
|
||||
]} {sizeClasses[size]}"
|
||||
class:rounded-lg={rounded === 'lg'}
|
||||
class:rounded-3xl={rounded === '3xl'}
|
||||
class:rounded-full={rounded === 'full'}
|
||||
class:shadow-md={shadow === 'md'}
|
||||
class:w-full={fullwidth}
|
||||
class:border
|
||||
{type}
|
||||
{disabled}
|
||||
{title}
|
||||
on:click
|
||||
class="inline-flex justify-center items-center transition-colors disabled:cursor-not-allowed disabled:opacity-60 {colorClasses[
|
||||
color
|
||||
]} {sizeClasses[size]}"
|
||||
class:rounded-lg={rounded === 'lg'}
|
||||
class:rounded-3xl={rounded === '3xl'}
|
||||
class:rounded-full={rounded === 'full'}
|
||||
class:shadow-md={shadow === 'md'}
|
||||
class:w-full={fullwidth}
|
||||
class:border
|
||||
>
|
||||
<slot />
|
||||
<slot />
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,37 +1,37 @@
|
|||
<script lang="ts">
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
import type Icon from 'svelte-material-icons/AbTesting.svelte';
|
||||
|
||||
export let logo: typeof Icon;
|
||||
export let backgroundColor = 'transparent';
|
||||
export let hoverColor = '#e2e7e9';
|
||||
export let size = '24';
|
||||
export let title = '';
|
||||
export let isOpacity = false;
|
||||
export let forceDark = false;
|
||||
export let hideMobile = false;
|
||||
export let logo: typeof Icon;
|
||||
export let backgroundColor = 'transparent';
|
||||
export let hoverColor = '#e2e7e9';
|
||||
export let size = '24';
|
||||
export let title = '';
|
||||
export let isOpacity = false;
|
||||
export let forceDark = false;
|
||||
export let hideMobile = false;
|
||||
</script>
|
||||
|
||||
<button
|
||||
{title}
|
||||
style:background-color={backgroundColor}
|
||||
style:--immich-icon-button-hover-color={hoverColor}
|
||||
class:dark:text-immich-dark-fg={!forceDark}
|
||||
class="rounded-full p-3 flex place-items-center place-content-center transition-all
|
||||
{title}
|
||||
style:background-color={backgroundColor}
|
||||
style:--immich-icon-button-hover-color={hoverColor}
|
||||
class:dark:text-immich-dark-fg={!forceDark}
|
||||
class="rounded-full p-3 flex place-items-center place-content-center 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'}"
|
||||
on:click
|
||||
on:click
|
||||
>
|
||||
<svelte:component this={logo} {size} />
|
||||
<slot />
|
||||
<svelte:component this={logo} {size} />
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--immich-icon-button-hover-color: #d3d3d3;
|
||||
}
|
||||
:root {
|
||||
--immich-icon-button-hover-color: #d3d3d3;
|
||||
}
|
||||
|
||||
.immich-circle-icon-button:hover {
|
||||
background-color: var(--immich-icon-button-hover-color) !important;
|
||||
}
|
||||
.immich-circle-icon-button:hover {
|
||||
background-color: var(--immich-icon-button-hover-color) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<script lang="ts" context="module">
|
||||
export type Color = 'transparent-primary' | 'transparent-gray' | 'overlay-primary';
|
||||
export type Color = 'transparent-primary' | 'transparent-gray' | 'overlay-primary';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import Button from './button.svelte';
|
||||
import Button from './button.svelte';
|
||||
|
||||
export let color: Color = 'transparent-primary';
|
||||
export let title: string | undefined = undefined;
|
||||
export let color: Color = 'transparent-primary';
|
||||
export let title: string | undefined = undefined;
|
||||
</script>
|
||||
|
||||
<Button size="icon" {color} {title} shadow={false} rounded="full" on:click>
|
||||
<slot />
|
||||
<slot />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<script lang="ts" context="module">
|
||||
export type Color = 'transparent-primary' | 'transparent-gray';
|
||||
export type Color = 'transparent-primary' | 'transparent-gray';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import Button from './button.svelte';
|
||||
import Button from './button.svelte';
|
||||
|
||||
export let color: Color = 'transparent-gray';
|
||||
export let color: Color = 'transparent-gray';
|
||||
</script>
|
||||
|
||||
<Button size="link" {color} shadow={false} rounded="lg" on:click>
|
||||
<slot />
|
||||
<slot />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,62 +1,60 @@
|
|||
<script lang="ts">
|
||||
import SwapVertical from 'svelte-material-icons/SwapVertical.svelte';
|
||||
import Check from 'svelte-material-icons/Check.svelte';
|
||||
import LinkButton from './buttons/link-button.svelte';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { fly } from 'svelte/transition';
|
||||
import SwapVertical from 'svelte-material-icons/SwapVertical.svelte';
|
||||
import Check from 'svelte-material-icons/Check.svelte';
|
||||
import LinkButton from './buttons/link-button.svelte';
|
||||
import { clickOutside } from '$lib/utils/click-outside';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
export let options: string[] = [];
|
||||
export let value = options[0];
|
||||
export let options: string[] = [];
|
||||
export let value = options[0];
|
||||
|
||||
let showMenu = false;
|
||||
let showMenu = false;
|
||||
|
||||
const handleClickOutside = () => {
|
||||
showMenu = false;
|
||||
};
|
||||
const handleClickOutside = () => {
|
||||
showMenu = false;
|
||||
};
|
||||
|
||||
const handleSelectOption = (index: number) => {
|
||||
value = options[index];
|
||||
showMenu = false;
|
||||
};
|
||||
const handleSelectOption = (index: number) => {
|
||||
value = options[index];
|
||||
showMenu = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<div id="dropdown-button" use:clickOutside on:outclick={handleClickOutside}>
|
||||
<!-- BUTTON TITLE -->
|
||||
<LinkButton on:click={() => (showMenu = true)}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<SwapVertical size="18" />
|
||||
{value}
|
||||
</div>
|
||||
</LinkButton>
|
||||
<!-- BUTTON TITLE -->
|
||||
<LinkButton on:click={() => (showMenu = true)}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<SwapVertical size="18" />
|
||||
{value}
|
||||
</div>
|
||||
</LinkButton>
|
||||
|
||||
<!-- DROP DOWN MENU -->
|
||||
{#if showMenu}
|
||||
<div
|
||||
transition:fly={{ y: -30, x: 30, duration: 200 }}
|
||||
class="absolute top-5 right-0 min-w-[250px] bg-gray-100 dark:bg-gray-700 rounded-2xl py-4 shadow-lg dark:text-white text-black z-50 text-md flex flex-col"
|
||||
>
|
||||
{#each options as option, index (option)}
|
||||
<button
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-4 transition-all grid grid-cols-[20px,1fr] place-items-center gap-2"
|
||||
on:click={() => handleSelectOption(index)}
|
||||
>
|
||||
{#if value == option}
|
||||
<div class="text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||
<Check size="18" />
|
||||
</div>
|
||||
<p
|
||||
class="justify-self-start text-immich-primary dark:text-immich-dark-primary font-medium"
|
||||
>
|
||||
{option}
|
||||
</p>
|
||||
{:else}
|
||||
<div />
|
||||
<p class="justify-self-start">
|
||||
{option}
|
||||
</p>
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<!-- DROP DOWN MENU -->
|
||||
{#if showMenu}
|
||||
<div
|
||||
transition:fly={{ y: -30, x: 30, duration: 200 }}
|
||||
class="absolute top-5 right-0 min-w-[250px] bg-gray-100 dark:bg-gray-700 rounded-2xl py-4 shadow-lg dark:text-white text-black z-50 text-md flex flex-col"
|
||||
>
|
||||
{#each options as option, index (option)}
|
||||
<button
|
||||
class="hover:bg-gray-300 dark:hover:bg-gray-800 p-4 transition-all grid grid-cols-[20px,1fr] place-items-center gap-2"
|
||||
on:click={() => handleSelectOption(index)}
|
||||
>
|
||||
{#if value == option}
|
||||
<div class="text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||
<Check size="18" />
|
||||
</div>
|
||||
<p class="justify-self-start text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||
{option}
|
||||
</p>
|
||||
{:else}
|
||||
<div />
|
||||
<p class="justify-self-start">
|
||||
{option}
|
||||
</p>
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue