module Coco module App module Elements class SystemBanner < Coco::Component include Concerns::AcceptsOptions include Concerns::WrapsComponent accepts_option :dismissable, from: [true, false], default: false wraps_component :alert do |args| theme = vivid_theme_name(args.fetch(:theme, nil)) || :info_vivid Coco::App::Elements::Alert.new( **args, theme: theme, banner: true, cloak: false, single_line: true, dismissable: dismissable?, condensed: true ) end %i[action secondary_action link].each do |slot_name| renders_one slot_name, ->(*args, **kwargs, &block) do alert.send("with_#{slot_name}".to_sym, *args, **kwargs, &block) end end renders_one :title, ->(text = nil, **kwargs, &block) do alert.public_send(:with_title, **kwargs) { text.presence || block.call } end renders_one :message, ->(text = nil, **kwargs, &block) do alert.public_send(:with_message, **kwargs) { text.presence || block.call } end before_render do if dismissable? && id.blank? raise ArgumentError, "Dismissable banners must be given an ID" end end attr_reader :dismiss_for, :id def initialize(id: nil, dismiss_for: nil, **) @id = id @dismiss_for = dismiss_for set_tag_attr(:id, id) end def dismissable? get_option_value(:dismissable) == true end def render? helpers.cookies[dismiss_cookie_name] != "true" end def dismiss_cookie_name "cb_system_banner_#{tag_attr(:id)&.underscore}_dismissed".to_sym end def alpine_data dismissable? ? { cookie_name: dismiss_cookie_name, cookie_expiry: dismiss_for&.in_days&.to_i, cookie_value: "true" } : {} end private def vivid_theme_name(theme) if theme.present? "#{theme.to_s.underscore.gsub("_vivid", "")}_vivid".to_sym end end end end end end