当前位置: 首页 > backend >正文

源滚滚React消息通知框架v1.0.2使用教程

🎯 简介

yggjs_rtoast 是一个专为React应用打造的现代化消息通知组件库,具有以下特点:

✨ 核心特性

  • 🚀 零依赖:不依赖任何第三方库,包体积小
  • 💎 TypeScript支持:完整的类型定义,开发体验极佳
  • 🎨 高度可定制:支持自定义样式、动画、位置等
  • 📱 响应式设计:完美适配移动端和桌面端
  • 高性能:内置缓存机制和性能优化
  • 🌈 科技主题:内置酷炫的科技风格设计
  • 🛡️ 可靠稳定:100%测试覆盖率,生产就绪

🎪 支持的功能

  • 5种消息类型:success、error、warning、info、debug
  • 6种显示位置:顶部/底部 × 左中右
  • 4种动画效果:滑动、淡入、弹跳、缩放
  • 智能交互:自动关闭、手动关闭、悬停暂停
  • 无障碍支持:符合ARIA标准,屏幕阅读器友好

🚀 快速开始

安装

使用 npm:

npm install yggjs_rtoast

使用 yarn:

yarn add yggjs_rtoast

使用 pnpm:

pnpm add yggjs_rtoast

最简单的例子

只需要2行代码,即可在你的React应用中显示消息通知:

import { toast } from 'yggjs_rtoast/tech'// 显示一条成功消息
toast.success('操作成功!')

就是这么简单!🎉

📚 基础使用

1. 导入方式

// 方式一:导入全局toast实例(推荐)
import { toast } from 'yggjs_rtoast/tech'// 方式二:导入默认实例
import toast from 'yggjs_rtoast/tech'// 方式三:导入类型(TypeScript用户)
import { ToastType, ToastOptions } from 'yggjs_rtoast/tech'

2. 基本消息类型

import { toast } from 'yggjs_rtoast/tech'function MyComponent() {const handleClick = () => {// 成功消息(绿色)toast.success('保存成功!')// 错误消息(红色)toast.error('网络错误,请重试')// 警告消息(橙色)toast.warning('磁盘空间不足')// 信息消息(蓝色)toast.info('有新版本可用')// 调试消息(灰色)toast.debug('调试信息:API响应时间 125ms')}return (<button onClick={handleClick}>显示消息通知</button>)
}

3. 通用方法

除了类型化的方法,还可以使用通用的 toast() 方法:

import { toast } from 'yggjs_rtoast/tech'// 使用通用方法,手动指定类型
toast('自定义消息', { type: 'success' })
toast('这是一条信息', { type: 'info' })

4. 设置持续时间

import { toast } from 'yggjs_rtoast/tech'// 3秒后自动关闭
toast.success('3秒后消失', { duration: 3000 })// 永不自动关闭(需要手动关闭)
toast.info('需要手动关闭', { duration: 0 })// 使用预设的持续时间常量
import { SHORT_DURATION, MEDIUM_DURATION, LONG_DURATION } from 'yggjs_rtoast/tech'toast.success('短时间显示', { duration: SHORT_DURATION })  // 3秒
toast.info('中等时间显示', { duration: MEDIUM_DURATION })   // 5秒
toast.warning('长时间显示', { duration: LONG_DURATION })   // 8秒

5. 控制关闭按钮

import { toast } from 'yggjs_rtoast/tech'// 显示关闭按钮(默认)
toast.success('可以手动关闭')// 不显示关闭按钮
toast.info('不能手动关闭', { closable: false })

项目实战

package.json

{"name": "yggjs-rtoast-example","version": "1.0.0","private": true,"description": "Example application for yggjs_rtoast","scripts": {"dev": "vite","build": "tsc && vite build","preview": "vite preview"},"dependencies": {"react": "^18.2.0","react-dom": "^18.2.0","react-router-dom": "^6.20.1","yggjs_rtoast": "1.0.2"},"devDependencies": {"@types/react": "^18.2.37","@types/react-dom": "^18.2.15","@vitejs/plugin-react": "^4.1.1","typescript": "^5.2.2","vite": "^4.5.0"}
}

tsconfig.json

{"compilerOptions": {"target": "ES2020","lib": ["ES2020", "DOM", "DOM.Iterable"],"module": "ESNext","skipLibCheck": true,"allowSyntheticDefaultImports": true,"esModuleInterop": true,"resolveJsonModule": true,"isolatedModules": true,"noEmit": true,"jsx": "react-jsx","strict": true,"noUnusedLocals": true,"noUnusedParameters": true,"noFallthroughCasesInSwitch": true,"moduleResolution": "bundler"},"extends": "./tsconfig.paths.json","include": ["src/**/*"],"exclude": ["node_modules","dist"]
}

vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'const useLocalSrc = process.env.USE_LOCAL_SRC === '1'export default defineConfig({plugins: [react()],resolve: {alias: useLocalSrc? {'yggjs_rtoast': path.resolve(__dirname, '../src'),'yggjs_rtoast/tech': path.resolve(__dirname, '../src/tech'),}: {},},server: {port: 3000,open: true}
})

