subcomponent 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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