app/components/primer/alpha/underline_nav.rb (39 lines of code) (raw):

# frozen_string_literal: true module Primer module Alpha # Use `UnderlineNav` to style navigation links with a minimal # underlined selected state, typically placed at the top # of the page. # # For panel navigation, use <%= link_to_component(Primer::Alpha::UnderlinePanels) %> instead. # # @accessibility # - By default, `UnderlineNav` renders links within a `<nav>` element. `<nav>` has an # implicit landmark role of `navigation` which should be reserved for main links. # For all other set of links, set tag to `:div`. # - See <%= link_to_component(Primer::Navigation::TabComponent) %> for additional # accessibility considerations. class UnderlineNav < Primer::Component include Primer::TabbedComponentHelper include Primer::UnderlineNavHelper BODY_TAG_DEFAULT = :ul TAG_DEFAULT = :nav TAG_OPTIONS = [TAG_DEFAULT, :div].freeze # Use the tabs to list page links. # # @param selected [Boolean] Whether the tab is selected. # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> renders_many :tabs, lambda { |selected: false, **system_arguments| system_arguments[:classes] = underline_nav_tab_classes(system_arguments[:classes]) Primer::Navigation::TabComponent.new( list: true, selected: selected, icon_classes: "UnderlineNav-octicon", **system_arguments ) } # Use actions for a call to action. # # @param tag [Symbol] (Primer::UnderlineNavHelper::ACTIONS_TAG_DEFAULT) <%= one_of(Primer::UnderlineNavHelper::ACTIONS_TAG_OPTIONS) %> # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> renders_one :actions, lambda { |tag: ACTIONS_TAG_DEFAULT, **system_arguments| system_arguments[:tag] = fetch_or_fallback(ACTIONS_TAG_OPTIONS, tag, ACTIONS_TAG_DEFAULT) system_arguments[:classes] = underline_nav_action_classes(system_arguments[:classes]) Primer::BaseComponent.new(**system_arguments) } # @example Default with `<nav>` # @description # `<nav>` is a landmark and should be reserved for main navigation links. See <%= link_to_accessibility %>. # @code # <%= render(Primer::Alpha::UnderlineNav.new(label: "Default with nav element")) do |component| %> # <% component.tab(href: "#", selected: true) { "Item 1" } %> # <% component.tab(href: "#") { "Item 2" } %> # <% component.actions do %> # <%= render(Primer::ButtonComponent.new) { "Button!" } %> # <% end %> # <% end %> # # @example With `<div>` # <%= render(Primer::Alpha::UnderlineNav.new(tag: :div, label: "With div element")) do |component| %> # <% component.tab(href: "#", selected: true) { "Item 1" } %> # <% component.tab(href: "#") { "Item 2" } %> # <% component.actions do %> # <%= render(Primer::ButtonComponent.new) { "Button!" } %> # <% end %> # <% end %> # # @example With icons and counters # <%= render(Primer::Alpha::UnderlineNav.new(label: "With icons and counters")) do |component| %> # <% component.tab(href: "#", selected: true) do |t| %> # <% t.icon(icon: :star) %> # <% t.text { "Item 1" } %> # <% end %> # <% component.tab(href: "#") do |t| %> # <% t.icon(icon: :star) %> # <% t.text { "Item 2" } %> # <% t.counter(count: 10) %> # <% end %> # <% component.tab(href: "#") do |t| %> # <% t.text { "Item 3" } %> # <% t.counter(count: 10) %> # <% end %> # <% component.actions do %> # <%= render(Primer::ButtonComponent.new) { "Button!" } %> # <% end %> # <% end %> # # @example Align right # <%= render(Primer::Alpha::UnderlineNav.new(label: "Align right", align: :right)) do |component| %> # <% component.tab(href: "#", selected: true) do |t| %> # <% t.text { "Item 1" } %> # <% end %> # <% component.tab(href: "#") do |t| %> # <% t.text { "Item 2" } %> # <% end %> # <% component.actions do %> # <%= render(Primer::ButtonComponent.new) { "Button!" } %> # <% end %> # <% end %> # # @example Customizing the body # <%= render(Primer::Alpha::UnderlineNav.new(label: "Default", body_arguments: { classes: "custom-class", border: true, border_color: :accent_emphasis })) do |c| %> # <% c.tab(selected: true, href: "#") { "Tab 1" }%> # <% c.tab(href: "#") { "Tab 2" } %> # <% c.tab(href: "#") { "Tab 3" } %> # <% end %> # # @param tag [Symbol] <%= one_of(Primer::Alpha::UnderlineNav::TAG_OPTIONS) %> # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the links, and distinguish it from similar elements. # @param align [Symbol] <%= one_of(Primer::UnderlineNavHelper::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavHelper::ALIGN_DEFAULT %> # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper. # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> def initialize(label:, tag: TAG_DEFAULT, align: ALIGN_DEFAULT, body_arguments: {}, **system_arguments) @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT) @system_arguments = system_arguments @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT) @system_arguments[:classes] = underline_nav_classes(@system_arguments[:classes], @align) @body_arguments = body_arguments @body_arguments[:tag] = :ul @body_arguments[:classes] = underline_nav_body_classes(@body_arguments[:classes]) aria_label_for_page_nav(label) end private def body Primer::BaseComponent.new(**@body_arguments) end end end end