rails_components 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 6f8e93ccb73397896fa9905a032a2134c1c0de2c
4
- data.tar.gz: af568ee8b46b7e64aec5c6c1491d0984239a3ac8
3
+ metadata.gz: 2a9892e6e453a2e8871728debfebfe8fa39bdc7c
4
+ data.tar.gz: 862da46086c74bec8e0f25f36df89d07eb4dfb8c
5
5
  SHA512:
6
- metadata.gz: 4a407dcd0bd60b1a211966988fbf454eb44ec3fa97e4d435c2ca6b43f3331bc624b6cce1dec52ca43d867cbb7e9a6d69f98e3e0be4f23f5bdeb1acbec80595fb
7
- data.tar.gz: a34cbac6e4c88caebcbf49f46defcba19ba7a97ee57a7858d7e5b6ac4c97f9e443b9eed7484f692afbbee2e8d6a3d25ed90c7ba59bedfabb59235ba15d710975
6
+ metadata.gz: 904185c83aa85ffc5557522e408ed079d1e0dbcbfdf9f94ffd0cfc3db9eaf4dd28b3813c7012ce19dd3ffba497fad19d5099cfcbb1ed075d217380746c54b345
7
+ data.tar.gz: 2aeed2b147ba742e5109163bc553d347624b520b21b121b1b32472fcde58b4e60f868ab412d7cbbb75b5d4b5cc30a801aa9b77047a4dcb904ded275469cd5011
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Rails Components
2
2
 
3
3
  write reusable components in your rails views. a thin wrapper around `render`
4
- that makes passing blocks, and html attributes to templates simple as pie.
4
+ that makes passing blocks and html attributes to partials simple as pie.
5
5
 
6
6
  ## Installation
7
7
 
@@ -104,10 +104,34 @@ if you're using haml, it already does this for you, and you can use props direct
104
104
  = yield
105
105
  ```
106
106
 
107
+ by default `html` combines the classes and html attributes, but you can pass
108
+ it a special key: `html_merge_strategy`, with one of these values:
109
+ - `:combine` - (default) values on duplicated keys are combined in an array
110
+ - `:merge` - normal ruby merge, duplicate keys are overriden by props' values
111
+ - `:replace` - only the attributes passed in by props are used
112
+
113
+ ```
114
+ <!-- component -->
115
+ <%= content_tag :div, props.html(class: "box") do %>
116
+ <%= yield %>
117
+ <% end %>
118
+
119
+ <!-- in a view -->
120
+ <%= component 'box', class: "big rectangle", html_merge_strategy: :merge do %>
121
+ <p>not a box!</p>
122
+ <% end %>
123
+ ```
124
+
125
+ ```html
126
+ <!-- output -->
127
+ <div class="big rectangle">
128
+ <p>not a box!</p>
129
+ </div>
130
+ ```
107
131
 
108
132
  ## Bigger Examples
109
133
 
110
- [Bootstrap modal][bsmodal]:
134
+ ### [Bootstrap modal](http://v4-alpha.getbootstrap.com/components/modal/)
111
135
 
112
136
  ```erb
113
137
  <!-- in a view -->
@@ -120,10 +144,8 @@ if you're using haml, it already does this for you, and you can use props direct
120
144
  <% end %>
121
145
  <%= component 'modal/footer' %>
122
146
  <% end %>
123
- ```
124
147
 
125
- ```erb
126
- <!-- components -->
148
+ <!-- the components -->
127
149
 
128
150
  <!-- app/views/components/_modal.html.erb -->
129
151
  <%= content_tag :div, props.html(class: 'modal fade', tabindex: '-1', role: 'dialog') do %>
