subcomponent 0.1.0 → 0.1.2

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: 0e45581419c661089fedb66b9c803a42f9edc3554585c24ddc0b8fa97e26a448
4
- data.tar.gz: e5863ed447bf64a00b37c50afb8d22ae68020ef3c6887f0872edcf1d42c0d463
3
+ metadata.gz: e1acf4e16006254b88c0d331759b3e3e76bd796cebba5972482ad44f9d3fe496
4
+ data.tar.gz: e752615b8bfe738fca66a171caed47c29ae1282082b3a86fb956dce2fa10a38c
5
5
  SHA512:
6
- metadata.gz: ca8c18a231cfc387a1545e5c894903890396365d1776d6432c2d7aa702ec0e07b4e7979934476fc1b77099837349b407a5fac4888dcba4fdcd65b30c3e598d24
7
- data.tar.gz: d8644df39b061f70c0213449f6b34e9b0f94f7cd69f8ecaa5b61388ca6cd9888e3e09e038b6b35c2631c5472b9f5dcaa66ffb8a399a356685623199b37fc83e1
6
+ metadata.gz: f2016e54ba1067df0a3ca62ed242d6b2cb9b62e10b7287066429571dc8950cf0c6b85dd1de49a97a0bad0e201634d9cfe9122759e7ed16774c491da4dc93491a
7
+ data.tar.gz: 6a3f6d01dad03800859a71287d9a376d8f9a92998f69625ae47607942dd831ecf39698a4b5f021adbec54412f757c4fbd8f4f19d4c6c11075d4759fbb62683da
data/README.md CHANGED
@@ -76,6 +76,63 @@ This will render:
76
76
  </div>
