subcomponent 0.1.0 → 0.1.1

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: c25d8e894e5b6c33b5c57ff245854c4e551cc386a81a0853eb7eb79deab09681
4
+ data.tar.gz: e77d20a23ae634f2f3327c607d203b61b8093b7d12760b997bd72d6ef1d62118
5
5
  SHA512:
6
- metadata.gz: ca8c18a231cfc387a1545e5c894903890396365d1776d6432c2d7aa702ec0e07b4e7979934476fc1b77099837349b407a5fac4888dcba4fdcd65b30c3e598d24
7
- data.tar.gz: d8644df39b061f70c0213449f6b34e9b0f94f7cd69f8ecaa5b61388ca6cd9888e3e09e038b6b35c2631c5472b9f5dcaa66ffb8a399a356685623199b37fc83e1
6
+ metadata.gz: b44838794980b5f214465e3f9045eeca9c5b9dec83cf129a913ac76bdf12545f4e9154cdf441fd124e331f81f4b4d6027f2bd94d40ced0e94182af905c098123
7
+ data.tar.gz: 56b791c3e2dd6760c9e856801ed2129afc56e6d842fb00e43fb84c143d9daf7ad45f1e9dc2ebe52406714f263b3425b6d69d028da4d5ac3392ce910429d3e242
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,29 @@ 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
+ _components[to] = _components[from].map(&:dup).tap do |comps|
180
+ comps.each do |comp|
181
+ comp._name = to
182
+ end
183
+ end
184
+ end
185
+
186
+ # This will be set to the index of the component when using `render_all`
187
+ #
188
+ # Returns an integer
189
+ #
190
+ def index
191
+ _index
157
192
  end
158
193
 
159
194
  # Yield the block passed to the component.
@@ -180,21 +215,13 @@ class Component
180
215
 
181
216
  protected
182
217
 
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
218
+ attr_accessor :_name, :_captured, :_building, :_index
219
+ attr_reader :_locals, :_components, :_block, :_parent, :_lookup_context
191
220
 
192
221
  # :nodoc:
193
222
  def _base_name
194
223
  on = self
195
- until on._parent.nil?
196
- on = on._parent
197
- end
224
+ on = on._parent until on._parent.nil?
198
225
  on._name
199
226
  end
200
227
 
@@ -1,3 +1,3 @@
1
1
  module Subcomponent
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.1'
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.1
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