1
1
module ClassVariants
2
2
class Instance
3
- attr_reader :base , :variants , :compound_variants , :defaults
4
-
5
- # rubocop:disable Naming/VariableName
6
- def initialize ( classes = nil , base : nil , variants : { } , compoundVariants : [ ] , compound_variants : [ ] , defaults : { } )
7
- warn <<~MSG if classes
8
- (ClassVariants) DEPRECATION WARNING: Use of positional argument for default classes is deprecated
9
- and will be removed in the next version. Use the `base` keyword argument instead.
10
- MSG
11
-
12
- warn <<~MSG unless compoundVariants . empty?
13
- (ClassVariants) DEPRECATION WARNING: Use of `compoundVariants` keyword argument is deprecated
14
- and will be removed in the next version. Use the `compound_variant` instead.
15
- MSG
16
-
17
- @base = base || classes
18
- @variants = expand_boolean_variants ( variants )
19
- @compound_variants = compound_variants . empty? ? compoundVariants : compound_variants
20
- @defaults = defaults
3
+ def initialize ( **options , &block )
4
+ raise ArgumentError , "Use of hash config and code block is not supported" if !options . empty? && block_given?
5
+
6
+ @base = options . empty? ? { } : { default : options . fetch ( :base , nil ) }
7
+ @variants = expand_variants ( options . fetch ( :variants , { } ) ) + expand_compound_variants ( options . fetch ( :compound_variants , [ ] ) )
8
+ @defaults = options . fetch ( :defaults , { } )
9
+
10
+ instance_eval ( &block ) if block_given?
21
11
end
22
- # rubocop:enable Naming/VariableName
23
12
24
- def render ( **overrides )
13
+ def render ( slot = :default , **overrides )
25
14
# Start with our default classes
26
- result = [ @base ]
15
+ result = [ @base [ slot ] ]
27
16
28
17
# Then merge the passed in overrides on top of the defaults
29
- selected = @defaults . merge ( overrides )
18
+ criteria = @defaults . merge ( overrides )
30
19
31
- selected . each do |variant_type , variant |
32
- # dig the classes out and add them to the result
33
- result << @variants . dig ( variant_type , variant )
34
- end
20
+ @variants . each do |candidate |
21
+ next unless candidate [ :slot ] == slot
35
22
36
- @compound_variants . each do |compound_variant |
37
- if ( compound_variant . keys - [ :class ] ) . all? { |key | selected [ key ] == compound_variant [ key ] }
38
- result << compound_variant [ :class ]
23
+ if ( candidate . keys - [ :class , :slot ] ) . all? { |key | criteria [ key ] == candidate [ key ] }
24
+ result << candidate [ :class ]
39
25
end
40
26
end
41
27
@@ -48,19 +34,62 @@ def render(**overrides)
48
34
49
35
private
50
36
51
- def expand_boolean_variants ( variants )
52
- expanded = variants . map do |key , value |
53
- case value
37
+ def base ( klass = nil , &block )
38
+ raise ArgumentError , "Use of positional argument and code block is not supported" if klass && block_given?
39
+
40
+ if block_given?
41
+ with_slots ( &block ) . each do |slot |
42
+ @base [ slot [ :slot ] ] = slot [ :class ]
43
+ end
44
+ else
45
+ @base [ :default ] = klass
46
+ end
47
+ end
48
+
49
+ def variant ( **options , &block )
50
+ raise ArgumentError , "Use of class option and code block is not supported" if options . key? ( :class ) && block_given?
51
+
52
+ if block_given?
53
+ with_slots ( &block ) . each do |slot |
54
+ @variants << options . merge ( slot )
55
+ end
56
+ else
57
+ @variants << options . merge ( slot : :default )
58
+ end
59
+ end
60
+
61
+ def defaults ( **options )
62
+ @defaults = options
63
+ end
64
+
65
+ def slot ( name = :default , **options )
66
+ raise ArgumentError , "class option is required" unless options . key? ( :class )
67
+
68
+ @slots << options . merge ( slot : name )
69
+ end
70
+
71
+ def with_slots
72
+ @slots = [ ]
73
+ yield
74
+ @slots
75
+ end
76
+
77
+ def expand_variants ( variants )
78
+ variants . flat_map do |property , values |
79
+ case values
54
80
when String
55
- s_key = key . to_s
56
- { s_key . delete_prefix ( "!" ) . to_sym => { !s_key . start_with? ( "!" ) => value } }
81
+ { property . to_s . delete_prefix ( "!" ) . to_sym => !property . to_s . start_with? ( "!" ) , :class => values , :slot => :default }
57
82
else
58
- { key => value }
83
+ values . map do |key , value |
84
+ { property => key , :class => value , :slot => :default }
85
+ end
59
86
end
60
87
end
88
+ end
61
89
62
- expanded . reduce do |output , next_variant |
63
- output . merge! ( next_variant ) { |_key , v1 , v2 | v1 . merge! ( v2 ) }
90
+ def expand_compound_variants ( compound_variants )
91
+ compound_variants . map do |compound_variant |
92
+ compound_variant . merge ( slot : :default )
64
93
end
65
94
end
66
95
end
0 commit comments