77
77
  ```
78
78
 
79
+ ### Example Component with multiple Subcomponents
80
+
81
+ Create a card component in `app/views/components/card/_card.html.erb`:
82
+ ```erb
83
+ <div>
84
+ <% this.copy_components :links, :mobile_links %>
85
+ <%= this.render :links %>
86
+ <%= this.render :mobile_links %>
87
+ <%= this.text || this.yield %>
88
+ </div>
89
+ ```
90
+
91
+ Create the link subcomponent in `app/views/components/card/_link.html.erb`:
92
+ ```erb
93
+ <a class="desktop" href="<%= this.url %>">
94
+ <%= this.index %>: <%= this.text %>
95
+ </a>
96
+ ```
97
+
98
+ Create the mobile_link subcomponent in `app/views/components/card/_mobile_link.html.erb`:
99
+ ```erb
100
+ <a class="mobile" href="<%= this.url %>">
101
+ <%= this.index %>: <%= this.text %>
102
+ </a>
103
+ ```
104
+
105
+ You can use `this.render_all` to render multiple subcomponent. The subcomponent will have access
106
+ to the locals and subcomponents passed in the view. The components `index` method will be set.
107
+
108
+ To use the component in a view:
109
+ ```erb
110
+ <%= component :card do |c| %>
111
+ <%= c.link text: 'Card Link 1', url: '#" %>
112
+ <%= c.link text: 'Card Link 2', url: '#" %>
113
+ <p>Card Text</p>
114
+ <% end %>
115
+ ```
116
+
117
+ This will render:
118
+ ```html
119
+ <div>
120
+ <a class="desktop" href="#">
121
+ 0: Card Link 1
122
+ </a>
123
+ <a class="desktop" href="#">
124
+ 1: Card Link 2
125
+ </a>
126
+ <a class="mobile" href="#">
127
+ 0: Card Link 1
128
+ </a>
129
+ <a class="mobile" href="#">
130
+ 1: Card Link 2
131
+ </a>
132
+ <p>Card Text</p>
133
+ </div>
134
+ ```
135
+
79
136
  ### Example Using Locals without method_missing.
80
137
 
81
138
  In some cases you may want to use a local variable that
@@ -1,19 +1,35 @@
1
1
  class Component
2
- attr_accessor :_renderer
3
- attr_accessor :_capture
2
+ attr_accessor :_renderer, :_capture
4
3
 
5
4
  # Use Component::ComponentHelper to create components.
6
- def initialize name, locals, lookup_context, parent, block
5
+ def initialize(name, locals, lookup_context, parent, block)
7
6
  @_name = name
8
7
  @_parent = parent
9
8
  @_locals = locals
10
9
  @_lookup_context = lookup_context
11
10
  @_block = block
11
+ @_index = 0
12
12
 
13
13
  @_components = {}
14
14
  @_building = false
15
15
  end
16
16
 
17
+ # :nodoc:
18
+ def initialize_dup(other)
19
+ @_name = other._name
20
+ @_parent = other._parent
21
+ @_locals = other._locals.dup
22
+ @_lookup_context = other._lookup_context
23
+ @_block = other._block
24
+ @_components = other._components.dup
25
+ @_building = false
26
+ @_renderer = other._renderer
27
+ @_capture = other._capture
28
+ @_index = 0
29
+
30
+ super
31
+ end
32
+
17
33
  # Specify and use local values or sub-components using method calls.
18
34
  #
19
35
  # == Locals
@@ -100,9 +116,8 @@ class Component
100
116
  #
101
117
  def require *local_keys
102
118
  missing = local_keys.reject { |k| _locals.key?(k) || _components.key?(k) }
103
- if missing.count > 0
104
- raise "The #{_name} component requires #{missing.join(", ")} local(s) or component(s)."
105
- end
119
+ raise "The #{_name} component requires #{missing.join(", ")} local(s) or component(s)." if missing.count > 0
120
+
106
121
  nil
107
122
  end
108
123
 
@@ -116,12 +131,12 @@ class Component
116
131
  #
117
132
  # returns: [<Component>, <Component>, ...]
118
133
  #
119
- def components key
134
+ def components(key)
120
135
  _components[key] || []
121
136
  end
122
137
 
123
138
  # This is used to access locals passed to the component.
124
- def local key
139
+ def local(key)
125
140
  _locals[key]
126
141
  end
127
142
 
@@ -135,13 +150,12 @@ class Component
135
150
  #
136
151
  # this.header.render
137
152
  #
138
- def render symbol = nil
153
+ def render(symbol = nil)
139
154
  if symbol.nil?
140
- if _parent.nil?
141
- raise "Cannot render a component without a symbol when it has a parent."
142
- else
143
- return _yield_renderer
144
- end
155
+ raise "Cannot render a component without a symbol when it has a parent." if _parent.nil?
156
+
157
+ return _yield_renderer
158
+
145
159
  end
146
160
  _components[symbol]&.first&._yield_renderer
147
161
  end
@@ -152,8 +166,31 @@ class Component
152
166
  #
153
167
  # Returns a string of all rednered sub-components.
154
168
  #
155
- def render_all symbol
156
- _components[symbol]&.map(&:_yield_renderer)&.join&.html_safe
169
+ def render_all(symbol)
170
+ _components[symbol]&.each_with_index { |e, i| e._index = i }&.map(&:_yield_renderer)&.join&.html_safe
171
+ end
172
+
173
+ # Copy all sub-components from one name to another.
174
+ # This is useful when you want to render a sub-component using two+ subcomponents
175
+ #
176
+ # this.copy_components :links, :mobile_links
177
+ #
178
+ def copy_components(from, to)
179
+ return if _components[from].nil?
180
+
181
+ _components[to] = _components[from].map(&:dup).tap do |comps|
182
+ comps.each do |comp|
183
+ comp._name = to
184
+ end
185
+ end
186
+ end
187
+
188
+ # This will be set to the index of the component when using `render_all`
189
+ #
190
+ # Returns an integer
191
+ #
192
+ def index
193
+ _index
157
194
  end
158
195
 
159
196
  # Yield the block passed to the component.
@@ -180,21 +217,13 @@ class Component
180
217
 
181
218
  protected
182
219
 
183
- attr_reader :_name
184
- attr_reader :_locals
185
- attr_reader :_components
186
- attr_reader :_block
187
- attr_reader :_parent
188
- attr_accessor :_captured
189
- attr_reader :_lookup_context
190
- attr_accessor :_building
220
+ attr_accessor :_name, :_captured, :_building, :_index
221
+ attr_reader :_locals, :_components, :_block, :_parent, :_lookup_context
191
222
 
192
223
  # :nodoc:
193
224
  def _base_name
194
225
  on = self
195
- until on._parent.nil?
196
- on = on._parent
197
- end
226
+ on = on._parent until on._parent.nil?
198
227
  on._name
199
228
  end
200
229
 
@@ -1,3 +1,3 @@
1
1
  module Subcomponent
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subcomponent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - candland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-08 00:00:00.000000000 Z
11
+ date: 2024-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  requirements: []
65
- rubygems_version: 3.3.7
65
+ rubygems_version: 3.3.26
66
66
  signing_key:
67
67
  specification_version: 4
68
68
  summary: Very simple parial based components