mtl 1.0.1

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.
Files changed (158) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +104 -0
  6. data/Rakefile +6 -0
  7. data/app/assets/javascripts/mtl/clickables.coffee +25 -0
  8. data/app/assets/javascripts/mtl/collapsible.coffee +43 -0
  9. data/app/assets/javascripts/mtl/configuration.coffee.erb +1 -0
  10. data/app/assets/javascripts/mtl/document_modal.coffee +130 -0
  11. data/app/assets/javascripts/mtl/dropdown.coffee +24 -0
  12. data/app/assets/javascripts/mtl/hooks.coffee +14 -0
  13. data/app/assets/javascripts/mtl/icon.coffee.erb +17 -0
  14. data/app/assets/javascripts/mtl/modal.coffee +32 -0
  15. data/app/assets/javascripts/mtl/select.coffee +44 -0
  16. data/app/assets/javascripts/mtl/templates.coffee +4 -0
  17. data/app/assets/javascripts/mtl/toc.coffee +31 -0
  18. data/app/assets/javascripts/mtl.js +42 -0
  19. data/app/assets/stylesheets/mtl/all.scss +69 -0
  20. data/app/assets/stylesheets/mtl/extend/_avatars.scss +37 -0
  21. data/app/assets/stylesheets/mtl/extend/_buttons.scss +31 -0
  22. data/app/assets/stylesheets/mtl/extend/_cards.scss +21 -0
  23. data/app/assets/stylesheets/mtl/extend/_chips.scss +3 -0
  24. data/app/assets/stylesheets/mtl/extend/_collection-files.scss +108 -0
  25. data/app/assets/stylesheets/mtl/extend/_document-modals.scss +95 -0
  26. data/app/assets/stylesheets/mtl/extend/_dropdown.scss +12 -0
  27. data/app/assets/stylesheets/mtl/extend/_forms.scss +66 -0
  28. data/app/assets/stylesheets/mtl/extend/_global.scss +77 -0
  29. data/app/assets/stylesheets/mtl/extend/_grid.scss +25 -0
  30. data/app/assets/stylesheets/mtl/extend/_material-icons.scss +37 -0
  31. data/app/assets/stylesheets/mtl/extend/_mixins.scss +10 -0
  32. data/app/assets/stylesheets/mtl/extend/_roboto-rails.scss +49 -0
  33. data/app/assets/stylesheets/mtl/extend/_side-nav.scss +22 -0
  34. data/app/assets/stylesheets/mtl/extend/_toc.scss +12 -0
  35. data/app/assets/stylesheets/mtl/extend/_typography.scss +32 -0
  36. data/app/assets/stylesheets/mtl/extend/forms/_input-fields.scss +50 -0
  37. data/app/assets/stylesheets/mtl/layouts/_default.scss +220 -0
  38. data/app/assets/stylesheets/mtl/layouts/_single.scss +25 -0
  39. data/app/views/mtl/header.html.erb +25 -0
  40. data/bin/coffeelint.rb +16 -0
  41. data/lib/generators/mtl/install_generator.rb +20 -0
  42. data/lib/generators/mtl/templates/_color.scss +410 -0
  43. data/lib/generators/mtl/templates/_variables.scss +330 -0
  44. data/lib/generators/mtl/templates/mtl.scss +8 -0
  45. data/lib/generators/mtl/templates/simple_form.rb +211 -0
  46. data/lib/mtl/rails/card_file_presenter.rb +70 -0
  47. data/lib/mtl/rails/view_helpers.rb +412 -0
  48. data/lib/mtl/simple_form/suffix.rb +52 -0
  49. data/lib/mtl/version.rb +6 -0
  50. data/lib/mtl.rb +38 -0
  51. data/mtl.gemspec +35 -0
  52. data/package.json +11 -0
  53. data/spec/mtl/rails/card_file_presenter_spec.rb +126 -0
  54. data/spec/mtl/rails/view_helpers_spec.rb +193 -0
  55. data/spec/mtl/simple_form/suffix_spec.rb +39 -0
  56. data/spec/mtl_spec.rb +34 -0
  57. data/spec/spec_helper.rb +18 -0
  58. data/spec/support/dom.rb +15 -0
  59. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.eot +0 -0
  60. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ijmap +1 -0
  61. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.svg +2373 -0
  62. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ttf +0 -0
  63. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff +0 -0
  64. data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff2 +0 -0
  65. data/vendor/assets/fonts/roboto/Roboto-Bold.eot +0 -0
  66. data/vendor/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  67. data/vendor/assets/fonts/roboto/Roboto-Bold.woff +0 -0
  68. data/vendor/assets/fonts/roboto/Roboto-Bold.woff2 +0 -0
  69. data/vendor/assets/fonts/roboto/Roboto-Light.eot +0 -0
  70. data/vendor/assets/fonts/roboto/Roboto-Light.ttf +0 -0
  71. data/vendor/assets/fonts/roboto/Roboto-Light.woff +0 -0
  72. data/vendor/assets/fonts/roboto/Roboto-Light.woff2 +0 -0
  73. data/vendor/assets/fonts/roboto/Roboto-Medium.eot +0 -0
  74. data/vendor/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
  75. data/vendor/assets/fonts/roboto/Roboto-Medium.woff +0 -0
  76. data/vendor/assets/fonts/roboto/Roboto-Medium.woff2 +0 -0
  77. data/vendor/assets/fonts/roboto/Roboto-Regular.eot +0 -0
  78. data/vendor/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
  79. data/vendor/assets/fonts/roboto/Roboto-Regular.woff +0 -0
  80. data/vendor/assets/fonts/roboto/Roboto-Regular.woff2 +0 -0
  81. data/vendor/assets/fonts/roboto/Roboto-Thin.eot +0 -0
  82. data/vendor/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
  83. data/vendor/assets/fonts/roboto/Roboto-Thin.woff +0 -0
  84. data/vendor/assets/fonts/roboto/Roboto-Thin.woff2 +0 -0
  85. data/vendor/assets/javascripts/lodash.js +16607 -0
  86. data/vendor/assets/javascripts/materialize/animation.js +9 -0
  87. data/vendor/assets/javascripts/materialize/buttons.js +91 -0
  88. data/vendor/assets/javascripts/materialize/cards.js +26 -0
  89. data/vendor/assets/javascripts/materialize/carousel.js +454 -0
  90. data/vendor/assets/javascripts/materialize/character_counter.js +72 -0
  91. data/vendor/assets/javascripts/materialize/chips.js +267 -0
  92. data/vendor/assets/javascripts/materialize/collapsible.js +160 -0
  93. data/vendor/assets/javascripts/materialize/date_picker/picker.date.js +1430 -0
  94. data/vendor/assets/javascripts/materialize/date_picker/picker.js +1123 -0
  95. data/vendor/assets/javascripts/materialize/dropdown.js +265 -0
  96. data/vendor/assets/javascripts/materialize/forms.js +681 -0
  97. data/vendor/assets/javascripts/materialize/global.js +45 -0
  98. data/vendor/assets/javascripts/materialize/hammer.min.js +1 -0
  99. data/vendor/assets/javascripts/materialize/init.js +173 -0
  100. data/vendor/assets/javascripts/materialize/initial.js +11 -0
  101. data/vendor/assets/javascripts/materialize/jquery.easing.1.3.js +205 -0
  102. data/vendor/assets/javascripts/materialize/jquery.hammer.js +33 -0
  103. data/vendor/assets/javascripts/materialize/jquery.timeago.min.js +1 -0
  104. data/vendor/assets/javascripts/materialize/leanModal.js +192 -0
  105. data/vendor/assets/javascripts/materialize/materialbox.js +269 -0
  106. data/vendor/assets/javascripts/materialize/parallax.js +58 -0
  107. data/vendor/assets/javascripts/materialize/prism.js +8 -0
  108. data/vendor/assets/javascripts/materialize/pushpin.js +71 -0
  109. data/vendor/assets/javascripts/materialize/scrollFire.js +48 -0
  110. data/vendor/assets/javascripts/materialize/scrollspy.js +283 -0
  111. data/vendor/assets/javascripts/materialize/sideNav.js +352 -0
  112. data/vendor/assets/javascripts/materialize/slider.js +321 -0
  113. data/vendor/assets/javascripts/materialize/tabs.js +148 -0
  114. data/vendor/assets/javascripts/materialize/toasts.js +136 -0
  115. data/vendor/assets/javascripts/materialize/tooltip.js +230 -0
  116. data/vendor/assets/javascripts/materialize/transitions.js +169 -0
  117. data/vendor/assets/javascripts/materialize/velocity.min.js +5 -0
  118. data/vendor/assets/javascripts/materialize/waves.js +338 -0
  119. data/vendor/assets/javascripts/pdfobject.js +254 -0
  120. data/vendor/assets/stylesheets/materialize/_buttons.scss +211 -0
  121. data/vendor/assets/stylesheets/materialize/_cards.scss +185 -0
  122. data/vendor/assets/stylesheets/materialize/_carousel.scss +85 -0
  123. data/vendor/assets/stylesheets/materialize/_chips.scss +74 -0
  124. data/vendor/assets/stylesheets/materialize/_collapsible.scss +90 -0
  125. data/vendor/assets/stylesheets/materialize/_color.scss +412 -0
  126. data/vendor/assets/stylesheets/materialize/_dropdown.scss +57 -0
  127. data/vendor/assets/stylesheets/materialize/_global.scss +781 -0
  128. data/vendor/assets/stylesheets/materialize/_grid.scss +147 -0
  129. data/vendor/assets/stylesheets/materialize/_icons-material-design.scss +5 -0
  130. data/vendor/assets/stylesheets/materialize/_materialbox.scss +42 -0
  131. data/vendor/assets/stylesheets/materialize/_mixins.scss +5 -0
  132. data/vendor/assets/stylesheets/materialize/_modal.scss +90 -0
  133. data/vendor/assets/stylesheets/materialize/_navbar.scss +182 -0
  134. data/vendor/assets/stylesheets/materialize/_normalize.scss +424 -0
  135. data/vendor/assets/stylesheets/materialize/_prefixer.scss +384 -0
  136. data/vendor/assets/stylesheets/materialize/_preloader.scss +334 -0
  137. data/vendor/assets/stylesheets/materialize/_roboto.scss +49 -0
  138. data/vendor/assets/stylesheets/materialize/_sideNav.scss +219 -0
  139. data/vendor/assets/stylesheets/materialize/_slider.scss +92 -0
  140. data/vendor/assets/stylesheets/materialize/_table_of_contents.scss +33 -0
  141. data/vendor/assets/stylesheets/materialize/_tabs.scss +56 -0
  142. data/vendor/assets/stylesheets/materialize/_toast.scss +65 -0
  143. data/vendor/assets/stylesheets/materialize/_tooltip.scss +32 -0
  144. data/vendor/assets/stylesheets/materialize/_typography.scss +61 -0
  145. data/vendor/assets/stylesheets/materialize/_variables.scss +313 -0
  146. data/vendor/assets/stylesheets/materialize/_waves.scss +177 -0
  147. data/vendor/assets/stylesheets/materialize/date_picker/_default.date.scss +435 -0
  148. data/vendor/assets/stylesheets/materialize/date_picker/_default.scss +201 -0
  149. data/vendor/assets/stylesheets/materialize/date_picker/_default.time.scss +125 -0
  150. data/vendor/assets/stylesheets/materialize/forms/_checkboxes.scss +220 -0
  151. data/vendor/assets/stylesheets/materialize/forms/_file-input.scss +38 -0
  152. data/vendor/assets/stylesheets/materialize/forms/_forms.scss +22 -0
  153. data/vendor/assets/stylesheets/materialize/forms/_input-fields.scss +273 -0
  154. data/vendor/assets/stylesheets/materialize/forms/_radio-buttons.scss +119 -0
  155. data/vendor/assets/stylesheets/materialize/forms/_range.scss +159 -0
  156. data/vendor/assets/stylesheets/materialize/forms/_select.scss +116 -0
  157. data/vendor/assets/stylesheets/materialize/forms/_switches.scss +78 -0
  158. metadata +309 -0
