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:
@@ -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 },
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Reference in New Issue
Block a user