mtl 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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