# frozen_string_literal: true module Ariadne # Use `FlashComponent` to inform users of successful messages, pending actions, or urgent notices class FlashComponent < Ariadne::Component include IconHelper DEFAULT_SCHEME = :default DISMISSIBLE_SCHEME_CLASS_MAPPINGS = { default: "ariadne-text-blue-500 ariadne-bg-blue-50 hover:ariadne-bg-blue-100 focus:ariadne-ring-offset-blue-50 focus:ariadne-ring-blue-600", info: "ariadne-text-blue-500 ariadne-bg-blue-50 hover:ariadne-bg-blue-100 focus:ariadne-ring-offset-blue-50 focus:ariadne-ring-blue-600", success: "ariadne-text-green-500 ariadne-bg-green-50 hover:ariadne-bg-green-100 focus:ariadne-ring-offset-green-50 focus:ariadne-ring-green-600", warning: "ariadne-text-yellow-500 ariadne-bg-yellow-50 hover:ariadne-bg-yellow-100 focus:ariadne-ring-offset-yellow-50 focus:ariadne-ring-yellow-600", danger: "ariadne-text-red-500 ariadne-bg-red-50 hover:ariadne-bg-red-100 focus:ariadne-ring-offset-red-50 focus:ariadne-ring-red-600", }.freeze VALID_DISMISSIBLE_SCHEMES = DISMISSIBLE_SCHEME_CLASS_MAPPINGS.keys.freeze BG_SCHEME_CLASS_MAPPINGS = { default: "ariadne-bg-blue-50", info: "ariadne-bg-blue-50", success: "ariadne-bg-green-50", warning: "ariadne-bg-yellow-50", danger: "ariadne-bg-red-50", }.freeze VALID_BG_SCHEMES = BG_SCHEME_CLASS_MAPPINGS.keys.freeze CONTENT_SCHEME_CLASS_MAPPINGS = { default: "ariadne-text-blue-700", info: "ariadne-text-blue-700", success: "ariadne-text-green-700", warning: "ariadne-text-yellow-700", danger: "ariadne-text-red-700", }.freeze VALID_CONTENT_SCHEMES = CONTENT_SCHEME_CLASS_MAPPINGS.keys.freeze # Optional visuals appearing to the left of the flash banner. # # Use: # # - `icon` for a <%= link_to_component(Ariadne::HeroiconComponent) %>. # # @option params [Symbol] :icon The rendered tag name # @option params [Symbol] :icon Name of <%= link_to_heroicons %> to use. # @option params [Symbol] :variant <%= one_of(HeroiconsHelper::Icon::VALID_VARIANTS, sort: false) %> # @option params [String] :classes <%= link_to_classes_docs %> # @option params [Hash] :attributes Same arguments as <%= link_to_component(Ariadne::HeroiconComponent) %>. renders_one :icon, lambda { |tag: :svg, icon:, variant:, classes: "", attributes: {}| @icon = icon @variant = variant tag = check_incoming_tag(:svg, tag) Ariadne::HeroiconComponent.new(tag: tag, icon: icon, variant: variant, classes: classes, attributes: attributes) } # Optional action content showed at the bottom of the component. # # @param tag [Symbol, String] The rendered tag name # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> renders_one :action, lambda { |tag: :div, classes: "", attributes: {}| tag = check_incoming_tag(:div, tag) actual_classes = class_names(classes) Ariadne::BaseComponent.new(tag: tag, classes: actual_classes, attributes: attributes) } # @example Schemes # <%= render(Ariadne::FlashComponent.new) { "This is a flash message!" } %> # <%= render(Ariadne::FlashComponent.new(scheme: :warning)) { "This is a warning flash message!" } %> # <%= render(Ariadne::FlashComponent.new(scheme: :danger)) { "This is a danger flash message!" } %> # <%= render(Ariadne::FlashComponent.new(scheme: :success)) { "This is a success flash message!" } %> # # @example Dismissible # <%= render(Ariadne::FlashComponent.new(dismissible: true)) { "This is a dismissible flash message!" } %> # # @example Icon # <%= render(Ariadne::FlashComponent.new) do |component| %> # <% component.icon(icon: :"user-group", variant: HeroiconsHelper::Icon::VARIANT_OUTLINE) %> # Look at this icon. # <% end %> # # @example With actions # <%= render(Ariadne::FlashComponent.new) do |component| %> # <% component.action do %> # <%= render(Ariadne::ButtonComponent.new(size: :sm)) { "Take action" } %> # <% end %> # This is a flash message with actions! # <% end %> # # @param tag [Symbol, String] The rendered tag name. # @param dismissible [Boolean] Whether the component can be dismissed with an X button. # @param icon [Symbol, String] Name of <%= link_to_heroicons %> to use. # @param scheme [Symbol] <%= one_of(Ariadne::FlashComponent::VALID_CONTENT_SCHEMES) %> # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] <%= link_to_attributes_docs %> def initialize(tag: :div, dismissible: false, scheme: DEFAULT_SCHEME, classes: "", attributes: {}) @dismissible = dismissible @tag = check_incoming_tag(:div, tag) @scheme = fetch_or_raise(VALID_CONTENT_SCHEMES, scheme) @classes = class_names( CONTENT_SCHEME_CLASS_MAPPINGS[@scheme], classes ) @attributes = attributes end # TODO: test this private def has_action? action.present? end # TODO: test this private def dismissible? @dismissible.present? end private def dismissible_classes DISMISSIBLE_SCHEME_CLASS_MAPPINGS[@scheme] end end end