@@ -0,0 +1,412 @@
1
+ require 'uri'
2
+ require 'mtl/rails/card_file_presenter'
3
+
4
+ module Mtl
5
+ module Rails
6
+ # Assortment of Rails view helpers to simplify rendering materialize css
7
+ # specific components like:
8
+ #
9
+ # - [Icons](#label-Icons),
10
+ # - [Avatars](#label-Avatars),
11
+ # - [Nav Toolbars / Headers](#label-Navbars+-2F+Headers)
12
+ # - or [Buttons](#label-Buttons)
13
+ #
14
+ # ## Buttons
15
+ #
16
+ # Helper methods to create flat, raised and floating material UI buttons.
17
+ #
18
+ # ## Flat buttons
19
+ #
20
+ # A simple flat button:
21
+ #
22
+ # ```erb
23
+ # <%= mtl_button_flat 'Cancel', users_path %>
24
+ # ```
25
+ #
26
+ # A colored flat button:
27
+ #
28
+ # ```erb
29
+ # <%= mtl_button_flat 'Delete', user_path(@user), class: 'red-text', method: :delete %>
30
+ # ```
31
+ #
32
+ # ## Raised button
33
+ #
34
+ # A default raised action button:
35
+ #
36
+ # ```erb
37
+ # <%= mtl_button "Next", next_user_path %>
38
+ # ```
39
+ #
40
+ # A raised button with a sprinkle of colour:
41
+ #
42
+ # ```erb
43
+ # <%= mtl_button "Ok", ok_path, class: 'green darken-2'
44
+ # ```
45
+ #
46
+ # ## Floating button
47
+ #
48
+ # A round red, large floating button:
49
+ #
50
+ # ```erb
51
+ # <%= mtl_button_floating :add, new_user_path, class: 'btn-large red'
52
+ # ```
53
+ #
54
+ # #### Reference
55
+ #
56
+ # - [Materialize CSS: Buttons](http://materializecss.com/buttons.html)
57
+ # - [Google: Buttons](https://material.google.com/components/buttons.html)
58
+ # - [Google: Floating Action Buttons](https://material.google.com/components/buttons-floating-action-button.html)
59
+ #
60
+ # # Navbars / Headers
61
+ #
62
+ # Provides a helper to render a nice navbar, that is supposed to work on both
63
+ # mobile as well as desktops. It is meant to be used with the mtl-default-layout
64
+ # as defined by Marco.
65
+ #
66
+ # Include the following in every template that requires a navbar:
67
+ #
68
+ # ```
69
+ # <%= mtl_header t('my.title') %>
70
+ # ```
71
+ #
72
+ # To render with a custom additional header content, this is then simply
73
+ # appended after the title in the layout.
74
+ #
75
+ # ```erb
76
+ # <%= mtl_header 'Dashboard' do %>
77
+ # <ul class="right">
78
+ # <li>Current User: Hans</li>
79
+ # <li><%= link_to 'Logout', logout_path %></li>
80
+ # </ul>
81
+ # <%- end %>
82
+ # ```
83
+ #
84
+ # This renders the appropriate HTML snippet, see #materialize_header for
85
+ # more options.
86
+ #
87
+ # #### Reference
88
+ #
89
+ # - [Materialize CSS: Navbar](http://materializecss.com/navbar.html)
90
+ #
91
+ # ## Avatars
92
+ #
93
+ # A simple avatar link, without a picture
94
+ #
95
+ # ```erb
96
+ # <%= mtl_avatar_link '/profile', 'John Doe' %>
97
+ # ```
98
+ #
99
+ # Render a large avatar link, with a custom user picture:
100
+ #
101
+ # ```erb
102
+ # <%= mtl_avatar_link '/profile', 'John Doe', '/john_doe.png', size: :large %>
103
+ # ```
104
+ #
105
+ # An avatar link, with a custom user picture and some html options
106
+ #
107
+ # ```erb
108
+ # <%= mtl_avatar_link '/profile', 'John Doe', '/john_doe.png', class: :red %>
109
+ # ```
110
+ #
111
+ # ### Unlinked avatars
112
+ #
113
+ # A simple avatar, without a picture
114
+ #
115
+ # ```erb
116
+ # <%= mtl_avatar 'John Doe' %>
117
+ # ```
118
+ #
119
+ # An avatar, with a picture
120
+ #
121
+ # ```erb
122
+ # <%= mtl_avatar 'John Doe', '/john_doe.png' %>
123
+ # ```
124
+ #
125
+ # An avatar, with a picture and some html options
126
+ #
127
+ # ```erb
128
+ # <%= mtl_avatar 'John Doe', '/john_doe.png', class: :red %>
129
+ # ```
130
+ #
131
+ # ### Avatar initials
132
+ #
133
+ # This helper generates the initials for the avatar, based on the person name. It supports
134
+ # combined names or emails, and will return either a single initial, either a 2 letter.
135
+ #
136
+ # **Examples:**
137
+ #
138
+ # - John Doe -> JD
139
+ # - John Von Doe -> JD
140
+ # - John Albert Von Doe -> JD
141
+ # - john@doe.com -> J
142
+ # - john.doe@doe.com -> JD
143
+ # - john-albert.von-doe@doe.com -> JD
144
+ #
145
+ # ```erb
146
+ # <%= mtl_avatar_initials 'John Doe' %>
147
+ # ```
148
+ #
149
+ # # Icons
150
+ #
151
+ # Renders using using Google Material Icon font:
152
+ #
153
+ # ```erb
154
+ # <%= mtl_icon :cloud # renders a "cloud" icon %>
155
+ # <%= mtl_icon :cloud, size: :large # renders a large cloud icon %>
156
+ #
157
+ # <%= mtl_icon :alert, class: 'right red' # add custom classes %>
158
+ # ```
159
+ #
160
+ # #### Reference
161
+ #
162
+ # - [List of available icons](https://design.google.com/icons/)
163
+ # - [Materialize CSS: Icons](http://materializecss.com/icons.html)
164
+ #
165
+ #
166
+ # # Card file for files collection
167
+ #
168
+ # Basic usage:
169
+ # ```erb
170
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg' %>
171
+ # ```
172
+ # ```html
173
+ # <a class="card-panel" href="/path/to/file.jpg" target="_blank" title="Document Dolorem.jpg">
174
+ # Document Dolorem.jpg
175
+ # <span class="grey-text">
176
+ # <i class="material-icons red-text">image</i>
177
+ # JPG
178
+ # </span>
179
+ # </a>
180
+ # ```
181
+ #
182
+ # With title option:
183
+ # ```erb
184
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg',
185
+ # title: 'foo' %>
186
+ # ```
187
+ # ```html
188
+ # <a class="card-panel" href="/path/to/file.jpg" target="_blank" title="foo">
189
+ # <strong>foo</strong>
190
+ # Document Dolorem.jpg
191
+ # <span class="grey-text">
192
+ # <i class="material-icons red-text">image</i>
193
+ # JPG
194
+ # </span>
195
+ # </a>
196
+ # ```
197
+ #
198
+ # With type option:
199
+ # ```erb
200
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg',
201
+ # type: 'bar' %>
202
+ # ```
203
+ # ```html
204
+ # <a class="card-panel" href="/path/to/file.jpg" target="_blank" title="Document Dolorem.jpg">
205
+ # Document Dolorem.jpg
206
+ # <span class="grey-text">
207
+ # <i class="material-icons blue-text">insert_drive_file</i>
208
+ # BAR
209
+ # </span>
210
+ # </a>
211
+ # ```
212
+ #
213
+ # With preview option:
214
+ # ```erb
215
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg',
216
+ # preview: '/path/to/preview.jpg' %>
217
+ # ```
218
+ # ```html
219
+ # <a class="card-panel card-panel-image" href="/path/to/file.jpg" target="_blank"
220
+ # title="Document Dolorem.jpg" style="background-image: url(/path/to/preview.jpg)">
221
+ # Document Dolorem.jpg
222
+ # <span class="grey-text">
223
+ # <i class="material-icons red-text">image</i>
224
+ # JPG
225
+ # </span>
226
+ # </a>
227
+ # ```
228
+ #
229
+ # With delete option:
230
+ # ```erb
231
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg',
232
+ # delete: '/path/to/delete/the/file' %>
233
+ # ```
234
+ # ```html
235
+ # <a class="card-panel" href="/path/to/file.jpg" target="_blank" title="Document Dolorem.jpg">
236
+ # Document Dolorem.jpg
237
+ # <span class="grey-text">
238
+ # <i class="material-icons red-text">image</i>
239
+ # JPG
240
+ # </span>
241
+ # <i class="close material-icons" data-mtl-href="/path/to/delete/the/file"
242
+ # data-method="delete">close</i>
243
+ # </a>
244
+ # ```
245
+ #
246
+ # With confirm option:
247
+ # ```erb
248
+ # <%= mtl_card_file 'Document Dolorem.jpg', '/path/to/file.jpg',
249
+ # delete: '/path/to/delete/the/file',
250
+ # confirm: 'Sure?' %>
251
+ # ```
252
+ # ```html
253
+ # <a class="card-panel" href="/path/to/file.jpg" target="_blank" title="Document Dolorem.jpg">
254
+ # Document Dolorem.jpg
255
+ # <span class="grey-text">
256
+ # <i class="material-icons red-text">image</i>
257
+ # JPG
258
+ # </span>
259
+ # <i class="close material-icons" data-mtl-href="/path/to/delete/the/file"
260
+ # data-method="delete" data-confirm="Sure?">close</i>
261
+ # </a>
262
+ # ```
263
+ module ViewHelpers
264
+ # Renders a flat button which does not visually lift like the raised buttons.
265
+ #
266
+ # @param label [String]
267
+ # @param url [String]
268
+ # @param options [Hash] Additional options that can be passed to `link_to`
269
+ # @return [String] HTML safe `<a/>` tag
270
+ def mtl_button_flat(label, url, options = {})
271
+ options[:class] = ['btn-flat', options[:class]].compact
272
+ mtl_button label, url, options
273
+ end
274
+
275
+ # Renders a round floating button, with an icon as it's label.
276
+ #
277
+ # @param icon [Symbol]
278
+ # @param url [String]
279
+ # @param options [Hash] Additional options passed to `link_to`
280
+ # @return [String] HTML safe `<a/>` tag
281
+ def mtl_button_floating(icon, url, options = {})
282
+ options[:class] = ['btn-floating', options[:class]].compact
283
+ mtl_button mtl_icon(icon), url, options
284
+ end
285
+
286
+ # Renders a flat button with the more_vert icon dots in a wrapper element.
287
+ # This is intended to be used to render these "more buttons" on the right,
288
+ # in cards or the navbar.
289
+ #
290
+ # ```erb
291
+ # <%= mtl_button_more '#dropdown', 'data-mtl-dropdown': true %>
292
+ # ```
293
+ #
294
+ # @param url [String] usually probably references the dropdown to trigger
295
+ # @param options [Hash] Additional options passed to `link_to`
296
+ # @return [String] HTML safe `<a/>` tag
297
+ def mtl_button_more(url, options = {})
298
+ wrapper_class = ['btn-more-wrapper', options.delete(:wrapper_class)].compact
299
+ options[:class] = ['btn-more', options[:class]].compact.flatten
300
+
301
+ btn = mtl_button_flat mtl_icon(:more_vert, size: :tiny), url, options
302
+ content_tag :div, btn, class: wrapper_class
303
+ end
304
+
305
+ # Renders a visually raised button, i.e. the default button style.
306
+ #
307
+ # @param label [String]
308
+ # @param url [String]
309
+ # @param options [Hash] Additional options passed to `link_to`
310
+ # @return [String] HTML safe `<a/>` tag
311
+ def mtl_button(label, url, options = {})
312
+ options[:class] = ['btn', Mtl.effects, options[:class]].compact
313
+ link_to label, url, options
314
+ end
315
+
316
+ # Renders a specialized template for the header.
317
+ #
318
+ # @param title [String] with the header to display, when set to `false`
319
+ # or an empty string, the rendering of the `<h1>` tag is skipped. By default
320
+ # it tries to use a translation via `.title` key
321
+ # @param back [String, Boolean] (URL) with a link to return to the previous view,
322
+ # when this string is present, then the menu is skipped and this link
323
+ # is always present
324
+ # @param menu [String, Boolean] (HTML ID) references the id of the aside menu / default
325
+ # nav menu to show / hide on mobile devices. The default used is `nav-menu`.
326
+ # When set to `false`, this button is skipped.
327
+ # @param class [String, Array] (HTML CLASS) additional, custom css class on header
328
+ # @yield Additional content to be rendered as part of the header
329
+ # @return [String] HTML safe string
330
+ def mtl_header(title = translate('.title', default: 'Menu'), **options, &block)
331
+ mtl_content = block_given? ? capture(&block) : nil
332
+ mtl_class = ['mtl-layout-default-header', options[:class]].compact.flatten.join(' ')
333
+
334
+ render file: 'mtl/header', locals: {
335
+ mtl_content: mtl_content,
336
+ mtl_title: title.presence,
337
+ mtl_back: options.fetch(:back, false),
338
+ mtl_menu: options.fetch(:menu, 'nav-menu'),
339
+ mtl_class: mtl_class
340
+ }
341
+ end
342
+
343
+ # Renders an avatar link, for the given url with the name's initials
344
+ #
345
+ # @param url [String]
346
+ # @param name [String]
347
+ # @param image_url [String] Optional image url for the avatar
348
+ # @option options [:small, :medium, :large] :size
349
+ # @param options [Hash] Additional options that can be passed to `link_to`
350
+ # @return [String] HTML safe `<a/>` tag
351
+ def mtl_avatar_link(url, name, image_url = nil, options = {})
352
+ options[:class] = [
353
+ 'mtl-avatar', Mtl.effects, options.delete(:size), options[:class]
354
+ ].compact
355
+ image = (image_url.present? ? image_tag(image_url, alt: name) : '')
356
+ link_to image + mtl_avatar_initials(name), url, options
357
+ end
358
+
359
+ # Renders an avatar, for the given name, with initials and an optional picture
360
+ #
361
+ # @param name [String]
362
+ # @param image_url [String] Optional image url for the avatar
363
+ # @option options [:small, :medium, :large] :size
364
+ # @param options [Hash] Additional options that can be passed to `link_to`
365
+ # @return [String] HTML safe `<span/>` tag
366
+ def mtl_avatar(name, image_url = nil, options = {})
367
+ options[:class] = ['mtl-avatar', options.delete(:size), options[:class]].compact
368
+ image = (image_url.present? ? image_tag(image_url, alt: name) : '')
369
+ content_tag :span, image + mtl_avatar_initials(name), options
370
+ end
371
+
372
+ # Creates initials based on the given name or email.
373
+ #
374
+ # @param name [String]
375
+ # @return [String]
376
+ # @!visibility private
377
+ def mtl_avatar_initials(name)
378
+ initials = name.to_s.upcase.split('@').first.to_s.split(/[^[:alpha:]]+/).map(&:first)
379
+ return initials.first.to_s if initials.length < 2
380
+ [initials.first, initials.last].join
381
+ end
382
+
383
+ # Renders an `<i class="material-icons">icon</i>` tag to display an icon.
384
+ #
385
+ # @param icon [Symbol] name of the icon to render, note that these are
386
+ # usually underscored, like e.g. `:aspect_ratio`
387
+ # @option options [:tiny, :small, :medium, :large] :size
388
+ # @param options [Hash] additional options passed to `content_tag`
389
+ # @return [String] HTML safe String
390
+ def mtl_icon(icon, options = {})
391
+ options[:class] = [Mtl.icon_class, options.delete(:size), options[:class]].compact
392
+ content_tag :i, icon, options
393
+ end
394
+
395
+ # Renders a card file tag to display the file and its informations, containing
396
+ # icons, file name, link and an optional preview
397
+ #
398
+ # @param filename [String] filename of the file
399
+ # @param href [String] url to pass to the link_to
400
+ # @option options [String] :title Title of the link, defaults to the filename
401
+ # @option options [String] :type To specify a custom file type, which will serve
402
+ # to display the icon. Will default to the file type based on the ext
403
+ # @option options [String] :preview URL to an image to use as the file preview
404
+ # @option options [String] :data-mtl-delete URL to use as the delete action, if any
405
+ # @param options [Hash] additional options passed to `content_tag`
406
+ # @return [String] HTML safe String
407
+ def mtl_card_file(filename, href, params = {})
408
+ CardFilePresenter.new(self).render(filename, href, params)
409
+ end
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,52 @@
1
+ # :nodoc:
2
+ module SimpleForm
3
+ # :nodoc:
4
+ module Components
5
+ # Support for `suffix:` option when using the simple_form gem. When using the
6
+ # provided `simple_form.rb` initializer everything should be properly setup
7
+ # to make use of this input component.
8
+ #
9
+ # ## Usage
10
+ #
11
+ # Render a field with the suffix _CHF_:
12
+ #
13
+ # ```erb
14
+ # <%= f.input :amount, suffix: 'CHF' %>
15
+ # ```
16
+ #
17
+ # Pass in custom HTML options to the suffix div:
18
+ #
19
+ # ```erb
20
+ # <%= f.input :amount, suffix: 'CHF', suffix_html: { class: 'red-text' } %>
21
+ # ```
22
+ #
23
+ module Suffix
24
+ def suffix(_wrapper_options = nil)
25
+ return unless suffix?
26
+
27
+ @suffix_tag ||= begin
28
+ additional_classes << 'has-suffix'
29
+ template.content_tag :div, suffix_label, suffix_html_options
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def suffix?
36
+ suffix_label
37
+ end
38
+
39
+ def suffix_label
40
+ options[:suffix].presence
41
+ end
42
+
43
+ def suffix_html_options
44
+ suffix_html = options.fetch(:suffix_html, {})
45
+ suffix_html[:class] = [suffix_html[:class], 'suffix'].compact
46
+ suffix_html
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ SimpleForm::Inputs::Base.send(:include, SimpleForm::Components::Suffix)
@@ -0,0 +1,6 @@
1
+ module Mtl
2
+ VERSION = '1.0.1'.freeze
3
+ MATERIALIZE_VERSION = '0.97.7'.freeze
4
+ ICONS_VERSION = '2.2.3'.freeze
5
+ LODASH_VERSION = '4.14.1'.freeze
6
+ end
data/lib/mtl.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'rails'
2
+ require 'mtl/version'
3
+
4
+ require 'mtl/rails/view_helpers'
5
+
6
+ # MTL configuration options are as follows:
7
+ module Mtl
8
+ # CSS classes added for effects on buttons
9
+ mattr_accessor :effects
10
+ @@effects = 'waves-effect waves-light'
11
+
12
+ # CSS classes added for icons
13
+ mattr_accessor :icon_class
14
+ @@icon_class = 'material-icons'
15
+
16
+ mattr_accessor :file_icons
17
+ @@file_icons = {
18
+ 'pdf' => [:picture_as_pdf, 'red-text'],
19
+ 'png' => [:image, 'red-text'],
20
+ 'jpg' => [:image, 'red-text'],
21
+ 'gif' => [:image, 'red-text'],
22
+ 'bmp' => [:image, 'red-text'],
23
+ 'other' => [:insert_drive_file, 'blue-text']
24
+ }
25
+
26
+ #:nodoc:
27
+ class Engine < ::Rails::Engine
28
+ initializer 'mtl.assets.precompile' do |app|
29
+ %w{stylesheets javascripts fonts}.each do |sub|
30
+ app.config.assets.paths << root.join('vendor', 'assets', sub).to_s
31
+ end
32
+ end
33
+
34
+ initializer 'mtl.view_helpers' do
35
+ ActionView::Base.send :include, Mtl::Rails::ViewHelpers
36
+ end
37
+ end
38
+ end
data/mtl.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mtl/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'mtl'
8
+ spec.version = Mtl::VERSION
9
+ spec.authors = ['Marco Plüss', 'Lukas Westermann', 'Loris Gavillet']
10
+ spec.email = ['marco@at-point.ch', 'lukas@at-point.ch', 'loris@at-point.ch']
11
+
12
+ spec.summary = 'Rails gem to package materialize-css for reuse between projects.'
13
+ spec.description = 'Reusable components and Rails helpers on top of materialize-css ' \
14
+ 'and material-design-icons.'
15
+ spec.homepage = 'https://github.com/at-point/mtl'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = %w{.gitignore Gemfile Rakefile LICENSE.txt README.md
19
+ mtl.gemspec package.json} +
20
+ Dir['{lib,app,bin,vendor,spec}/**/*.{rb,erb,js,coffee,scss,gif,jpg,svg,eot,ttf,woff,woff2,ijmap}']
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = %w{lib}
24
+
25
+ spec.required_ruby_version = '>= 2.2'
26
+
27
+ spec.add_dependency 'railties', '>= 4.2', '< 6'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.11'
30
+ spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'yard', '~> 0.8'
32
+ spec.add_development_dependency 'rspec', '> 3.0'
33
+ spec.add_development_dependency 'actionview'
34
+ spec.add_development_dependency 'simple_form', '>= 3.3'
35
+ end
data/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "mtl",
3
+ "license": "MIT",
4
+ "private": true,
5
+ "dependencies": {
6
+ "pdfobject": "2.0",
7
+ "lodash": "4.14.1",
8
+ "material-design-icons": "2.2.3",
9
+ "materialize-css": "https://github.com/Dogfalo/materialize.git#171a9ef"
10
+ }
11
+ }
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+ require 'action_view'
3
+ require 'mtl/rails/card_file_presenter'
4
+ require 'mtl/rails/view_helpers'
5
+
6
+ RSpec.describe Mtl::Rails::CardFilePresenter, dom: true do
7
+ let(:view) { ActionView::Base.new }
8
+ subject { described_class.new(view) }
9
+
10
+ before do
11
+ view.send(:extend, Mtl::Rails::ViewHelpers)
12
+ end
13
+
14
+ context '#render' do
15
+ it 'renders a basic file card with filename and href' do
16
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg')).to match_dom <<-HTML
17
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " href="/path/to/file.jpg">
18
+ <span class="truncate">Document Dolorem.jpg</span>
19
+ <span class="secondary">
20
+ <i class="material-icons red-text">image</i>
21
+ JPG
22
+ </span>
23
+ </a>
24
+ HTML
25
+ end
26
+
27
+ it 'renders a file card with filename, href and a custom title' do
28
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', title: 'foo')).to match_dom <<-HTML
29
+ <a title="foo" target="_blank" class="card-panel " href="/path/to/file.jpg">
30
+ <strong class="truncate">foo</strong>
31
+ <span class="truncate">Document Dolorem.jpg</span>
32
+ <span class="secondary">
33
+ <i class="material-icons red-text">image</i>
34
+ JPG
35
+ </span>
36
+ </a>
37
+ HTML
38
+ end
39
+
40
+ it 'renders a file card with filename, href and a custom type' do
41
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', type: 'bar')).to match_dom <<-HTML
42
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " href="/path/to/file.jpg">
43
+ <span class="truncate">Document Dolorem.jpg</span>
44
+ <span class="secondary">
45
+ <i class="material-icons blue-text">insert_drive_file</i>
46
+ BAR
47
+ </span>
48
+ </a>
49
+ HTML
50
+ end
51
+
52
+ it 'renders a file card with filename, href and a custom preview' do
53
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', preview: '/path/to/preview.jpg')).to match_dom <<-HTML
54
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel card-panel-image" style="background-image: url(/path/to/preview.jpg)" href="/path/to/file.jpg">
55
+ <span class="truncate">Document Dolorem.jpg</span>
56
+ <span class="secondary">
57
+ <i class="material-icons red-text">image</i>
58
+ JPG
59
+ </span>
60
+ </a>
61
+ HTML
62
+ end
63
+
64
+ it 'renders a file card with filename, href and a custom custom delete' do
65
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', delete: '/path/to/delete/the/file')).to match_dom <<-HTML
66
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " href="/path/to/file.jpg">
67
+ <span class="truncate">Document Dolorem.jpg</span>
68
+ <span class="secondary">
69
+ <i class="material-icons red-text">image</i>
70
+ JPG
71
+ </span>
72
+ <i class="material-icons close" data-method="delete" data-mtl-href="/path/to/delete/the/file">close</i>
73
+ </a>
74
+ HTML
75
+ end
76
+
77
+ it 'renders a file card with filename, href and a custom custom delete and a confirm' do
78
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', delete: '/path/to/delete/the/file', confirm: 'sure?')).to match_dom <<-HTML
79
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " href="/path/to/file.jpg">
80
+ <span class="truncate">Document Dolorem.jpg</span>
81
+ <span class="secondary">
82
+ <i class="material-icons red-text">image</i>
83
+ JPG
84
+ </span>
85
+ <i class="material-icons close" data-method="delete" data-mtl-href="/path/to/delete/the/file" data-confirm="sure?">close</i>
86
+ </a>
87
+ HTML
88
+ end
89
+
90
+ it 'renders a file card with filename, href and document modal options' do
91
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', modal: true)).to match_dom <<-HTML
92
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " data-mtl-document-modal="open" data-mtl-document-name="Document Dolorem.jpg" href="/path/to/file.jpg">
93
+ <span class="truncate">Document Dolorem.jpg</span>
94
+ <span class="secondary">
95
+ <i class="material-icons red-text">image</i>
96
+ JPG
97
+ </span>
98
+ </a>
99
+ HTML
100
+ end
101
+
102
+ it 'renders a file card with filename, href and custom data attributes' do
103
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', data: { something: '42' })).to match_dom <<-HTML
104
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " data-something="42" href="/path/to/file.jpg">
105
+ <span class="truncate">Document Dolorem.jpg</span>
106
+ <span class="secondary">
107
+ <i class="material-icons red-text">image</i>
108
+ JPG
109
+ </span>
110
+ </a>
111
+ HTML
112
+ end
113
+
114
+ it 'renders a file card with filename, href, document modal options and custom data attributes' do
115
+ expect(subject.render('Document Dolorem.jpg', '/path/to/file.jpg', modal: true, data: { something: '42' })).to match_dom <<-HTML
116
+ <a title="Document Dolorem.jpg" target="_blank" class="card-panel " data-something="42" data-mtl-document-modal="open" data-mtl-document-name="Document Dolorem.jpg" href="/path/to/file.jpg">
117
+ <span class="truncate">Document Dolorem.jpg</span>
118
+ <span class="secondary">
119
+ <i class="material-icons red-text">image</i>
120
+ JPG
121
+ </span>
122
+ </a>
123
+ HTML
124
+ end
125
+ end
126
+ end