feat: badge icons (#776)

feat: badges
This commit is contained in:
Jason Rasmussen
2026-09-03 10:24:53 -04:00
committed by GitHub
parent c8d29d4f7c
commit e609882b1c
5 changed files with 72 additions and 12 deletions
@@ -5,6 +5,8 @@
import closeExample from './CloseExample.svelte?raw';
import ColorExample from './ColorExample.svelte';
import colorExample from './ColorExample.svelte?raw';
import IconExample from './IconExample.svelte';
import iconExample from './IconExample.svelte?raw';
import ShapeExample from './ShapeExample.svelte';
import shapeExample from './ShapeExample.svelte?raw';
import SizeExample from './SizeExample.svelte';
@@ -17,6 +19,7 @@
{ title: 'Size', code: sizeExample, component: SizeExample },
{ title: 'Color', code: colorExample, component: ColorExample },
{ title: 'Shape', code: shapeExample, component: ShapeExample },
{ title: 'Icon', code: iconExample, component: IconExample },
{ title: 'Close', code: closeExample, component: CloseExample },
]}
/>
@@ -0,0 +1,31 @@
<script lang="ts">
import Closable from '$lib/components/Closable.svelte';
import { Badge, Stack, Text } from '@immich/ui';
import { mdiLightbulb, mdiLightningBolt } from '@mdi/js';
</script>
<Stack gap={4}>
<div>
<Text fontWeight="medium" class="mb-2">Leading</Text>
<Badge leadingIcon={mdiLightbulb}>Slow</Badge>
</div>
<div>
<Text fontWeight="medium" class="mb-2">Trailing</Text>
<Badge trailingIcon={mdiLightningBolt}>Fast</Badge>
</div>
<div>
<Text fontWeight="medium" class="mb-2">Leading & Trailing</Text>
<Badge leadingIcon={mdiLightbulb} trailingIcon={mdiLightningBolt}>Super-Fast</Badge>
</div>
<div>
<Text fontWeight="medium" class="mb-2">Closable</Text>
<Closable>
{#snippet child({ onClose })}
<Badge leadingIcon={mdiLightningBolt} trailingIcon={mdiLightbulb} {onClose}>Super-Fast</Badge>
{/snippet}
</Closable>
</div>
</Stack>
@@ -1,8 +1,9 @@
<script lang="ts">
import IconButton from '$lib/components/IconButton/IconButton.svelte';
import IconWrapper from '$lib/internal/IconWrapper.svelte';
import { t } from '$lib/services/translation.svelte.js';
import { styleVariants } from '$lib/styles.js';
import type { Color, Shape, Size, TranslationProps } from '$lib/types.js';
import type { Color, IconLike, Shape, Size, TranslationProps } from '$lib/types.js';
import { cleanClass } from '$lib/utilities/internal.js';
import { mdiClose } from '@mdi/js';
import type { Snippet } from 'svelte';
@@ -13,6 +14,8 @@
size?: Size;
color?: Color;
shape?: Shape;
leadingIcon?: IconLike;
trailingIcon?: IconLike;
class?: string;
translations?: TranslationProps<'close'>;
onClose?: () => void;
@@ -25,6 +28,8 @@
class: className,
color = 'primary',
shape = 'semi-round',
leadingIcon,
trailingIcon,
translations,
onClose,
close,
@@ -76,7 +81,14 @@
className,
)}
>
{#if leadingIcon}
<IconWrapper {size} icon={leadingIcon} />
{/if}
{@render children?.()}
{#if trailingIcon}
<IconWrapper {size} icon={trailingIcon} />
{/if}
{#if onClose}
<IconButton
icon={mdiClose}
+3 -11
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import Icon from '$lib/components/Icon/Icon.svelte';
import LoadingSpinner from '$lib/components/LoadingSpinner/LoadingSpinner.svelte';
import Tooltip from '$lib/components/Tooltip/Tooltip.svelte';
import IconWrapper from '$lib/internal/IconWrapper.svelte';
import { styleVariants } from '$lib/styles.js';
import type { ButtonProps, Size } from '$lib/types.js';
import { isExternalLink, resolveUrl } from '$lib/utilities/common.js';
@@ -127,25 +127,17 @@
className,
),
);
const iconSizes = {
tiny: 'h-4 w-4',
small: 'h-4 w-4',
medium: 'h-4 w-4',
large: 'h-6 w-6',
giant: 'h-8 w-8',
};
</script>
{#snippet content()}
{#if leadingIcon && !loading}
<div>
<Icon size="100%" class={iconSizes[size]} icon={leadingIcon} aria-hidden />
<IconWrapper {size} icon={leadingIcon} />
</div>
{/if}
{@render children?.()}
{#if trailingIcon}
<Icon size="100%" class={iconSizes[size]} icon={trailingIcon} aria-hidden />
<IconWrapper {size} icon={trailingIcon} />
{/if}
{/snippet}
@@ -0,0 +1,22 @@
<script lang="ts">
import Icon from '$lib/components/Icon/Icon.svelte';
import type { Size } from '$lib/types.js';
import type { IconLike } from '$lib/types.js';
type Props = {
icon: IconLike;
size?: Size;
};
const { icon, size = 'medium' }: Props = $props();
const iconSizes = {
tiny: 'h-4 w-4',
small: 'h-4 w-4',
medium: 'h-4 w-4',
large: 'h-6 w-6',
giant: 'h-8 w-8',
};
</script>
<Icon size="100%" class={iconSizes[size]} {icon} aria-hidden />