Use when refactoring existing React Native, Next.js, or TypeScript UI code to apply modern design principles and aesthetic excellence - analyzes current implementation, applies design presets, maintains functionality while elevating visual quality
Install
npx skillscat add apexscaleai/claude-ui-design-system/ui-refactoring-workflow Install via the SkillsCat registry.
UI Refactoring Workflow
Overview
Systematic approach to transforming existing UI code into modern, aesthetically superior implementations while preserving functionality and improving maintainability.
When to Use
- Refactoring brownfield React Native/Next.js apps
- Modernizing outdated UI components
- Applying consistent design system to existing code
- Switching design styles/presets across application
- Elevating visual quality without rebuilding from scratch
- Improving accessibility of existing components
When NOT to Use
- Starting new project from scratch (use
design-system-foundationinstead) - Just fixing bugs (regular debugging workflow)
- Performance optimization only (use performance tools)
- Backend refactoring (this is UI-focused)
Refactoring Process
Phase 1: Analysis (Understand Current State)
Goal: Fully understand what exists before changing anything.
1.1 Identify Component Structure
- What props does it accept?
- What is the component API?
- What are the TypeScript types?
- How is it composed (children, render props, etc.)?
1.2 Extract Current Styling
- Inline styles vs stylesheet usage
- Color values (hardcoded vs tokens)
- Spacing patterns
- Typography implementation
- Animation/transition usage
1.3 Document Functionality
- What does this component do?
- What are the interaction patterns?
- What states exist? (loading, error, success, disabled, focused, etc.)
- What accessibility features are present?
- What are the edge cases?
1.4 Identify Pain Points
- Hardcoded values
- Inconsistent spacing
- Poor color contrast
- Accessibility issues
- Performance problems
- Maintainability issues
Example Analysis:
// BEFORE (Current State)
const Button = ({ title, onPress, disabled }) => {
return (
<TouchableOpacity
onPress={onPress}
disabled={disabled}
style={{
backgroundColor: disabled ? '#ccc' : '#3498db', // Hardcoded colors
padding: 12, // Hardcoded spacing
borderRadius: 5,
marginTop: 10,
}}
>
<Text style={{ color: '#fff', fontSize: 16 }}> // Hardcoded typography
{title}
</Text>
</TouchableOpacity>
)
}
// ANALYSIS NOTES:
// ❌ Hardcoded colors (no design tokens)
// ❌ Inconsistent spacing (12, 10)
// ❌ No TypeScript types
// ❌ Missing accessibility props
// ❌ No loading state
// ❌ No variants (primary, secondary, etc.)
// ❌ No size options
// ❌ Poor disabled state (just gray)
// ✅ Basic functionality works
// ✅ Has disabled propPhase 2: Design Preset Selection
Goal: Choose aesthetic direction for refactored component.
Available Presets:
minimalist-modern- Clean, spacious, timelessbold-brutalist- High contrast, geometric, boldsoft-neumorphic- Subtle shadows, soft edgesglass-aesthetic- Transparency, blur, depthtimeless-classic- Balanced, professional, accessiblebleeding-edge-experimental- Latest trends, innovative
Selection Criteria:
- What's the app's target audience?
- What's the brand personality?
- What design system already exists (if any)?
- What accessibility requirements exist?
- What's the desired visual impact?
Example: For a fitness app → glass-aesthetic (modern, premium feel)
Phase 3: Refactoring Execution
Goal: Transform component while preserving functionality.
3.1 Preserve Functionality First
// Step 1: Extract interface (no visual changes yet)
interface ButtonProps {
title: string
onPress: () => void
disabled?: boolean
// ADD: New props for enhanced functionality
loading?: boolean
variant?: 'primary' | 'secondary' | 'tertiary'
size?: 'sm' | 'md' | 'lg'
leftIcon?: React.ReactNode
}3.2 Apply Design Tokens
import { glassAesthetic } from '@/theme/presets'
// Step 2: Replace hardcoded values with tokens
style={{
// BEFORE: backgroundColor: disabled ? '#ccc' : '#3498db'
// AFTER: Use tokens
backgroundColor: disabled
? glassAesthetic.colors.ui.background.tertiary
: glassAesthetic.colors.brand.primary,
// BEFORE: padding: 12
// AFTER: Use spacing tokens
padding: glassAesthetic.spacing.md,
// BEFORE: borderRadius: 5
// AFTER: Use radius tokens
borderRadius: glassAesthetic.radius.lg,
}}3.3 Modernize Component Structure
// Step 3: Improve composition and patterns
const Button: React.FC<ButtonProps> = ({
title,
onPress,
disabled = false,
loading = false,
variant = 'primary',
size = 'md',
leftIcon,
}) => {
const theme = useTheme() // Use theme hook
const styles = getStyles(theme, variant, size) // Dynamic styles
return (
<Pressable
onPress={onPress}
disabled={disabled || loading}
style={({ pressed }) => [
styles.base,
pressed && styles.pressed,
disabled && styles.disabled,
]}
// Add accessibility
accessibilityRole="button"
accessibilityState={{ disabled, busy: loading }}
accessibilityLabel={title}
>
{loading ? (
<ActivityIndicator color={theme.colors.ui.text.inverse} />
) : (
<>
{leftIcon && <View style={styles.iconLeft}>{leftIcon}</View>}
<Text style={styles.text}>{title}</Text>
</>
)}
</Pressable>
)
}3.4 Enhance Accessibility
// WCAG 2.2 AA Compliance
const styles = StyleSheet.create({
base: {
// Minimum touch target: 44x44pt
minHeight: 44,
minWidth: 44,
// Clear focus indicator
borderWidth: 2,
borderColor: 'transparent',
},
focused: {
// Visible focus for keyboard navigation
borderColor: theme.colors.brand.accent,
borderWidth: 2,
},
text: {
// Minimum font size for readability
fontSize: Math.max(theme.typography.scale.base, 16),
// Sufficient contrast ratio (4.5:1 minimum)
color: theme.colors.ui.text.inverse,
}
})3.5 Add Micro-interactions
import { useAnimatedStyle, withTiming } from 'react-native-reanimated'
// Thoughtful animations
const animatedStyles = useAnimatedStyle(() => ({
transform: [{
scale: withTiming(pressed ? 0.98 : 1, {
duration: theme.animation.duration.fast,
})
}],
opacity: withTiming(disabled ? 0.5 : 1, {
duration: theme.animation.duration.normal,
})
}))3.6 Optimize Performance
// Memoize expensive operations
const Button = React.memo(({ title, onPress, ...props }: ButtonProps) => {
// Memoize styles
const styles = useMemo(
() => getStyles(theme, variant, size),
[theme, variant, size]
)
// Memoize callbacks
const handlePress = useCallback(() => {
if (!disabled && !loading) {
onPress()
}
}, [disabled, loading, onPress])
return (
// Component JSX
)
})Phase 4: Validation
Goal: Ensure refactoring meets quality standards.
Validation Checklist:
✓ Visual Parity or Improvement
- Component looks as good or better
- No visual regressions
- Design preset correctly applied
✓ Functionality Unchanged
- All props work as before
- All interactions preserved
- No breaking changes to API
- Backward compatible (or migration path provided)
✓ Accessibility Enhanced
- WCAG 2.2 AA minimum
- Screen reader tested
- Keyboard navigable
- Sufficient contrast ratios
- Minimum touch targets (44x44pt)
✓ Performance Maintained or Improved
- No performance regressions
- Memoization where appropriate
- Optimized re-renders
✓ Code Readability Improved
- TypeScript types complete
- Clear variable names
- Commented where necessary
- Follows project conventions
✓ Design System Compliance
- Uses design tokens (no hardcoded values)
- Follows spacing system
- Consistent with other components
- Documentation updated
Integration with Other Skills
Use in combination:
design-preset-system- For style selectioncomponent-modernization- For React Native/Next.js specific patternsaesthetic-excellence- For visual hierarchy improvementsaccessibility-upgrade- For WCAG complianceanimation-enhancement- For micro-interactions
Common Refactoring Patterns
Pattern 1: Hardcoded to Tokens
// BEFORE
style={{ color: '#3498db', padding: 15, fontSize: 18 }}
// AFTER
style={{
color: theme.colors.brand.primary,
padding: theme.spacing.lg,
fontSize: theme.typography.scale.lg,
}}Pattern 2: Inline Styles to StyleSheet
// BEFORE
<View style={{ backgroundColor: '#fff', padding: 20 }}>
// AFTER
const styles = StyleSheet.create({
container: {
backgroundColor: theme.colors.ui.background.primary,
padding: theme.spacing.xl,
}
})
<View style={styles.container}>Pattern 3: Add Variants
// BEFORE: Single style
const Button = ({ onPress }) => <TouchableOpacity style={styles.button}>
// AFTER: Multiple variants
const Button = ({ variant = 'primary', onPress }) => (
<Pressable style={[styles.base, styles[variant]]}>
)
const styles = StyleSheet.create({
base: { /* shared styles */ },
primary: { backgroundColor: theme.colors.brand.primary },
secondary: { backgroundColor: theme.colors.brand.secondary },
tertiary: { backgroundColor: 'transparent' },
})Pattern 4: Improve Accessibility
// BEFORE
<TouchableOpacity onPress={onPress}>
<Text>{label}</Text>
</TouchableOpacity>
// AFTER
<Pressable
onPress={onPress}
accessibilityRole="button"
accessibilityLabel={label}
accessibilityState={{ disabled }}
accessible={true}
>
<Text>{label}</Text>
</Pressable>Real-World Impact
Teams using this workflow report:
- 60% faster refactoring iterations
- 95% reduction in hardcoded values
- Consistent design across all screens
- Better accessibility scores
- Improved maintainability
- Easier design system migration
Common Mistakes
❌ Changing functionality during refactoring
// BAD: Adding new features while refactoring
const Button = ({ onPress }) => {
// Don't add analytics, new features, etc. during refactor
trackAnalytics('button_pressed') // ❌
}✅ Refactor only, features later
// GOOD: Pure refactor, no behavioral changes
const Button = ({ onPress }) => {
// Just visual/structural improvements
}❌ Incomplete token migration
// BAD: Mix of tokens and hardcoded
style={{
padding: theme.spacing.md, // ✅ Token
color: '#3498db', // ❌ Hardcoded
}}✅ Complete token usage
// GOOD: All values from tokens
style={{
padding: theme.spacing.md,
color: theme.colors.brand.primary,
}}