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
- #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
- #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
#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
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/components/view_component_reflex/component.rb', line 142 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_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
165 166 167 |
# File 'app/components/view_component_reflex/component.rb', line 165 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 |