🍞
汎用パンクズリストコンポーネントを作ってみた(Ruby on Rails)
パンクズリストを汎用コンポーネントとして再利用できるようしました。
※前提として gem view_component
の導入が必要です。
コード
# frozen_string_literal: true
class BreadcrumbsComponent < ViewComponent::Base
def initialize(items:)
super
@items = items
@data_scope_path = "components/#{self.class.name.underscore}"
end
def call
content_tag(:nav, aria: { label: "breadcrumb" }, data: { scope_path: @data_scope_path }) do
concat(content_tag(:ol, class: "breadcrumb", itemscope: "", itemtype: "https://schema.org/BreadcrumbList") do
@items.each_with_index do |item, index|
index == @items.size - 1 ? concat(last_breadcrumb_item(item, index)) : concat(breadcrumb_item(item, index))
end
end)
end
end
private
def last_breadcrumb_item(item, index)
content_tag(
:li,
class: "breadcrumb-item active",
aria: { current: "page" },
itemprop: "itemListElement",
itemscope: "",
itemtype: "https://schema.org/ListItem"
) do
concat(content_tag(:span, item[:name], itemprop: "name"))
concat(tag.meta(itemprop: "position", content: (index + 1).to_s))
end
end
def breadcrumb_item(item, index)
content_tag(
:li,
class: "breadcrumb-item",
itemprop: "itemListElement",
itemscope: "",
itemtype: "https://schema.org/ListItem"
) do
concat(link_to(item[:path], itemprop: "item") do
content_tag(:span, item[:name], itemprop: "name")
end)
concat(tag.meta(itemprop: "position", content: (index + 1).to_s))
concat(content_tag(:span, "/", class: "arrow"))
end
end
end
[data-scope-path="components/breadcrumbs_component"] {
.breadcrumb {
display: flex;
align-items: center;
justify-content: flex-start;
margin: 0;
padding: 0;
overflow-y: scroll;
white-space: nowrap;
}
.breadcrumb-item {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 0;
list-style: none;
}
.arrow {
display: block;
margin: 0 0.6rem;
}
}
使い方
<%= render(Application::Common::BreadcrumbsComponent.new(items: [
{ name: "TOP", path: root_path },
{ name: "Articles", path: articles_path },
{ name: @article.title, path: article_path(@article.id) }
])) %>
使いたい人はコピペしてどうぞ。
Discussion