Why components?
Components make it easy to build a more consistent user interface, which ends up feeling much higher quality to your users. Additionally, shipping new features with a library of components is much easier than building everything from scratch or wrestling with various partials.
A few components in a production Rails application
Breadcrumbs are useful navigation elements for providing a hierarchy of pages your users can navigate through.
In Phlex, a breadcrumb component could be called like this:
🔓 Unlock content
Purchase this course to unlock this video, source code, and content.
class Show < ▓▓▓▓▓▓▓▓▓▓▓▓▓::▓▓▓▓▓▓▓▓▓
attr_writer :item
def ▓▓▓▓▓ = ▓▓▓▓▓.▓▓▓▓
def ▓▓▓▓ = ▓▓▓▓▓.▓▓▓▓
def ▓▓▓▓▓▓▓▓
▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓ do
▓ ▓▓▓ ▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓ ▓▓▓▓▓
▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓▓▓▓▓, :name) }
▓ ▓▓▓▓▓ ▓▓▓ ▓▓ ▓ ▓▓▓▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓
▓▓▓▓▓.▓▓▓▓▓▓▓▓▓.▓▓▓▓▓▓▓.▓▓▓▓ do |▓▓▓▓|
▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓, :name) }
end
▓ ▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓ ▓▓▓▓
▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓▓, :name) }
end
end
end
▓▓▓▓ ▓▓▓▓ ▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓
<%= ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓.▓▓▓ do %>
<% ▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓▓▓▓▓, :name) } %>
<% ▓▓.▓▓▓▓▓ do %>
<%= ▓▓▓▓▓▓▓(▓▓▓▓▓, :name) %>
<% end %>
<% end %>
The component
▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓ ▓▓ ▓ ▓▓ ▓▓ ▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓
class Components::BreadcrumbComponent < ▓▓▓▓▓▓▓▓▓▓::▓▓▓▓
▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓(class: "breadcrumbs m-0 p-0") do
▓▓ do
▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓
yield
end
end
end
▓ ▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓
def ▓▓▓▓▓(&)
▓▓(&)
end
end
▓▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓
Build a UI kit for your app
▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓ ▓▓▓▓▓▓ ▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓
class Show < ▓▓▓▓▓▓▓▓▓▓▓▓▓::▓▓▓▓▓▓▓▓▓
▓ ▓▓▓
def ▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓ do
▓▓.▓▓▓▓▓ {
▓ ▓▓▓▓▓▓ ▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓::▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓.▓▓▓(
title: ▓▓▓▓▓.▓▓▓▓,
icon: ▓▓▓▓▓.▓▓▓▓,
subtitle: ▓▓▓▓▓.▓▓▓▓▓▓▓▓▓▓▓
)
}
▓ ▓▓▓
▓▓▓▓▓.▓▓▓▓▓▓▓▓▓.▓▓▓▓▓▓▓.▓▓▓▓ do |▓▓▓▓|
▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓, :name) }
end
▓ ▓▓▓
▓▓.▓▓▓▓▓ { ▓▓▓▓(▓▓▓▓▓, :name) }
end
end
end
Easier to reason through for highly stateful user interfaces
▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
class Item < ▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓ ▓▓▓▓▓ do |▓▓|
▓▓.▓▓▓▓▓(:created_at)
▓▓.▓▓▓▓▓(:updated_at)
▓▓.▓▓▓▓▓(:user) { ▓▓▓▓▓.▓▓▓▓.▓▓▓▓ }
if ▓▓▓▓▓.▓▓▓▓▓▓▓▓▓▓
▓▓.▓▓▓▓▓(:expires_at)
end
end
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓(class: "join") do
▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓), class: "join-item") { "Edit" }
▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓), class: "join-item") { "Change icon" }
▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓.▓▓▓▓▓), class: "join-item") { "Label" }
end
▓▓▓▓ title: "More..." do |▓▓|
▓▓.▓▓▓▓ do
▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓)) { "Copy" }
end
▓▓.▓▓▓▓ enabled: ▓▓▓▓▓▓▓▓.▓▓▓▓▓▓▓▓▓▓▓▓▓.▓▓▓▓▓▓▓▓ do
▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓)) { "Loan" }
end
▓▓.▓▓▓▓ enabled: ▓▓▓▓▓▓▓▓.▓▓▓▓.▓▓▓▓▓▓▓▓ do
▓▓▓▓▓▓▓(▓▓▓▓▓.▓▓▓▓▓▓▓▓ ? ▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓.▓▓▓▓▓▓▓▓) : ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓)) { "Move" }
end
▓▓.▓▓▓▓ do
▓▓▓▓▓▓(▓▓▓▓▓, confirm: "Are you sure?") { "Delete" }
end
end
end
end
▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓
▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓
Integrates into design system workflows
▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓ ▓▓ ▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓
▓▓ ▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓ ▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓
