rails_components 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +161 -22
- data/lib/rails_components.rb +1 -1
- data/lib/rails_components/html_helpers.rb +12 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a9892e6e453a2e8871728debfebfe8fa39bdc7c
|
4
|
+
data.tar.gz: 862da46086c74bec8e0f25f36df89d07eb4dfb8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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]
|
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
|
-
|
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
|
-
[
|
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
|
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
|
-
|
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
|
-
|
347
|
+
and allowing you to use reserved words, which doesn't work with render
|
225
348
|
|
226
349
|
```erb
|
227
|
-
<!-- won't work! rails
|
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
|
-
##
|
359
|
+
## Motivation
|
239
360
|
|
240
|
-
|
241
|
-
|
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
|
-
##
|
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/
|
data/lib/rails_components.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
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:
|
48
|
+
summary: a thin wrapper around render that makes passing blocks and html attributes
|
49
|
+
to partials simple as pie.
|
49
50
|
test_files: []
|