view_component-contrib 0.2.3 → 0.2.4

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: e77986cf3606cd3c99d8bb42308ea152a0d2795d5e1f1976a047b46fc536ff17
4
- data.tar.gz: 92cd0f179bdff4b3526ff93bd760116071c23ccff4c1693b772fbd93bfe3eb62
3
+ metadata.gz: 66619dee8f7cb3f26eddce9c5809ce7c879f8f464f2fa8ed140cd5a0ba08bfbd
4
+ data.tar.gz: e0f4013b8bebd93cab59f17ed52f1a6bd92c401b672919f49b386019296b0b1a
5
5
  SHA512:
6
- metadata.gz: 2719170e4c8a3b4f721f04cc7450302b10ac8fdc66046299921942d59a63dc1063e229f17657821b0b8879ced4d8ac0e968814fb527e0d5d8d9571ca507fa88f
7
- data.tar.gz: 9b3f4ce732f3fd73668dfc70d15a80a2f96a52c5593ad6a2150e8df3e25234e9593c2d5d4cda39d2f0bd0e9f08e9958e290b7fb887541140fc3e2bc9d0f57e0e
6
+ metadata.gz: 9d35a906a4c66e3097266b2b3f8df662fac38dd5f0ce4580e35d5e0a99cd3c90ee2ce6c5db36c3fc8ec16a9e9359fc600e61b205075d55ac36d853b77e6afb00
7
+ data.tar.gz: d66d56152567959e2f9cbe57ee0b9becaaeeed366179c88bfaf17b9bc1dd92b50295c996a03e169bfd397f9d2444d4ba8e3c9e7e7c48fe91cca49c5f658d00ca
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.2.4 (2025-01-03)
6
+
7
+ - Add inheritance strategies to style variants ([@omarluq][])
8
+
9
+ - Add special `class:` variant to `style` helper. For appending classes.
10
+ Inspired by https://cva.style/docs/getting-started/extending-components
11
+
5
12
  ## 0.2.3 (2024-07-31)
6
13
 
7
14
  - Fix publishing transpiled files (and bring Ruby 2.7 support back) ([@palkan][])
data/README.md CHANGED
@@ -277,6 +277,15 @@ And in the template:
277
277
  </div>
278
278
  ```
279
279
 
280
+ You can also add additional classes through thr `style` method using the special `class:` variant, like so:
281
+
282
+ ```erb
283
+ <div>
284
+ <button class="<%= style(size:, theme:, class: 'extra-class') %>">Click me</button>
285
+ <img src="..." class="<%= style(:image, orient: :portrait) %>">
286
+ </div>
287
+ ```
288
+
280
289
  Finally, you can inject into the class list compilation process to add your own logic:
281
290
 
282
291
  ```ruby
@@ -292,6 +301,69 @@ class ButtonComponent < ViewComponent::Base
292
301
  end
293
302
  ```
294
303
 
304
+ ### Style variants inheritance
305
+
306
+ Style variants support three inheritance strategies when extending components:
307
+
308
+ 1. `override` (default behavior): Completely replaces parent variants.
309
+ 2. `merge` (deep merge): Preserves all variant keys unless explicitly overwritten.
310
+ 3. `extend` (shallow merge): Preserves variants unless explicitly overwritten.
311
+
312
+ Consider an example:
313
+
314
+ ```ruby
315
+ class Parent::Component < ViewComponent::Base
316
+ include ViewComponentContrib::StyleVariants
317
+
318
+ style do
319
+ variants do
320
+ size {
321
+ md { "text-md" }
322
+ lg { "text-lg" }
323
+ }
324
+ disabled {
325
+ yes { "opacity-50" }
326
+ }
327
+ end
328
+ end
329
+ end
330
+
331
+ # Using override strategy (default)
332
+ class Child::Component < Parent::Component
333
+ style do
334
+ variants do
335
+ size {
336
+ lg { "text-larger" }
337
+ }
338
+ end
339
+ end
340
+ end
341
+
342
+ # Using merge strategy
343
+ class Child::Component < Parent::Component
344
+ style do
345
+ variants(strategy: :merge) do
346
+ size {
347
+ lg { "text-larger" }
348
+ }
349
+ end
350
+ end
351
+ end
352
+
353
+ # Using extend strategy
354
+ class Child::Component < Parent::Component
355
+ style do
356
+ variants(strategy: :extend) do
357
+ size {
358
+ lg { "text-larger" }
359
+ }
360
+ end
361
+ end
362
+ end
363
+ ```
364
+
365
+ 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.
366
+
295
367
  ### Dependent (or compound) styles
296
368
 
297
369
  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
 
@@ -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.4"
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.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-31 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: view_component