Skip to main content
viewcomponent-coder Build component-based UIs with ViewComponent and view_component-contrib. Use when creating reusable UI components, implementing slots and style variants, or building component previews. Triggers on ViewComponent creation, component patterns, Lookbook previews, or UI component architecture.
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill viewcomponent-coder命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Create distinctive, production-grade frontend interfaces with high design quality. Use when building web components, pages, or applications. Includes framework-specific guidance for Tailwind, React, Vue, and Rails/Hotwire ecosystems.
Skill file structure, naming conventions, directory layout, frontmatter requirements, and invocation control. Use when creating skill files or slash commands to ensure correct format and validation.
Forces adversarial reasoning before committing to decisions. Triggers on architectural choices, approach selection, and planning phases to prevent premature commitment bias.
majesticlabs-dev
majesticlabs-dev/majestic-marketplace
打开 GitHub 仓库
name viewcomponent-coder description Build component-based UIs with ViewComponent and view_component-contrib. Use when creating reusable UI components, implementing slots and style variants, or building component previews. Triggers on ViewComponent creation, component patterns, Lookbook previews, or UI component architecture.
ViewComponent Patterns
Build modern, component-based UIs with ViewComponent using Evil Martians' view_component-contrib patterns.
When to Use This Skill
Creating ViewComponent classes
Implementing slots and style variants
Building Lookbook previews
Testing components in isolation
Refactoring partials to components
Core Principle: Components Over Partials
Prefer ViewComponents over partials for reusable UI.
Why ViewComponents?
Better encapsulation than partials
Testable in isolation
Object-oriented approach with explicit contracts
IDE support and type safety
Performance benefits (compiled templates)
Setup
gem "view_component"
gem "view_component-contrib"
gem "dry-initializer"
gem "lookbook"
gem "inline_svg"
Install with Rails template:
rails app:template LOCATION=
"https://railsbytes.com/script/zJosO5"
Base Classes
class ApplicationViewComponent < ViewComponentContrib::Base
extend Dry::Initializer
end
class ApplicationViewComponentPreview < ViewComponentContrib::Preview::Base
self .abstract_class = true
end
Basic Component with dry-initializer
class ButtonComponent < ApplicationViewComponent
option :text
option :variant , default: -> { :primary }
option :size , default: -> { :md }
end
<%# app/components/button_component.html.erb %>
<button class="btn btn-<%= variant %> btn-<%= size %>">
<%= text %>
</button>
Style Variants DSL Replace manual VARIANTS hashes with the Style Variants DSL:
class ButtonComponent < ApplicationViewComponent
include ViewComponentContrib::StyleVariants
option :text
option :color , default: -> { :primary }
option :size , default: -> { :md }
style do
base { %w[font-medium rounded-full] }
variants {
color {
primary { %w[bg-blue-500 text-white] }
secondary { %w[bg-gray-500 text-white] }
danger { %w[bg-red-500 text-white] }
}
size {
sm { "text-sm px-2 py-1" }
md { "text-base px-4 py-2" }
lg { "text-lg px-6 py-3" }
}
}
compound(size: :lg , color: :primary ) { "uppercase" }
defaults { { color: :primary , size: :md } }
end
end
<button class="<%= style(color:, size:) %>">
<%= text %>
</button>
Component with Slots class CardComponent < ApplicationViewComponent
renders_one :header
renders_one :footer
renders_many :actions
end
<%= render CardComponent.new do |card| %>
<% card.with_header do %>
<h3>Title</h3>
<% end %>
<p>Body content</p>
<% card.with_action do %>
<%= helpers.link_to "Edit", edit_path %>
<% end %>
<% end %>
Important Rules 1. Prefix Rails helpers with helpers.
<%# CORRECT %>
<%= helpers.link_to "Home", root_path %>
<%= helpers.image_tag "logo.png" %>
<%= helpers.inline_svg_tag "icons/user.svg" %>
<%# WRONG - will fail in component context %>
<%= link_to "Home", root_path %>
Exception : t() i18n helper does NOT need prefix:
2. SVG Icons as Separate Files
Store SVGs in app/assets/images/icons/ and render with inline_svg gem:
<%= helpers.inline_svg_tag "icons/user.svg", class: "w-5 h-5" %>
Don't inline SVG markup in Ruby code - use separate files instead.
Conditional Rendering class AlertComponent < ApplicationViewComponent
option :message
option :type , default: -> { :info }
option :dismissible , default: -> { true }
def render?
message.present?
end
end
Lookbook Previews
class ButtonComponentPreview < ApplicationViewComponentPreview
def default
render ButtonComponent .new(text: "Click me" )
end
def primary
render ButtonComponent .new(text: "Primary" , color: :primary )
end
def all_sizes
render_with(wrapper: :flex_row ) do
safe_join([
render(ButtonComponent .new(text: "Small" , size: :sm )),
render(ButtonComponent .new(text: "Medium" , size: :md )),
render(ButtonComponent .new(text: "Large" , size: :lg ))
])
end
end
end
Access at: http://localhost:3000/lookbook
Testing Components RSpec .describe ButtonComponent , type: :component do
it "renders button text" do
render_inline(ButtonComponent .new(text: "Click me" ))
expect(page).to have_button("Click me" )
end
it "applies style variant classes" do
render_inline(ButtonComponent .new(text: "Save" , color: :primary , size: :lg ))
expect(page).to have_css("button.bg-blue-500.text-lg" )
end
end
Detailed References For advanced patterns and examples:
references/patterns.md - Slots, collections, polymorphic components, Turbo integration
references/style-variants.md - Full Style Variants DSL, compound variants, TailwindMerge