# frozen_string_literal: true module Ariadne # Represents the top navigation bar on every page. class HeaderComponent < Ariadne::Component DEFAULT_CLASSES = "ariadne-sticky ariadne-top-0 ariadne-z-50 ariadne-px-4 ariadne-py-5 ariadne-bg-white ariadne-shadow-sm shadow-slate-900/5 ariadne-transition ariadne-duration-500" # ariadne-flex ariadne-flex-wrap ariadne-items-center ariadne-justify-between ariadne-bg-white dark:ariadne-shadow-none dark:ariadne-bg-transparent LINK_CLASSES = "ariadne-rounded-lg ariadne-py-1 ariadne-px-2 text-slate-700 hover:bg-slate-100 hover:text-slate-900" DEFAULT_TEXT_LOGO_CLASSES = "ariadne-flex ariadne-items-center ariadne-font-bold ariadne-text-xl" DEFAULT_IMAGE_LOGO_CLASSES = "ariadne-h-10 ariadne-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 = "ariadne-inline-block ariadne-rounded-lg ariadne-py-1 ariadne-px-2 ariadne-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 ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-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 ariadne-inline-flex ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-py-2 ariadne-px-4 ariadne-text-sm ariadne-font-semibold focus:ariadne-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