diff --git a/components/CopyButton.tsx b/components/CopyButton.tsx index e03791d..7cc6bd9 100644 --- a/components/CopyButton.tsx +++ b/components/CopyButton.tsx @@ -73,15 +73,15 @@ export const CopyButton: React.FC = ({ const iconSize = size === 'small' ? 14 : size === 'medium' ? 16 : 18; const colorClasses: Record = { - primary: 'text-blue-600 hover:bg-blue-50', - secondary: 'text-gray-600 hover:bg-gray-50', - success: 'text-green-600 hover:bg-green-50', - error: 'text-red-600 hover:bg-red-50', - info: 'text-blue-600 hover:bg-blue-50', + primary: 'text-primary hover:bg-primary/10', + secondary: 'text-foreground hover:bg-muted', + success: 'text-green-600 hover:bg-green-500/10', + error: 'text-red-600 hover:bg-red-500/10', + info: 'text-primary hover:bg-primary/10', warning: 'text-amber-600 hover:bg-amber-50', }; - const colorClass = colorClasses[color] || `text-[${color}] hover:bg-gray-50`; + const colorClass = colorClasses[color] || `text-[${color}] hover:bg-muted`; return ( - {selectedFile.name} - {t('qrCode:clickToChange')} + {selectedFile.name} + {t('qrCode:clickToChange')} ) : ( <> - - {t('qrCode:clickToUpload')} - {t('qrCode:supportFormats')} + + + {t('qrCode:clickToUpload')} + + + {t('qrCode:supportFormats')} + )} diff --git a/components/PageErrorBoundary.tsx b/components/PageErrorBoundary.tsx index 143e88d..37c3fba 100644 --- a/components/PageErrorBoundary.tsx +++ b/components/PageErrorBoundary.tsx @@ -47,11 +47,11 @@ export class PageErrorBoundary extends Component {

该页面加载失败

-

+

页面在加载或渲染时遇到错误,您可以重试或切换到其他工具。

{this.state.error && ( -
+
                   {this.state.error.toString()}
                 
diff --git a/components/PageHeader.tsx b/components/PageHeader.tsx index 7a14865..61377ab 100644 --- a/components/PageHeader.tsx +++ b/components/PageHeader.tsx @@ -92,7 +92,7 @@ export default function PageHeader({
{/* 副标题 */} {subtitle && ( - + {subtitle} )} diff --git a/components/PageSkeleton.tsx b/components/PageSkeleton.tsx index 65c2239..55565e4 100644 --- a/components/PageSkeleton.tsx +++ b/components/PageSkeleton.tsx @@ -14,7 +14,7 @@ interface PageSkeletonProps { */ function DashboardCardSkeleton() { return ( -
+
diff --git a/components/QrCodePreview.tsx b/components/QrCodePreview.tsx index 5828dec..13e5d8f 100644 --- a/components/QrCodePreview.tsx +++ b/components/QrCodePreview.tsx @@ -15,21 +15,23 @@ const QrCodePreview = ({ qrCodeDataUrl, onDownload, onCopy }: QrCodePreviewProps if (!qrCodeDataUrl) { return ( -
- {t('qrCode:qrCodeWillShow')} +
+ + {t('qrCode:qrCodeWillShow')} +
); } return ( -
+
QR Code
@@ -413,7 +413,7 @@ const TextInputArea = forwardRef((props type="button" onClick={handleClear} title={t('textInputArea.clear')} - className="p-1 rounded-md text-gray-400 hover:text-red-600 hover:bg-red-50 transition-colors" + className="p-1 rounded-md text-muted-foreground hover:text-red-600 hover:bg-red-500/10 transition-colors" > diff --git a/components/TopBar.tsx b/components/TopBar.tsx index 3a502c7..e171182 100644 --- a/components/TopBar.tsx +++ b/components/TopBar.tsx @@ -156,27 +156,27 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) const isDashboard = currentPage === 'dashboard'; return ( -
+
{!isDashboard && ( )}
- + {t('common:appName')}
-
+
void }) onFocus={() => setShowResults(true)} onKeyDown={handleKeyDown} aria-label={t('common:buttons.search')} - className="w-full pl-9 pr-8 py-1.5 text-sm rounded-lg border border-transparent bg-gray-50 focus:bg-white focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 transition-all" + className="w-full pl-9 pr-8 py-1.5 text-sm rounded-lg border border-transparent bg-muted focus:bg-background focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all" /> {searchQuery && ( @@ -206,7 +206,7 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void })
{showResults && (searchQuery.trim() || displayedHistory.length > 0) && ( -
+
    {searchQuery.trim() ? ( searchResults.length > 0 ? ( @@ -217,17 +217,17 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) aria-selected={selectedIndex === index} onClick={() => handleSelectFeature(feature)} className={`flex items-center gap-3 px-3 py-2 cursor-pointer transition-colors ${ - selectedIndex === index ? 'bg-blue-50' : 'hover:bg-gray-50' + selectedIndex === index ? 'bg-primary/10' : 'hover:bg-muted' }`} > -
    +
    {feature.icon && }
    -

    +

    {t(feature.labelKey)}

    -

    +

    {t(feature.descriptionKey)}

    @@ -235,13 +235,13 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) )) ) : (
  • -

    {t('common:buttons.noResults')}

    +

    {t('common:buttons.noResults')}

  • ) ) : ( <>
  • - + {t('common:buttons.recentSearch')}
  • @@ -255,13 +255,13 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) setSelectedIndex(-1); }} className={`flex items-center gap-3 px-3 py-2 cursor-pointer transition-colors ${ - selectedIndex === index ? 'bg-blue-50' : 'hover:bg-gray-50' + selectedIndex === index ? 'bg-primary/10' : 'hover:bg-muted' }`} > -
    +
    - {item} + {item} ))} @@ -277,7 +277,7 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) onClick={toggleLanguage} aria-label={t('common:buttons.toggleLanguage')} title={t('common:buttons.toggleLanguage')} - className="p-1.5 rounded-md hover:bg-gray-100 transition-colors" + className="p-1.5 rounded-md hover:bg-accent transition-colors" > @@ -286,7 +286,7 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) onClick={cycleThemeMode} aria-label={t('common:buttons.toggleTheme')} title={t(`common:buttons.themeMode.${mode}`)} - className="p-1.5 rounded-md hover:bg-gray-100 transition-colors" + className="p-1.5 rounded-md hover:bg-accent transition-colors" > @@ -295,7 +295,7 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) onClick={handleOpenInTab} aria-label={t('common:buttons.openInTab')} title={t('common:buttons.openInTab')} - className="p-1.5 rounded-md hover:bg-gray-100 transition-colors" + className="p-1.5 rounded-md hover:bg-accent transition-colors" > @@ -304,7 +304,7 @@ export default function TopBar({ onOpenOptions }: { onOpenOptions: () => void }) onClick={onOpenOptions} aria-label={t('common:buttons.settings')} title={t('common:buttons.settings')} - className="p-1.5 rounded-md hover:bg-gray-100 transition-colors" + className="p-1.5 rounded-md hover:bg-accent transition-colors" > diff --git a/components/__tests__/PageHeader.test.tsx b/components/__tests__/PageHeader.test.tsx index 7f7b8ad..55fab2b 100644 --- a/components/__tests__/PageHeader.test.tsx +++ b/components/__tests__/PageHeader.test.tsx @@ -84,7 +84,7 @@ describe('PageHeader 组件系统', () => { it('无副标题时不渲染副标题区域', () => { const { container } = render(); - const subtitles = container.querySelectorAll('.text-gray-500'); + const subtitles = container.querySelectorAll('.text-muted-foreground'); expect(subtitles.length).toBe(0); }); }); diff --git a/components/__tests__/SwitchButtonGroup.test.tsx b/components/__tests__/SwitchButtonGroup.test.tsx index 0e685d6..0fde098 100644 --- a/components/__tests__/SwitchButtonGroup.test.tsx +++ b/components/__tests__/SwitchButtonGroup.test.tsx @@ -21,10 +21,10 @@ describe('SwitchButtonGroup 组件', () => { const buttonA = screen.getByRole('button', { name: /选项A/i }); const buttonB = screen.getByRole('button', { name: /选项B/i }); - // 选中的按钮有 bg-white text-blue-600 shadow-sm 类 - expect(buttonA).toHaveClass('bg-white', 'text-blue-600', 'shadow-sm'); - // 未选中的按钮有 text-gray-500 类 - expect(buttonB).toHaveClass('text-gray-500'); + // 选中的按钮有 bg-background text-primary shadow-sm 类 + expect(buttonA).toHaveClass('bg-background', 'text-primary', 'shadow-sm'); + // 未选中的按钮有 text-muted-foreground 类 + expect(buttonB).toHaveClass('text-muted-foreground'); }); it('点击未选中按钮时应触发 onChange 并传入选中值', () => { @@ -122,8 +122,8 @@ describe('SwitchButtonGroup 组件', () => { const button2 = screen.getByRole('button', { name: /^2$/i }); const button4 = screen.getByRole('button', { name: /^4$/i }); - expect(button2).toHaveClass('text-gray-500'); - expect(button4).toHaveClass('bg-white', 'text-blue-600', 'shadow-sm'); + expect(button2).toHaveClass('text-muted-foreground'); + expect(button4).toHaveClass('bg-background', 'text-primary', 'shadow-sm'); }); it('点击 number 选项时应传回 number 值', () => { diff --git a/components/__tests__/TextInputArea.test.tsx b/components/__tests__/TextInputArea.test.tsx index 2bd7816..10388a2 100644 --- a/components/__tests__/TextInputArea.test.tsx +++ b/components/__tests__/TextInputArea.test.tsx @@ -334,7 +334,7 @@ describe('TextInputArea 组件', () => { ); const btn = screen.getByText('主要'); - expect(btn).toHaveClass('bg-blue-600', 'text-white'); + expect(btn).toHaveClass('bg-primary', 'text-white'); }); }); @@ -346,7 +346,7 @@ describe('TextInputArea 组件', () => { it('不设置 title 时不渲染标题', () => { const { container } = render( {}} />); - expect(container.querySelector('.text-gray-500')).not.toBeInTheDocument(); + expect(container.querySelector('.text-muted-foreground')).not.toBeInTheDocument(); }); }); diff --git a/entrypoints/options/App.tsx b/entrypoints/options/App.tsx index 9f9d8ba..76be67a 100644 --- a/entrypoints/options/App.tsx +++ b/entrypoints/options/App.tsx @@ -91,14 +91,14 @@ function SortableFeatureRow({
    {/* 拖拽手柄 */}
    -
    +
    {t(feature.labelKey)}
    {feature.descriptionKey && (
    {t(feature.descriptionKey)} @@ -140,12 +140,12 @@ function SortableFeatureRow({ aria-checked={isChecked} disabled={isDisabled} onClick={() => onToggle(pageKey)} - className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${ - isChecked ? 'bg-blue-600' : 'bg-gray-200' + className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${ + isChecked ? 'bg-primary' : 'bg-muted' } ${isDisabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`} > @@ -306,16 +306,16 @@ export default function App() { if (!isLoaded) { return (
    -
    +
    ); } return ( -
    +
    {/* 顶部标题与导航栏 */} -
    +
    } @@ -333,8 +333,8 @@ export default function App() { onClick={(e) => handleWindowTypeChange(e, type)} className={`px-4 sm:px-6 py-2 text-[0.9rem] font-bold transition-colors duration-200 ${ windowType === type - ? 'text-blue-600 border-b-2 border-blue-600' - : 'text-gray-500 hover:text-gray-700' + ? 'text-primary border-b-2 border-primary' + : 'text-muted-foreground hover:text-foreground' }`} > {type === 'popup' ? 'Popup 窗口' : type === 'sidepanel' ? '侧边栏' : '标签页'} @@ -343,7 +343,7 @@ export default function App() {
    @@ -133,9 +133,9 @@ export default function TextMode({ onSwitchToImageMode }: TextModeProps = {}) { )} {output && ( -
    +
    - {outputLabel} + {outputLabel}
    - + {title} {description && ( - + {description} )}
    { e.currentTarget.style.color = colorCode; @@ -88,9 +88,7 @@ export default function ToolCard({
    {snapshot != null && ( -
    - {snapshot} -
    +
    {snapshot}
    )}
    diff --git a/pages/HtmlToMarkdown/index.tsx b/pages/HtmlToMarkdown/index.tsx index 5656818..6070675 100644 --- a/pages/HtmlToMarkdown/index.tsx +++ b/pages/HtmlToMarkdown/index.tsx @@ -65,14 +65,14 @@ export default function HtmlToMarkdownPage() {