view_component-contrib 0.2.3 → 0.2.5

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: e77986cf3606cd3c99d8bb42308ea152a0d2795d5e1f1976a047b46fc536ff17
4
- data.tar.gz: 92cd0f179bdff4b3526ff93bd760116071c23ccff4c1693b772fbd93bfe3eb62
3
+ metadata.gz: 7c4462e19792094a58f7e978536c6d87d605ae446bdc9adf797ff0b4365878be
4
+ data.tar.gz: 21d2ebe79737dd36a048798dacf1fc01fa92dba6d7d957b1e939bf4cf284402d
5
5
  SHA512:
6
- metadata.gz: 2719170e4c8a3b4f721f04cc7450302b10ac8fdc66046299921942d59a63dc1063e229f17657821b0b8879ced4d8ac0e968814fb527e0d5d8d9571ca507fa88f
7
- data.tar.gz: 9b3f4ce732f3fd73668dfc70d15a80a2f96a52c5593ad6a2150e8df3e25234e9593c2d5d4cda39d2f0bd0e9f08e9958e290b7fb887541140fc3e2bc9d0f57e0e
6
+ metadata.gz: 741c7ff4d79e22782f0ea396ec70587b249fd26431931afa08cd1b704cf0f9e0ef905b2e4cb2af3fcc8bf936da94a38c3c22ee2a5496aa889b55f46f05e0be5c
7
+ data.tar.gz: 376bae69f57424b9a583ed467197fe4bb2678de1106c84e85cec53cb9e5887a6dc52248289ad8b413c1d6499be1134cf60dc5f26d49bd8ba65a89edc52604443
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.2.5 (2025-08-11)
6
+
7
+ - Fix compatibility with view_component v4.
8
+
9
+ ## 0.2.4 (2025-01-03)
10
+
11
+ - Add inheritance strategies to style variants ([@omarluq][])
12
+
13
+ - Add special `class:` variant to `style` helper. For appending classes.
14
+ Inspired by https://cva.style/docs/getting-started/extending-components
15
+
5
16
  ## 0.2.3 (2024-07-31)
6
17
 
7
18
  - Fix publishing transpiled files (and bring Ruby 2.7 support back) ([@palkan][])
data/README.md CHANGED
@@ -81,6 +81,10 @@ config.autoload_paths << Rails.root.join("app", "frontend", "components")
81
81
  First, we need to specify the lookup path for previews in the app's configuration:
82
82
 
83
83
  ```ruby
84
+ # view_component >= v4
85
+ config.view_component.previews.paths << Rails.root.join("app", "frontend", "components")
86
+
87
+ # view_component <= v3
84
88
  config.view_component.preview_paths << Rails.root.join("app", "frontend", "components")
85
89
  ```
86
90
 
@@ -277,6 +281,15 @@ And in the template:
277
281
  </div>
278
282
  ```
279
283
 
284
+ You can also add additional classes through thr `style` method using the special `class:` variant, like so:
285
+
286
+ ```erb
287
+ <div>
288
+ <button class="<%= style(size:, theme:, class: 'extra-class') %>">Click me</button>
289
+ <img src="..." class="<%= style(:image, orient: :portrait) %>">
290
+ </div>
291
+ ```
292
+
280
293
  Finally, you can inject into the class list compilation process to add your own logic:
281
294
 
282
295
  ```ruby
@@ -292,6 +305,69 @@ class ButtonComponent < ViewComponent::Base
292
305
  end