@@ -197,11 +219,110 @@ if you're using haml, it already does this for you, and you can use props direct
197
219
  ```
198
220
 
199
221
 
200
- [Basscss navigation]
222
+ ### A navbar, based off of the [basscss guide](http://www.basscss.com/v7/docs/guides/ui/#navbars)
223
+
224
+ ```
225
+ <!-- in a view -->
226
+ <%= component 'navbar', class: "white bg-green" do %>
227
+ <div class="left">
228
+ <%= component 'navbar/item', "Burgers", href: "#!" %>
229
+ <%= component 'navbar/item', "An example", href: "#!", class: "btn-narrow" %>
230
+ </div>
231
+ <div class="right">
232
+ <%= component 'navbar/item', "My Account", href: "#!" %>
233
+ </div>
234
+ <div class="overflow-hidden px2 py1">
235
+ <%= component 'input', name: "whatever", class: "right m0 fit bg-darken-1", placeholder: "Search" %>
236
+ </div>
237
+ <% end %>
238
+ ```
239
+
240
+ ```erb
241
+ <!-- app/views/components/_navbar.html.erb -->
242
+ <%= content_tag :div, props.html(class: "clearfix mb2") do %>
243
+ <%= yield %>
244
+ <% end %>
245
+
246
+ <!-- app/views/components/navbar/_item.html.erb -->
247
+ <%= link_to href, props.html(class: "btn m0 py2") do %>
248
+ <%= yield %>
249
+ <% end %>
250
+
251
+ <!-- app/views/components/_input.html.erb -->
252
+ <%= text_field_tag local_assigns[:name], local_assigns[:value], props.html(class: "input border-box").except(:name, :value) %>
253
+ ```
254
+
255
+ ### Tachyons [image with title and subtitle](http://tachyons.io/components/collections/square-title-subtitle/index.html)
256
+
257
+ ```
258
+ <%= component "square", 'Title of piece',
259
+ subtitle: "Subtitle of piece", image_url: "http://mrmrs.io/images/0008.jpg" %>
260
+ ```
261
+
262
+ ```erb
263
+ <!-- component -->
264
+ <article class="fl w-100 w-50-m w-25-ns pa2-ns">
265
+ <div class="aspect-ratio aspect-ratio--1x1">
266
+ <img style="background-image:url(<%= j image_url %>);"
267
+ class="db bg-center cover aspect-ratio--object" />
268
+ </div>
269
+ <%= link_to url, class: "ph2 ph0-ns pb3 link db" do %>
270
+ <h3 class="f5 f4-ns mb0 black-90"><%= yield %></h3>
271
+ <h3 class="f6 f5 fw4 mt2 black-60"><%= subtitle %></h3>
272
+ <% end %>
273
+ </article>
274
+ ```
275
+
276
+ You might find later that you need to reuse and change specific parts of this
277
+ component, or use it with it's contents in a different order.
278
+ You can split it up into many small components as needed, without having to
279
+ change the original way your component is used:
280
+
281
+ ```erb
282
+ <!-- component -->
283
+ <%= component 'square/container' do %>
284
+ <%= component 'square/image_container' do %>
285
+ <%= component 'square/image', props.slice(:image_url) %>
286
+ <% end %>
287
+ <%= component 'square/link', props.slice(:url) do %>
288
+ <%= component 'square/title' do %><%= yield %><% end %>
289
+ <%= component 'square/subtitle', subtitle %>
290
+ <% end %>
291
+ <% end %>
292
+
293
+ <!-- app/views/components/square/_container.html.erb -->
294
+ <%= content_tag :article, props.html(class: "fl w-100 w-50-m w-25-ns pa2-ns") do %>
295
+ <%= yield %>
296
+ <% end %>
297
+
298
+ <!-- app/views/components/square/_image.html.erb -->
299
+ <%= image_tag '', props.html(style: "background-image:url(#{j image_url});",
300
+ class: "db bg-center cover aspect-ratio--object") %>
301
+
302
+ <!-- app/views/components/square/_image_container.html.erb -->
303
+ <%= content_tag :div, props.html(class: "aspect-ratio aspect-ratio--1x1") do %>
304
+ <%= yield %>
305
+ <% end %>
306
+
307
+ <!-- app/views/components/square/_link.html.erb -->
308
+ <%= link_to props[:url], props.html(class: "ph2 ph0-ns pb3 link db").except(:url) do %>
309
+ <%= yield %>
310
+ <% end %>
311
+
312
+ <!-- app/views/components/square/_subtitle.html.erb -->
313
+ <%= content_tag props.fetch(:tag_name, :h3), props.html(class: "f6 f5 fw4 mt2 black-60").except(:tag_name) do %>
314
+ <%= yield %>
315
+ <% end %>
316
+
317
+ <!-- app/views/components/square/_title.html.erb -->
318
+ <%= content_tag props.fetch(:tag_name, :h3), props.html(class: "f5 f4-ns mb0 black-90").except(:tag_name) do %>
319
+ <%= yield %>
320
+ <% end %>
321
+ ```
201
322
 
202
323
  ## How this compares to `render`
203
324
 
204
- `component` is a wrapper around `render` [under the hood](./lib/rails_components.rb):
325
+ `component` [is a wrapper](./lib/rails_components.rb) around `render`
205
326
 
206
327
  ```erb
207
328
  <%= component 'modal', title: "Example" do %>
@@ -209,48 +330,68 @@ if you're using haml, it already does this for you, and you can use props direct
209
330
  <% end %>
210
331
  ```
211
332
 
333
+ is equivalent to:
334
+
212
335
  ```erb
213
336
  <%= render layout: 'component/modal', locals: { title: "Example" } do %>
214
337
  Modal content!
215
338
  <% end %>
216
339
  ```
217
340
 
218
- Where it shines is taking arguments instead of blocks
341
+ where it shines is taking arguments instead of blocks
219
342
 
220
343
  ```erb
