card/lib/card/view/options/visibility.rb
class Card
class View
module Options
# manages showing and hiding optional view renders
module Visibility
# tracks show/hide value for each view with an explicit setting
# eg { toggle: :hide }
def viz_hash
@viz_hash ||= {}
end
# test methods
def hide? view
viz_hash[view&.to_sym] == :hide
end
def show? view
!hide? view
end
def explicit_show? view
viz_hash[view&.to_sym] == :show
end
# write methods
def show *views
viz views, :show
end
def hide *views
viz views, :hide
end
# force write methods
def show! *views
viz views, :show, true
end
def hide! *views
viz views, :hide, true
end
# advanced write method
VIZ_SETTING = { show: :show, true => :show,
hide: :hide, false => :hide, nil => :hide }.freeze
def viz views, setting, force=false
Array.wrap(views).flatten.each do |view|
view = view.to_sym
next if !force && viz_hash[view]
viz_hash[view] = VIZ_SETTING[setting]
end
end
def visible? view
viz view, yield unless viz_hash[view]
show? view
end
# test whether view is optional
# (@optional is set in normalize_options
# @return [true/false]
def optional?
@optional
end
# translate raw hide, show options (which can be strings, symbols,
# arrays, etc)
def process_visibility
viz_hash.reverse_merge! parent.viz_hash if parent
process_visibility_options live_options
viz requested_view, @optional if @optional && !viz_hash[requested_view]
end
private
# if true, #process returns nil
def hide_requested_view?
optional? && hide?(requested_view)
end
# takes an options_hash and processes it to update viz_hash
def process_visibility_options options_hash
%i[hide show].each do |setting|
views = View.normalize_list(options_hash.delete(setting)).map(&:to_sym)
viz views, setting, true
end
end
def normalized_visibility_options
viz_hash.each_with_object({}) do |(key, val), hash|
hash[val] ||= []
hash[val] << key
end
end
end
end
end
end