feat(ui): 添加基础 UI 组件

- Avatar: 用户头像组件,支持图片和文字头像
- Toggle: 开关切换组件,用于设置项
- AILogo: AI 助手 Logo 组件,品牌标识
This commit is contained in:
gaoziman 2025-12-17 22:53:52 +08:00
parent fefacff0d1
commit ee9dc67708
3 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,26 @@
'use client';
import { cn } from '@/lib/utils';
interface AILogoProps {
size?: number;
className?: string;
}
export function AILogo({ size = 48, className }: AILogoProps) {
return (
<svg
viewBox="0 0 48 48"
fill="none"
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
className={cn('text-[var(--color-primary)]', className)}
>
<path
d="M24 4L26.5 18.5L41 16L29.5 24L41 32L26.5 29.5L24 44L21.5 29.5L7 32L18.5 24L7 16L21.5 18.5L24 4Z"
fill="currentColor"
/>
</svg>
);
}

View File

@ -0,0 +1,31 @@
'use client';
import { cn } from '@/lib/utils';
interface AvatarProps {
name: string;
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export function Avatar({ name, size = 'md', className }: AvatarProps) {
const initial = name.charAt(0).toUpperCase();
const sizeClasses = {
sm: 'w-6 h-6 text-xs',
md: 'w-8 h-8 text-sm',
lg: 'w-10 h-10 text-base',
};
return (
<div
className={cn(
'flex items-center justify-center rounded-full bg-[var(--color-primary)] text-white font-semibold',
sizeClasses[size],
className
)}
>
{initial}
</div>
);
}

View File

@ -0,0 +1,32 @@
'use client';
import { cn } from '@/lib/utils';
interface ToggleProps {
checked: boolean;
onChange: (checked: boolean) => void;
className?: string;
}
export function Toggle({ checked, onChange, className }: ToggleProps) {
return (
<button
type="button"
role="switch"
aria-checked={checked}
onClick={() => onChange(!checked)}
className={cn(
'relative w-11 h-6 rounded-full transition-colors duration-150 ease-in-out',
checked ? 'bg-[var(--color-primary)]' : 'bg-[var(--color-border)]',
className
)}
>
<span
className={cn(
'absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow-sm transition-transform duration-150 ease-in-out',
checked && 'translate-x-5'
)}
/>
</button>
);
}