# frozen_string_literal: true module Ariadne # Represents the top navigation bar on every page. class HeaderComponent < Ariadne::Component DEFAULT_CLASSES = "sticky top-0 z-50 px-4 py-5 bg-white shadow-sm shadow-slate-900/5 transition duration-500" # flex flex-wrap items-center justify-between bg-white dark:shadow-none dark:bg-transparent LINK_CLASSES = "rounded-lg py-1 px-2 text-slate-700 hover:bg-slate-100 hover:text-slate-900" DEFAULT_TEXT_LOGO_CLASSES = "flex items-center font-bold text-xl" DEFAULT_IMAGE_LOGO_CLASSES = "h-10 w-auto" # Leading visuals at the far left of the header. You can pass either # `src` or `as_text` but not both. # # @param href [String] Where the logo should link to. # @param src [String] The URL of the image logo. # @param alt [String] Alt text for accessibility. # @param as_text [Boolean] The text to display # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> renders_one :logo, lambda { |href: nil, src: nil, alt: nil, as_text: false, classes: "", attributes: {}| @href = href if as_text.present? actual_classes = class_names(DEFAULT_TEXT_LOGO_CLASSES, classes) @text_logo = Ariadne::Text.new(tag: :span, classes: actual_classes, attributes: attributes) else actual_classes = class_names(DEFAULT_IMAGE_LOGO_CLASSES, classes) actual_attributes = { width: 40, height: 40 }.merge(attributes) @image_logo = Ariadne::ImageComponent.new(src: src, alt: alt, classes: actual_classes, attributes: actual_attributes) end } # Text within the header, representing navigation. # # @param tag [String, Symbol] The tag to use for the link. # @param href [String] The link destination. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> DEFAULT_NAV_LINK_CLASSES = "inline-block rounded-lg py-1 px-2 text-sm text-slate-700 hover:bg-slate-100 hover:text-slate-900" renders_many :navigation_links, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}| actual_classes = class_names(DEFAULT_NAV_LINK_CLASSES, classes) Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes) } # Text within the header, representing actions. # # @param tag [String, Symbol] The tag to use for the link. # @param href [String] The link destination. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> renders_many :action_links, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}| actual_classes = class_names(DEFAULT_NAV_LINK_CLASSES, classes) Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes) } # Text within the header, representing a signup. # # @param tag [String, Symbol] The tag to use for the link. # @param href [String] The link destination. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> DEFAULT_SIGNUP_LINK_CLASSES = "group inline-flex items-center justify-center rounded-full py-2 px-4 text-sm font-semibold focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2" renders_one :signup_link, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}| actual_classes = class_names(DEFAULT_SIGNUP_LINK_CLASSES, classes) Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes) } DEFAULT_PROFILE_LINK_CLASSES = "group inline-flex items-center justify-center rounded-full py-2 px-4 text-sm font-semibold focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2" renders_one :profile_link, lambda { |tag: Ariadne::LinkComponent::DEFAULT_TAG, href:, classes: "", attributes: {}| actual_classes = class_names(DEFAULT_PROFILE_LINK_CLASSES, classes) Ariadne::LinkComponent.new(tag: tag, href: href, classes: actual_classes, attributes: attributes) } # @example Basic example # # <%= render(Ariadne::HeaderComponent.new) do |header| %> # <%= header.logo(as_text: true) { "GitHub" } %> # <%= header.navigation_link(href: "#features") { "Features" } %> # <%= header.login_link(href: "/login") { "Login" } %> # <% end %> # # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> def initialize(classes: "", attributes: {}) @classes = class_names( DEFAULT_CLASSES, classes ) @attributes = attributes end private def has_logo? logo.present? end private def has_text_logo? logo.present? && @text_logo.present? end private def has_image_logo? logo.present? && @image_logo.present? end private def has_signup_link? signup_link.present? end private def has_profile_link? profile_link.present? end end end