Skip to main content

tailwind-plus-migration

This skill should be used when creating ViewComponent wrappers for Tailwind Plus UI Blocks. It guides the process of fetching Tailwind Plus component documentation, designing a ViewComponent interface, generating component code with proper variant handling, creating unit tests, and setting up Lookbook previews with automatically generated variants.

Source facts

Repository
dgalarza/dotfiles
Last source activity
March 20, 2026 at 17:58
Detected SKILL.md language
English
Stars
5
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
6 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
tailwind-plus-migration
description
This skill should be used when creating ViewComponent wrappers for Tailwind Plus UI Blocks. It guides the process of fetching Tailwind Plus component documentation, designing a ViewComponent interface, generating component code with proper variant handling, creating unit tests, and setting up Lookbook previews with automatically generated variants.
# Tailwind Plus Migration Skill ## Purpose Streamline the migration from home-grown UI components to Tailwind Plus UI Blocks by automating the creation of well-structured, tested, and documented ViewComponent wrappers. ## When to Use This Skill Use this skill when: - Creating a new ViewComponent wrapper for a Tailwind Plus UI Block - You have a component name (e.g., "Button", "Select") or HTML example - You need the component in `app/components/` - You need unit tests in `spec/components/` - You need a Lookbook preview in `spec/components/previews/` **Do NOT use for:** - Modifying existing components (use normal editing) - Refactoring without a Tailwind Plus migration goal - Creating entirely custom components without a Tailwind Plus basis ## Workflow ### Phase 1: Component Definition (User Input) The user provides: - **Component name** (e.g., "Button", "Modal", "Select") OR - **HTML example** (paste the Tailwind Plus HTML block) - **Project-specific requirements** (optional, e.g., "needs to support a loading state") ### Phase 2: Fetch Tailwind Plus Documentation Use context7 to retrieve the Tailwind Plus UI Block documentation: 1. Resolve the library ID for Tailwind Plus UI Blocks 2. Fetch the component documentation with focus on: - HTML structure and class requirements - Available variants and states - Props/attributes supported - Slot/content areas available - Accessibility features (ARIA, roles) **Key information to extract:** - All variant options (e.g., primary, secondary, ghost, etc.) - All size options (e.g., sm, md, lg, xl) - All state combinations (disabled, loading, active, etc.) - Required vs. optional content/slots - Customization points (colors, icons, etc.) ### Phase 3: Design ViewComponent Interface Analyze the Tailwind Plus documentation and design a Ruby interface: 1. **Props**: Map HTML attributes to Ruby parameters - Variants as symbol enums - Sizes as symbol enums - Boolean flags for states - **Always include `**html_options`** for flexibility 2. **Slots**: Identify content areas that map to `renders_one` or `renders_many` - Icon slots (typically `renders_one`) - List items (typically `renders_many`) - Footer/header actions - Custom content areas 3. **Class Mappings**: Create constant hashes for variants and sizes - Use `VARIANT_MAPPINGS` hash with symbols as keys - Use `SIZE_MAPPINGS` hash with symbols as keys - Extract base classes that apply to all variants - Use `.fetch(key, default)` to safely handle unknown values 4. **Helper Methods**: Identify any conditional logic - Methods that return CSS classes based on state - Methods that determine visibility (e.g., `show_icon?`) - Private methods for computed values ### Phase 4: Generate ViewComponent Create the ViewComponent file using the structure from `assets/viewcomponent_template.rb`: ```ruby # app/components/[component_name]_component.rb class [COMPONENT_NAME]Component < ApplicationComponent VARIANT_MAPPINGS = { # variant_name: "tailwind classes" }.freeze SIZE_MAPPINGS = { # size_name: "tailwind classes" }.freeze # renders_one and renders_many declarations def initialize( # All props with sensible defaults **html_options ) # Store all parameters end private # attr_reader for all instance variables def component_classes # Combine base, variant, size, and state classes end # Additional helper methods as needed end ``` **Important patterns:** - Always use `attr_reader` in private section for all instance variables - Use `.freeze` on constant hashes - Build CSS classes by combining base + variant + size + state + custom - Use `strip` to clean up final class string - Handle unknown variant/size values with sensible defaults using `.fetch()` ### Phase 5: Create Component Template Create the ERB template at `app/components/[component_name]_component.html.erb`: 1. Use the HTML structure from Tailwind Plus docs 2. Replace hardcoded classes with `component_classes` method 3. Implement `renders_one` and `renders_many` slots 4. Add accessibility attributes (aria-*, role, etc.) 5. Add `data-testid` attributes for testing Example structure: ```erb <button class="<%= component_classes %>" <%= html_attributes %>> <% if icon.present? %> <%= render icon %> <% end %> <%= content %> </button> ``` ### Phase 6: Generate Unit Tests Create RSpec tests at `spec/components/[component_name]_component_spec.rb`: Use the template from `assets/rspec_template.rb`. Generate test cases for: 1. **Basic rendering**: Component renders without errors 2. **Variants**: Each variant renders with correct classes - Test each variant in VARIANT_MAPPINGS - Verify correct classes are applied - Test default variant behavior 3. **Sizes**: Each size renders with correct classes - Test each size in SIZE_MAPPINGS - Verify correct classes are applied - Test default size behavior 4. **States**: Disabled/loading/active states work - Test each state that has class changes - Verify classes appear/disappear correctly 5. **HTML options**: Custom classes and attributes are applied - Test passing custom `class:` option - Test passing custom `data:` attributes - Verify they're appended correctly **Test patterns to follow:** ```ruby # For variant testing it 'renders [variant] variant' do render_inline(described_class.new(variant: :[variant])) expect(rendered_component).to include('[Expected class]') end # For state testing it 'applies disabled state' do render_inline(described_class.new(disabled: true)) expect(rendered_component).to include('opacity-50') expect(rendered_component).to include('cursor-not-allowed') end ``` ### Phase 7: Generate Lookbook Preview Create Lookbook preview files: 1. **Preview class** at `spec/components/previews/[component_name]_preview.rb` - Use template from `assets/lookbook_template.rb` - Create preview methods for each section 2. **Preview template** at `spec/components/previews/[component_name]_preview/[method].html.erb` - Use template from `assets/lookbook_template.html.erb` - Show all variants automatically - Show all sizes automatically - Show all states automatically - Create organized sections with clear labels **Lookbook preview methods:** - `default`: Basic usage example - `variants`: All variant combinations - `sizes`: All size options - `states`: Disabled, loading, active, etc. - `all_variants`: Optional—comprehensive showcase ### Phase 8: Document Usage Add inline documentation to the component for LLM consumption: ```ruby # At the top of the component class: # [COMPONENT_NAME]Component # # A Tailwind Plus wrapper for the [Component] UI block. # # Variants: :primary, :secondary, :ghost (default: :primary) # Sizes: :sm, :md, :lg (default: :md) # States: disabled boolean # # Usage: # <%= render ButtonComponent.new( # variant: :primary, # size: :lg, # class: 'my-custom-class' # ) %> # # With slots: # <%= render ButtonComponent.new do |c| %> # <% c.with_icon { icon_svg } %> # <% end %> ``` ## Input Examples ### Example 1: By Component Name **User says:** > Create a Button component from Tailwind Plus **Skill does:** 1. Looks up "Button" in Tailwind Plus UI Blocks docs via context7 2. Extracts variants (primary, secondary, ghost, danger) 3. Extracts sizes (sm, md, lg) 4. Generates ViewComponent with VARIANT_MAPPINGS and SIZE_MAPPINGS 5. Creates RSpec tests for all variants and sizes 6. Creates Lookbook preview with variant showcase 7. Documents the component with usage examples ### Example 2: By HTML Example **User pastes:** ```html <div class="relative inline-flex group"> <select class="peer h-12 w-full border border-gray-200 px-4 py-2 text-black focus:border-blue-400"> <option>Option 1</option> <option>Option 2</option> </select> <!-- Custom arrow icon --> </div> ``` **Skill does:** 1. Identifies this as a custom Select component 2. Fetches Tailwind Plus Select documentation 3. Maps the HTML structure to a ViewComponent 4. Creates variant mappings for states (default, error, disabled) 5. Generates full component with tests and preview ## Output Artifacts For each component created, generate: 1. **ViewComponent** (`app/components/[component_name]_component.rb`) - 50-100 lines with proper structure - VARIANT_MAPPINGS and SIZE_MAPPINGS constants - Clear private methods for class building - Inline documentation 2. **Template** (`app/components/[component_name]_component.html.erb`) - Direct translation of Tailwind Plus HTML - All slots implemented - Accessibility attributes present - data-testid attributes for testing 3. **RSpec Tests** (`spec/components/[component_name]_component_spec.rb`) - Tests for variants, sizes, states, HTML options - Clear test descriptions - Ready to run (fill in exact class names) 4. **Lookbook Preview** - Preview class at `spec/components/previews/[component_name]_preview.rb` - Preview templates showing all variants - Organized sections with descriptions - Screenshot-ready 5. **Documentation** (inline in component) - Component purpose - Available variants - Available sizes - Usage examples - Slot documentation (if applicable) ## Reference Material - See `references/tailwind-plus-guide.md` for integration overview - See `assets/viewcomponent_template.rb` for component structure pattern - See `assets/rspec_template.rb` for test patterns - See `assets/lookbook_template.rb` and `lookbook_template.html.erb` for preview patterns ## Success Criteria A successful component migration should result in: - ✅ ViewComponent renders correctly with all variants and sizes - ✅ RSpec tests pass with 100% of variants and states tested - ✅ Lookbook preview displays all variants and states visually - ✅ Component can be used in templates: `<%= render ButtonComponent.new(variant: :primary) %>` - ✅ Inline documentation explains props, variants, and usage - ✅ VARIANT_MAPPINGS and SIZE_MAPPINGS use constant hashes (frozen) - ✅ No hardcoded class strings in helper methods—all classes from mappings or methods ## Example Output Structure ``` Created: app/components/button_component.rb Created: app/components/button_component.html.erb Created: spec/components/button_component_spec.rb Created: spec/components/previews/button_preview.rb Created: spec/components/previews/button_preview/default.html.erb Created: spec/components/previews/button_preview/variants.html.erb Created: spec/components/previews/button_preview/sizes.html.erb Created: spec/components/previews/button_preview/states.html.erb Next steps: 1. Run tests: bundle exec rspec spec/components/button_component_spec.rb 2. View in Lookbook: bin/lookbook 3. Update any test assertions with correct class names 4. Commit files and create PR ```
View on GitHub