mtl 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +104 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/mtl/clickables.coffee +25 -0
- data/app/assets/javascripts/mtl/collapsible.coffee +43 -0
- data/app/assets/javascripts/mtl/configuration.coffee.erb +1 -0
- data/app/assets/javascripts/mtl/document_modal.coffee +130 -0
- data/app/assets/javascripts/mtl/dropdown.coffee +24 -0
- data/app/assets/javascripts/mtl/hooks.coffee +14 -0
- data/app/assets/javascripts/mtl/icon.coffee.erb +17 -0
- data/app/assets/javascripts/mtl/modal.coffee +32 -0
- data/app/assets/javascripts/mtl/select.coffee +44 -0
- data/app/assets/javascripts/mtl/templates.coffee +4 -0
- data/app/assets/javascripts/mtl/toc.coffee +31 -0
- data/app/assets/javascripts/mtl.js +42 -0
- data/app/assets/stylesheets/mtl/all.scss +69 -0
- data/app/assets/stylesheets/mtl/extend/_avatars.scss +37 -0
- data/app/assets/stylesheets/mtl/extend/_buttons.scss +31 -0
- data/app/assets/stylesheets/mtl/extend/_cards.scss +21 -0
- data/app/assets/stylesheets/mtl/extend/_chips.scss +3 -0
- data/app/assets/stylesheets/mtl/extend/_collection-files.scss +108 -0
- data/app/assets/stylesheets/mtl/extend/_document-modals.scss +95 -0
- data/app/assets/stylesheets/mtl/extend/_dropdown.scss +12 -0
- data/app/assets/stylesheets/mtl/extend/_forms.scss +66 -0
- data/app/assets/stylesheets/mtl/extend/_global.scss +77 -0
- data/app/assets/stylesheets/mtl/extend/_grid.scss +25 -0
- data/app/assets/stylesheets/mtl/extend/_material-icons.scss +37 -0
- data/app/assets/stylesheets/mtl/extend/_mixins.scss +10 -0
- data/app/assets/stylesheets/mtl/extend/_roboto-rails.scss +49 -0
- data/app/assets/stylesheets/mtl/extend/_side-nav.scss +22 -0
- data/app/assets/stylesheets/mtl/extend/_toc.scss +12 -0
- data/app/assets/stylesheets/mtl/extend/_typography.scss +32 -0
- data/app/assets/stylesheets/mtl/extend/forms/_input-fields.scss +50 -0
- data/app/assets/stylesheets/mtl/layouts/_default.scss +220 -0
- data/app/assets/stylesheets/mtl/layouts/_single.scss +25 -0
- data/app/views/mtl/header.html.erb +25 -0
- data/bin/coffeelint.rb +16 -0
- data/lib/generators/mtl/install_generator.rb +20 -0
- data/lib/generators/mtl/templates/_color.scss +410 -0
- data/lib/generators/mtl/templates/_variables.scss +330 -0
- data/lib/generators/mtl/templates/mtl.scss +8 -0
- data/lib/generators/mtl/templates/simple_form.rb +211 -0
- data/lib/mtl/rails/card_file_presenter.rb +70 -0
- data/lib/mtl/rails/view_helpers.rb +412 -0
- data/lib/mtl/simple_form/suffix.rb +52 -0
- data/lib/mtl/version.rb +6 -0
- data/lib/mtl.rb +38 -0
- data/mtl.gemspec +35 -0
- data/package.json +11 -0
- data/spec/mtl/rails/card_file_presenter_spec.rb +126 -0
- data/spec/mtl/rails/view_helpers_spec.rb +193 -0
- data/spec/mtl/simple_form/suffix_spec.rb +39 -0
- data/spec/mtl_spec.rb +34 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/dom.rb +15 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.eot +0 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ijmap +1 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.svg +2373 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.ttf +0 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff +0 -0
- data/vendor/assets/fonts/material-icons/MaterialIcons-Regular.woff2 +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Bold.eot +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Bold.woff +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Bold.woff2 +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Light.eot +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Light.ttf +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Light.woff +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Light.woff2 +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Medium.eot +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Medium.woff +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Medium.woff2 +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Regular.eot +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Regular.woff +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Regular.woff2 +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Thin.eot +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Thin.woff +0 -0
- data/vendor/assets/fonts/roboto/Roboto-Thin.woff2 +0 -0
- data/vendor/assets/javascripts/lodash.js +16607 -0
- data/vendor/assets/javascripts/materialize/animation.js +9 -0
- data/vendor/assets/javascripts/materialize/buttons.js +91 -0
- data/vendor/assets/javascripts/materialize/cards.js +26 -0
- data/vendor/assets/javascripts/materialize/carousel.js +454 -0
- data/vendor/assets/javascripts/materialize/character_counter.js +72 -0
- data/vendor/assets/javascripts/materialize/chips.js +267 -0
- data/vendor/assets/javascripts/materialize/collapsible.js +160 -0
- data/vendor/assets/javascripts/materialize/date_picker/picker.date.js +1430 -0
- data/vendor/assets/javascripts/materialize/date_picker/picker.js +1123 -0
- data/vendor/assets/javascripts/materialize/dropdown.js +265 -0
- data/vendor/assets/javascripts/materialize/forms.js +681 -0
- data/vendor/assets/javascripts/materialize/global.js +45 -0
- data/vendor/assets/javascripts/materialize/hammer.min.js +1 -0
- data/vendor/assets/javascripts/materialize/init.js +173 -0
- data/vendor/assets/javascripts/materialize/initial.js +11 -0
- data/vendor/assets/javascripts/materialize/jquery.easing.1.3.js +205 -0
- data/vendor/assets/javascripts/materialize/jquery.hammer.js +33 -0
- data/vendor/assets/javascripts/materialize/jquery.timeago.min.js +1 -0
- data/vendor/assets/javascripts/materialize/leanModal.js +192 -0
- data/vendor/assets/javascripts/materialize/materialbox.js +269 -0
- data/vendor/assets/javascripts/materialize/parallax.js +58 -0
- data/vendor/assets/javascripts/materialize/prism.js +8 -0
- data/vendor/assets/javascripts/materialize/pushpin.js +71 -0
- data/vendor/assets/javascripts/materialize/scrollFire.js +48 -0
- data/vendor/assets/javascripts/materialize/scrollspy.js +283 -0
- data/vendor/assets/javascripts/materialize/sideNav.js +352 -0
- data/vendor/assets/javascripts/materialize/slider.js +321 -0
- data/vendor/assets/javascripts/materialize/tabs.js +148 -0
- data/vendor/assets/javascripts/materialize/toasts.js +136 -0
- data/vendor/assets/javascripts/materialize/tooltip.js +230 -0
- data/vendor/assets/javascripts/materialize/transitions.js +169 -0
- data/vendor/assets/javascripts/materialize/velocity.min.js +5 -0
- data/vendor/assets/javascripts/materialize/waves.js +338 -0
- data/vendor/assets/javascripts/pdfobject.js +254 -0
- data/vendor/assets/stylesheets/materialize/_buttons.scss +211 -0
- data/vendor/assets/stylesheets/materialize/_cards.scss +185 -0
- data/vendor/assets/stylesheets/materialize/_carousel.scss +85 -0
- data/vendor/assets/stylesheets/materialize/_chips.scss +74 -0
- data/vendor/assets/stylesheets/materialize/_collapsible.scss +90 -0
- data/vendor/assets/stylesheets/materialize/_color.scss +412 -0
- data/vendor/assets/stylesheets/materialize/_dropdown.scss +57 -0
- data/vendor/assets/stylesheets/materialize/_global.scss +781 -0
- data/vendor/assets/stylesheets/materialize/_grid.scss +147 -0
- data/vendor/assets/stylesheets/materialize/_icons-material-design.scss +5 -0
- data/vendor/assets/stylesheets/materialize/_materialbox.scss +42 -0
- data/vendor/assets/stylesheets/materialize/_mixins.scss +5 -0
- data/vendor/assets/stylesheets/materialize/_modal.scss +90 -0
- data/vendor/assets/stylesheets/materialize/_navbar.scss +182 -0
- data/vendor/assets/stylesheets/materialize/_normalize.scss +424 -0
- data/vendor/assets/stylesheets/materialize/_prefixer.scss +384 -0
- data/vendor/assets/stylesheets/materialize/_preloader.scss +334 -0
- data/vendor/assets/stylesheets/materialize/_roboto.scss +49 -0
- data/vendor/assets/stylesheets/materialize/_sideNav.scss +219 -0
- data/vendor/assets/stylesheets/materialize/_slider.scss +92 -0
- data/vendor/assets/stylesheets/materialize/_table_of_contents.scss +33 -0
- data/vendor/assets/stylesheets/materialize/_tabs.scss +56 -0
- data/vendor/assets/stylesheets/materialize/_toast.scss +65 -0
- data/vendor/assets/stylesheets/materialize/_tooltip.scss +32 -0
- data/vendor/assets/stylesheets/materialize/_typography.scss +61 -0
- data/vendor/assets/stylesheets/materialize/_variables.scss +313 -0
- data/vendor/assets/stylesheets/materialize/_waves.scss +177 -0
- data/vendor/assets/stylesheets/materialize/date_picker/_default.date.scss +435 -0
- data/vendor/assets/stylesheets/materialize/date_picker/_default.scss +201 -0
- data/vendor/assets/stylesheets/materialize/date_picker/_default.time.scss +125 -0
- data/vendor/assets/stylesheets/materialize/forms/_checkboxes.scss +220 -0
- data/vendor/assets/stylesheets/materialize/forms/_file-input.scss +38 -0
- data/vendor/assets/stylesheets/materialize/forms/_forms.scss +22 -0
- data/vendor/assets/stylesheets/materialize/forms/_input-fields.scss +273 -0
- data/vendor/assets/stylesheets/materialize/forms/_radio-buttons.scss +119 -0
- data/vendor/assets/stylesheets/materialize/forms/_range.scss +159 -0
- data/vendor/assets/stylesheets/materialize/forms/_select.scss +116 -0
- data/vendor/assets/stylesheets/materialize/forms/_switches.scss +78 -0
- 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)
|
data/lib/mtl/version.rb
ADDED
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,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
|