Class: ViewComponentReflex::Component

Inherits:
ViewComponent::Base
  • Object
show all
Defined in:
app/components/view_component_reflex/component.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.init_stimulus_reflexObject



4
5
6
7
8
9
10
11
# File 'app/components/view_component_reflex/component.rb', line 4

def init_stimulus_reflex
  if name.include? "::"
    @stimulus_reflex ||= module_parent.const_set(name.split("::").last + "Reflex", Class.new(Reflex))
  else
    @stimulus_reflex ||= Object.const_set(name + "Reflex", Class.new(Reflex))
  end
  @stimulus_reflex.component_class = self
end

.stimulus_controllerObject



14
15
16
# File 'app/components/view_component_reflex/component.rb', line 14

def self.stimulus_controller
  name.chomp("Component").underscore.dasherize
end

Instance Method Details

#can_render_to_string?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'app/components/view_component_reflex/component.rb', line 41

def can_render_to_string?
  omitted_from_state.empty?
end

#collection_keyObject



75
76
77
# File 'app/components/view_component_reflex/component.rb', line 75

def collection_key
  nil
end

#component_controller(opts_or_tag = :div, opts = {}, &blk) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/components/view_component_reflex/component.rb', line 22

def component_controller(opts_or_tag = :div, opts = {}, &blk)
  self.class.init_stimulus_reflex
  init_key

  tag = :div
  if opts_or_tag.is_a? Hash
    options = opts_or_tag
  else
    tag = opts_or_tag
    options = opts
  end
  options[:data] = {
    controller: self.class.stimulus_controller,
    key: key,
    **(options[:data] || {})
  }
   tag, capture(&blk), options
end

#init_keyObject

key is required if you’re using state We can’t initialize the session state in the initial method because it doesn’t have a view_context yet This is the next best place to do it



49
50
51
52
53
54
55
# File 'app/components/view_component_reflex/component.rb', line 49

def init_key
  # we want the erb file that renders the component. `caller` gives the file name,
  # and line number, which should be unique. We hash it to make it a nice number
  key = caller.select { |p| p.include? ".html.erb" }[1]&.hash.to_s
  key += collection_key.to_s if collection_key
  @key = key
end

#keyObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'app/components/view_component_reflex/component.rb', line 87

def key
  # initialize session state
  if !stimulus_reflex? || ViewComponentReflex::Engine.state_adapter.state(request, @key).empty?

    new_state = create_safe_state

    ViewComponentReflex::Engine.state_adapter.store_state(request, @key, new_state)
    ViewComponentReflex::Engine.state_adapter.store_state(request, "#{@key}_initial", new_state)
  else
    initial_state = ViewComponentReflex::Engine.state_adapter.state(request, "#{@key}_initial")
    ViewComponentReflex::Engine.state_adapter.state(request, @key).each do |k, v|
      instance_value = instance_variable_get(k)
      if permit_parameter?(initial_state[k], instance_value)
        ViewComponentReflex::Engine.state_adapter.set_state(request, controller, "#{@key}_initial", { k => instance_value })
        ViewComponentReflex::Engine.state_adapter.set_state(request, controller, @key, { k => instance_value })
      else
        instance_variable_set(k, v)
      end
    end
  end
  @key
end

#omitted_from_stateObject



83
84
85
# File 'app/components/view_component_reflex/component.rb', line 83

def omitted_from_state
  []
end

#permit_parameter?(initial_param, new_param) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
# File 'app/components/view_component_reflex/component.rb', line 79

def permit_parameter?(initial_param, new_param)
  initial_param != new_param
end

#reflex_tag(reflex, name, content_or_options_with_block = {}, options = {}, escape = true, &block) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/components/view_component_reflex/component.rb', line 57

def reflex_tag(reflex, name, content_or_options_with_block = {}, options = {}, escape = true, &block)
  action, method = reflex.to_s.split("->")
  if method.nil?
    method = action
    action = "click"
  end
  data_attributes = {
    reflex: "#{action}->#{self.class.name}##{method}",
    key: key
  }
  if content_or_options_with_block.is_a?(Hash)
    merge_data_attributes(content_or_options_with_block, data_attributes)
  else
    merge_data_attributes(options, data_attributes)
  end
  (name, content_or_options_with_block, options, escape, &block)
end

#safe_instance_variablesObject



110
111
112
# File 'app/components/view_component_reflex/component.rb', line 110

def safe_instance_variables
  instance_variables - unsafe_instance_variables
end

#stimulus_reflex?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'app/components/view_component_reflex/component.rb', line 18

def stimulus_reflex?
  helpers.controller.instance_variable_get(:@stimulus_reflex)
end