Citrus migrate
Skill valasubramanian-kr/wallet-web-developer/skills/citrus-migrate
Claude plugin orchestrating spec-to-code automation workflow, enabling developers to leverage Claude Skills for productivity.From the repository description
npx -y skills add valasubramanian-kr/wallet-web-developer --skill citrus-migrateAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
43.4 KB, ~10.3k tokens by cl100k_base, as published. Nobody here has run it
Citrus Migration Skill
Purpose
Migrate a single React component from vanilla/legacy UI to Citrus design system, following established patterns and maintaining existing functionality.
Usage
/citrus-migrate <component-path> [screenshot-path] [comments]
Arguments:
<component-path>(required): Relative path to React component (e.g.,src/components/AddCardForm/AddCardForm.tsx)[screenshot-path](optional): Path to Figma screenshot showing post-migration UI[comments](optional): Migration instructions/hints for the skill (e.g., "Use ValidationMessage for Message component")
Examples:
# Basic migration
/citrus-migrate src/components/AddCardForm/AddCardForm.tsx
# With Figma screenshot
/citrus-migrate src/components/CardList/CardList.tsx ~/Downloads/cardlist-figma.png
# With user comments/instructions
/citrus-migrate src/components/ErrorDisplay/ErrorDisplay.tsx "Use ValidationMessage Citrus component for migrating Message component"
# With screenshot and comments
/citrus-migrate src/components/PaymentForm/PaymentForm.tsx ~/Downloads/payment-form.png "Follow ui/citrus/FormInput component pattern for form controls"
What This Skill Does
Initial Migration Mode
- Parse Arguments: Parse component path, optional screenshot, and optional user comments/instructions
- Analyze Component: Read component, CSS, and tests to understand structure and dependencies
- Process User Comments: Incorporate user-provided migration instructions and component preferences
- Check Dependencies: Flag unmigrated custom UI dependencies, warn user to migrate them first
- Visual Analysis (if screenshot provided): Analyze Figma screenshot to guide migration
- Map Components: Search citrus-react extensively for component matches (honoring user comments), propose wrappers if needed
- Migrate Component Files: Update .tsx, .module.css, and .test.ts files following CITRUS_MIGRATION.md patterns
- Full CSS Refactor: Group/organize styles, remove unused, apply Citrus utilities
- Ask Clarifications: Use AskUserQuestion for mapping gaps, approach decisions, confirmations
- Report Results: Display migration summary and next steps for testing
Feedback Mode (Re-run on Already Migrated Component)
- Detect Previous Migration: Check if migration document exists for this component
- Read Previous Migration: Load migration history and current state
- Process Feedback: Parse user feedback comments and determine changes needed
- Apply Feedback: Make incremental refinements based on feedback
- Replace components as requested
- Apply/remove utility classes
- Answer questions about utilities
- Cleanup CSS as requested
- Update Migration Document: Append feedback iteration with changes made
- Report Results: Display feedback summary and updates
IMPORTANT: No git actions, no auto-tests, no build validation. User handles all testing.
Instructions
You are performing autonomous Citrus migration for a single React component in the hosted-payment-page library.
Prerequisites
Required Context Files (read these first):
- Migration Plan:
context/CITRUS_MIGRATION.md(in wallet-web-developer repo)- Contains complete migration strategy, guidelines, and component mapping reference
- Step-by-step migration process documentation
- Utility classes reference and CSS bundling strategy
- Wrapper component patterns and best practices
External Repo Access (via GitHub MCP):
krogertechnology/citrus-web- CSS utilities, styles, design tokens, utility classeskrogertechnology/citrus-react- React components, props, TypeScript definitions, usage examples
Working Directory:
- Skill runs in the context of the hosted-payment-page library
- Migration Plan is accessed from the wallet-web-developer repo context directory
Step 0: Parse and Validate Arguments
Parse skill arguments from user input:
# Expected format: /citrus-migrate <component-path> [screenshot-path] [comments]
# Extract component-path (required)
COMPONENT_PATH="<first-arg>"
# Extract screenshot-path (optional)
SCREENSHOT_PATH="<second-arg-if-present-and-is-image>"
# Extract user comments/instructions (optional)
USER_COMMENTS="<remaining-args-or-quoted-string>"
Argument Parsing Logic:
- First arg is always component path
- Second arg:
- If it's an image file path (.png, .jpg, .jpeg) → screenshot
- Otherwise → user comments
- Third arg (if second was screenshot): user comments
Validation:
- Check
COMPONENT_PATHis provided and exists - Check file extension is
.tsx - If
SCREENSHOT_PATHprovided, check file exists and is image format (.png, .jpg, .jpeg) USER_COMMENTSis optional, no validation needed- Fail fast with clear error if validation fails
Example validation:
if [ -z "$COMPONENT_PATH" ]; then
echo "❌ Error: Component path is required"
echo "Usage: /citrus-migrate <component-path> [screenshot-path] [comments]"
exit 1
fi
if [ ! -f "$COMPONENT_PATH" ]; then
echo "❌ Error: Component file not found: $COMPONENT_PATH"
exit 1
fi
if [[ "$COMPONENT_PATH" != *.tsx ]]; then
echo "❌ Error: Component must be a .tsx file"
exit 1
fi
# Validate screenshot if provided
if [ -n "$SCREENSHOT_PATH" ]; then
if [ ! -f "$SCREENSHOT_PATH" ]; then
echo "❌ Error: Screenshot file not found: $SCREENSHOT_PATH"
exit 1
fi
if [[ ! "$SCREENSHOT_PATH" =~ \.(png|jpg|jpeg)$ ]]; then
echo "❌ Error: Screenshot must be an image file (.png, .jpg, .jpeg)"
exit 1
fi
fi
Check for Previous Migration:
# Check if migration document exists
MIGRATION_DOC="workflow/citrus-migration/<ComponentName>-migration.md"
if [ -f "$MIGRATION_DOC" ]; then
echo "✓ Previous migration detected - entering FEEDBACK MODE"
MODE="FEEDBACK"
else
echo "✓ No previous migration found - entering INITIAL MIGRATION MODE"
MODE="INITIAL"
fi
Output:
✓ Component: src/components/AddCardForm/AddCardForm.tsx
✓ Screenshot: ~/Downloads/figma-addcardform.png [OR "No screenshot provided"]
✓ User Comments: "Use ValidationMessage for Message component" [OR "No user comments provided"]
✓ Mode: [INITIAL MIGRATION / FEEDBACK MODE]
Branch based on mode:
- INITIAL MIGRATION MODE: Proceed to Step 1 (normal migration flow)
- FEEDBACK MODE: Proceed to Step 0.5 (feedback processing flow)
Step 0.5: Feedback Processing Flow (FEEDBACK MODE ONLY)
IMPORTANT: This step only executes when a previous migration document exists and user provides feedback comments.
If no user comments provided in FEEDBACK MODE:
⚠️ Warning: Re-running migration on already migrated component without feedback comments.
This will re-migrate the component from scratch.
Do you want to:
1. Provide feedback comments to refine the existing migration
2. Re-migrate from scratch (overwrite previous migration)
3. Cancel
Read Previous Migration Context:
- Read
workflow/citrus-migration/<ComponentName>-migration.md - Extract:
- Previous component mappings
- CSS changes made
- Wrappers created
- Dependencies handled
- Feedback iterations (if any previous feedback)
Process Feedback Comments:
Categorize feedback into action types:
-
Component Replacement Feedback:
- Pattern: "Use [NewComponent] instead of [OldComponent]"
- Example: "Instead of ValidationMessage, use GlobalMessage"
- Action: Replace component imports and usage
-
CSS Utility Feedback:
- Pattern: "Use [utility-class] and remove [custom-class]"
- Example: "Use 'w-full' utility class and remove custom CSS class 'fullWidth'"
- Action: Apply utility class, remove custom CSS
-
Utility Class Query:
- Pattern: "Do we have utility class for [css-property]?"
- Example: "Do we have matching utility class for margin-bottom 10px?"
- Action: Search citrus-web for matching utility, propose replacement
-
CSS Cleanup Feedback:
- Pattern: "Cleanup CSS module" / "Remove unused CSS" / "Optimize CSS"
- Action: Analyze CSS module, remove unused classes, consolidate duplicates
-
General Refinement:
- Any other feedback requesting changes or improvements
- Action: Interpret feedback and apply changes
Execute Feedback Actions:
## Feedback Analysis
**Feedback Provided**: "<USER_COMMENTS>"
**Feedback Type**: [Component Replacement / CSS Utility / Utility Query / CSS Cleanup / General]
**Actions to Take**:
1. [Action 1 based on feedback]
2. [Action 2 based on feedback]
3. [Action 3 based on feedback]
**Files to Modify**:
- [List files that will be updated based on feedback]
For Component Replacement Feedback:
- Search citrus-react for the new component specified
- Read component props and usage from citrus-react
- Update imports in component file
- Replace old component usage with new component
- Preserve all props and behavior
- Update tests if component structure changes
For CSS Utility Feedback:
- Search citrus-web styles.config.js for the utility class mentioned
- Verify utility class exists in both esperanto.css and citrus.light.css
- Apply utility class to component
- Remove custom CSS class from module.css
- Update component to use utility class
For Utility Class Query:
- Search citrus-web styles.config.js for matching utilities
- Check both spacing utilities and custom properties
- Report findings to user:
✓ Found matching utility class: 'mb-[value]' for margin-bottom Available options: - mb-2 (margin-bottom: 0.5rem / 8px) - mb-2.5 (margin-bottom: 0.625rem / 10px) ← Exact match - mb-3 (margin-bottom: 0.75rem / 12px) Recommendation: Use 'mb-2.5' utility class Would you like to apply this change? - If user confirms, apply the change
For CSS Cleanup Feedback:
- Read current CSS module
- Analyze for:
- Unused classes (not referenced in component)
- Duplicate styles (can be consolidated)
- Classes that can be replaced with Citrus utilities
- Overly specific selectors
- Propose cleanup plan to user via AskUserQuestion
- Apply approved cleanup changes
Update Migration Document with Feedback Iteration:
Append to existing migration document:
---
## Feedback Iteration <N>
**Date**: <timestamp>
**Feedback**: "<USER_COMMENTS>"
**Feedback Type**: [Type]
**Changes Made**:
- [Change 1]
- [Change 2]
- [Change 3]
**Files Modified**:
- [File 1] - [What changed]
- [File 2] - [What changed]
**Component Mapping Updates** (if applicable):
| Previous | Updated | Reason |
|----------|---------|--------|
| [OldComponent] | [NewComponent] | User feedback |
**CSS Updates** (if applicable):
| Previous | Updated | Reason |
|----------|---------|--------|
| .customClass | w-full | User feedback - use utility class |
**Outcome**: [Success / Partial / Need more feedback]
---
Report Feedback Results:
✓ Feedback applied to <ComponentName>
Feedback: "<USER_COMMENTS>"
Changes Applied:
- [Change 1]
- [Change 2]
- [Change 3]
Files Modified:
- ✓ src/components/<ComponentName>/<ComponentName>.tsx
- ✓ src/components/<ComponentName>/<ComponentName>.module.css
- [Other files if applicable]
Migration Document Updated: workflow/citrus-migration/<ComponentName>-migration.md
- Added Feedback Iteration <N>
Next Steps:
1. Review changes: git diff src/components/<ComponentName>/
2. Run tests: yarn test
3. Visually verify changes
4. If satisfied, commit changes
5. If more refinements needed, re-run skill with additional feedback
⚠️ IMPORTANT: No git actions were performed. Review and commit changes manually.
After Feedback Processing: Exit skill (do NOT proceed to Step 1)
Step 1: Read Context and Component Files (INITIAL MIGRATION MODE ONLY)
Read migration context:
-
Read
context/CITRUS_MIGRATION.mdfrom wallet-web-developer repo- Extract migration steps and guidelines
- Review component mapping reference table
- Note CSS bundling strategy and utility classes
- Understand wrapper component strategy for reusable UI
-
Process user comments (if provided):
- Parse user instructions for specific component mappings
- Extract any reference components to follow (e.g., "Follow ui/citrus/FormInput")
- Identify specific Citrus components to use (e.g., "Use ValidationMessage for Message")
- Note any custom migration requirements or constraints
- These comments take precedence over default discovery for mentioned components
Read target component files:
- Component file:
<COMPONENT_PATH> - CSS file:
<COMPONENT_PATH>.replace('.tsx', '.module.css') - Test file:
<COMPONENT_PATH>.replace('.tsx', '.test.tsx')or__tests__/<ComponentName>.test.tsx - Related files referenced in component imports
If screenshot provided:
- Read and analyze the screenshot using Read tool with image support
- Extract visual patterns, component layout, spacing, colors, typography
- Identify Citrus components visible in the design
- Note any differences from current implementation
Document findings:
## Component Analysis
**Component**: <ComponentName>
**Path**: <COMPONENT_PATH>
**Type**: [Reusable UI Component / Consumer Component]
**Current Implementation**:
- HTML Elements: <list of div, input, button, etc.>
- Custom UI Components: <list from src/components/ui/>
- Citrus Components: <list from @kds/citrus-react>
- CSS Module: <path> (<N> lines, <N> KB)
- Tests: <path> (<N> test cases)
**Dependencies** (other custom components):
- <ComponentName1> (from src/components/ui/) - ⚠️ NOT MIGRATED
- <ComponentName2> (from src/components/ui/) - ⚠️ NOT MIGRATED
**Screenshot Analysis** [if provided]:
- Visual Layout: <description>
- Citrus Components Identified: <list>
- Design Tokens: <colors, spacing, typography>
- Key Differences from Current: <list>
**User Comments/Instructions** [if provided]:
- <User instruction 1>
- <User instruction 2>
- Examples:
- "Use ValidationMessage Citrus component for migrating Message component"
- "Follow ui/citrus/FormInput component pattern for form controls"
- "Keep existing error handling logic, just wrap with Citrus components"
Step 2: Check Dependencies and Flag Blockers
Dependency Check Logic:
-
Identify custom UI imports:
- Parse imports from
../uior@/components/ui - Exclude Citrus imports (from
@kds/citrus-react) - Exclude non-UI imports (hooks, utils, services)
- Parse imports from
-
Check migration status:
- For each custom UI component, check if Citrus equivalent exists in
src/components/ui/citrus/ - If NOT found → unmigrated dependency
- If found → already migrated ✓
- For each custom UI component, check if Citrus equivalent exists in
-
Flag blockers:
⚠️ **Migration Blockers Detected** The following custom UI components are used by <ComponentName> but have NOT been migrated to Citrus: - `InputComponent` (from src/components/ui/...) - **Action Required**: Migrate first OR create Citrus wrapper - **Citrus Equivalent**: Check src/components/ui/citrus/ - `CustomComponent` (from src/components/ui/...) - **Action Required**: Migrate first OR create Citrus wrapper - **Citrus Equivalent**: Not found - needs investigation **Recommendation**: - If these are reusable UI components (exported from src/components/ui/index.ts): Create Citrus wrappers in src/components/ui/citrus/ following the wrapper pattern from CITRUS_MIGRATION.md - If these are consumer components: Migrate them separately before migrating <ComponentName> **Proceed?** - ✅ Yes - Continue migration, I'll handle dependencies manually - ❌ No - Stop migration, let me migrate dependencies first -
Use AskUserQuestion to confirm if blockers exist:
{ "questions": [{ "question": "This component has unmigrated dependencies. How would you like to proceed?", "header": "Dependencies", "options": [ {"label": "Continue migration", "description": "Proceed with migration, I'll handle dependencies separately"}, {"label": "Stop migration", "description": "Stop here, let me migrate dependencies first"}, {"label": "Create wrappers", "description": "Create Citrus wrappers for dependencies as part of this migration"} ], "multiSelect": false }] } -
Handle response:
- "Stop migration" → Exit gracefully with summary of blockers
- "Continue migration" → Proceed to Step 3
- "Create wrappers" → Add wrapper creation to migration plan (Step 4)
If NO blockers:
✓ No unmigrated dependencies detected
✓ Safe to proceed with migration
Step 3: Component Mapping Discovery
Goal: Map current vanilla/custom UI elements to Citrus components by extensively searching citrus-react repo.
Use Task tool with Explore agent for component discovery:
Task(
subagent_type="Explore",
description="Discover Citrus component matches",
model="haiku",
prompt="""
You are discovering Citrus component matches for migration.
CONTEXT:
- Component to migrate: <ComponentName>
- Current elements: <list of HTML elements and custom UI>
- Citrus repo: krogertechnology/citrus-react
- User Comments: <USER_COMMENTS if provided, otherwise "None">
IMPORTANT: If user comments specify a particular Citrus component to use for a legacy component,
prioritize that mapping. For example:
- "Use ValidationMessage for Message component" → Use ValidationMessage instead of searching
- "Follow ui/citrus/FormInput pattern" → Reference existing FormInput wrapper as example
TASK:
For each element/component in the list, search citrus-react extensively:
1. Search by element type:
- <input> → Search for "Input", "TextField", "TextInput"
- <button> → Search for "Button", "IconButton", "ButtonGroup"
- <select> → Search for "Select", "Dropdown", "Combobox"
- <h1-h6> → Search for "Headline", "Heading", "Title", "Typography"
- <p>, <span> → Search for "Paragraph", "Text", "Body"
- <label> → Search for "Label", "FormLabel"
- <checkbox> → Search for "Checkbox", "FormCheckbox"
2. Search by functionality:
- Form inputs → "FormControl", "Form", "Input"
- Error messages → "Message", "Alert", "Notification", "ErrorMessage"
- Loading states → "Spinner", "Loader", "LoadingIndicator", "Skeleton"
- Modals → "Modal", "Dialog", "Overlay"
- Tooltips → "Tooltip", "Popover", "HelpText"
3. For each match found:
- Component name and import path
- Props available (check TypeScript definitions)
- Usage examples (check Storybook or tests)
- Whether it's a standalone component or needs FormControl wrapper
4. If NO exact match found:
- Note this explicitly
- Suggest creating a wrapper component in src/components/ui/citrus/
5. Return findings in this format:
## Component Mapping Results
| Current Element | Citrus Component | Import Path | Props | Notes |
|----------------|------------------|-------------|-------|-------|
| <input type="text"> | Input | @kds/citrus-react | value, onChange, disabled, ... | Use with Label wrapper |
| <h2> | Headline | @kds/citrus-react | tag, size, className | tag="h2" size="s" |
| <CustomCheckbox> | Checkbox | @kds/citrus-react | checked, onChange, disabled | Wrap in Label component |
| <ErrorMessage> | Message | @kds/citrus-react | type, message | **NOT FOUND** - create wrapper? |
**Wrappers Needed**:
- [List wrappers needed based on component analysis]
- Example: InputWrapper (wraps Label + Input) - if component uses custom input with label
- Example: CheckboxWrapper (wraps Label + Checkbox) - if component uses custom checkbox with label
**Component Props to Preserve**:
- [List existing props from legacy component that should be preserved in wrapper]
- Common props: label, disabled, required, invalid, className, wrapperClassName
**Citrus Components to Import Directly**:
- [List components that can be used directly without wrappers]
- Example: Headline (for headings), Button (for buttons), etc.
"""
)
Handle mapping results:
-
If component not found in citrus-react → Ask user via AskUserQuestion:
{ "questions": [{ "question": "No Citrus equivalent found for <ElementName>. How should we handle it?", "header": "Mapping", "options": [ {"label": "Keep as-is", "description": "Leave the current implementation unchanged"}, {"label": "Create wrapper", "description": "Create a Citrus wrapper component following the wrapper pattern from CITRUS_MIGRATION.md"}, {"label": "Use alternative", "description": "I'll suggest a different Citrus component"} ], "multiSelect": false }] } -
Document final component mapping table for reference
Step 4: Plan Migration Approach
Create migration plan considering:
- Component type (Reusable UI vs Consumer)
- Wrapper creation needs
- CSS refactoring scope
- Test updates needed
- User clarifications from Steps 2-3
- User comments/instructions (if provided - incorporate these into the plan)
Process user comments:
- If user specified a Citrus component to use → Use that component, skip discovery for that mapping
- If user referenced an existing wrapper pattern → Follow that pattern instead of generic
- If user provided custom requirements → Add to plan and document
- User comments override default discovery and should be honored
Use AskUserQuestion for key decisions (skip if user comments already address these):
{
"questions": [
{
"question": "This is a reusable UI component exported from src/components/ui/. Should we create a Citrus wrapper in src/components/ui/citrus/?",
"header": "Wrapper",
"options": [
{"label": "Create wrapper (Recommended)", "description": "Create new Citrus wrapper following the wrapper pattern from CITRUS_MIGRATION.md"},
{"label": "Migrate in-place", "description": "Update existing component to use Citrus directly"},
{"label": "Skip for now", "description": "Mark as TODO for future migration"}
],
"multiSelect": false
},
{
"question": "CSS refactoring approach for this component?",
"header": "CSS",
"options": [
{"label": "Full reorganization (Recommended)", "description": "Group styles, remove unused, apply Citrus utilities, clean up"},
{"label": "Minimal changes", "description": "Only replace what maps to Citrus utilities, keep rest as-is"},
{"label": "Keep existing CSS", "description": "Don't touch CSS, only update components"}
],
"multiSelect": false
}
]
}
Document migration plan:
## Migration Plan
**Approach**: [Wrapper Component / In-Place Migration]
**CSS Strategy**: [Full Reorganization / Minimal / No Changes]
**User Comments**: [User instructions provided / None]
**User Instructions Applied**:
- [List how user comments are being incorporated]
- [Example: "Using ValidationMessage component as specified for Message migration"]
- [Example: "Following ui/citrus/FormInput pattern as requested"]
**Steps**:
1. [✓/☐] Create wrapper components in src/components/ui/citrus/ (if needed for reusable UI)
- [List specific wrappers needed based on component analysis]
- Follow wrapper pattern from CITRUS_MIGRATION.md
2. [✓/☐] Update component imports
- Remove: [List legacy imports to remove]
- Add: [List Citrus wrapper imports from ../ui/citrus]
- Add: [List direct Citrus imports from @kds/citrus-react]
3. [✓/☐] Replace component usage
- [List specific replacements based on component mapping]
- Example: Replace custom input structure with Citrus wrapper
- Example: Replace heading elements with Headline component
- Preserve existing props and behavior
4. [✓/☐] Refactor CSS
- Remove unused classes: [List classes to remove]
- Group similar styles: [List styles to group/consolidate]
- Apply Citrus utilities: [List utility classes to apply]
- Keep layout-specific styles: [List component-specific layout to preserve]
5. [✓/☐] Update tests
- Update selectors for new component structure
- Verify test coverage maintained
- Add new tests for Citrus component integration (if needed)
6. [✓/☐] Document changes
- Add comments for future components needing migration
- Update component props documentation
Step 5: Execute Migration
Execute migration in this order:
5.1: Create Wrapper Components (if needed)
If creating wrappers for reusable UI components:
-
Create directory structure:
mkdir -p src/components/ui/citrus/<ComponentCategory>/ -
Create wrapper component following the wrapper pattern from CITRUS_MIGRATION.md:
General Wrapper Pattern:
import { FC } from 'react'; import { <CitrusComponent>, Label } from '@kds/citrus-react'; import styles from './<Category>.module.css'; // 1. Extend appropriate HTML attributes for the base element export interface <WrapperName>Props extends <BaseHTMLAttributes> { // 2. Add required props from legacy component label: string; // 3. Add optional props for customization wrapperClassName?: string; isRequired?: boolean; isInvalid?: boolean; // 4. Add any component-specific props from legacy implementation [key: string]: any; } export const <WrapperName>: FC<<WrapperName>Props> = ({ label, id, wrapperClassName = '', className = '', // 5. Extract component-specific props ...props }) => { // 6. Add any custom logic from legacy component (validation, formatting, etc.) return ( <div className={`${styles.wrapperLayout} ${wrapperClassName}`}> <Label htmlFor={id}> {label} <CitrusComponent id={id} className={className} aria-label={label} {...props} /> </Label> </div> ); }; -
Create CSS module for wrapper (minimal layout only):
.wrapperLayout { display: flex; flex-direction: column; } -
Create index.ts to export wrapper:
export * from './<WrapperName>'; -
Update src/components/ui/citrus/index.ts:
export * from './<ComponentCategory>';
Key Principles for Wrapper Creation:
- Extend appropriate HTML attributes for type safety
- Preserve all props from legacy component
- Wrap Citrus component with Label if needed for accessibility
- Minimal CSS (layout only, no styling)
- Add aria attributes for accessibility
- Implement any custom logic from legacy component
- Match existing component API to minimize consumer changes
5.2: Update Component File (.tsx)
-
Update imports:
// Remove old imports based on component mapping - import { <LegacyComponents> } from '<old-source>'; // Add Citrus wrapper imports (for reusable UI components) + import { <WrapperComponents> } from '../ui/citrus'; // Add direct Citrus imports (for components that don't need wrappers) + import { <CitrusComponents> } from '@kds/citrus-react'; // Keep existing non-UI imports and unmigrated components import { <UnmigratedComponents> } from '../ui'; // NOT YET MIGRATED -
Replace component usage based on component mapping from Step 3:
General Pattern:
- Replace legacy component structure with Citrus wrapper or direct import
- Add
idprop to interactive elements for accessibility - Preserve all existing props and event handlers
- Keep error/validation rendering in parent component (NOT in wrapper)
- Update CSS class names as needed for new structure
- Maintain all conditional rendering logic
For Wrapped Components (when using wrappers from ../ui/citrus):
// Replace legacy custom component <LegacyComponent label="Field Label" value={value} onChange={handleChange} {...existingProps} /> // With Citrus wrapper <CitrusWrapper id="field-id" // Add for accessibility label="Field Label" value={value} onChange={handleChange} {...existingProps} />For Direct Citrus Components (Typography, Buttons, etc.):
// Replace HTML element <h2 className={styles.header}>Section Title</h2> // With Citrus component <Headline tag="h2" size="<size>" className={styles.headerLayout}> Section Title </Headline> // Check citrus-react documentation for: // - Available props (tag, size, className, etc.) // - Size values (xs, s, m, l, xl, etc.) // - Other component-specific props -
Preserve all props and behavior:
- Keep all event handlers
- Keep all validation logic
- Keep all conditional rendering
- Keep all state management
- Do NOT change component logic
5.3: Refactor CSS Module (.module.css)
Full reorganization approach (following CITRUS_MIGRATION.md guidelines):
-
Identify and remove unused classes:
- Classes for elements replaced by Citrus components
- Duplicate or redundant styles
- Legacy browser-specific hacks no longer needed
- Styles that can be replaced by Citrus utilities
-
Group and consolidate similar styles:
/* BEFORE: Multiple similar classes */ .field1 { margin-bottom: 1rem; } .field2 { margin-bottom: 1rem; } .field3 { margin-bottom: 1rem; } /* AFTER: Grouped into single class */ .fieldRow { margin-bottom: 1rem; } -
Apply Citrus utility classes where appropriate:
- Replace custom spacing with CSS variables or utility classes
- Use Citrus color tokens for colors
- Use Citrus spacing scale for consistent spacing
- Reference citrus-web styles.config.js for available utilities }
-
Keep component-specific layout styles:
- Layout unique to this component's structure
- Complex positioning or flex/grid arrangements
- Component-specific responsive behavior
- Z-index and stacking contexts
- Animations or transitions specific to this component
-
Remove redundant responsive styles:
- Styles that are no longer needed after migration
- Duplicate media queries
- Layout fixes that Citrus components handle natively
-
Target outcome:
- 30-50% reduction in CSS lines
- Only component-specific layout remains
- Typography and basic spacing handled by Citrus
- Cleaner, more maintainable CSS module
5.4: Update Tests (.test.tsx)
-
Update component imports in test file:
// Match component file imports to maintain test consistency import { <WrapperComponents> } from '../ui/citrus'; import { <CitrusComponents> } from '@kds/citrus-react'; -
Update test selectors for new structure:
- If component structure changed, update queries accordingly
- Prefer accessible queries (getByRole, getByLabelText)
- Maintain same test coverage and assertions
- Update data-testid if used for targeting elements
-
Verify test coverage maintained:
- All existing tests should still pass
- Add new tests ONLY if new functionality added
- Update snapshot tests if structure changed
-
Don't run tests - user will run them manually
5.5: Update Related Files
If component has other related files:
- Update Storybook stories (if exists)
- Update documentation (if exists)
- Update examples (if exists)
- Update any component-specific README or usage docs
Step 6: Document Migration
Create migration summary document at workflow/citrus-migration/<ComponentName>-migration.md:
# Citrus Migration: <ComponentName>
**Date**: <timestamp>
**Component Path**: <COMPONENT_PATH>
**Screenshot**: [Provided/Not Provided]
**User Comments**: [Provided/Not Provided]
---
## Migration Summary
**Component Type**: [Reusable UI Component / Consumer Component]
**Migration Approach**: [Wrapper Component / In-Place Migration]
**CSS Strategy**: [Full Reorganization / Minimal / No Changes]
**User Comments Applied** [if provided]:
- [List user instructions that were followed]
- Examples:
- "Used ValidationMessage component as specified for Message migration"
- "Followed ui/citrus/FormInput pattern for form controls"
- "Kept existing error handling logic as requested"
**Changes Made**:
- [X] Created wrapper components in src/components/ui/citrus/ (if applicable)
- [List wrappers created with line counts]
- [X] Updated component imports (N imports added, N removed)
- [X] Replaced component usage (N instances)
- [X] Refactored CSS module (before → after lines, N% reduction)
- [X] Updated tests (N test cases, N selectors updated)
**Files Modified**:
- ✓ src/components/<ComponentName>/<ComponentName>.tsx
- ✓ src/components/<ComponentName>/<ComponentName>.module.css
- ✓ src/components/<ComponentName>/__tests__/<ComponentName>.test.tsx
- [List any wrapper files created]
- [List any other files modified]
---
## Component Mapping
| Original | Citrus Replacement | Import Source | Notes |
|----------|-------------------|---------------|-------|
| [Legacy component/element] | [Citrus component] | [Import path] | [Wrapper created / Direct import / Props] |
| [Example: <input> + <label>] | [Example: InputWrapper] | [../ui/citrus] | [Wrapper created] |
| [Example: <h2>] | [Headline] | [@kds/citrus-react] | [Direct import, tag="h2" size="s"] |
| [Unmigrated component] | [Unmigrated component] | [../ui] | [**NOT MIGRATED** - future task] |
---
## CSS Changes
**Removed Classes** (N classes, ~N lines):
- [List removed classes]
- [Classes no longer needed after Citrus migration]
- [Redundant or duplicate styles]
**Updated Classes** (N classes):
- [List modified classes and what changed]
**Added Classes** (N classes):
- [List new classes needed for layout]
**Preserved Classes** (N classes):
- [List component-specific classes preserved]
- [Layout classes still needed]
- [Media queries preserved]
**Bundle Size Impact**: ~N KB reduction (N lines → N lines CSS)
---
## Dependencies Status
**Migrated Dependencies** (used in this component):
- [List components migrated to Citrus as part of this migration]
- [Wrapper created / Direct import]
**Unmigrated Dependencies** (flagged for future migration):
- [List custom components still using legacy UI]
- [Path to component] - Keep as-is for now
**Note**: [Summary of unmigrated dependencies and migration strategy]
---
## Testing Checklist
**Manual Testing Required**:
- [ ] Run `yarn test` to verify all tests pass
- [ ] Run `yarn start` to start dev server
- [ ] Visually verify component renders correctly
- [ ] Test all component interactions and functionality
- [ ] Test error/edge case states display correctly
- [ ] Test responsive behavior (mobile, tablet, desktop)
- [ ] Verify accessibility (keyboard navigation, screen reader, ARIA)
- [ ] Compare with Figma screenshot (if provided)
**Expected Test Results**:
- All existing tests should pass
- Component behavior unchanged
- Visual appearance consistent (or improved if screenshot provided)
---
## Next Steps
1. **Test Migration**:
```bash
yarn test
yarn start
-
Review Changes:
git diff src/components/<ComponentName>/ git diff src/components/ui/citrus/ -
If Tests Pass:
- Review and commit changes
- Update migration tracking document
- Proceed to next component
-
If Tests Fail:
- Review test failures
- Fix issues or rollback changes
- Re-run migration with clarifications
-
Future Migrations:
- [List unmigrated dependencies that need migration]
- [Update this component after dependencies are migrated]
Migration Patterns Learned
Wrapper Component Pattern (if wrappers were created):
- [Describe wrapper pattern used]
- [Key props preserved from legacy component]
- [Custom logic implemented]
- [Accessibility improvements]
Component Replacement Pattern:
- [How legacy components were replaced with Citrus]
- [Import strategy used]
- [Props mapping approach]
- [Error/validation handling approach]
CSS Refactoring Pattern:
- [Classes removed and why]
- [Classes consolidated and how]
- [Citrus utilities applied]
- [Layout patterns preserved]
Migration completed successfully - ready for testing
### Step 7: Report Results
Display migration summary to user:
✓ Citrus migration completed for <ComponentName>
User Comments: [Provided/Not Provided]
- [If provided, list user instructions that were applied]
Files Modified:
- ✓ src/components/<ComponentName>/<ComponentName>.tsx (N replacements)
- ✓ src/components/<ComponentName>/<ComponentName>.module.css (N% reduction)
- ✓ src/components/<ComponentName>/tests/<ComponentName>.test.tsx (N selectors updated)
Wrappers Created (if applicable):
- [List wrapper files created]
Component Mapping:
- [Legacy] → [Citrus] (wrapper/direct import)
- [List all component replacements]
- [If user comments specified mapping, note: "As per user instruction"]
- [Unmigrated] → [Unmigrated] (NOT MIGRATED - future task)
CSS Impact:
- Removed: N classes (~N lines)
- Updated: N classes
- Added: N classes
- Total reduction: N → N lines (N%)
Bundle Size: ~N KB reduction (estimated)
Dependencies:
- ✓ [Migrated dependencies]
- ⚠️ [Unmigrated dependencies flagged for future]
Screenshot Analysis: [Completed/Skipped]
Migration Document: workflow/citrus-migration/<ComponentName>-migration.md
Next Steps:
- Review changes: git diff src/components/<ComponentName>/
- Run tests: yarn test
- Start dev server: yarn start
- Visually verify component renders correctly
- Test all interactions and error states
- If tests pass, commit changes and proceed to next component
⚠️ IMPORTANT: No git actions were performed. Review and commit changes manually.
## Error Handling
### Common Errors
**Component file not found**:
- Exit with error: "Component file not found at <COMPONENT_PATH>"
- Suggest checking path and trying again
**Screenshot file not found** (if provided):
- Exit with error: "Screenshot file not found at <SCREENSHOT_PATH>"
- Suggest checking path or proceeding without screenshot
**Unmigrated dependencies detected**:
- Ask user via AskUserQuestion how to proceed
- Options: Continue / Stop / Create wrappers
**Citrus component not found in citrus-react**:
- Ask user via AskUserQuestion for alternative
- Suggest creating wrapper or keeping as-is
**CSS module not found**:
- Continue without CSS refactoring
- Note in migration document: "No CSS module found"
**Test file not found**:
- Continue without test updates
- Note in migration document: "No test file found"
### Recovery Strategies
**Migration partially complete**:
- Document which files were modified
- Suggest manual rollback if needed
- Provide clear error message for what failed
**User cancels migration mid-way**:
- Document progress made
- List files modified so far
- Suggest manual cleanup or completion
**Citrus repo access fails**:
- Fall back to CITRUS_MIGRATION.md component catalog
- Warn user: "Could not access citrus-react repo, using fallback mapping"
## Token Optimization
**Efficient agent usage**:
- Use Explore agent (haiku model) for component discovery (~10-15k tokens)
- Read only necessary files (component, CSS, tests, CITRUS_MIGRATION.md)
- Use tables for component mapping (saves ~5k tokens vs. prose)
- Reference file:line numbers instead of code blocks
- Keep migration document concise (<5 KB)
**Avoid token waste**:
- Don't re-read CITRUS_MIGRATION.md multiple times (cache it after first read)
- Don't fetch entire citrus-react repo
- Don't include full code examples in prompts
- Use targeted Grep searches vs. broad exploration
**Target token budget**:
- Context reading: ~20-30k tokens
- Component discovery: ~10-15k tokens
- Migration execution: ~10-15k tokens
- Total: ~40-60k tokens per component migration
## Examples
### Example 1: Reusable UI Component
```bash
/citrus-migrate src/components/ui/CustomInput/CustomInput.tsx
Expected outcome:
- Create Citrus wrapper in src/components/ui/citrus/CustomInput.tsx
- Replicate existing component props and behavior
- Wrap Citrus component appropriately (with Label if needed)
- Create minimal CSS module for layout
- Export from src/components/ui/citrus/index.ts
Example 2: Consumer Component with Screenshot
/citrus-migrate src/components/MyComponent/MyComponent.tsx ~/Downloads/my-component-figma.png
Expected outcome:
- Analyze Figma screenshot for visual guidance
- Map components based on screenshot analysis + citrus-react search
- Update imports to use Citrus wrappers/components
- Replace component usage following CITRUS_MIGRATION.md guidelines
- Full CSS refactoring (30-50% reduction target)
- Update tests with new selectors
- Document unmigrated dependencies as future tasks
Example 3: Component with User Comments/Instructions
/citrus-migrate src/components/ErrorDisplay/ErrorDisplay.tsx "Use ValidationMessage Citrus component for migrating Message component"
Expected outcome:
- Skip discovery for Message component → Use ValidationMessage as specified
- Apply user instruction in component mapping
- Document user comment in migration plan and final document
- Prioritize user's specified component over default discovery
Example 4: Component with Screenshot and User Comments
/citrus-migrate src/components/PaymentForm/PaymentForm.tsx ~/Downloads/payment-form.png "Follow ui/citrus/FormInput pattern for all form controls. Keep validation logic intact."
Expected outcome:
- Analyze Figma screenshot for visual guidance
- Reference existing ui/citrus/FormInput wrapper as pattern for all form controls
- Preserve validation logic as requested
- Document both screenshot analysis and user instructions
- Create consistent wrapper pattern following FormInput
Example 5: Component with Unmigrated Dependencies
/citrus-migrate src/components/ComplexComponent/ComplexComponent.tsx
Expected outcome:
- Detect custom UI dependencies not yet migrated
- Flag blocker and ask user how to proceed (Continue/Stop/Create wrappers)
- If user chooses "Stop", exit gracefully with blocker summary
- If user chooses "Continue", proceed and document dependencies in migration doc
- If user chooses "Create wrappers", create wrappers as part of migration
Success Criteria
Migration is successful when:
- ✓ All target files (.tsx, .module.css, .test.tsx) migrated
- ✓ Component behavior preserved (no logic changes)
- ✓ CSS reduced by 30-50% through cleanup and utilities
- ✓ Wrapper components follow the wrapper pattern from CITRUS_MIGRATION.md
- ✓ User comments/instructions honored and applied correctly (if provided)
- ✓ Migration document created with full details (including user comments applied)
- ✓ No git actions performed
- ✓ User provided with clear next steps for testing
- ✓ Dependencies flagged for future migration if not migrated
Migration fails when:
- ✗ Component logic or behavior changed
- ✗ Cannot find suitable Citrus equivalent and user declines wrapper
- ✗ Critical files cannot be read or written
- ✗ Unmigrated dependencies exist and user chooses to stop
Notes
DO:
- Follow CITRUS_MIGRATION.md guidelines
- Search citrus-web and citrus-react extensively via GitHub MCP
- Ask clarifying questions via AskUserQuestion
- Document all decisions and changes
- Preserve component logic and behavior exactly
- Flag unmigrated dependencies
- Create wrappers following the pattern from CITRUS_MIGRATION.md
DO NOT:
- Perform any git actions (stage, commit, push, branch)
- Run tests or build validation
- Change component logic or state management
- Auto-migrate dependencies without user confirmation
- Bundle Citrus styles in component CSS
- Skip CSS refactoring (unless user chooses minimal approach)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.