view_component_reflex 1.7.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e5577d7e345a14f59567739802588506a300b2caa96bba74bd4f12a93752a04
4
- data.tar.gz: be4d877d89d50555bde7f1ba929ef4fd5b1e60c72f2e7e921e33e2623574bfa7
3
+ metadata.gz: 2a3e7ed47e432ef756d8359ace66447aedd995d240eb423007ec868c9dfa0402
4
+ data.tar.gz: bb836fc180d285454b516ced91b92cc309320d9257c5da71a17c2789631fcd0f
5
5
  SHA512:
6
- metadata.gz: 60530d55c39126bd6be3d5be688f08cbe4e84e0b16e444334e438d99ec1a6b05a1f08c102407bea04b9c73ca5ace4bbb4ec013529810bc5363c6bd09e4224d70
7
- data.tar.gz: ceebff13ff2407be15ad1d3e851f78130a7bec2d00cdd260bd3ed78d32ebfce596f1763d6608b822d628f0ce91b164a53c47ee2296755733ddac01888ae1bf8c
6
+ metadata.gz: 594bf37cfa1ef0798df664220190d694d3c164ee25516b0220ba6f884b4bf3667a52cfb0668d7d0ae2d684d17c18296862f5ae2473ace3b23ac8496f29825ba6
7
+ data.tar.gz: d82970ac5abd4aea2ffb675f261ba7c6b840e1f866f9b93b51c368cead4fff06d9ac1e7c8211f679f0f58a4d6b78557fe2c553b66bec982ddaf7d1cf0c5e8433
data/README.md CHANGED
@@ -108,6 +108,19 @@ def collection_key
108
108
  end
