view_component 2.18.1 → 2.18.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.

Potentially problematic release.


This version of view_component might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b7c014848a75fb2a72a784a34b2c264de34a510c97c446614285f1854cd995a
4
- data.tar.gz: 7a58ac8988ff8fea69e366ce21b2bff7a9f0a54bd4411f89630a701433064327
3
+ metadata.gz: a2198b33fb53185423a45c6f13023650604e7dacc2f5b44c2455f44b684ffdbc
4
+ data.tar.gz: f9eaffd030eb7bef12b243cfdf42333e4f5b28bf6a975f6b4720b65ef0d6aedc
5
5
  SHA512:
6
- metadata.gz: ed456c91f637872701a85eb71ed7d9dc0e12453ece026fcba2c2c4c2fedc1bbd1769caed36735cd90ac42b68582b3379e4acede29b749d65813d38e60cd01afc
7
- data.tar.gz: cb73cf684f8e10a49cd56b7e001688f8a05aeb842604b5d0204b0b0f4c8017abda00556665a02a163c0a1019107f1beb13a2a32ea4492c38efedc87e4af336a0
6
+ metadata.gz: 9ab6f420e32b85e912b4407ab3679e3fd696800547aecaa13c15c7833c82564f7ba8bc7db4fad8dbd7aa201250db156901486ee3c12b13f37ffedca3e5cbacf1
7
+ data.tar.gz: 22103cb47921ba57712808c6a3130f48926a40179a3564fab9b2235dc892edde3ed81df28e6c23535685d13121b4be1f232836612e7132d4be04143595eebb6d
@@ -1,5 +1,15 @@
1
1
  # master
2
2
 
3
+ # 2.18.2
4
+
5
+ * Raise an error if controller or view context is accessed during initialize as they are only available in render.
6
+
7
+ *Julian Nadeau*
8
+
9
+ * Collate test coverage across CI builds, ensuring 100% test coverage.
10
+
11
+ *Joel Hawksley*
12
+
3
13
  # 2.18.1
4
14
 
5
15
  * Fix bug where previews didn't work when monkey patch was disabled.
data/README.md CHANGED
@@ -47,6 +47,10 @@ Traditional Rails views have an implicit interface, making it hard to reason abo
47
47
 
48
48
  ViewComponents use a standard Ruby initializer that clearly defines what is needed to render, making them easier (and safer) to reuse than partials.
49
49
 
50
+ #### Performance
51
+
52
+ Based on our [benchmarks](performance/benchmark.rb), ViewComponents are ~10x faster than partials.
53
+
50
54
  #### Standards
51
55
 
52
56
  Views often fail basic Ruby code quality standards: long methods, deep conditional nesting, and mystery guests abound.
@@ -164,19 +168,17 @@ Returning:
164
168
 
165
169
  _Slots are currently under development as a successor to Content Areas. The Slot APIs should be considered unfinished and subject to breaking changes in non-major releases of ViewComponent._
166
170
 
167
- Slots enable multiple blocks of content to be passed to a single ViewComponent.
168
-
169
- Slots exist in two forms: normal slots and collection slots.
171
+ Slots enable multiple blocks of content to be passed to a single ViewComponent, reducing the need for sub-components (e.g. ModalHeader, ModalBody).
170
172
 
171
- Normal slots can be rendered once per component. They expose an accessor with the name of the slot that returns an instance of `ViewComponent::Slot`, etc.
173
+ By default, slots can be rendered once per component. They provide an accessor with the name of the slot (`#header`) that returns an instance of `ViewComponent::Slot`, etc.
172
174
 
173
- Collection slots can be rendered multiple times. They expose an accessor with the pluralized name of the slot (`#rows`), which is an Array of `ViewComponent::Slot` instances.
175
+ Slots declared with `collection: true` can be rendered multiple times. They provide an accessor with the pluralized name of the slot (`#rows`), which is an Array of `ViewComponent::Slot` instances.
174
176
 
175
- To learn more about the design of the Slots API, see https://github.com/github/view_component/pull/348.
177
+ To learn more about the design of the Slots API, see https://github.com/github/view_component/pull/348 and https://github.com/github/view_component/discussions/325.
176
178
 
177
179
  ##### Defining Slots
178
180
 
179
- Slots are defined by the `with_slot` macro:
181
+ Slots are defined by `with_slot`:
180
182
 
181
183
  `with_slot :header`
182
184
 
