require 'active_support/concern' module Compony module ComponentMixins module Default # api description # This module contains all methods for Component that concern labelling and look. module Labelling extend ActiveSupport::Concern # DSL method and accessor When assigning via DSL, pass format as first # parameter. When accessing the value, pass format as named parameter # (e.g. `format: :short`).
A component either generates labels # without data (e.g. "New user") or with data (e.g. "Edit John Doe"). # This needs to be consistent across all formats. If the block generates # labels with data, the label block must take exactly one argument, # otherwise none. Label blocks with data are given the data as argument. # The block is expected to return the label in the given format.
# Examples: # - Setting a block with data: `label(:short){ |data| "Edit #{data.label}" }` # - Setting a block without data: `label(:short){ 'New user' }` # - Reading a component's label with data: `comp.label(User.first, format: :short)` # - Reading a component's label without data: `comp.label(format: :short)` def label(data_or_format = nil, format: :long, &block) format = data_or_format if block_given? format ||= :long format = format.to_sym if block_given? # Assignment via DSL if format == :all @label_blocks[:short] = block @label_blocks[:long] = block else @label_blocks[format] = block end else # Retrieval of the actual label fail('Label format :all may only be used for setting a label (with a block), not for retrieving it.') if format == :all label_block = @label_blocks[format] || fail("Format #{format} was not found for #{inspect}.") case label_block.arity when 0 label_block.call when 1 data_or_format ||= data if data_or_format.blank? fail "Label block of #{inspect} takes an argument, but no data was provided and a call to `data` did not return any data either." end label_block.call(data_or_format) else fail "#{inspect} has a label block that takes 2 or more arguments, which is unsupported." end end end # DSL method and accessor for an icon. # While this is not used in Compony directly, this is useful if your front-end uses an icon library such as fontawesome. def icon(&block) if block_given? @icon_block = block else @icon_block.call end end # DSL method and accessor # While this is not used in Compony directly, this is useful if you use a custom button component class that supports colors. def color(&block) if block_given? @color_block = block else @color_block.call end end private def init_labelling # Provide defaults @label_blocks = { long: -> { "#{I18n.t(family_name.humanize)}: #{I18n.t(comp_name.humanize)}" }, short: -> { I18n.t(comp_name.humanize) } } @icon_block = -> { :'arrow-right' } @color_block = -> { :primary } end end end end end