# frozen_string_literal: true module Bulmacomp # Make an html structure for a bulma dropdown # # @example empty dropdown # render Bulmacomp::DropdownComponent.new() # # # @example dropdown with title and elements # render Bulmacomp::DropdownComponent.new(title: 'title', elements: [1,2]) # # # # @example dropdown with yield, elements and other option # = render Bulmacomp::DropdownComponent.new(title: 'title', elements: [1,2], id: 'menu', # button_options: {class: 'button is-success'}, icon: nil) do # some content # # # class DropdownComponent < ViewComponent::Base # @param [Hash] opts # options to generate content # @option opts [String] title # Content of button, default empty string # @option opts [Array] elements # collection of dropdown-item # @option opts [String] icon # icon span class content for button, # default: # @option opts {Hash} button_options # options for button tag # @option opts [String] :* # each key going as content tag option, default is class: 'dropdown' # @yield [optional] dropdown content def initialize(title: nil, elements: [], icon: default_icon, button_options: {}, **opts) super @title = tag.span title if title.present? @elements = elements @icon = tag.span icon, class: 'icon is-small' if icon.present? @button_options = default_button_options.merge(button_options) @opts = default_opts.merge(opts) end # @return [String] default content for button icon def default_icon ''.html_safe end # @return [Hash] default option for content tag def default_opts { class: 'dropdown' } end # return [Hash] default option for button tag def default_button_options { class: 'button', aria: { haspopup: 'true', controls: 'dropdown-menu' } } end # Generated html string for bulma dropdown # @return [String] def call tag.div safe_join([tag_trigger, tag_content]), **@opts end # generated html for '.dropdown-trigger' div # @return [String] def tag_trigger tag.div tag.button(safe_join([@title, @icon]), **@button_options), class: 'dropdown-trigger' end # generated html for '.dropdown-content' div. # Map each content of {elements} in a '.dropdown-item' div and add yield content # @return [String] def tag_content tag.div safe_join([@elements.map { |e| tag.div(e, class: 'dropdown-item') }, content]), class: 'dropdown-content' end end end