@@ -184,11 +186,11 @@ To define a collection slot, add `collection: true`:
184
186
 
185
187
  `with_slot :row, collection: true`
186
188
 
187
- To define a slot with a custom class, pass `class_name`:
189
+ To define a slot with a custom Ruby class, pass `class_name`:
188
190
 
189
191
  `with_slot :body, class_name: 'BodySlot`
190
192
 
191
- Slot classes should be subclasses of `ViewComponent::Slot`.
193
+ _Note: Slot classes must be subclasses of `ViewComponent::Slot`._
192
194
 
193
195
  ##### Example ViewComponent with Slots
194
196
 
@@ -202,12 +204,12 @@ class BoxComponent < ViewComponent::Base
202
204
  with_slot :row, collection: true, class_name: "Row"
203
205
 
204
206
  class Header < ViewComponent::Slot
205
- def initialize(class_names: "")
206
- @class_names = class_names
207
+ def initialize(classes: "")
208
+ @classes = classes
207
209
  end
208
210
 
209
- def class_names
210
- "Box-header #{@class_names}"
211
+ def classes
212
+ "Box-header #{@classes}"
211
213
  end
212
214
  end
213
215
 
@@ -240,7 +242,7 @@ end
240
242
  ```erb
241
243
  <div class="Box">
242
244
  <% if header %>
243
- <div class="<%= header.class_names %>">
245
+ <div class="<%= header.classes %>">
244
246
  <%= header.content %>
245
247
  </div>
246
248
  <% end %>
@@ -260,7 +262,7 @@ end
260
262
  <% end %>
261
263
  <% if footer %>
262
264
  <div class="Box-footer">
263
- <%= footer %>
265
+ <%= footer.content %>
264
266
  </div>
265
267
  <% end %>
266
268
  </div>
@@ -269,7 +271,7 @@ end
269
271
  `# index.html.erb`
270
272
  ```erb
271
273
  <%= render(BoxComponent.new) do |component| %>
272
- <% component.slot(:header, class_names: "my-class-name") do %>
274
+ <% component.slot(:header, classes: "my-class-name") do %>
273
275
  This is my header!
274
276
  <% end %>
275
277
  <% component.slot(:body) do %>
@@ -360,6 +362,32 @@ bin/rails generate component Example title content --sidecar
360
362
  create app/components/example_component/example_component.html.erb
361
363
  ```
362
364
 
365
+ #### Component file inside Sidecar directory
366
+
367
+ It's also possible to place the Ruby component file inside the sidecar directory, grouping all related files in the same folder:
368
+
369
+ _Note: Avoid giving your containing folder the same name as your `.rb` file or there will be a conflict between Module and Class definitions_
370
+
371
+ ```
372
+ app/components
373
+ ├── ...
374
+ ├── example
375
+ | ├── component.rb
376
+ | ├── component.css
377
+ | ├── component.html.erb
378
+ | └── component.js
379
+ ├── ...
380
+
381
+ ```
382
+
383
+ The component can then be rendered using the folder name as a namespace:
384
+
385
+ ```erb
386
+ <%= render(Example::Component.new(title: "my title")) do %>
387
+ Hello, World!
388
+ <% end %>
389
+ ```
390
+
363
391
  ### Conditional Rendering
364
392
 
365
393
  Components can implement a `#render?` method to be called after initialization to determine if the component should render.
@@ -1003,6 +1031,11 @@ ViewComponent is built by:
1003
1031
  |@johannesengl|@czj|@mrrooijen|@bradparker|@mattbrictson|
1004
1032
  |Berlin, Germany|Paris, France|The Netherlands|Brisbane, Australia|San Francisco|
1005
1033
 
1034
+ |<img src="https://avatars.githubusercontent.com/mixergtz?s=256" alt="mixergtz" width="128" />|<img src="https://avatars.githubusercontent.com/jules2689?s=256" alt="jules2689" width="128" />|
1035
+ |:---:|:---:|
1036
+ |@mixergtz|@jules2689|
1037
+ |Medellin, Colombia|Toronto, Canada|
1038
+
1006
1039
  ## License
1007
1040
 
1008
1041
  ViewComponent is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -12,6 +12,8 @@ module ViewComponent
12
12
  include ActiveSupport::Configurable
13
13
  include ViewComponent::Previewable
14
14
 
15
+ ViewContextCalledBeforeRenderError = Class.new(StandardError)
16
+
15
17
  # For CSRF authenticity tokens in forms
