update: generalize button components

This commit is contained in:
rasmusq
2025-12-19 23:23:46 +01:00
parent 466704a23a
commit cb4539a982
4 changed files with 87 additions and 17 deletions

View File

@@ -1,5 +1,6 @@
<script lang="ts">
import { X, Pencil } from 'lucide-svelte';
import IconButton from './IconButton.svelte';
let {
color = $bindable(null),
@@ -39,14 +40,14 @@
<div class="flex items-center gap-2">
{#if color}
<button
type="button"
<IconButton
onclick={clearColor}
class="{buttonSize} flex items-center justify-center rounded-full border border-input hover:bg-accent transition-colors"
{color}
{size}
aria-label="Clear color"
>
<X class={iconSize} />
</button>
</IconButton>
{/if}
<label
class="{buttonSize} flex items-center justify-center rounded-full border border-input hover:opacity-90 transition-opacity cursor-pointer relative overflow-hidden"

View File

@@ -79,7 +79,14 @@
</script>
<div class="relative dropdown-menu">
<Button variant="outline" size="icon" onclick={toggleMenu} aria-label={ariaLabel}>
<Button
variant="outline"
size="icon"
onclick={toggleMenu}
aria-label={ariaLabel}
class={color ? 'hover-themed' : ''}
style={color ? `--hover-bg: ${color}20;` : ''}
>
{@render icon()}
</Button>
@@ -117,3 +124,9 @@
</div>
{/if}
</div>
<style>
:global(.hover-themed:hover) {
background-color: var(--hover-bg) !important;
}
</style>

View File

@@ -0,0 +1,52 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';
interface Props extends HTMLButtonAttributes {
color?: string | null;
rounded?: 'full' | 'md' | 'lg';
size?: 'sm' | 'md' | 'lg';
children: Snippet;
}
let {
color = null,
rounded = 'full',
size = 'md',
class: className = '',
children,
...restProps
}: Props = $props();
const sizeClasses = {
sm: 'w-8 h-8',
md: 'w-10 h-10',
lg: 'w-12 h-12'
};
const roundedClasses = {
full: 'rounded-full',
md: 'rounded-md',
lg: 'rounded-lg'
};
const baseClasses = 'flex items-center justify-center border border-input transition-colors';
const sizeClass = sizeClasses[size];
const roundedClass = roundedClasses[rounded];
</script>
<button
type="button"
class="{baseClasses} {sizeClass} {roundedClass} {className}"
class:hover:bg-accent={!color}
style={color ? `--hover-bg: ${color}20;` : ''}
{...restProps}
>
{@render children()}
</button>
<style>
button[style*='--hover-bg']:hover {
background-color: var(--hover-bg);
}
</style>

View File

@@ -6,6 +6,7 @@
import { Pencil, Check, X } from "lucide-svelte";
import ColorPicker from "$lib/components/ui/ColorPicker.svelte";
import ThemePicker from "$lib/components/ui/theme-picker.svelte";
import IconButton from "$lib/components/ui/IconButton.svelte";
import type { Wishlist } from "$lib/server/schema";
import { languageStore } from '$lib/stores/language.svelte';
import { getCardStyle } from '$lib/utils/colors';
@@ -100,8 +101,7 @@
{:else}
<h1 class="text-3xl font-bold leading-[2.25rem]">{wishlistTitle}</h1>
{/if}
<button
type="button"
<IconButton
onclick={() => {
if (editingTitle) {
saveTitle();
@@ -109,7 +109,9 @@
editingTitle = true;
}
}}
class="shrink-0 w-8 h-8 flex items-center justify-center rounded-full border border-input hover:bg-accent transition-colors"
color={wishlistColor}
size="sm"
class="shrink-0"
aria-label={editingTitle ? "Save title" : "Edit title"}
>
{#if editingTitle}
@@ -117,7 +119,7 @@
{:else}
<Pencil class="w-4 h-4" />
{/if}
</button>
</IconButton>
</div>
<div class="flex items-center gap-2 shrink-0">
<ThemePicker
@@ -145,8 +147,7 @@
<div class="space-y-2">
<div class="flex items-center justify-between gap-2">
<Label for="wishlist-description">{t.form.descriptionOptional}</Label>
<button
type="button"
<IconButton
onclick={() => {
if (editingDescription) {
saveDescription();
@@ -154,7 +155,9 @@
editingDescription = true;
}
}}
class="flex-shrink-0 w-8 h-8 flex items-center justify-center rounded-full border border-input hover:bg-accent transition-colors"
color={wishlistColor}
size="sm"
class="flex-shrink-0"
aria-label={editingDescription ? "Save description" : "Edit description"}
>
{#if editingDescription}
@@ -162,7 +165,7 @@
{:else}
<Pencil class="w-4 h-4" />
{/if}
</button>
</IconButton>
</div>
{#if editingDescription}
<Textarea
@@ -190,14 +193,15 @@
<Label for="wishlist-end-date">{t.form.endDateOptional}</Label>
<div class="flex items-center gap-2">
{#if wishlistEndDate}
<button
type="button"
<IconButton
onclick={clearEndDate}
class="flex-shrink-0 w-8 h-8 flex items-center justify-center rounded-full border border-input hover:bg-accent transition-colors"
color={wishlistColor}
size="sm"
class="flex-shrink-0"
aria-label="Clear end date"
>
<X class="w-4 h-4" />
</button>
</IconButton>
{/if}
<Input
id="wishlist-end-date"