diff --git a/CLAUDE.md b/CLAUDE.md index 75b503b5..a951bdab 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -194,7 +194,8 @@ import { quickInsert } from '../../../services/canvas-operations'; ### UI 规范 -- **Tooltips**:始终使用 `theme='light'` +- **Tooltips**:始终使用 `theme='light'`,高层级容器内需显式设置更高 `zIndex` (如 20000) +- **状态表意**:优先使用量化组件(如信号格)而非单一颜色圆点来展示程度差异 - **按钮圆角**:8px - **卡片圆角**:12px - **动画时长**:150-300ms,ease-out 曲线 diff --git a/docs/CODING_RULES.md b/docs/CODING_RULES.md index 632b0d20..5ff43754 100644 --- a/docs/CODING_RULES.md +++ b/docs/CODING_RULES.md @@ -3936,6 +3936,63 @@ const matchesSource = !filters.activeSource || filters.activeSource === 'ALL' || ## UI 交互规范 +#### Tooltip 样式统一规范 + +**场景**: 在项目中使用 TDesign 的 `Tooltip` 组件时。 + +❌ **错误示例**: +```tsx + + ); @@ -258,6 +259,7 @@ export const ModelDropdown: React.FC = ({ }} >
+ = ({ @@ -111,6 +112,7 @@ export const CharacterSelector: React.FC = ({ key={character.id} content={character.sourcePrompt || `@${character.username}`} theme="light" + showArrow={false} >
= ({
+{completedCharacters.length - maxVisible} diff --git a/packages/drawnix/src/components/media-library/MediaLibraryGrid.tsx b/packages/drawnix/src/components/media-library/MediaLibraryGrid.tsx index 304a1d15..6acdbbfd 100644 --- a/packages/drawnix/src/components/media-library/MediaLibraryGrid.tsx +++ b/packages/drawnix/src/components/media-library/MediaLibraryGrid.tsx @@ -780,13 +780,13 @@ export function MediaLibraryGrid({ }; return ( - +
diff --git a/packages/drawnix/src/components/shared/ModelHealthBadge.tsx b/packages/drawnix/src/components/shared/ModelHealthBadge.tsx index db4a57ee..d89f814d 100644 --- a/packages/drawnix/src/components/shared/ModelHealthBadge.tsx +++ b/packages/drawnix/src/components/shared/ModelHealthBadge.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { Tooltip } from 'tdesign-react'; import { useModelHealth } from '../../hooks/useModelHealth'; import './model-health-badge.scss'; @@ -37,14 +38,53 @@ export const ModelHealthBadge: React.FC = ({ return null; } - const { statusLabel, statusColor } = status; + const { statusLabel, statusColor, errorRate } = status; + + // 计算信号格数 (0-3格) 和 颜色 + // errorRate 是 0-100 + let bars = 3; + let barColor = statusColor; + + if (errorRate > 80) { + bars = 1; + barColor = '#991B1B'; // 深红色 + } else if (errorRate > 50) { + bars = 1; + barColor = '#EF4444'; // 红色 + } else if (errorRate > 20) { + bars = 2; + barColor = '#C2410C'; // 深橙色 + } else if (errorRate >= 1) { + bars = 2; + barColor = '#F97316'; // 浅橙色 + } else { + bars = 3; + barColor = '#10B981'; // 绿色 (0 或 接近 0) + } return ( - + 0 ? `${statusLabel} (拥挤度:${errorRate}%)` : statusLabel} + theme="light" + placement="top" + showArrow={false} + zIndex={20000} + > +
+
= 1 ? 'active' : ''}`} + style={{ backgroundColor: bars >= 1 ? barColor : undefined }} + /> +
= 2 ? 'active' : ''}`} + style={{ backgroundColor: bars >= 2 ? barColor : undefined }} + /> +
= 3 ? 'active' : ''}`} + style={{ backgroundColor: bars >= 3 ? barColor : undefined }} + /> +
+ ); }; diff --git a/packages/drawnix/src/components/shared/media-preview/MediaViewport.tsx b/packages/drawnix/src/components/shared/media-preview/MediaViewport.tsx index ba7c27bd..86d7ff16 100644 --- a/packages/drawnix/src/components/shared/media-preview/MediaViewport.tsx +++ b/packages/drawnix/src/components/shared/media-preview/MediaViewport.tsx @@ -337,6 +337,7 @@ export const MediaViewport: React.FC = ({ content={toolbarOrientation === 'horizontal' ? '切换为垂直布局' : '切换为水平布局'} theme="light" placement="top" + showArrow={false} >
+ } + theme="light" + placement="bottom" + showArrow={false} + > [详情] )} diff --git a/packages/drawnix/src/components/ttd-dialog/shared/AspectRatioSelector.tsx b/packages/drawnix/src/components/ttd-dialog/shared/AspectRatioSelector.tsx index 5515943a..80c88550 100644 --- a/packages/drawnix/src/components/ttd-dialog/shared/AspectRatioSelector.tsx +++ b/packages/drawnix/src/components/ttd-dialog/shared/AspectRatioSelector.tsx @@ -74,12 +74,13 @@ export const AspectRatioSelector: React.FC = ({
{ASPECT_RATIO_OPTIONS.map((option) => ( - +
= ({ content={option.description} theme="light" placement="top" + showArrow={false} >