view_component-contrib 0.2.2 → 0.2.3
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/.rbnext/3.0/view_component_contrib/style_variants.rb +211 -0
- data/lib/view_component_contrib/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e77986cf3606cd3c99d8bb42308ea152a0d2795d5e1f1976a047b46fc536ff17
|
4
|
+
data.tar.gz: 92cd0f179bdff4b3526ff93bd760116071c23ccff4c1693b772fbd93bfe3eb62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2719170e4c8a3b4f721f04cc7450302b10ac8fdc66046299921942d59a63dc1063e229f17657821b0b8879ced4d8ac0e968814fb527e0d5d8d9571ca507fa88f
|
7
|
+
data.tar.gz: 9b3f4ce732f3fd73668dfc70d15a80a2f96a52c5593ad6a2150e8df3e25234e9593c2d5d4cda39d2f0bd0e9f08e9958e290b7fb887541140fc3e2bc9d0f57e0e
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,211 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponentContrib
|
4
|
+
# Organize style in variants that can be combined.
|
5
|
+
# Inspired by https://www.tailwind-variants.org and https://cva.style/docs/getting-started/variants
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# class ButtonComponent < ViewComponent::Base
|
10
|
+
# include ViewComponentContrib::StyleVariants
|
11
|
+
#
|
12
|
+
# erb_template <<~ERB
|
13
|
+
# <button class="<%= style(size: 'sm', color: 'secondary') %>">Click me</button>
|
14
|
+
# ERB
|
15
|
+
#
|
16
|
+
# style do
|
17
|
+
# base {
|
18
|
+
# %w(
|
19
|
+
# font-medium bg-blue-500 text-white rounded-full
|
20
|
+
# )
|
21
|
+
# }
|
22
|
+
# variants {
|
23
|
+
# color {
|
24
|
+
# primary { %w(bg-blue-500 text-white) }
|
25
|
+
# secondary { %w(bg-purple-500 text-white) }
|
26
|
+
# }
|
27
|
+
# size {
|
28
|
+
# sm { "text-sm" }
|
29
|
+
# md { "text-base" }
|
30
|
+
# lg { "px-4 py-3 text-lg" }
|
31
|
+
# }
|
32
|
+
# }
|
33
|
+
# defaults { {size: :md, color: :primary} }
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# attr_reader :size, :color
|
37
|
+
#
|
38
|
+
# def initialize(size: :md, color: :primary)
|
39
|
+
# @size = size
|
40
|
+
# @color = color
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
module StyleVariants
|
45
|
+
class VariantBuilder
|
46
|
+
attr_reader :unwrap_blocks
|
47
|
+
|
48
|
+
def initialize(unwrap_blocks = true)
|
49
|
+
@unwrap_blocks = unwrap_blocks
|
50
|
+
@variants = {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def build(&block)
|
54
|
+
instance_eval(&block)
|
55
|
+
@variants
|
56
|
+
end
|
57
|
+
|
58
|
+
def respond_to_missing?(name, include_private = false)
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(name, &block)
|
63
|
+
return super unless block_given?
|
64
|
+
|
65
|
+
@variants[name] = if unwrap_blocks
|
66
|
+
VariantBuilder.new(false).build(&block)
|
67
|
+
else
|
68
|
+
block
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class StyleSet
|
74
|
+
def initialize(&init_block)
|
75
|
+
@base_block = nil
|
76
|
+
@defaults = {}
|
77
|
+
@variants = {}
|
78
|
+
@compounds = {}
|
79
|
+
|
80
|
+
instance_eval(&init_block) if init_block
|
81
|
+
end
|
82
|
+
|
83
|
+
def base(&block)
|
84
|
+
@base_block = block
|
85
|
+
end
|
86
|
+
|
87
|
+
def defaults(&block)
|
88
|
+
@defaults = block.call.freeze
|
89
|
+
end
|
90
|
+
|
91
|
+
def variants(&block)
|
92
|
+
@variants = VariantBuilder.new(true).build(&block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def compound(**variants, &block)
|
96
|
+
@compounds[variants] = block
|
97
|
+
end
|
98
|
+
|
99
|
+
def compile(**variants)
|
100
|
+
acc = Array(@base_block&.call || [])
|
101
|
+
|
102
|
+
config = @defaults.merge(variants.compact)
|
103
|
+
|
104
|
+
config.each do |variant, value|
|
105
|
+
value = cast_value(value)
|
106
|
+
variant = @variants.dig(variant, value) || next
|
107
|
+
styles = variant.is_a?(::Proc) ? variant.call(**config) : variant
|
108
|
+
acc.concat(Array(styles))
|
109
|
+
end
|
110
|
+
|
111
|
+
@compounds.each do |compound, value|
|
112
|
+
next unless compound.all? { |k, v| config[k] == v }
|
113
|
+
|
114
|
+
styles = value.is_a?(::Proc) ? value.call(**config) : value
|
115
|
+
acc.concat(Array(styles))
|
116
|
+
end
|
117
|
+
|
118
|
+
acc
|
119
|
+
end
|
120
|
+
|
121
|
+
def dup
|
122
|
+
copy = super
|
123
|
+
copy.instance_variable_set(:@defaults, @defaults.dup)
|
124
|
+
copy.instance_variable_set(:@variants, @variants.dup)
|
125
|
+
copy.instance_variable_set(:@compounds, @compounds.dup)
|
126
|
+
copy
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def cast_value(val)
|
132
|
+
case val
|
133
|
+
when true then :yes
|
134
|
+
when false then :no
|
135
|
+
else
|
136
|
+
val
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class StyleConfig # :nodoc:
|
142
|
+
DEFAULT_POST_PROCESSOR = ->(compiled) { compiled.join(" ") }
|
143
|
+
|
144
|
+
attr_reader :postprocessor
|
145
|
+
|
146
|
+
def initialize
|
147
|
+
@styles = {}
|
148
|
+
@postprocessor = DEFAULT_POST_PROCESSOR
|
149
|
+
end
|
150
|
+
|
151
|
+
def define(name, &block)
|
152
|
+
styles[name] = StyleSet.new(&block)
|
153
|
+
end
|
154
|
+
|
155
|
+
def compile(name, **variants)
|
156
|
+
styles[name]&.compile(**variants).then do |compiled|
|
157
|
+
next unless compiled
|
158
|
+
|
159
|
+
postprocess(compiled)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Allow defining a custom postprocessor
|
164
|
+
def postprocess_with(callable = nil, &block)
|
165
|
+
@postprocessor = callable || block
|
166
|
+
end
|
167
|
+
|
168
|
+
def dup
|
169
|
+
copy = super
|
170
|
+
copy.instance_variable_set(:@styles, @styles.dup)
|
171
|
+
copy
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
attr_reader :styles
|
177
|
+
|
178
|
+
def postprocess(compiled) ; postprocessor.call(compiled); end
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.included(base)
|
182
|
+
base.extend ClassMethods
|
183
|
+
end
|
184
|
+
|
185
|
+
module ClassMethods
|
186
|
+
# Returns the name of the default style set based on the class name:
|
187
|
+
# MyComponent::Component => my_component
|
188
|
+
# Namespaced::MyComponent => my_component
|
189
|
+
def default_style_name
|
190
|
+
@default_style_name ||= name.demodulize.sub(/(::Component|Component)$/, "").underscore.presence || "component"
|
191
|
+
end
|
192
|
+
|
193
|
+
def style(name = default_style_name, &block)
|
194
|
+
style_config.define(name.to_sym, &block)
|
195
|
+
end
|
196
|
+
|
197
|
+
def style_config
|
198
|
+
@style_config ||=
|
199
|
+
if superclass.respond_to?(:style_config)
|
200
|
+
superclass.style_config.dup
|
201
|
+
else
|
202
|
+
StyleConfig.new
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def style(name = self.class.default_style_name, **variants)
|
208
|
+
self.class.style_config.compile(name.to_sym, **variants)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
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.
|
4
|
+
version: 0.2.3
|
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:
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: view_component
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- LICENSE.txt
|
148
148
|
- README.md
|
149
149
|
- app/views/view_component_contrib/preview.html.erb
|
150
|
+
- lib/.rbnext/3.0/view_component_contrib/style_variants.rb
|
150
151
|
- lib/view_component-contrib.rb
|
151
152
|
- lib/view_component_contrib.rb
|
152
153
|
- lib/view_component_contrib/base.rb
|
@@ -170,7 +171,7 @@ metadata:
|
|
170
171
|
documentation_uri: http://github.com/palkan/view_component-contrib
|
171
172
|
homepage_uri: http://github.com/palkan/view_component-contrib
|
172
173
|
source_code_uri: http://github.com/palkan/view_component-contrib
|
173
|
-
post_install_message:
|
174
|
+
post_install_message:
|
174
175
|
rdoc_options: []
|
175
176
|
require_paths:
|
176
177
|
- lib
|
@@ -185,8 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
186
|
- !ruby/object:Gem::Version
|
186
187
|
version: '0'
|
187
188
|
requirements: []
|
188
|
-
rubygems_version: 3.4.
|
189
|
-
signing_key:
|
189
|
+
rubygems_version: 3.4.19
|
190
|
+
signing_key:
|
190
191
|
specification_version: 4
|
191
192
|
summary: A collection of extensions and developer tools for ViewComponent
|
192
193
|
test_files: []
|