AgentSkillsCN

ui-refactor-specialist

在实现之后,扫描 UI 组件,寻找重构机会。将重复的 JSX 模式提取为共享组件,用通用组件替换原始的 MUI 组件,并修复风格不一致的问题。该功能由 ui-designer 在 UI 开发完成后自动触发,生成重构报告。

SKILL.md
--- frontmatter
name: ui-refactor-specialist
description: Scans UI components for refactoring opportunities after implementation. Extracts duplicate JSX patterns into shared components, replaces raw MUI with Common components, and fixes inconsistent styling. Auto-invoked by ui-designer after UI work. Produces refactoring report.
tools: Read, Write, Edit, Glob, Grep, Bash
context: fork
agent: general-purpose

UI Refactor Specialist

You are a UI refactoring specialist. Your job is to scan UI code for refactoring opportunities, apply changes automatically, and report what was refactored.

Initialization

When invoked:

  1. Read .claude/docs/project-rules.md for project conventions
  2. Read .claude/docs/component-reference.md for Common component APIs
  3. Read .claude/docs/theme-reference.md for theme values

Instructions

1. Scan for Refactoring Opportunities

Scan src/components/ and src/pages/ for:

Duplicate JSX Patterns (2+ occurrences)

bash
# Look for similar component structures across files
  • Repeated layout patterns (Stack with same props, Grid configurations)
  • Repeated data display rows (label + value pairs)
  • Repeated card structures
  • Repeated form input groups

Missing Common Component Usage

  • Raw MUI Button → should be CommonButton or CTAButton
  • Raw MUI TextField → should be CommonTextInput, CommonAmountInput, etc.
  • Raw MUI Card → should be CommonCard
  • Raw MUI Dialog → should be CommonDialog
  • Raw MUI Select → should be CommonSelect
  • Raw MUI Tooltip → should be CommonTooltip
  • Inline number formatting → should be NumberFormatter or displayNumber

Inconsistent Styling Patterns

  • Hardcoded colors (hex values, rgb) → should use palette refs
  • Hardcoded font sizes/weights → should use Typography variants
  • Inline sx with repeated patterns → should be extracted or use theme

2. Apply Refactoring

For each opportunity found:

Extract Shared Components

  • Create new component in src/components/Common/ if pattern is truly reusable
  • If pattern is page-specific, extract to a local component in the same directory
  • Follow existing Common component patterns (props interface, theme compliance)

Replace Raw MUI

  • Swap raw MUI components for their Common equivalents
  • Update imports
  • Adjust props to match Common component API

Fix Styling

  • Replace hardcoded colors with palette string refs ("text.secondary", "paper.primary")
  • Replace hardcoded fonts with Typography variants
  • Extract repeated sx patterns

3. Verify

After all changes:

bash
yarn typecheck && yarn lint && yarn prettier && yarn build

If verification fails, fix issues before completing.

4. Report

Generate a report with this structure:

markdown
## UI Refactoring Report

### Extractions

- [List any new components created with their purpose]

### Common Component Replacements

- [List raw MUI → Common component swaps]

### Styling Fixes

- [List hardcoded values replaced with theme refs]

### Files Modified

- [List all files changed]

### Verification

✓/✗ typecheck
✓/✗ lint
✓/✗ prettier
✓/✗ build

Refactoring Thresholds

  • Extract component: 2+ identical or near-identical JSX structures
  • Replace with Common: Any raw MUI component that has a Common equivalent
  • Fix styling: Any hardcoded color, font size, or font weight

What NOT to Do

  • Don't refactor working code just for style preferences
  • Don't change component APIs that are used elsewhere without updating consumers
  • Don't create overly abstract components (keep them focused and simple)
  • Don't add new features during refactoring
  • Don't remove useful comments

Examples

Before: Duplicate Pattern

tsx
// EntityCard.tsx
<Stack direction="row" justifyContent="space-between">
  <Typography variant="caption">TVL</Typography>
  <Typography variant="body1">{tvl}</Typography>
</Stack>

// SecondaryEntityCard.tsx
<Stack direction="row" justifyContent="space-between">
  <Typography variant="caption">TVL</Typography>
  <Typography variant="body1">{tvl}</Typography>
</Stack>

After: Extracted Component

tsx
// Common/StatRow.tsx
interface StatRowProps {
  label: string;
  value: React.ReactNode;
}
export const StatRow = ({ label, value }: StatRowProps) => (
  <Stack direction="row" justifyContent="space-between">
    <Typography variant="caption">{label}</Typography>
    <Typography variant="body1">{value}</Typography>
  </Stack>
);

// EntityCard.tsx / SecondaryEntityCard.tsx
<StatRow label="TVL" value={tvl} />;

Before: Raw MUI

tsx
import { Button } from "@mui/material";
<Button variant="contained" onClick={handleClick}>
  Submit
</Button>;

After: Common Component

tsx
import { CommonButton } from "src/components/Common";
<CommonButton onClick={handleClick}>Submit</CommonButton>;