index.html

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8" /><link rel="icon" type="image/svg+xml" href="/vite.svg" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>YggJS RToast - 科技风消息通知组件</title><style>body {margin: 0;padding: 0;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background: linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%);color: #ffffff;min-height: 100vh;}</style></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body>
</html>

src/main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'ReactDOM.createRoot(document.getElementById('root')!).render(<React.StrictMode><App /></React.StrictMode>,
)

src/App.tsx

import React from 'react'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { toast } from 'yggjs_rtoast/tech'
import { HomePage } from './pages/HomePage'
import { ToastDemoPage } from './pages/ToastDemoPage'
import './styles/global.css'
import './styles/toast.css'function App() {// 可选:启动时来一条欢迎信息React.useEffect(() => {const timer = setTimeout(() => {toast.info('欢迎使用 YggJS RToast 科技风全局消息组件!', { duration: 2000 })}, 300)return () => clearTimeout(timer)}, [])return (<Router><div className="tech-container"><h1 className="tech-title">YggJS RToast</h1><p style={{ textAlign: 'center', marginBottom: '2rem', color: '#888' }}>专为React打造的科技风消息通知组件库</p><Routes><Route path="/" element={<HomePage />} /><Route path="/demo" element={<ToastDemoPage />} /></Routes></div></Router>)
}export default App

src/styles/global.css

