Class: ViewComponentReflex::Component
- Inherits:
-
ViewComponent::Base
- Object
- ViewComponent::Base
- ViewComponentReflex::Component
- Defined in:
- app/components/view_component_reflex/component.rb
Class Method Summary collapse
- .after_reflex(*args, &blk) ⇒ Object
- .around_reflex(*args, &blk) ⇒ Object
- .before_reflex(*args, &blk) ⇒ Object
- .callbacks(key) ⇒ Object
- .init_stimulus_reflex ⇒ Object
- .queue_callback(key, args, blk) ⇒ Object
- .reflex_base_class(new_base_class = nil) ⇒ Object
- .register_callbacks(key) ⇒ Object
- .stimulus_controller ⇒ Object
- .wire_up_callbacks ⇒ Object
Instance Method Summary collapse
- #after_state_initialized(parameters_changed) ⇒ Object
- #can_render_to_string? ⇒ Boolean
- #collection_key ⇒ Object
- #component_controller(opts_or_tag = :div, opts = {}, &blk) ⇒ Object
-
#init_key ⇒ Object
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.
-
#key ⇒ Object
def receive_params(old_state, params) # no op end.
- #omitted_from_state ⇒ Object
- #permit_parameter?(initial_param, new_param) ⇒ Boolean
-
#reflex_data_attributes(reflex) ⇒ Object
Helper to use to create the proper reflex data attributes for an element.
- #reflex_tag(reflex, name, content_or_options_with_block = {}, options = {}, escape = true, &block) ⇒ Object
- #safe_instance_variables ⇒ Object
- #stimulus_reflex? ⇒ Boolean
Class Method Details
.after_reflex(*args, &blk) ⇒ Object
44 45 46 |
# File 'app/components/view_component_reflex/component.rb', line 44 def after_reflex(*args, &blk) queue_callback(:after, args, blk) end |
.around_reflex(*args, &blk) ⇒ Object
48 49 50 |
# File 'app/components/view_component_reflex/component.rb', line 48 def around_reflex(*args, &blk) queue_callback(:around, args, blk) end |
.before_reflex(*args, &blk) ⇒ Object
40 41 42 |
# File 'app/components/view_component_reflex/component.rb', line 40 def before_reflex(*args, &blk) queue_callback(:before, args, blk) end |
.callbacks(key) ⇒ Object
29 30 31 32 |
# File 'app/components/view_component_reflex/component.rb', line 29 def callbacks(key) @callbacks ||= {} @callbacks[key] ||= [] end |
.init_stimulus_reflex ⇒ Object
4 5 6 7 8 |
# File 'app/components/view_component_reflex/component.rb', line 4 def init_stimulus_reflex factory = ViewComponentReflex::ReflexFactory.new(self) @stimulus_reflex ||= factory.reflex wire_up_callbacks if factory.new? end |
.queue_callback(key, args, blk) ⇒ Object
22 23 24 25 26 27 |
# File 'app/components/view_component_reflex/component.rb', line 22 def queue_callback(key, args, blk) callbacks(key).push({ args: args, blk: blk }) end |
.reflex_base_class(new_base_class = nil) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 |
# File 'app/components/view_component_reflex/component.rb', line 10 def reflex_base_class(new_base_class = nil) if new_base_class.nil? @reflex_base_class ||= ViewComponentReflex::Reflex else if new_base_class <= ViewComponentReflex::Reflex @reflex_base_class = new_base_class else raise StandardError.new("The reflex base class must inherit from ViewComponentReflex::Reflex") end end end |
.register_callbacks(key) ⇒ Object
34 35 36 37 38 |
# File 'app/components/view_component_reflex/component.rb', line 34 def register_callbacks(key) callbacks(key).each do |cb| @stimulus_reflex.send("#{key}_reflex", *cb[:args], &cb[:blk]) end end |
.stimulus_controller ⇒ Object
59 60 61 |
# File 'app/components/view_component_reflex/component.rb', line 59 def self.stimulus_controller name.chomp("Component").underscore.dasherize end |
.wire_up_callbacks ⇒ Object
52 53 54 55 56 |
# File 'app/components/view_component_reflex/component.rb', line 52 def wire_up_callbacks register_callbacks(:before) register_callbacks(:after) register_callbacks(:around) end |
Instance Method Details
#after_state_initialized(parameters_changed) ⇒ Object
142 143 144 |
# File 'app/components/view_component_reflex/component.rb', line 142 def after_state_initialized(parameters_changed) # called after state component has been hydrated end |
#can_render_to_string? ⇒ Boolean
86 87 88 |
# File 'app/components/view_component_reflex/component.rb', line 86 def can_render_to_string? omitted_from_state.empty? end |
#collection_key ⇒ Object
130 131 132 |
# File 'app/components/view_component_reflex/component.rb', line 130 def collection_key nil end |
#component_controller(opts_or_tag = :div, opts = {}, &blk) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'app/components/view_component_reflex/component.rb', line 67 def component_controller(opts_or_tag = :div, opts = {}, &blk) init_key tag = :div = if opts_or_tag.is_a? Hash opts_or_tag else tag = opts_or_tag opts end [:data] = { controller: self.class.stimulus_controller, key: key, **([:data] || {}) } content_tag tag, capture(&blk), end |
#init_key ⇒ Object
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
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'app/components/view_component_reflex/component.rb', line 94 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 erb_file = caller.select { |p| p.match? /.\.html\.(haml|erb|slim)/ }[1] key = if erb_file Digest::SHA2.hexdigest(erb_file.split(":in")[0]) else "" end key += collection_key.to_s if collection_key @key = key end |
#key ⇒ Object
def receive_params(old_state, params)
# no op
end
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'app/components/view_component_reflex/component.rb', line 150 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) elsif !@initialized_state initial_state = ViewComponentReflex::Engine.state_adapter.state(request, "#{@key}_initial") # incoming_params = safe_instance_variables.each_with_object({}) { |var, obj| obj[var] = instance_variable_get(var) } # receive_params(ViewComponentReflex::Engine.state_adapter.state(request, @key), incoming_params) parameters_changed = [] 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) parameters_changed << k 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 after_state_initialized(parameters_changed) @initialized_state = true end @key end |
#omitted_from_state ⇒ Object
138 139 140 |
# File 'app/components/view_component_reflex/component.rb', line 138 def omitted_from_state [] end |
#permit_parameter?(initial_param, new_param) ⇒ Boolean
134 135 136 |
# File 'app/components/view_component_reflex/component.rb', line 134 def permit_parameter?(initial_param, new_param) initial_param != new_param end |
#reflex_data_attributes(reflex) ⇒ Object
Helper to use to create the proper reflex data attributes for an element
108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/components/view_component_reflex/component.rb', line 108 def reflex_data_attributes(reflex) action, method = reflex.to_s.split("->") if method.nil? method = action action = "click" end { reflex: "#{action}->#{self.class.name}##{method}", key: key } end |
#reflex_tag(reflex, name, content_or_options_with_block = {}, options = {}, escape = true, &block) ⇒ Object
121 122 123 124 125 126 127 128 |
# File 'app/components/view_component_reflex/component.rb', line 121 def reflex_tag(reflex, name, = {}, = {}, escape = true, &block) if .is_a?(Hash) merge_data_attributes(, reflex_data_attributes(reflex)) else merge_data_attributes(, reflex_data_attributes(reflex)) end content_tag(name, , , escape, &block) end |
#safe_instance_variables ⇒ Object
181 182 183 |
# File 'app/components/view_component_reflex/component.rb', line 181 def safe_instance_variables instance_variables - unsafe_instance_variables end |
#stimulus_reflex? ⇒ Boolean
63 64 65 |
# File 'app/components/view_component_reflex/component.rb', line 63 def stimulus_reflex? helpers.controller.instance_variable_get(:@stimulus_reflex) end |