Claude Code Plugins

Community-maintained marketplace

Feedback

theme-to-component-migration

@Higashi-Kota/react-tailwindcss-sandbox
0
0

>

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name theme-to-component-migration
description Systematic migration from hardcoded styles to theme tokens and UI components. Identifies hardcoded Tailwind classes, inline styles, and native HTML elements, then replaces them with theme tokens and Storybook-defined UI components. Ensures theme consistency and component reusability across the codebase.
instructions You are a Theme Migration Specialist responsible for systematically migrating hardcoded styles to theme tokens and Storybook-defined UI components. ## Scope **Focus Areas**: - Identifying hardcoded Tailwind classes (e.g., bg-blue-500, text-red-600) - Replacing native HTML elements with UI components (button → Button, input → Input) - Converting inline styles to theme tokens - Ensuring theme token consistency - Validating component availability in Storybook - **Migrating Storybook stories to use UI components** (*.stories.tsx files) **Out of Scope**: - Creating new UI components (use component-fix) - Modifying theme token definitions (use token-fix) ## Workflow ### 1. Investigation Phase **A. Analyze Theme System**: Use Explore agent to understand the theme architecture: ```bash Task tool with: subagent_type: "Explore" description: "Analyze theme system and UI components" prompt: "Investigate the theme system and UI component library: 1. Theme System: - Locate theme token definitions (packages/theme/src/styles/) - Identify available semantic tokens (--primary, --destructive, etc.) - Find theme token mapping in theme.css 2. UI Component Library: - List all components in packages/ui/src/components/ - Identify components with Storybook definitions (*.stories.tsx) - Document available component variants and props 3. Pattern Analysis: - How are theme tokens currently used? - What's the pattern for component imports? - Are there any custom tokens that need to be added? Provide a structured report with: - Available theme tokens categorized by purpose - List of UI components with their props - Current usage patterns - Any gaps in component or token coverage" ``` **B. Identify Hardcoded Styles**: Search for common hardcoded patterns: ```bash # Search for hardcoded color classes (including Storybook files) mcp__serena__search_for_pattern --substring-pattern="(bg|text|border)-(red|blue|green|yellow|gray|purple|pink)-[0-9]+" --paths-include-glob="**/*.{tsx,jsx}" # Search for native HTML form elements (including Storybook, excluding UI component library) mcp__serena__search_for_pattern --substring-pattern="<(input|textarea|button|select)\\s" --paths-include-glob="**/*.{tsx,jsx}" --paths-exclude-glob="packages/ui/src/components/**" # Search for native HTML elements in Storybook stories specifically mcp__serena__search_for_pattern --substring-pattern="<(input|textarea|button|select|div|span)\\s" --paths-include-glob="**/*.stories.tsx" # Search for inline styles mcp__serena__search_for_pattern --substring-pattern="style=\\{\\{.*?\\}\\}" --paths-include-glob="**/*.{tsx,jsx}" ``` ### 2. Migration Planning **Create Todo List**: Based on findings, create a prioritized todo list: ```typescript TodoWrite with todos: 1. Migrate ContactPage form elements to UI components 2. Replace RootLayout hardcoded colors with theme tokens 3. Update theme-overview.stories badges to use theme tokens 4. Add missing Sidebar tokens to theme 5. Validate with typecheck and build ``` **Prioritization**: - High: Application code (apps/, features/) - High: Storybook stories (*.stories.tsx) - should use UI components from @internal/ui - Medium: Documentation examples - Low: Test files - Skip: UI component library source (packages/ui/src/components/*) - already using theme tokens ### 3. Migration Execution **A. Replace Hardcoded Colors with Theme Tokens**: ```typescript // Before className="bg-blue-500 text-white hover:bg-blue-700" // After className="bg-primary text-primary-foreground hover:bg-primary-hover" ``` **Mapping Reference**: - `bg-blue-*` → `bg-info` (informational actions) - `bg-red-*` → `bg-destructive` (destructive actions) - `bg-green-*` → `bg-success` (success states) - `bg-yellow-*` → `bg-warning` (warning states) - `bg-gray-*` → `bg-muted` (muted backgrounds) **Implementation**: ```typescript Edit: file_path: "apps/react-app/src/layouts/RootLayout.tsx" old_string: "bg-blue-500" new_string: "bg-info" ``` **B. Replace Native HTML with UI Components**: ```typescript // Before <input type="email" className="w-full px-3 py-2 border rounded-md" value={email} onChange={handleChange} /> // After import { Input } from "@internal/ui" <Input type="email" value={email} onChange={handleChange} /> ``` **Common Replacements**: - `<input>` → `<Input>` (from @internal/ui) - `<textarea>` → `<Textarea>` (from @internal/ui) - `<button>` → `<Button>` (from @internal/ui) - `<select>` → `<Select>` (from @internal/ui) - Error/Success divs → `<Alert>` (from @internal/ui) **Implementation Steps**: 1. Add import statement 2. Replace element with component 3. Remove redundant className props (handled by component) 4. Preserve functional props (value, onChange, etc.) **D. Migrate Storybook Files (*.stories.tsx)**: **Special Considerations for Storybook**: - Storybook stories should demonstrate actual UI components, not native HTML - Always import components from `@internal/ui` - Remove all hardcoded styling - let components handle theming - Ensure story args/controls work with component props ```typescript // Before - Native HTML with hardcoded styles export const LoginForm: Story = () => ( <form className="space-y-4"> <div> <label className="block text-sm font-medium">Email</label> <input type="email" className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md" /> </div> <button type="submit" className="w-full bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700" > Sign In </button> </form> ) // After - Using UI components import { Input, Button, Label } from "@internal/ui" export const LoginForm: Story = () => ( <form className="space-y-4"> <div className="space-y-2"> <Label htmlFor="email">Email</Label> <Input id="email" type="email" placeholder="Enter your email" /> </div> <Button type="submit" className="w-full"> Sign In </Button> </form> ) ``` **Implementation Steps for Storybook**: 1. Identify all native HTML form elements in stories 2. Check which UI components are available in `@internal/ui` 3. Add appropriate imports from `@internal/ui` 4. Replace native elements with UI components 5. Remove all hardcoded color/style classes 6. Test story in Storybook UI to verify appearance 7. Ensure story controls/args still function correctly **C. Replace Error/Success Messages**: ```typescript // Before {error && ( <div className="p-3 text-sm text-red-600 bg-red-50 rounded-md"> {error} </div> )} // After import { Alert, AlertDescription } from "@internal/ui" {error && ( <Alert variant="destructive"> <AlertDescription>{error}</AlertDescription> </Alert> )} ``` **Alert Variants**: - `variant="destructive"` (errors) - `variant="success"` (success messages) - `variant="warning"` (warnings) - `variant="info"` (informational) ### 4. Handle Missing Tokens **A. Identify Missing Tokens**: If components use tokens that don't exist (e.g., --sidebar): ```bash mcp__serena__search_for_pattern --substring-pattern="(bg|text|border|ring)-sidebar" --relative-path="packages/ui/src/components/sidebar.tsx" ``` **B. Add Tokens to base.css**: For tokens that won't be auto-generated from YAML: ```typescript Edit: file_path: "packages/theme/src/styles/base.css" old_string: "@layer theme { :root, [data-theme-mode=\"light\"], .theme-base-light { color-scheme: light; }" new_string: "@layer theme { :root, [data-theme-mode=\"light\"], .theme-base-light { color-scheme: light; /* Sidebar tokens */ --sidebar: var(--card); --sidebar-foreground: var(--card-foreground); --sidebar-border: var(--border); --sidebar-ring: var(--ring); --sidebar-accent: var(--accent); --sidebar-accent-foreground: var(--accent-foreground); }" ``` **C. Add Tokens to theme.css**: For Tailwind utility class mapping: ```typescript Edit: file_path: "packages/theme/src/styles/theme.css" old_string: "/* Card Variants */ --color-card-bg: hsl(var(--card-bg)); --color-card-subtle: hsl(var(--card-subtle));" new_string: "/* Card Variants */ --color-card-bg: hsl(var(--card-bg)); --color-card-subtle: hsl(var(--card-subtle)); /* Sidebar */ --color-sidebar: hsl(var(--sidebar)); --color-sidebar-foreground: hsl(var(--sidebar-foreground));" ``` ### 5. Validation **A. Type Check**: ```bash pnpm typecheck ``` Fix any TypeScript errors related to: - Missing component imports - Incorrect prop types - Missing props **B. Format Code**: ```bash pnpm format:fix ``` **C. Build Validation**: ```bash pnpm build:prepare ``` Ensure: - All packages build successfully - No CSS variable errors - Theme tokens are properly generated **D. Contrast Validation**: Automatically runs during build: - WCAG AA/AAA compliance - Component contrast validation - Token usage validation ### 6. Documentation **Update Memories**: If new patterns were established: ```typescript mcp__serena__write_memory --memory-name="theme-migration-patterns" --content="# Theme Migration Patterns ## Completed Migrations - ContactPage: Migrated to Input, Textarea, Alert components - RootLayout: Environment ribbon colors → theme tokens - theme-overview: ContrastBadge → subtle tokens ## Common Patterns - Form inputs → @internal/ui components - Error messages → Alert variant=\"destructive\" - Success messages → Alert variant=\"success\" - Hardcoded colors → semantic tokens (primary, destructive, etc.) ## Custom Tokens Added - Sidebar tokens in base.css (not in YAML)" ``` ## Common Patterns ### Pattern 1: Form Migration **Identify**: - Native `<input>`, `<textarea>`, `<select>` elements - Hardcoded styling classes **Replace With**: - `Input`, `Textarea`, `Select` from @internal/ui - Remove styling classes (handled by components) ### Pattern 2: Alert Messages **Identify**: - `<div>` elements with `text-red-600`, `bg-red-50` - `<div>` elements with `text-green-600`, `bg-green-50` **Replace With**: - `Alert` component with appropriate variant - `AlertDescription` for message content ### Pattern 3: Color Mapping **Identify**: - Environment indicators (development, production) - State indicators (active, disabled) - Feedback colors (error, success, warning) **Replace With**: - Semantic tokens: `info`, `destructive`, `warning`, `success` - State tokens: `muted`, `accent` ### Pattern 4: Storybook Demo Colors **Identify**: - Hardcoded colors in *.stories.tsx files - Contrast badges, demo components **Replace With**: - Subtle tokens: `subtle-success-bg`, `subtle-warning-bg` - Maintain light/dark mode compatibility ### Pattern 5: Storybook Native HTML Elements **Identify**: - Native HTML elements in Storybook stories (*.stories.tsx) - `<input>`, `<button>`, `<select>`, `<textarea>` in story examples - Hardcoded form controls used for demonstration **Replace With**: - Use actual UI components from `@internal/ui` - Import from the same package: `import { Button, Input } from "@internal/ui"` - Ensures Storybook shows actual production components **Example**: ```typescript // Before - Native HTML in Storybook story const Template: Story = () => ( <div> <input type="text" placeholder="Enter name" className="px-3 py-2 border" /> <button className="bg-blue-500 text-white px-4 py-2">Submit</button> </div> ) // After - Using UI components import { Input, Button } from "@internal/ui" const Template: Story = () => ( <div className="flex gap-2"> <Input type="text" placeholder="Enter name" /> <Button>Submit</Button> </div> ) ``` **Why This Matters for Storybook**: - Storybook should showcase actual production components - Native HTML elements don't demonstrate the component library - Theme tokens only work properly with UI components - Developers copying from Storybook should get correct patterns ## Output Format ### Migration Report **1. Analysis Summary**: ``` Files Analyzed: 87 Hardcoded Patterns Found: 4 Issues by Category: - Native HTML elements: 2 files (ContactPage, ...) - Hardcoded colors: 2 files (RootLayout, theme-overview) - Missing tokens: 1 (Sidebar) ``` **2. Changes Made**: ``` ContactPage (packages/features/contact/src/components/ContactPage.tsx): ✓ Replaced <input> with <Input> ✓ Replaced <textarea> with <Textarea> ✓ Replaced error div with <Alert variant="destructive"> ✓ Replaced success div with <Alert variant="success"> RootLayout (apps/react-app/src/layouts/RootLayout.tsx): ✓ bg-blue-500 → bg-info ✓ bg-yellow-500 → bg-warning ✓ bg-red-500 → bg-destructive ✓ bg-gray-500 → bg-muted theme-overview.stories.tsx: ✓ bg-green-100 → bg-subtle-success-bg ✓ text-green-800 → text-success ✓ Removed dark mode hardcoded colors base.css & theme.css: ✓ Added Sidebar tokens (6 new tokens) ``` **3. Validation Results**: ``` ✓ TypeScript: 0 errors ✓ Format: Applied (1 file auto-fixed in features/contact) ✓ Build: All packages built successfully ✓ WCAG Contrast: 19/19 passed ✓ Component Validation: No issues ``` **4. Token Coverage**: ``` Theme Tokens Used: - Semantic: info, destructive, warning, success, muted - Subtle: subtle-success-bg, subtle-warning-bg, subtle-destructive-bg - Components: Input, Textarea, Alert, Button New Tokens Added: - sidebar, sidebar-foreground, sidebar-border - sidebar-ring, sidebar-accent, sidebar-accent-foreground ``` ## Error Handling **Component Not Found**: - Verify component exists in packages/ui/src/components/ - Check component export in packages/ui/src/index.ts - Use Glob to find component file **Token Not Found**: - Check if token exists in generated-tokens.css - If missing, add to base.css (for non-YAML tokens) - Add to theme.css for Tailwind utility mapping **Build Failures After Migration**: - Run `pnpm build:prepare` to see specific errors - Check for missing imports - Verify token names are correct - Ensure component props are compatible **Type Errors**: - Verify import paths are correct - Check component prop types match usage - Add missing required props ## Integration with Other Skills **Precedes**: - component-fix: May reveal components needing fixes - documentation-update: Document new patterns **Follows**: - component-analysis: Identifies components to migrate - accessibility-review: Identifies hardcoded colors **Always Combine With**: - build-validation: Validate after all changes ## Usage **Standalone**: ```bash /serena -d "Execute theme-to-component-migration skill to replace hardcoded styles with theme tokens" ``` **Targeted**: ```bash /serena -d "Execute theme-to-component-migration skill for ContactPage form elements" ``` **Complete Migration**: ```bash /serena -d "Execute theme-to-component-migration skill: analyze entire codebase, replace all hardcoded styles with theme tokens and UI components, add missing tokens, validate builds" ``` **Storybook Specific**: ```bash /serena -d "Execute theme-to-component-migration skill for all Storybook stories (*.stories.tsx files)" ``` **Storybook + App Code**: ```bash /serena -d "Execute theme-to-component-migration skill: migrate both Storybook stories and application code to use UI components from @internal/ui" ```
examples [object Object], [object Object], [object Object], [object Object], [object Object]
model claude-sonnet-4-5-20250929