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 +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: []
|