109
109
  ```
110
110
 
111
+ ### refresh!(selectors)
112
+ Refresh a specific element on the page. Using this will implicitly run `prevent_render!`.
113
+ If you want to render a specific element, as well as the component, a common pattern would be to pass `selector` as one of the parameters
114
+
115
+ ```
116
+ def my_method
117
+ refresh! '#my-special-element', selector
118
+ end
119
+ ```
120
+
121
+ ### selector
122
+ Returns the unique selector for this component. Useful to pass to `refresh!` when refreshing custom elements.
123
+
111
124
  ### prevent_refresh!
112
125
  By default, VCR will re-render your component after it executes your method. `revent_refresh!` prevents this from happening.
113
126
 
@@ -2,95 +2,8 @@ module ViewComponentReflex
2
2
  class Component < ViewComponent::Base
3
3
  class << self
4
4
  def init_stimulus_reflex
5
- klass = self
6
- @stimulus_reflex ||= Object.const_set(name + "Reflex", Class.new(StimulusReflex::Reflex) {
7
- def refresh!(primary_selector = "[data-controller~=\"#{stimulus_controller}\"][data-key=\"#{element.dataset[:key]}\"]", *selectors)
8
- save_state
9
- @channel.send :render_page_and_broadcast_morph, self, [primary_selector, *selectors], {
10
- "dataset" => element.dataset.to_h,
11
- "args" => [],
12
- "attrs" => element.attributes.to_h,
13
- "selectors" => ["body"],
14
- "target" => "#{self.class.name}##{method_name}",
15
- "url" => request.url,
16
- "permanent_attribute_name" => "data-reflex-permanent"
17
- }
18
- end
19
-
20
- def refresh_all!
21
- refresh!("body")
22
- end
23
-
24
- # SR's delegate_call_to_reflex in channel.rb
25
- # uses method to gather the method parameters, but since we're abusing
26
- # method_missing here, that'll always fail
27
- def method(name)
28
- name.to_sym.to_proc
29
- end
30
-
31
- def respond_to_missing?(name, _ = false)
32
- !!name.to_proc
33
- end
34
-
35
- before_reflex do |a|
36
- a.send a.method_name
37
- throw :abort
38
- end
39
-
40
- def method_missing(name, *args)
41
- super unless respond_to_missing?(name)
42
- state.each do |k, v|
43
- component.instance_variable_set(k, v)
44
- end
45
- name.to_proc.call(component, *args)
46
- refresh! unless @prevent_refresh
47
- end
48
-
49
- def prevent_refresh!
50
- @prevent_refresh = true
51
- end
52
-
53
- define_method :component_class do
54
- @component_class ||= klass
55
- end
56
-
57
- private :component_class
58
-
59
- private
60
-
61
- def stimulus_controller
62
- component_class.stimulus_controller
63
- end
64
-
65
- def component
66
- return @component if @component
67
- @component = component_class.allocate
68
- reflex = self
69
- exposed_methods = [:params, :request, :element, :refresh!, :refresh_all!, :stimulus_controller, :session, :prevent_refresh!]
70
- exposed_methods.each do |meth|
71
- @component.define_singleton_method(meth) do |*a|
72
- reflex.send(meth, *a)
73
- end
74
- end
75
- @component
76
- end
77
-
78
- def set_state(new_state = {})
79
- ViewComponentReflex::Engine.state_adapter.set_state(request, controller, element.dataset[:key], new_state)
80
- end
81
-
82
- def state
83
- ViewComponentReflex::Engine.state_adapter.state(request, element.dataset[:key])
84
- end
85
-
86
- def save_state
87
- new_state = {}
88
- component.safe_instance_variables.each do |k|
89
- new_state[k] = component.instance_variable_get(k)
90
- end
91
- set_state(new_state)
92
- end
93
- })
5
+ @stimulus_reflex ||= Object.const_set(name + "Reflex", Class.new(Reflex))
6
+ @stimulus_reflex.component_class = self
94
7
  end
95
8
  end
96
9
 
@@ -121,6 +34,10 @@ module ViewComponentReflex
121
34
  content_tag tag, capture(&blk), options
122
35
  end
123
36
 
37
+ def can_render_to_string?
38
+ omitted_from_state.empty?
39
+ end
40
+
124
41
  # key is required if you're using state
125
42
  # We can't initialize the session state in the initial method
126
43
  # because it doesn't have a view_context yet
@@ -0,0 +1,123 @@
1
+ module ViewComponentReflex
2
+ class Reflex < StimulusReflex::Reflex
3
+ include CableReady::Broadcaster
4
+
5
+ class << self
6
+ attr_accessor :component_class
7
+ end
8
+
9
+ def refresh!(primary_selector = nil, *rest)
10
+ save_state
11
+
12
+ if primary_selector.nil? && !component.can_render_to_string?
13
+ primary_selector = selector
14
+ end
15
+ if primary_selector
16
+ prevent_refresh!
17
+
18
+ controller.process(url_params[:action])
19
+ document = Nokogiri::HTML(controller.response.body)
20
+ [primary_selector, *rest].each do |s|
21
+ html = document.css(s)
22
+ if html.present?
23
+ cable_ready[channel.stream_name].inner_html(
24
+ selector: s,
25
+ html: html.inner_html,
26
+ children_only: true
27
+ )
28
+ end
29
+ end
30
+ else
31
+ refresh_component!
32
+ end
33
+ end
34
+
35
+ def refresh_component!
36
+ component.tap do |k|
37
+ k.define_singleton_method(:key) do
38
+ element.dataset[:key]
39
+ end
40
+ end
41
+ cable_ready[channel.stream_name].outer_html(
42
+ selector: selector,
43
+ html: controller.render_component_to_string(component)
44
+ )
45
+ end
46
+
47
+ def refresh_all!
48
+ refresh!("body")
49
+ end
50
+
51
+ def selector
52
+ "[data-controller~=\"#{stimulus_controller}\"][data-key=\"#{element.dataset[:key]}\"]"
53
+ end
54
+
55
+ # SR's delegate_call_to_reflex in channel.rb
56
+ # uses method to gather the method parameters, but since we're abusing
57
+ # method_missing here, that'll always fail
58
+ def method(name)
59
+ name.to_sym.to_proc
60
+ end
61
+
62
+ def respond_to_missing?(name, _ = false)
63
+ !!name.to_proc
64
+ end
65
+
66
+ before_reflex do |a|
67
+ a.send a.method_name
68
+ throw :abort
69
+ end
70
+
71
+ def method_missing(name, *args)
72
+ super unless respond_to_missing?(name)
73
+ state.each do |k, v|
74
+ component.instance_variable_set(k, v)
75
+ end
76
+ name.to_proc.call(component, *args)
77
+ refresh! unless @prevent_refresh
78
+ end
79
+
80
+ def prevent_refresh!
81
+ @prevent_refresh = true
82
+ end
83
+
84
+ private
85
+
86
+ def component_class
87
+ self.class.component_class
88
+ end
89
+
90
+ def stimulus_controller
91
+ component_class.stimulus_controller
92
+ end
93
+
94
+ def component
95
+ return @component if @component
96
+ @component = component_class.allocate
97
+ reflex = self
98
+ exposed_methods = [:params, :request, :element, :refresh!, :refresh_all!, :stimulus_controller, :session, :prevent_refresh!, :selector]
99
+ exposed_methods.each do |meth|
100
+ @component.define_singleton_method(meth) do |*a|
101
+ reflex.send(meth, *a)
102
+ end
103
+ end
104
+ @component
105
+ end
106
+
107
+ def set_state(new_state = {})
108
+ ViewComponentReflex::Engine.state_adapter.set_state(request, controller, element.dataset[:key], new_state)
109
+ end
110
+
111
+ def state
112
+ ViewComponentReflex::Engine.state_adapter.state(request, element.dataset[:key])
113
+ end
114
+
115
+ def save_state
116
+ new_state = {}
117
+ component.safe_instance_variables.each do |k|
118
+ new_state[k] = component.instance_variable_get(k)
119
+ end
120
+ set_state(new_state)
121
+ end
122
+ end
123
+ end
@@ -1,7 +1,7 @@
1
1
  require "view_component_reflex/state_adapter/session"
2
2
  require "view_component_reflex/state_adapter/memory"
3
3
  require "view_component_reflex/engine"
4
- require 'stimulus_reflex'
4
+ require "stimulus_reflex"
5
5
 
6
6
  module ViewComponentReflex
7
7
  # Your code goes here...
@@ -1,3 +1,3 @@
1
1
  module ViewComponentReflex
2
- VERSION = '1.7.2'
2
+ VERSION = '2.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component_reflex
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua LeBlanc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-06 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -69,6 +69,7 @@ files:
69
69
  - README.md
70
70
  - Rakefile
71
71
  - app/components/view_component_reflex/component.rb
72
+ - app/reflexes/view_component_reflex/reflex.rb
72
73
  - lib/view_component_reflex.rb
73
74
  - lib/view_component_reflex/engine.rb
74
75
  - lib/view_component_reflex/state_adapter/memory.rb