221
344
  <%= component 'modal', 'Modal content!', title: "Example" do %>
222
345
  ```
223
346
 
224
- And allowing you to use reserved words, which doesn't work with render
347
+ and allowing you to use reserved words, which doesn't work with render
225
348
 
226
349
  ```erb
227
- <!-- won't work! rails can't make `class` a local variable -->
350
+ <!-- won't work! rails tries to make "class" a local variable -->
228
351
  <%= render layout: 'component/modal', locals: { class: "fancy-modal" } do %>
229
352
  Modal content!
230
353
  <% end %>
231
- ```
232
354
 
233
- ```erb
234
355
  <!-- works! -->
235
356
  <%= component 'modal', 'Modal content!', class: "fancy-modal" do %>
236
357
  ```
237
358
 
238
- ## What's the future of this project, will it be maintained, etc
359
+ ## Motivation
239
360
 
240
- Hard to say. If you're worried about dependencies, copy it into your project
241
- as a helper. I would be surprised if `render` gets any big changes.
361
+ Working on rails apps where the same css class declarations were repeated
362
+ many times over, making changing common components very difficult. This
363
+ abstraction is particularily helpful when using functional/atomic/utility css
364
+ classes.
365
+
366
+ From the [basscss docs](http://www.basscss.com/v7/docs/guides/tips/#handle-complexity-in-markup):
367
+
368
+ > Large projects will inevitably become more complex. Handling and
369
+ > maintaining that complexity in markup templates is much easier than
370
+ > adding complexity to your stylesheet. Before abstracting combinations
371
+ > of styles out in to new styles, make sure to look for patterns and
372
+ > think about reusability, and consider ways in which your templating
373
+ > engine can DRY up your code. If you’re constantly duplicating the
374
+ > same markup to create UI elements like media player controls or
375
+ > modals, make use of things like partials, helpers, or __components__
376
+ > to keep things maintainable.
377
+
378
+ (emphasis added)
242
379
 
243
- This project serves more as documentation and examples of how to write
244
- components in a rails app (as opposed to adhoc files in `app/views/shared`.)
245
380
 
246
381
  ## Configuration
247
382
 
248
383
  TODO
249
384
 
250
- ## Goals
385
+ ## What's the future of this project, will it be maintained, etc
386
+
387
+ Hard to say. If you're worried about dependencies, copy it into your project
388
+ as a helper. render's api is probably not getting any big changes, so hopefully
389
+ it creates a minimal amount of headaches.
390
+
391
+ This project's goal is to act as documentation and examples of how to write
392
+ components in a rails app. adhoc files in `app/views/shared` doesn't make
393
+ anyone happy.
251
394
 
252
- - make it as easy to write reusable components
253
- - feel familiar to existing rails helpers, like `link_to` or `content_tag`
254
395
 
255
396
  ## TODO
256
397
 
@@ -259,5 +400,3 @@ TODO
259
400
  - figure out how to make vim-rails jump to files (gf) properly
260
401
  - point out that mixing erb and haml has issues
261
402
 
262
- [bsmodal]: http://v4-alpha.getbootstrap.com/components/modal/
263
- [bspanel]: http://v4-alpha.getbootstrap.com/components/card/
@@ -5,7 +5,7 @@ module RailsComponents
5
5
  COMPONENT_RESERVED_WORDS = %i(class return super).freeze
6
6
 
7
7
  def component(component_template, text_or_locals_with_block = nil, locals = nil, &block)
8
- unless RailsComponents.configuration.template_directory.nil?
8
+ if RailsComponents.configuration.template_directory
9
9
  component_template = [RailsComponents.configuration.template_directory, component_template].join('/')
10
10
  end
11
11
 
@@ -2,7 +2,18 @@
2
2
  module RailsComponents
3
3
  module HtmlHelpers
4
4
  def html(html_attributes_to_merge = {})
5
- merge(html_attributes_to_merge) { |key, v1, v2| [v1, v2].flatten(1) }
5
+ strategy = delete(:html_merge_strategy) || :combine
6
+
7
+ case strategy.to_sym
8
+ when :combine
9
+ merge(html_attributes_to_merge) { |key, v1, v2| [v1, v2].flatten(1) }
10
+ when :merge
11
+ html_attributes_to_merge.merge(self)
12
+ when :replace
13
+ self
14
+ else
15
+ raise "unknown html_merge_stragey: #{strategy}"
16
+ end
6
17
  end
7
18
  end
8
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Schilling
@@ -45,5 +45,6 @@ rubyforge_project:
45
45
  rubygems_version: 2.6.1
46
46
  signing_key:
47
47
  specification_version: 4
48
- summary: Rails view components
48
+ summary: a thin wrapper around render that makes passing blocks and html attributes
49
+ to partials simple as pie.
49
50
  test_files: []