# frozen_string_literal: true module Ariadne # Use `Blankslate` when there is a lack of content within a page or section. Use as placeholder to tell users why something isn't there. # # @accessibility # - The blankslate uses a semantic heading that must be set at the appropriate level based on the hierarchy of the page. # - All blankslate visuals have been programmed as decorative images, using `aria-hidden=”true”` and `img alt=””`, which will hide the visual from screen reader users. # - The blankslate supports a primary and secondary action. Both actions have been built as semantic links with primary and secondary styling. # - `secondary_action` text should be meaningful out of context and clearly describe the destination. Avoid using vague text like, "Learn more" or "Click here". class BlankslateComponent < Ariadne::Component DEFAULT_TAG = :div TAG_OPTIONS = [DEFAULT_TAG].freeze DEFAULT_CLASSES = "ariadne-text-center" # Optional visual that renders an <%= link_to_component(Ariadne::HeroiconComponent) %>. # # @param tag [Symbol, String] The rendered tag name # @param icon [String] Name of <%= link_to_heroicons %> to use. # @param size [Symbol] <%= one_of(Ariadne::HeroiconComponent::SIZE_MAPPINGS, sort: false) %> # @param variant [String] <%= one_of(HeroiconsHelper::Icon::VALID_VARIANTS, sort: false) %> # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. renders_one :icon, lambda { |tag: :svg, icon:, size: Ariadne::HeroiconComponent::SIZE_DEFAULT, variant: HeroiconsHelper::Icon::VARIANT_SOLID, classes: "", attributes: {}| @icon = icon @variant = variant tag = check_incoming_tag(:svg, tag) Ariadne::HeroiconComponent.new(tag: tag, icon: icon, size: size, variant: variant, classes: classes, attributes: attributes) } # Optional visual that renders an <%= link_to_component(Ariadne::ImageComponent) %>. # # @param tag [Symbol, String] The rendered tag name # @param src [String] The source url of the image. # @param alt [String] Specifies an alternate text for the image. # @param lazy [Boolean] Whether or not to lazily load the image. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> DEFAULT_IMAGE_SIZE = 56 renders_one :image, lambda { |tag: Ariadne::ImageComponent::DEFAULT_TAG, src:, alt:, lazy: false, classes: "", attributes: {}| attributes[:height] = DEFAULT_IMAGE_SIZE attributes[:width] = DEFAULT_IMAGE_SIZE Ariadne::ImageComponent.new(tag: tag, src: src, alt: alt, lazy: lazy, classes: classes, attributes: attributes) } # Required heading. # # @param tag [Symbol, String] <%= one_of(Ariadne::HeadingComponent::TAG_OPTIONS) %> # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. DEFAULT_HEADING_CLASSES = "ariadne-text-3xl ariadne-font-extrabold ariadne-tracking-tight ariadne-text-gray-900 sm:ariadne-text-4xl" renders_one :heading, lambda { |tag: :h1, classes: "", attributes: {}| actual_classes = merge_class_names(DEFAULT_HEADING_CLASSES, classes) Ariadne::HeadingComponent.new(tag: tag, classes: actual_classes, attributes: attributes) } # Optional description. # # - The description should always be informative and actionable. # - Don't use phrases like "You can". # # @param tag [Symbol, String] The rendered tag name # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. renders_one :description, lambda { |tag: :p, classes: "", attributes: {}| actual_tag = check_incoming_tag(:p, tag) Ariadne::BaseComponent.new(tag: actual_tag, classes: classes, attributes: attributes) } # Optional primary action # # The `primary_action` slot renders an anchor link which is visually styled as a button to provide more emphasis to the # Blankslate's primary action. # # @param href [String] URL to be used for the primary action. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. renders_one :primary_action, lambda { |href: nil, tag: :a, method: nil, size: :md, scheme: :default, classes: "", attributes: {}| attributes[:href] = href attributes[:method] = method Ariadne::ButtonComponent.new( tag: tag, type: Ariadne::BaseButton::DEFAULT_TYPE, scheme: scheme, size: size, classes: classes, attributes: attributes, ) } # Optional secondary action # # The `secondary_action` slot renders a normal anchor link, which can be used to redirect the user to additional information # (e.g. Help documentation). # # @param href [String] URL to be used for the secondary action. # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. renders_one :secondary_action, lambda { |href:, classes: "", attributes: {}| attributes[:href] = href Ariadne::LinkComponent.new(href: href, classes: classes, attributes: attributes) } # @example Basic # <%= render Ariadne::BlankslateComponent.new do |c| %> # <% c.with_heading(tag: :h2) { "heading" } %> # <% c.with_description { "Description"} %> # <% end %> # # @example Icon # @description # Add an `icon` to give additional context. Refer to the [Heroicons](https://heroicons.com) documentation to choose an icon. # @code # <%= render Ariadne::BlankslateComponent.new do |c| %> # <% c.with_icon(icon: :"globe-europe-africa") %> # <% c.with_heading(tag: :h2) { "heading" } %> # <% c.with_description { "Description"} %> # <% end %> # # @example Using an image # @description # Add an `image` to give context that an Octicon couldn't. # @code # <%= render Ariadne::BlankslateComponent.new do |c| %> # <% c.with_image(src: "https://github.githubassets.com/images/modules/site/features/security-icon.svg", alt: "Security - secure vault") %> # <% c.with_heading(tag: :h2){ "heading" } %> # <% end %> # # @param tag [Symbol, String] The rendered tag name # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> def initialize(tag: DEFAULT_TAG, classes: "", attributes: {}) @tag = check_incoming_tag(DEFAULT_TAG, tag) @classes = merge_class_names(DEFAULT_CLASSES, classes) @attributes = attributes end def render? heading.present? end end end