feat(ui): 集成 shadcn/ui 原语、Framer Motion 动画和 Sonner Toast

- 添加 shadcn/ui 风格原语组件 (Button, Input, Dialog, Select, Slider, Switch, Tooltip)
- 集成 Framer Motion 动画库,添加动画预设
- 集成 Sonner Toast 通知系统
- 改造 ChatMessage 添加淡入动画和复制按钮
- 改造 Sidebar 添加动画、空状态引导和骨架屏
- 改造 ConfigPanel 使用新原语组件
- 优化 Chat 页面空状态和连接状态指示器
- 添加 tailwindcss-animate 插件
This commit is contained in:
2025-12-12 17:20:41 +08:00
parent 67c6918b28
commit cbbe9c7af1
26 changed files with 2272 additions and 514 deletions
+88
View File
@@ -0,0 +1,88 @@
import type { Variants, Transition } from 'framer-motion';
// 基础过渡配置
export const springTransition: Transition = {
type: 'spring',
stiffness: 400,
damping: 30,
};
export const smoothTransition: Transition = {
duration: 0.2,
ease: 'easeOut',
};
// 淡入上滑
export const fadeInUp: Variants = {
initial: { opacity: 0, y: 10 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -10 },
};
// 右滑入
export const slideInRight: Variants = {
initial: { opacity: 0, x: 20 },
animate: { opacity: 1, x: 0 },
exit: { opacity: 0, x: 20 },
};
// 左滑入
export const slideInLeft: Variants = {
initial: { opacity: 0, x: -20 },
animate: { opacity: 1, x: 0 },
exit: { opacity: 0, x: -20 },
};
// 缩放淡入
export const scaleIn: Variants = {
initial: { opacity: 0, scale: 0.95 },
animate: { opacity: 1, scale: 1 },
exit: { opacity: 0, scale: 0.95 },
};
// 列表项 stagger
export const staggerContainer: Variants = {
animate: {
transition: {
staggerChildren: 0.05,
},
},
};
export const staggerItem: Variants = {
initial: { opacity: 0, y: 10 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -10 },
};
// 弹性缩放(按钮点击)
export const tapScale = {
whileHover: { scale: 1.02 },
whileTap: { scale: 0.98 },
};
// 图标按钮弹性
export const iconButtonTap = {
whileHover: { scale: 1.1 },
whileTap: { scale: 0.9 },
};
// 侧边栏滑入
export const sidebarSlide: Variants = {
initial: { x: '-100%' },
animate: { x: 0 },
exit: { x: '-100%' },
};
// 弹窗
export const modalOverlay: Variants = {
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
};
export const modalContent: Variants = {
initial: { opacity: 0, scale: 0.95, y: -20 },
animate: { opacity: 1, scale: 1, y: 0 },
exit: { opacity: 0, scale: 0.95, y: -20 },
};
+6
View File
@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}