ruby_styler 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc2d2697f71503415f4c55bf9c37c7355c4302b432a9d23d9645601f5043049d
4
+ data.tar.gz: e3b806e9688d6fdb3610d9f7ab9d86822895c7be0f02ab1f50ec9379689b42d8
5
+ SHA512:
6
+ metadata.gz: 04a9713884e011cab7c1df484e76ec92155cbf9620b3689d9bfa3de376d492bbed9659436cdc07964cd52ac195e06e8f6c0a2c5b5bdca7cc2008233235e858a0
7
+ data.tar.gz: 549b2c02f204d3b5cf898564c2dbb016f8e835ef5077407ac71973582f4c557a7dc71457411c32a5849ae2f16681d4f36f4891b3ace0df38466c424345d182de
data/README.md ADDED
@@ -0,0 +1,333 @@
1
+ # Styler
2
+
3
+ A tool for styling html by composing css utility classes, like Tachyons.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "ruby_styler"
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ruby_styler
20
+
21
+ ## Usage
22
+
23
+ ### Define styles
24
+
25
+ You can declare styles with a name and an already defined css class, for example if you define a `style`
26
+ named `btn`, like this...
27
+
28
+ ```ruby
29
+ styles = Styler.new do
30
+ style :btn, ["white", "bg_blue"]
31
+ end
32
+ ```
33
+
34
+ That will build and `styles` object where you can call `btn` on it...
35
+
36
+ ```ruby
37
+ styles.btn.to_s # => "white bg_blue"
38
+ ```
39
+
40
+ You would be able to use it like this in your erb files...
41
+
42
+ ```erb
43
+ <button class="<%= styles.btn %>">My button</button>
44
+ ```
45
+
46
+ or in haml...
47
+
48
+ ```haml
49
+ %button{class: styles.btn} My button
50
+ ```
51
+
52
+ To output...
53
+
54
+ ```html
55
+ <button class="white bg_blue">My button</button>
56
+ ```
57
+
58
+ ### Compose styles
59
+
60
+ You can define many of this styles and compose them...
61
+
62
+ ```ruby
63
+ styles = Styler.new do
64
+ style :btn, ["padding3", "margin3"]
65
+ style :blue_btn, [btn, "white", "bg_blue"]
66
+ end
67
+ ```
68
+
69
+ ```haml
70
+ %button{class: styles.btn} My button
71
+ %button{class: styles.blue_btn} My button
72
+ ```
73
+
74
+ And the output would be...
75
+
76
+ ```html
77
+ <button class="padding3 margin3">My button</button>
78
+ <button class="padding3 margin3 white bg_blue">My button</button>
79
+ ```
80
+
81
+ ### Substract styles
82
+
83
+ By composing your styles you can also substract classes from previous styles, like this...
84
+
85
+ ```ruby
86
+ styles = Styler.new do
87
+ style :default, ["pa3", "white", "bg_blue"]
88
+ style :danger, [default - "bg_blue", "bg_red"]
89
+ end
90
+
91
+ styles.default.to_s # => "pa3 white bg_blue"
92
+ styles.danger.to_s # => "pa3 white bg_red"
93
+ ```
94
+
95
+ ### Passing arguments to styles
96
+
97
+ You can also define styles that expect an argument, to help you decide which styles to display, like this...
98
+
99
+ ```ruby
100
+ styles = Styler.new do
101
+ style :default_color do |project|
102
+ if project[:color] == "blue"
103
+ ["bg_blue"]
104
+ else
105
+ ["bg_red"]
106
+ end
107
+ end
108
+ end
109
+
110
+ project = { color: "blue" }
111
+ styles.default_color(project).to_s # => "bg_blue"
112
+ ```
113
+
114
+ And you can use this styles to build other styles, like this...
115
+
116
+ ```ruby
117
+ project = { color: "blue" }
118
+
119
+ styles = Styler.new do
120
+ style :default_color do |project|
121
+ if project[:color] == "blue"
122
+ ["bg_blue"]
123
+ else
124
+ ["bg_red"]
125
+ end
126
+ end
127
+
128
+ style :title, [default_color(project), "pa3"]
129
+ end
130
+
131
+ styles.title(project).to_s # => "bg_blue pa3"
132
+ ```
133
+
134
+ Or like this...
135
+
136
+ ```ruby
137
+ styles = Styler.new do
138
+ style :default_color do |project|
139
+ if project[:color] == "blue"
140
+ ["bg_blue"]
141
+ else
142
+ ["bg_red"]
143
+ end
144
+ end
145
+
146
+ style :title do |project|
147
+ [default_color(project), "pa3"]
148
+ end
149
+ end
150
+
151
+ project = { color: "blue" }
152
+ styles.title(project).to_s # => "bg_blue pa3"
153
+ ```
154
+
155
+ ### Define collections
156
+
157
+ You can define collections as "namespaces" for your styles...
158
+
159
+ ```ruby
160
+ styles = Styler.new do
161
+ collection :buttons do
162
+ style :default, ["pa3", "blue"]
163
+ style :danger, [default - "blue", "red"]
164
+ end
165
+ end
166
+
167
+ styles.respond_to?(:default) # => false
168
+ styles.respond_to?(:danger) # => false
169
+ styles.buttons.default.to_s # => "pa3 blue"
170
+ styles.buttons.danger.to_s # => "pa3 red"
171
+ ```
172
+
173
+ ### Nested collections
174
+
175
+ You can define nested collections to build complete themes...
176
+
177
+ ```ruby
178
+ styles = Styler.new do
179
+ collection :v1 do
180
+ collection :buttons do
181
+ style :default, ["pa3", "blue"]
182
+ end
183
+ end
184
+
185
+ collection :v2 do
186
+ collection :buttons do
187
+ style :default, ["pa3", "red"]
188
+ end
189
+ end
190
+ end
191
+
192
+ styles.v1.buttons.default.to_s # => "pa3 blue"
193
+ styles.v2.buttons.default.to_s # => "pa3 red"
194
+ ```
195
+
196
+ ### Define collection with arguments
197
+
198
+ Like with the styles, you can define collections that require arguments, like this..
199
+
200
+ ```ruby
201
+ styles = Styler.new do
202
+ collection :buttons do |project|
203
+ if project[:color] == "blue"
204
+ style :default, ["pa3", "blue"]
205
+ else
206
+ style :default, ["pa3", "red"]
207
+ end
208
+ end
209
+ end
210
+
211
+ project = { color: "blue" }
212
+ styles.buttons(project).default.to_s # => "pa3 blue"
213
+ ```
214
+
215
+ ### Select a collection with an alias
216
+
217
+ ```ruby
218
+ styles = Styler.new do
219
+ collection :v1 do
220
+ collection :buttons do
221
+ style :default, ["pa3", "blue"]
222
+ end
223
+ end
224
+
225
+ collection :v2 do
226
+ collection :buttons do
227
+ style :default, ["pa3", "red"]
228
+ end
229
+ end
230
+
231
+ collection_alias :theme, v1
232
+ end
233
+
234
+ styles.theme.buttons.default.to_s # => "pa3 blue"
235
+ ```
236
+
237
+ ### Collection alias with a block
238
+
239
+ ```ruby
240
+ styles = Styler.new do
241
+ collection :v1 do
242
+ collection :buttons do
243
+ style :default, ["pa3", "blue"]
244
+ end
245
+ end
246
+
247
+ collection :v2 do
248
+ collection :buttons do
249
+ style :default, ["pa3", "red"]
250
+ end
251
+ end
252
+
253
+ collection_alias :theme do |current_version|
254
+ if current_version == "v1"
255
+ v1
256
+ else
257
+ v2
258
+ end
259
+ end
260
+ end
261
+
262
+ styles.theme("v1").buttons.default.to_s # => "pa3 blue"
263
+ styles.theme("v2").buttons.default.to_s # => "pa3 red"
264
+ ```
265
+
266
+ ### Select a collection from other styler
267
+
268
+ ```ruby
269
+ v1 = Styler.new do
270
+ collection :buttons do
271
+ style :default, ["pa3", "blue"]
272
+ end
273
+ end
274
+
275
+ v2 = Styler.new do
276
+ collection :buttons do
277
+ style :default, ["pa3", "red"]
278
+ end
279
+ end
280
+
281
+ styles = Styler.new do
282
+ collection_alias :theme do |current_version|
283
+ if current_version == "v1"
284
+ v1
285
+ else
286
+ v2
287
+ end
288
+ end
289
+ end
290
+
291
+ styler.theme("v1").buttons.default.to_s # => "pa3 blue"
292
+ styler.theme("v2").buttons.default.to_s # => "pa3 red"
293
+ ```
294
+
295
+ ### Copy styles from collection
296
+
297
+ If you need to use the styles from other collection, but you need to override
298
+ some of them, you can copy the styles and then override what you want.
299
+
300
+ ```ruby
301
+ styles = Styler.new do
302
+ collection :v1 do
303
+ collection :buttons do
304
+ style :default, ["pa3", "blue"]
305
+ style :danger, [default - "blue", "red"]
306
+ end
307
+ end
308
+
309
+ collection :v2 do
310
+ collection :buttons do
311
+ copy_styles_from collection: v1.buttons
312
+ style :danger, [v1.buttons.danger - "red", "orange"]
313
+ end
314
+ end
315
+ end
316
+
317
+ expect(styles.v2.buttons.default.to_s).to eq "pa3 blue"
318
+ expect(styles.v2.buttons.danger.to_s).to eq "pa3 orange"
319
+ ```
320
+
321
+ ## Development
322
+
323
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
324
+
325
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
326
+
327
+ ## Contributing
328
+
329
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bhserna/styler.
330
+
331
+ ## License
332
+
333
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,91 @@
1
+ class Styler::Collection < SimpleDelegator
2
+ attr_reader :parent, :name, :style_names, :collection_names
3
+
4
+ def initialize(parent = nil, name = :default)
5
+ super(parent) if parent
6
+ @parent = parent
7
+ @name = name
8
+ @style_names = []
9
+ @collection_names = []
10
+ end
11
+
12
+ def ==(other)
13
+ self.class == other.class && name == other.name
14
+ end
15
+
16
+ def style(name, styles = nil, &block)
17
+ @style_names << name
18
+
19
+ if styles
20
+ define_singleton_method(name) do |*args|
21
+ Styler::Style.new(self, name, styles)
22
+ end
23
+ else
24
+ define_singleton_method(name) do |*args|
25
+ styles = instance_exec(*args, &block)
26
+ Styler::Style.new(self, name, styles)
27
+ end
28
+ end
29
+ end
30
+
31
+ def collection(name, &block)
32
+ @collection_names << name
33
+
34
+ define_singleton_method(name) do |*args|
35
+ self.class.new(self, name).tap do |c|
36
+ c.instance_exec(*args, &block)
37
+ end
38
+ end
39
+ end
40
+
41
+ def collection_alias(name, collection = nil, &block)
42
+ @collection_names << name
43
+
44
+ define_singleton_method(name) do |*args|
45
+ if collection
46
+ collection
47
+ else
48
+ instance_exec(*args, &block)
49
+ end
50
+ end
51
+ end
52
+
53
+ def copy_styles_from(collection:)
54
+ collection.styles.each do |style|
55
+ style(style.name, style.to_a)
56
+ end
57
+ end
58
+
59
+ def path
60
+ return "root" if parent.nil?
61
+ "#{parent.path}.#{name}"
62
+ end
63
+
64
+ def repeted_styles
65
+ nested_styles
66
+ .group_by(&:to_a)
67
+ .select { |_, styles| styles.count > 1 }
68
+ .to_h
69
+ .values
70
+ end
71
+
72
+ def styles
73
+ style_names.map { |name| send(name) }
74
+ end
75
+
76
+ def collections
77
+ collection_names.map { |name| send(name) }
78
+ end
79
+
80
+ def nested_styles
81
+ styles + nested_collections.flat_map(&:styles)
82
+ end
83
+
84
+ def nested_collections
85
+ if collections.empty?
86
+ []
87
+ else
88
+ collections + collections.flat_map(&:nested_collections)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,27 @@
1
+ class Styler::Style
2
+ attr_reader :collection, :name, :styles
3
+
4
+ def initialize(collection, name, styles = [])
5
+ @collection = collection
6
+ @name = name
7
+ @styles = styles
8
+ end
9
+
10
+ def ==(other)
11
+ self.class == other.class &&
12
+ name == other.name &&
13
+ to_a == other.to_a
14
+ end
15
+
16
+ def -(other)
17
+ Styler::StyleSubstraction.new(self, other)
18
+ end
19
+
20
+ def to_a
21
+ styles.map(&:to_s)
22
+ end
23
+
24
+ def to_s
25
+ to_a.join(" ")
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ class Styler::StyleSubstraction
2
+ attr_reader :a, :b
3
+
4
+ def initialize(a, b)
5
+ @a, @b = a, b
6
+ end
7
+
8
+ def -(other)
9
+ self.class.new(self, other)
10
+ end
11
+
12
+ def to_a
13
+ if b.is_a? String
14
+ a.to_a - [b.to_s]
15
+ else
16
+ a.to_a - b.to_a
17
+ end
18
+ end
19
+
20
+ def to_s
21
+ to_a.join(" ")
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Styler
2
+ VERSION = "0.1.0"
3
+ end
data/lib/styler.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "delegate"
2
+
3
+ require "styler/version"
4
+
5
+ require "styler/collection"
6
+ require "styler/style"
7
+ require "styler/style_substraction"
8
+
9
+ module Styler
10
+ def self.new(&block)
11
+ Collection.new.tap do |c|
12
+ c.instance_eval(&block)
13
+ end
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_styler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Benito Horacio Serna Sandoval
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description:
28
+ email:
29
+ - bhserna@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/styler.rb
36
+ - lib/styler/collection.rb
37
+ - lib/styler/style.rb
38
+ - lib/styler/style_substraction.rb
39
+ - lib/styler/version.rb
40
+ homepage: https://github.com/bhserna/styler
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.7.0
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.2.3
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: A tool for styling html by composing css utility classes
63
+ test_files: []