Some checks failed
CI / Backend (pull_request) Successful in 44s
CI / UI (pull_request) Successful in 25s
CI / UI (push) Successful in 27s
Release / Test backend (push) Successful in 42s
CI / Backend (push) Successful in 44s
Release / Check ui (push) Successful in 24s
Release / Docker / caddy (push) Failing after 1m4s
Release / Docker / backend (push) Failing after 44s
Release / Docker / ui (push) Failing after 29s
Release / Docker / runner (push) Failing after 54s
Release / Gitea Release (push) Has been skipped
- Add CSS custom property token system in app.css (@theme + [data-theme] overrides) - Three themes: amber (default), slate (indigo/dark), rose (dark pink) - Flash prevention via inline <script> in <svelte:head> sets data-theme before paint - Theme context (setContext/getContext) in +layout.svelte for live preview - Theme persisted via PocketBase user_settings (PBUserSettings.theme field) - /api/settings GET/PUT updated to handle theme field alongside existing settings - Profile page: new Appearance section with 3 colour-swatch theme picker - Full token migration across all 36 route/component files: zinc/amber hardcoded Tailwind classes → CSS var utilities (bg-(--color-surface), etc.) - UI primitives (Badge, Button, Card, Dialog, Separator, Textarea) migrated - accent-amber-400 replaced with inline style accent-color: var(--color-brand)
59 lines
1.9 KiB
Svelte
59 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import type { Snippet } from 'svelte';
|
|
import { cn } from '$lib/utils';
|
|
|
|
type Variant = 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link';
|
|
type Size = 'default' | 'sm' | 'lg' | 'icon';
|
|
|
|
interface Props {
|
|
variant?: Variant;
|
|
size?: Size;
|
|
disabled?: boolean;
|
|
type?: 'button' | 'submit' | 'reset';
|
|
class?: string;
|
|
onclick?: (e: MouseEvent) => void;
|
|
children?: Snippet;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
let {
|
|
variant = 'default',
|
|
size = 'default',
|
|
disabled = false,
|
|
type = 'button',
|
|
class: className = '',
|
|
onclick,
|
|
children,
|
|
...rest
|
|
}: Props = $props();
|
|
|
|
const base =
|
|
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-(--color-brand) focus-visible:ring-offset-2 focus-visible:ring-offset-(--color-surface) disabled:pointer-events-none disabled:opacity-50';
|
|
|
|
const variants: Record<Variant, string> = {
|
|
default: 'bg-(--color-brand) text-(--color-surface) hover:bg-(--color-brand-dim)',
|
|
secondary: 'bg-(--color-surface-3) text-(--color-text) hover:bg-(--color-border)',
|
|
outline: 'border border-(--color-border) bg-transparent text-(--color-muted) hover:bg-(--color-surface-2) hover:text-(--color-text)',
|
|
ghost: 'bg-transparent text-(--color-muted) hover:bg-(--color-surface-2) hover:text-(--color-text)',
|
|
destructive: 'bg-(--color-danger)/20 text-(--color-danger) hover:bg-(--color-danger)/30',
|
|
link: 'text-(--color-brand) underline-offset-4 hover:underline bg-transparent p-0 h-auto',
|
|
};
|
|
|
|
const sizes: Record<Size, string> = {
|
|
default: 'h-9 px-4 py-2',
|
|
sm: 'h-8 rounded-md px-3 text-xs',
|
|
lg: 'h-11 rounded-md px-8',
|
|
icon: 'h-9 w-9',
|
|
};
|
|
</script>
|
|
|
|
<button
|
|
{type}
|
|
{disabled}
|
|
class={cn(base, variants[variant], sizes[size], className)}
|
|
{onclick}
|
|
{...rest}
|
|
>
|
|
{@render children?.()}
|
|
</button>
|