/* 科技风全局样式 */
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;background: linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%);color: #ffffff;min-height: 100vh;overflow-x: hidden;
}/* 科技风容器 */
.tech-container {max-width: 1200px;margin: 0 auto;padding: 20px;
}/* 科技风卡片 */
.tech-card {background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);backdrop-filter: blur(10px);border: 1px solid rgba(255, 255, 255, 0.1);border-radius: 12px;padding: 24px;margin: 16px 0;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3),0 0 0 1px rgba(255, 255, 255, 0.05),inset 0 1px 0 rgba(255, 255, 255, 0.1);transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.tech-card:hover {transform: translateY(-4px);box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4),0 0 0 1px rgba(255, 255, 255, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}/* 科技风按钮 */
.tech-button {background: linear-gradient(135deg, rgba(59, 130, 246, 0.8) 0%, rgba(37, 99, 235, 0.8) 100%);border: 1px solid rgba(59, 130, 246, 0.3);color: #ffffff;padding: 12px 24px;border-radius: 8px;font-size: 14px;font-weight: 500;cursor: pointer;transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);text-decoration: none;display: inline-block;margin: 8px;box-shadow: 0 4px 16px rgba(59, 130, 246, 0.2),0 0 0 1px rgba(59, 130, 246, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.tech-button:hover {transform: translateY(-2px);box-shadow: 0 8px 24px rgba(59, 130, 246, 0.3),0 0 0 1px rgba(59, 130, 246, 0.2),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}.tech-button:active {transform: translateY(0);
}/* 成功按钮 */
.tech-button--success {background: linear-gradient(135deg, rgba(16, 185, 129, 0.8) 0%, rgba(5, 150, 105, 0.8) 100%);border-color: rgba(16, 185, 129, 0.3);box-shadow: 0 4px 16px rgba(16, 185, 129, 0.2),0 0 0 1px rgba(16, 185, 129, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.tech-button--success:hover {box-shadow: 0 8px 24px rgba(16, 185, 129, 0.3),0 0 0 1px rgba(16, 185, 129, 0.2),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}/* 错误按钮 */
.tech-button--error {background: linear-gradient(135deg, rgba(239, 68, 68, 0.8) 0%, rgba(220, 38, 38, 0.8) 100%);border-color: rgba(239, 68, 68, 0.3);box-shadow: 0 4px 16px rgba(239, 68, 68, 0.2),0 0 0 1px rgba(239, 68, 68, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.tech-button--error:hover {box-shadow: 0 8px 24px rgba(239, 68, 68, 0.3),0 0 0 1px rgba(239, 68, 68, 0.2),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}/* 警告按钮 */
.tech-button--warning {background: linear-gradient(135deg, rgba(245, 158, 11, 0.8) 0%, rgba(217, 119, 6, 0.8) 100%);border-color: rgba(245, 158, 11, 0.3);box-shadow: 0 4px 16px rgba(245, 158, 11, 0.2),0 0 0 1px rgba(245, 158, 11, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.tech-button--warning:hover {box-shadow: 0 8px 24px rgba(245, 158, 11, 0.3),0 0 0 1px rgba(245, 158, 11, 0.2),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}/* 科技风标题 */
.tech-title {font-size: 2.5rem;font-weight: 700;background: linear-gradient(135deg, #00d4ff 0%, #0099cc 50%, #0066ff 100%);-webkit-background-clip: text;-webkit-text-fill-color: transparent;background-clip: text;text-align: center;margin-bottom: 2rem;text-shadow: 0 0 20px rgba(0, 212, 255, 0.3);
}.tech-subtitle {font-size: 1.5rem;font-weight: 600;color: #00d4ff;margin-bottom: 1rem;text-shadow: 0 0 10px rgba(0, 212, 255, 0.3);
}/* 科技风导航 */
.tech-nav {display: flex;justify-content: center;gap: 16px;margin-bottom: 2rem;flex-wrap: wrap;
}.tech-nav-link {background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);border: 1px solid rgba(255, 255, 255, 0.1);color: #ffffff;padding: 12px 24px;border-radius: 8px;text-decoration: none;font-weight: 500;transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);backdrop-filter: blur(10px);
}.tech-nav-link:hover {background: linear-gradient(135deg, rgba(0, 212, 255, 0.2) 0%, rgba(0, 153, 204, 0.2) 100%);border-color: rgba(0, 212, 255, 0.3);transform: translateY(-2px);box-shadow: 0 8px 24px rgba(0, 212, 255, 0.2);
}.tech-nav-link.active {background: linear-gradient(135deg, rgba(0, 212, 255, 0.3) 0%, rgba(0, 153, 204, 0.3) 100%);border-color: rgba(0, 212, 255, 0.5);color: #00d4ff;
}/* 科技风网格 */
.tech-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 24px;margin: 2rem 0;
}/* 科技风代码块 */
.tech-code {background: rgba(0, 0, 0, 0.5);border: 1px solid rgba(255, 255, 255, 0.1);border-radius: 8px;padding: 16px;font-family: 'Courier New', monospace;font-size: 14px;color: #00ff88;overflow-x: auto;margin: 16px 0;
}/* 响应式设计 */
@media (max-width: 768px) {.tech-container {padding: 16px;}.tech-title {font-size: 2rem;}.tech-nav {flex-direction: column;align-items: center;}.tech-grid {grid-template-columns: 1fr;}
}

src/styles/toast.css

/* 科技风 Toast 样式 */
.ygg-toast-container {position: fixed !important;z-index: 9999 !important;pointer-events: none;display: flex;flex-direction: column;gap: 8px;padding: 16px;max-width: 420px;width: auto;min-width: 300px;
}/* 位置样式 */
.ygg-toast-container--top-left {top: 0;left: 0;
}.ygg-toast-container--top-center {top: 0;left: 50%;transform: translateX(-50%);
}.ygg-toast-container--top-right {top: 0;right: 0;
}.ygg-toast-container--bottom-left {bottom: 0;left: 0;
}.ygg-toast-container--bottom-center {bottom: 0;left: 50%;transform: translateX(-50%);
}.ygg-toast-container--bottom-right {bottom: 0;right: 0;
}/* Toast 基础样式 */
.ygg-toast {position: relative;pointer-events: auto;display: flex;align-items: center;gap: 12px;padding: 16px 20px;border-radius: 8px;backdrop-filter: blur(10px);background: rgba(30, 30, 30, 0.95);border: 1px solid rgba(255, 255, 255, 0.2);box-shadow:0 8px 32px rgba(0, 0, 0, 0.5),0 0 0 1px rgba(255, 255, 255, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.15);font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;font-size: 14px;line-height: 1.4;color: #ffffff;cursor: pointer;transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);overflow: hidden;min-width: 280px;
}.ygg-toast::before {content: '';position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);pointer-events: none;
}.ygg-toast:hover {transform: translateY(-2px);box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4),0 0 0 1px rgba(255, 255, 255, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.15);
}/* Toast 类型样式 */
.ygg-toast--success {background: linear-gradient(135deg, rgba(16, 185, 129, 0.9) 0%, rgba(5, 150, 105, 0.9) 100%);border-color: rgba(16, 185, 129, 0.3);box-shadow: 0 8px 32px rgba(16, 185, 129, 0.2),0 0 0 1px rgba(16, 185, 129, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.ygg-toast--error {background: linear-gradient(135deg, rgba(239, 68, 68, 0.9) 0%, rgba(220, 38, 38, 0.9) 100%);border-color: rgba(239, 68, 68, 0.3);box-shadow: 0 8px 32px rgba(239, 68, 68, 0.2),0 0 0 1px rgba(239, 68, 68, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.ygg-toast--warning {background: linear-gradient(135deg, rgba(245, 158, 11, 0.9) 0%, rgba(217, 119, 6, 0.9) 100%);border-color: rgba(245, 158, 11, 0.3);box-shadow: 0 8px 32px rgba(245, 158, 11, 0.2),0 0 0 1px rgba(245, 158, 11, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}.ygg-toast--info {background: linear-gradient(135deg, rgba(59, 130, 246, 0.9) 0%, rgba(37, 99, 235, 0.9) 100%);border-color: rgba(59, 130, 246, 0.3);box-shadow: 0 8px 32px rgba(59, 130, 246, 0.2),0 0 0 1px rgba(59, 130, 246, 0.1),inset 0 1px 0 rgba(255, 255, 255, 0.1);
}/* 图标样式 */
.ygg-toast__icon {flex-shrink: 0;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;
}/* 消息内容样式 */
.ygg-toast__message {flex: 1;font-weight: 500;text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}/* 关闭按钮样式 */
.ygg-toast__close {flex-shrink: 0;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;background: rgba(255, 255, 255, 0.1);border: none;border-radius: 4px;color: rgba(255, 255, 255, 0.8);cursor: pointer;transition: all 0.2s ease;font-size: 16px;line-height: 1;
}.ygg-toast__close:hover {background: rgba(255, 255, 255, 0.2);color: #ffffff;transform: scale(1.1);
}/* 进度条样式 */
.ygg-toast__progress {position: absolute;bottom: 0;left: 0;height: 3px;background: linear-gradient(90deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%);border-radius: 0 0 8px 8px;transition: width linear;box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
}/* 动画样式 */
@keyframes ygg-toast-slide-in-right {from {transform: translateX(100%);opacity: 0;}to {transform: translateX(0);opacity: 1;}
}@keyframes ygg-toast-slide-out-right {from {transform: translateX(0);opacity: 1;}to {transform: translateX(100%);opacity: 0;}
}@keyframes ygg-toast-slide-in-left {from {transform: translateX(-100%);opacity: 0;}to {transform: translateX(0);opacity: 1;}
}@keyframes ygg-toast-slide-out-left {from {transform: translateX(0);opacity: 1;}to {transform: translateX(-100%);opacity: 0;}
}@keyframes ygg-toast-fade-in {from {opacity: 0;transform: scale(0.9);}to {opacity: 1;transform: scale(1);}
}@keyframes ygg-toast-fade-out {from {opacity: 1;transform: scale(1);}to {opacity: 0;transform: scale(0.9);}
}@keyframes ygg-toast-bounce-in {0% {opacity: 0;transform: scale(0.3);}50% {opacity: 1;transform: scale(1.05);}70% {transform: scale(0.9);}100% {opacity: 1;transform: scale(1);}
}@keyframes ygg-toast-zoom-in {from {opacity: 0;transform: scale(0.5);}to {opacity: 1;transform: scale(1);}
}/* 动画类 */
.ygg-toast--slide-enter {animation: ygg-toast-slide-in-right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.ygg-toast--slide-exit {animation: ygg-toast-slide-out-right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.ygg-toast--fade-enter {animation: ygg-toast-fade-in 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.ygg-toast--fade-exit {animation: ygg-toast-fade-out 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}.ygg-toast--bounce-enter {animation: ygg-toast-bounce-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}.ygg-toast--zoom-enter {animation: ygg-toast-zoom-in 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}/* 响应式设计 */
@media (max-width: 480px) {.ygg-toast-container {left: 8px !important;right: 8px !important;max-width: none;padding: 8px;}.ygg-toast-container--top-center,.ygg-toast-container--bottom-center {transform: none;}.ygg-toast {padding: 12px 16px;font-size: 13px;}
}

src/pages/HomePage.tsx

import { Link } from 'react-router-dom'export const HomePage: React.FC = () => {return (<div><div className="tech-card"><h2 className="tech-subtitle">欢迎使用 YggJS RToast</h2><p style={{ marginBottom: '1.5rem', lineHeight: '1.6' }}>YggJS RToast 是一个专为React应用设计的现代化消息通知组件库。它采用科技风格的视觉设计,提供丰富的功能和优秀的用户体验。</p><div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}><Link to="/demo" className="tech-button">🚀 开始体验</Link><Link to="/docs" className="tech-button">📚 查看文档</Link></div></div><div className="tech-card"><h2 className="tech-subtitle">快速导航</h2><div className="tech-grid"><ahref="/demo"target="_blank"rel="noopener noreferrer"className="tech-card"style={{ margin: 0, textDecoration: 'none', color: 'inherit', display: 'block' }}><h3 style={{ color: '#00d4ff', marginBottom: '0.5rem' }}>🚀 科技消息示例页</h3><p style={{ color: '#ccc', lineHeight: '1.5' }}>点击后在新标签打开,演示所有消息类型与功能</p></a></div></div></div>)
}

src/pages/ToastDemoPage.tsx

import React, { useEffect, useState } from 'react'
import { toast } from 'yggjs_rtoast/tech'
import type { ToastData } from 'yggjs_rtoast/tech'export const ToastDemoPage: React.FC = () => {const [toasts, setToasts] = useState<ToastData[]>([])const { success, error, warning, info } = toastconst [customMessage, setCustomMessage] = useState('这是一条自定义消息')const [duration, setDuration] = useState(4000)useEffect(() => {// 订阅全局 toast 变化,仅用于示例展示数量const unsubscribe = toast.subscribe((list) => setToasts([...list]))return unsubscribe}, [])const handleBasicToasts = () => {success('操作成功!数据已保存')setTimeout(() => error('网络连接失败,请检查网络设置'), 500)setTimeout(() => warning('磁盘空间不足,建议清理缓存'), 1000)setTimeout(() => info('系统将在5分钟后进行维护'), 1500)}const handleSimpleTest = () => {console.log('点击了测试按钮')const id = success('测试消息 - ' + new Date().toLocaleTimeString())console.log('创建了Toast,ID:', id)}const handleCustomToast = () => {toast.toast(customMessage, {type: 'info',duration: duration,closable: true,animation: 'bounce',pauseOnHover: true,})}const handlePersistentToast = () => {toast.toast('这是一个持久化消息,不会自动消失', {type: 'warning',duration: 0,closable: true,})}const handleCustomIcon = () => {success('自定义图标消息', {icon: <span style={{ fontSize: '20px' }}>🎉</span>,})}const handleLongMessage = () => {info('这是一条很长的消息内容,用来测试组件在处理长文本时的表现。消息内容可能包含多行文本,组件应该能够正确地显示和处理这些内容。',{ duration: 6000 })}const handleClickableToast = () => {toast.toast('点击这条消息查看详情', {type: 'info',onClick: () => {alert('您点击了消息!')},duration: 8000,})}const demoSections = [{title: '基本类型',description: '展示四种基本的消息类型',action: handleBasicToasts,buttonText: '显示基本类型',buttonClass: 'tech-button',},{title: '自定义消息',description: '自定义消息内容和持续时间',action: handleCustomToast,buttonText: '显示自定义消息',buttonClass: 'tech-button',customControls: (<div style={{ marginTop: '16px' }}><div style={{ marginBottom: '12px' }}><label style={{ display: 'block', marginBottom: '4px', color: '#ccc' }}>消息内容:</label><inputtype="text"value={customMessage}onChange={(e) => setCustomMessage(e.target.value)}style={{width: '100%',padding: '8px 12px',background: 'rgba(255, 255, 255, 0.1)',border: '1px solid rgba(255, 255, 255, 0.2)',borderRadius: '4px',color: '#fff',fontSize: '14px',}}/></div><div><label style={{ display: 'block', marginBottom: '4px', color: '#ccc' }}>持续时间:{duration}ms</label><inputtype="range"min="1000"max="10000"step="500"value={duration}onChange={(e) => setDuration(Number(e.target.value))}style={{ width: '100%' }}/></div></div>),},{title: '持久化消息',description: '不会自动消失的消息,需要手动关闭',action: handlePersistentToast,buttonText: '显示持久化消息',buttonClass: 'tech-button--warning',},{title: '自定义图标',description: '使用自定义图标的消息',action: handleCustomIcon,buttonText: '显示自定义图标',buttonClass: 'tech-button--success',},{title: '长消息内容',description: '测试长文本内容的显示效果',action: handleLongMessage,buttonText: '显示长消息',buttonClass: 'tech-button',},{title: '可点击消息',description: '点击消息可以触发自定义事件',action: handleClickableToast,buttonText: '显示可点击消息',buttonClass: 'tech-button',},]return (<div><div className="tech-card"><h2 className="tech-subtitle">Toast 组件演示</h2><p style={{ marginBottom: '1.5rem', color: '#ccc', lineHeight: '1.6' }}>这里展示了 YggJS RToast 组件的各种功能和用法。点击下面的按钮来体验不同类型的消息通知。</p><div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', marginBottom: '1rem' }}><button className="tech-button tech-button--success" onClick={handleSimpleTest}>🧪 简单测试</button><button className="tech-button--error" onClick={() => toast.dismissAll()}>清除所有消息</button><div style={{ color: '#00d4ff', fontSize: '14px' }}>当前Toast数量: {toasts.length}</div></div>{/* 调试信息 */}{toasts.length > 0 && (<div className="tech-card" style={{ margin: '16px 0', background: 'rgba(0, 212, 255, 0.1)' }}><h4 style={{ color: '#00d4ff', marginBottom: '8px' }}>调试信息</h4><pre style={{ fontSize: '12px', color: '#ccc', overflow: 'auto' }}>{JSON.stringify(toasts.map(t => ({ id: t.id, type: t.type, message: t.message })), null, 2)}</pre></div>)}</div><div className="tech-grid">{demoSections.map((section, index) => (<div key={index} className="tech-card" style={{ margin: 0 }}><h3 style={{ color: '#00d4ff', marginBottom: '0.5rem' }}>{section.title}</h3><p style={{ color: '#ccc', lineHeight: '1.5', marginBottom: '1rem' }}>{section.description}</p>{section.customControls}<buttonclassName={section.buttonClass}onClick={section.action}style={{ marginTop: section.customControls ? '16px' : '0' }}>{section.buttonText}</button></div>))}</div><div className="tech-card"><h2 className="tech-subtitle">使用提示</h2><ul style={{ color: '#ccc', lineHeight: '1.6', paddingLeft: '20px' }}><li>消息默认会在4秒后自动消失</li><li>鼠标悬停在消息上时会暂停自动消失计时</li><li>点击消息右上角的 × 按钮可以手动关闭</li><li>消息支持多种动画效果:滑入、淡入、弹跳、缩放</li><li>可以同时显示多条消息,支持堆叠显示</li><li>支持自定义图标、样式和点击事件</li></ul></div></div>)
}
http://www.xdnf.cn/news/18635.html

相关文章:

  • 《支付回调状态异常的溯源与架构级修复》
  • 【RAGFlow代码详解-3】核心服务
  • Linux驱动之DMA(三)
  • ubuntu中网卡的 IP 及网关配置设置为永久生效
  • Maxwell学习笔记
  • 8月精选!Windows 11 25H2 【版本号:26200.5733】
  • 从技术精英到“芯”途末路:一位工程师的沉沦与救赎
  • IC验证 APB 项目(二)——框架结构(总)
  • 项目编译 --- 基于cmake ninja编译 rtos项目
  • COSMIC智能化编写工具:革命性提升软件文档生成效率
  • 20.13 ChatGLM3 QLoRA微调实战:3步实现高效低资源训练
  • Shell Case 条件语句详解
  • 数据挖掘 4.8 评估泛化能力
  • k8s原理及操作
  • Go语言环境安装
  • Spring面试题及详细答案 125道(16-25) -- 核心概念与基础2
  • Jwt令牌设置介绍
  • c++基础知识入门
  • Https之(三)TLS双向认证
  • 打响“A+H”双重上市突围战,云天励飞实力如何?
  • 云原生俱乐部-RH294知识点归纳(3)
  • [滑动窗口]1493. 删掉一个元素以后全为 1 的最长子数组
  • 今天学习计算机网格技术的TCP,UDP以及OSPF
  • 【AI智能体】Dify 搭建业务单据差异核对助手实战详解
  • 【Spring Cloud 微服务】3.智能路由器——深入理解与配置负载均衡
  • 【数据结构】从基础到实战:全面解析归并排序与计数排序
  • 在 Docker 容器中查看 Python 版本
  • SpringBoot的学生学习笔记共享系统设计与实现
  • SO_REUSEADDR
  • 计算机视觉与自然语言处理技术体系概述