293
306
  ```
294
307
 
308
+ ### Style variants inheritance
309
+
310
+ Style variants support three inheritance strategies when extending components:
311
+
312
+ 1. `override` (default behavior): Completely replaces parent variants.
313
+ 2. `merge` (deep merge): Preserves all variant keys unless explicitly overwritten.
314
+ 3. `extend` (shallow merge): Preserves variants unless explicitly overwritten.
315
+
316
+ Consider an example:
317
+
318
+ ```ruby
319
+ class Parent::Component < ViewComponent::Base
320
+ include ViewComponentContrib::StyleVariants
321
+
322
+ style do
323
+ variants do
324
+ size {
325
+ md { "text-md" }
326
+ lg { "text-lg" }
327
+ }
328
+ disabled {
329
+ yes { "opacity-50" }
330
+ }
331
+ end
332
+ end
333
+ end
334
+
335
+ # Using override strategy (default)
336
+ class Child::Component < Parent::Component
337
+ style do
338
+ variants do
339
+ size {
340
+ lg { "text-larger" }
341
+ }
342
+ end
343
+ end
344
+ end
345
+
346
+ # Using merge strategy
347
+ class Child::Component < Parent::Component
348
+ style do
349
+ variants(strategy: :merge) do
350
+ size {
351
+ lg { "text-larger" }
352
+ }
353
+ end
354
+ end
355
+ end
356
+
357
+ # Using extend strategy
358
+ class Child::Component < Parent::Component
359
+ style do
360
+ variants(strategy: :extend) do
361
+ size {
362
+ lg { "text-larger" }
363
+ }
364
+ end
365
+ end
366
+ end
367
+ ```
368
+
369
+ In this example, the `override` strategy will only keep the `size.lg` variant, dropping all others. The `merge` strategy preserves all variants and their keys, only replacing the `size.lg` value. The `extend` strategy keeps all variants but replaces all keys of the overwritten `size` variant.
370
+
295
371
  ### Dependent (or compound) styles
296
372
 
297
373
  Sometimes it might be necessary to define complex styling rules, e.g., when a combination of variants requires adding additional styles. That's where usage of Ruby blocks for configuration becomes useful. For example:
@@ -77,7 +77,10 @@ module ViewComponentContrib
77
77
  @variants = {}
78
78
  @compounds = {}
79
79
 
80
- instance_eval(&init_block) if init_block
80
+ return unless init_block
81
+
82
+ @init_block = init_block
83
+ instance_eval(&init_block)
81
84
  end
82
85
 
83
86
  def base(&block)
@@ -88,8 +91,34 @@ module ViewComponentContrib
88
91
  @defaults = block.call.freeze
89
92
  end
90
93
 
91
- def variants(&block)
92
- @variants = VariantBuilder.new(true).build(&block)
94
+ def variants(strategy: :override, &block)
95
+ variants = build_variants(&block)
96
+ @variants = handle_variants(variants, strategy)
97
+ end
98
+
99
+ def build_variants(&block)
100
+ VariantBuilder.new(true).build(&block)
101
+ end
102
+
103
+ def handle_variants(variants, strategy)
104
+ return variants if strategy == :override
105
+
106
+ parent_variants = find_parent_variants
107
+ return variants unless parent_variants
108
+
109
+ return parent_variants.deep_merge(variants) if strategy == :merge
110
+
111
+ parent_variants.merge(variants) if strategy == :extend
112
+ end
113
+
114
+ def find_parent_variants
115
+ parent_component = @init_block.binding.receiver.superclass
116
+ return unless parent_component.respond_to?(:style_config)
117
+
118
+ parent_config = parent_component.style_config
119
+ default_parent_style = parent_component.default_style_name
120
+ parent_style_set = parent_config.instance_variable_get(:@styles)[default_parent_style.to_sym]
121
+ parent_style_set.instance_variable_get(:@variants).deep_dup
93
122
  end
94
123
 
95
124
  def compound(**variants, &block)
@@ -115,6 +144,8 @@ module ViewComponentContrib
115
144
  acc.concat(Array(styles))
116
145
  end
117
146
 
147
+ acc.concat(Array(config[:class]))
148
+ acc.concat(Array(config[:class_name]))
118
149
  acc
119
150
  end
120
151
 
@@ -2,11 +2,25 @@
2
2
 
3
3
  module ViewComponentContrib
4
4
  class Railtie < Rails::Railtie
5
- config.view_component.preview_paths << File.join(ViewComponentContrib::APP_PATH, "views")
5
+ if !config.view_component.previews.nil?
6
+ config.view_component.previews.paths << File.join(ViewComponentContrib::APP_PATH, "views")
7
+ else
8
+ config.view_component.preview_paths << File.join(ViewComponentContrib::APP_PATH, "views")
9
+ end
6
10
 
7
11
  initializer "view_component-contrib.skip_loading_previews_if_disabled" do
8
- unless Rails.application.config.view_component.show_previews
9
- previews = Rails.application.config.view_component.preview_paths.flat_map do |path|
12
+ vc_config = Rails.application.config.view_component
13
+
14
+ preview_enabled = (!vc_config.previews.nil?) ?
15
+ vc_config.previews.enabled :
16
+ vc_config.show_previews
17
+
18
+ unless preview_enabled
19
+ preview_paths = (!vc_config.previews.nil?) ?
20
+ vc_config.previews.paths :
21
+ vc_config.preview_paths
22
+
23
+ previews = preview_paths.flat_map do |path|
10
24
  Pathname(path).glob("**/*preview.rb")
11
25
  end
12
26
  Rails.autoloaders.each { |autoloader| autoloader.ignore(previews) }
@@ -77,7 +77,10 @@ module ViewComponentContrib
77
77
  @variants = {}
78
78
  @compounds = {}
79
79
 
80
- instance_eval(&init_block) if init_block
80
+ return unless init_block
81
+
82
+ @init_block = init_block
83
+ instance_eval(&init_block)
81
84
  end
82
85
 
83
86
  def base(&block)
@@ -88,8 +91,34 @@ module ViewComponentContrib
88
91
  @defaults = block.call.freeze
89
92
  end
90
93
 
91
- def variants(&block)
92
- @variants = VariantBuilder.new(true).build(&block)
94
+ def variants(strategy: :override, &block)
95
+ variants = build_variants(&block)
96
+ @variants = handle_variants(variants, strategy)
97
+ end
98
+
99
+ def build_variants(&block)
100
+ VariantBuilder.new(true).build(&block)
101
+ end
102
+
103
+ def handle_variants(variants, strategy)
104
+ return variants if strategy == :override
105
+
106
+ parent_variants = find_parent_variants
107
+ return variants unless parent_variants
108
+
109
+ return parent_variants.deep_merge(variants) if strategy == :merge
110
+
111
+ parent_variants.merge(variants) if strategy == :extend
112
+ end
113
+
114
+ def find_parent_variants
115
+ parent_component = @init_block.binding.receiver.superclass
116
+ return unless parent_component.respond_to?(:style_config)
117
+
118
+ parent_config = parent_component.style_config
119
+ default_parent_style = parent_component.default_style_name
120
+ parent_style_set = parent_config.instance_variable_get(:@styles)[default_parent_style.to_sym]
121
+ parent_style_set.instance_variable_get(:@variants).deep_dup
93
122
  end
94
123
 
95
124
  def compound(**variants, &block)
@@ -115,6 +144,8 @@ module ViewComponentContrib
115
144
  acc.concat(Array(styles))
116
145
  end
117
146
 
147
+ acc.concat(Array(config[:class]))
148
+ acc.concat(Array(config[:class_name]))
118
149
  acc
119
150
  end
120
151
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ViewComponentContrib # :nodoc:all
4
- VERSION = "0.2.3"
4
+ VERSION = "0.2.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-31 00:00:00.000000000 Z
11
+ date: 2025-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: view_component
@@ -171,7 +171,7 @@ metadata:
171
171
  documentation_uri: http://github.com/palkan/view_component-contrib
172
172
  homepage_uri: http://github.com/palkan/view_component-contrib
173
173
  source_code_uri: http://github.com/palkan/view_component-contrib
174
- post_install_message:
174
+ post_install_message:
175
175
  rdoc_options: []
176
176
  require_paths:
177
177
  - lib
@@ -187,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  version: '0'
188
188
  requirements: []
189
189
  rubygems_version: 3.4.19
190
- signing_key:
190
+ signing_key:
191
191
  specification_version: 4
192
192
  summary: A collection of extensions and developer tools for ViewComponent
193
193
  test_files: []