16
18
  delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
17
19
 
@@ -108,11 +110,13 @@ module ViewComponent
108
110
  end
109
111
 
110
112
  def controller
113
+ raise ViewContextCalledBeforeRenderError, "`controller` can only be called at render time." if view_context.nil?
111
114
  @controller ||= view_context.controller
112
115
  end
113
116
 
114
117
  # Provides a proxy to access helper methods from the context of the current controller
115
118
  def helpers
119
+ raise ViewContextCalledBeforeRenderError, "`helpers` can only be called at render time." if view_context.nil?
116
120
  @helpers ||= controller.view_context
117
121
  end
118
122
 
@@ -381,17 +385,17 @@ module ViewComponent
381
385
 
382
386
  location_without_extension = source_location.chomp(File.extname(source_location))
383
387
 
384
- extenstions = ActionView::Template.template_handler_extensions.join(",")
388
+ extensions = ActionView::Template.template_handler_extensions.join(",")
385
389
 
386
- # view files in the same directory as te component
387
- sidecar_files = Dir["#{location_without_extension}.*{#{extenstions}}"]
390
+ # view files in the same directory as the component
391
+ sidecar_files = Dir["#{location_without_extension}.*{#{extensions}}"]
388
392
 
389
393
  # view files in a directory named like the component
390
394
  directory = File.dirname(source_location)
391
395
  filename = File.basename(source_location, ".rb")
392
396
  component_name = name.demodulize.underscore
393
397
 
394
- sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extenstions}}"]
398
+ sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
395
399
 
396
400
  (sidecar_files - [source_location] + sidecar_directory_files)
397
401
  end
@@ -44,21 +44,11 @@ module ViewComponent # :nodoc:
44
44
  result.merge(layout: @layout)
45
45
  end
46
46
 
47
- # Returns the component object class associated to the preview.
48
- def component
49
- name.chomp("Preview").constantize
50
- end
51
-
52
47
  # Returns all of the available examples for the component preview.
53
48
  def examples
54
49
  public_instance_methods(false).map(&:to_s).sort
55
50
  end
56
51
 
57
- # Returns +true+ if the example of the component preview exists.
58
- def example_exists?(example)
59
- examples.include?(example)
60
- end
61
-
62
52
  # Returns +true+ if the preview exists.
63
53
  def exists?(preview)
64
54
  all.any? { |p| p.preview_name == preview }
@@ -104,10 +94,6 @@ module ViewComponent # :nodoc:
104
94
  def preview_paths
105
95
  Base.preview_paths
106
96
  end
107
-
108
- def show_previews
109
- Base.show_previews
110
- end
111
97
  end
112
98
  end
113
99
  end
@@ -14,7 +14,11 @@ module ViewComponent
14
14
  assert_no_selector("body")
15
15
  end
16
16
  rescue LoadError
17
+ # We don't have a test case for running an application without capybara installed.
18
+ # It's probably fine to leave this without coverage.
19
+ # :nocov:
17
20
  warn "WARNING in `ViewComponent::TestHelpers`: You must add `capybara` to your Gemfile to use Capybara assertions." if ENV["DEBUG"]
21
+ # :nocov:
18
22
  end
19
23
 
20
24
  attr_reader :rendered_component
@@ -4,7 +4,7 @@ module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 2
6
6
  MINOR = 18
7
- PATCH = 1
7
+ PATCH = 2
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.18.1
4
+ version: 2.18.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-10 00:00:00.000000000 Z
11
+ date: 2020-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '7.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: benchmark-ips
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 2.8.2
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 2.8.2
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: bundler
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -157,19 +171,19 @@ dependencies:
157
171
  - !ruby/object:Gem::Version
158
172
  version: 0.18.0
159
173
  - !ruby/object:Gem::Dependency
160
- name: simplecov-erb
174
+ name: simplecov-console
161
175
  requirement: !ruby/object:Gem::Requirement
162
176
  requirements:
163
177
  - - "~>"
164
178
  - !ruby/object:Gem::Version
165
- version: '0.1'
179
+ version: 0.7.2
166
180
  type: :development
167
181
  prerelease: false
168
182
  version_requirements: !ruby/object:Gem::Requirement
169
183
  requirements:
170
184
  - - "~>"
171
185
  - !ruby/object:Gem::Version
172
- version: '0.1'
186
+ version: 0.7.2
173
187
  description:
174
188
  email:
175
189
  - opensource+view_component@github.com