ladda_on_rails 0.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.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.un~
19
+ *.DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ladda_on_rails.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Robbie Marcelo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # LaddaOnRails
2
+
3
+ A Ruby Gem of [Ladda.js] for your Rails Asset Pipeline
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ladda_on_rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ladda_on_rails
18
+
19
+ ## Usage
20
+
21
+ # Add this in your application.js
22
+
23
+ //= require ladda
24
+ //= require spin
25
+
26
+ # And in your application.css
27
+
28
+ //= require ladda
29
+
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
38
+
39
+ ## License
40
+
41
+ MIT License. Copyright (c) 2013 Robbie Marcelo, see [LICENSE] for full
42
+ details.
43
+
44
+
45
+ [LICENSE]: http://github.com/rbmrclo/ladda_on_rails/blob/master/LICENSE.txt
46
+ [Ladda.js]: http://github.com/hakimel/Ladda
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,261 @@
1
+ /*!
2
+ * Ladda 0.4.0
3
+ * http://lab.hakim.se/ladda
4
+ * MIT licensed
5
+ *
6
+ * Copyright (C) 2013 Hakim El Hattab, http://hakim.se
7
+ */
8
+ (function( root, factory ) {
9
+
10
+ // CommonJS
11
+ if( typeof exports === 'object' ) {
12
+ module.exports = factory();
13
+ }
14
+ // AMD module
15
+ else if( typeof define === 'function' && define.amd ) {
16
+ define( [ './spin' ], factory );
17
+ }
18
+ // Browser global
19
+ else {
20
+ root.Ladda = factory( root.Spinner );
21
+ }
22
+
23
+ }
24
+ (this, function( Spinner ) {
25
+ 'use strict';
26
+
27
+ // All currently instantiated instances of Ladda
28
+ var ALL_INSTANCES = [];
29
+
30
+ /**
31
+ * Creates a new instance of Ladda which wraps the
32
+ * target button element.
33
+ *
34
+ * @return An API object that can be used to control
35
+ * the loading animation state.
36
+ */
37
+ function create( button ) {
38
+
39
+ if( typeof button === 'undefined' ) {
40
+ throw "Button target must be defined.";
41
+ }
42
+
43
+ // Create the spinner
44
+ var spinner = createSpinner( button.getAttribute( 'data-size' ) );
45
+
46
+ // Wrapper element for the spinner
47
+ var spinnerWrapper = document.createElement( 'span' );
48
+ spinnerWrapper.className = 'ladda-spinner';
49
+ button.appendChild( spinnerWrapper );
50
+
51
+ // Timeout used to delay stopping of the spin animation
52
+ var spinnerTimeout;
53
+
54
+ var instance = {
55
+
56
+ start: function() {
57
+
58
+ button.setAttribute( 'disabled', '' );
59
+ button.setAttribute( 'data-loading', '' );
60
+
61
+ clearTimeout( spinnerTimeout );
62
+ spinner.spin( spinnerWrapper );
63
+
64
+ this.setProgress( 0 );
65
+
66
+ return this; // chain
67
+
68
+ },
69
+
70
+ stop: function() {
71
+
72
+ button.removeAttribute( 'disabled' );
73
+ button.removeAttribute( 'data-loading' );
74
+
75
+ // Kill the animation after a delay to make sure it
76
+ // runs for the duration of the button transition
77
+ clearTimeout( spinnerTimeout );
78
+ spinnerTimeout = setTimeout( function() { spinner.stop(); }, 1000 );
79
+
80
+ return this; // chain
81
+
82
+ },
83
+
84
+ toggle: function() {
85
+
86
+ if( this.isLoading() ) {
87
+ this.stop();
88
+ }
89
+ else {
90
+ this.start();
91
+ }
92
+
93
+ return this; // chain
94
+
95
+ },
96
+
97
+ setProgress: function( progress ) {
98
+
99
+ var progressElement = button.querySelector( '.ladda-progress' );
100
+
101
+ // Remove the progress bar if we're at 0 progress
102
+ if( progress === 0 && progressElement && progressElement.parentNode ) {
103
+ progressElement.parentNode.removeChild( progressElement );
104
+ }
105
+ else {
106
+ if( !progressElement ) {
107
+ progressElement = document.createElement( 'div' );
108
+ progressElement.className = 'ladda-progress';
109
+ button.appendChild( progressElement );
110
+ }
111
+
112
+ progressElement.style.width = ( ( progress || 0 ) * button.offsetWidth ) + 'px';
113
+ }
114
+
115
+ },
116
+
117
+ enable: function() {
118
+
119
+ this.stop();
120
+
121
+ return this; // chain
122
+
123
+ },
124
+
125
+ disable: function () {
126
+
127
+ this.stop();
128
+ button.setAttribute( 'disabled', '' );
129
+
130
+ return this; // chain
131
+
132
+ },
133
+
134
+ isLoading: function() {
135
+
136
+ return button.hasAttribute( 'data-loading' );
137
+
138
+ }
139
+
140
+ };
141
+
142
+ ALL_INSTANCES.push( instance );
143
+
144
+ return instance;
145
+
146
+ }
147
+
148
+ /**
149
+ * Binds the target buttons to automatically enter the
150
+ * loading state when clicked.
151
+ *
152
+ * @param target Either an HTML element or a CSS selector.
153
+ * @param options
154
+ * - timeout Number of milliseconds to wait before
155
+ * automatically cancelling the animation.
156
+ */
157
+ function bind( target, options ) {
158
+
159
+ options = options || {};
160
+
161
+ var targets = [];
162
+
163
+ if( typeof target === 'string' ) {
164
+ targets = [].slice.call( document.querySelectorAll( target ) );
165
+ }
166
+ else if( typeof target === 'object' && typeof target.nodeName === 'string' ) {
167
+ targets = [ targets ];
168
+ }
169
+
170
+ for( var i = 0, len = targets.length; i < len; i++ ) {
171
+
172
+ (function() {
173
+ var element = targets[i];
174
+
175
+ // Make sure we're working with a DOM element
176
+ if( typeof element.addEventListener === 'function' ) {
177
+ var instance = create( element );
178
+ var timeout = -1;
179
+
180
+ element.addEventListener( 'click', function() {
181
+
182
+ instance.start();
183
+
184
+ // Set a loading timeout if one is specified
185
+ if( typeof options.timeout === 'number' ) {
186
+ clearTimeout( timeout );
187
+ timeout = setTimeout( instance.stop, options.timeout );
188
+ }
189
+
190
+ // Invoke callbacks
191
+ if( typeof options.callback === 'function' ) {
192
+ options.callback.apply( null, [ instance ] );
193
+ }
194
+
195
+ }, false );
196
+ }
197
+ })();
198
+
199
+ }
200
+
201
+ }
202
+
203
+ /**
204
+ * Stops ALL current loading animations.
205
+ */
206
+ function stopAll() {
207
+
208
+ for( var i = 0, len = ALL_INSTANCES.length; i < len; i++ ) {
209
+ ALL_INSTANCES[i].stop();
210
+ }
211
+
212
+ }
213
+
214
+ function createSpinner( size ) {
215
+
216
+ var lines = 12,
217
+ radius = 8,
218
+ length = 5,
219
+ width = 3;
220
+
221
+ switch( size ) {
222
+ case 'xs':
223
+ radius = 6;
224
+ length = 4;
225
+ width = 2;
226
+ break;
227
+ case 's':
228
+ radius = 6;
229
+ length = 4;
230
+ width = 2;
231
+ break;
232
+ case 'xl':
233
+ radius = 8;
234
+ length = 6;
235
+ break;
236
+ }
237
+
238
+ return new Spinner( {
239
+ color: '#fff',
240
+ lines: lines,
241
+ radius: radius,
242
+ length: length,
243
+ width: width,
244
+ zIndex: 'initial',
245
+ top: 'auto',
246
+ left: 'auto',
247
+ className: ''
248
+ } );
249
+
250
+ }
251
+
252
+ // Public API
253
+ return {
254
+
255
+ bind: bind,
256
+ create: create,
257
+ stopAll: stopAll
258
+
259
+ };
260
+
261
+ }));
@@ -0,0 +1,349 @@
1
+ //fgnass.github.com/spin.js#v1.3
2
+
3
+ /*!
4
+ * Copyright (c) 2011-2013 Felix Gnass
5
+ * Licensed under the MIT license
6
+ */
7
+ (function(root, factory) {
8
+
9
+ /* CommonJS */
10
+ if (typeof exports == 'object') module.exports = factory()
11
+
12
+ /* AMD module */
13
+ else if (typeof define == 'function' && define.amd) define(factory)
14
+
15
+ /* Browser global */
16
+ else root.Spinner = factory()
17
+ }
18
+ (this, function() {
19
+ "use strict";
20
+
21
+ var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
22
+ , animations = {} /* Animation rules keyed by their name */
23
+ , useCssAnimations /* Whether to use CSS animations or setTimeout */
24
+
25
+ /**
26
+ * Utility function to create elements. If no tag name is given,
27
+ * a DIV is created. Optionally properties can be passed.
28
+ */
29
+ function createEl(tag, prop) {
30
+ var el = document.createElement(tag || 'div')
31
+ , n
32
+
33
+ for(n in prop) el[n] = prop[n]
34
+ return el
35
+ }
36
+
37
+ /**
38
+ * Appends children and returns the parent.
39
+ */
40
+ function ins(parent /* child1, child2, ...*/) {
41
+ for (var i=1, n=arguments.length; i<n; i++)
42
+ parent.appendChild(arguments[i])
43
+
44
+ return parent
45
+ }
46
+
47
+ /**
48
+ * Insert a new stylesheet to hold the @keyframe or VML rules.
49
+ */
50
+ var sheet = (function() {
51
+ var el = createEl('style', {type : 'text/css'})
52
+ ins(document.getElementsByTagName('head')[0], el)
53
+ return el.sheet || el.styleSheet
54
+ }())
55
+
56
+ /**
57
+ * Creates an opacity keyframe animation rule and returns its name.
58
+ * Since most mobile Webkits have timing issues with animation-delay,
59
+ * we create separate rules for each line/segment.
60
+ */
61
+ function addAnimation(alpha, trail, i, lines) {
62
+ var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
63
+ , start = 0.01 + i/lines * 100
64
+ , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
65
+ , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
66
+ , pre = prefix && '-' + prefix + '-' || ''
67
+
68
+ if (!animations[name]) {
69
+ sheet.insertRule(
70
+ '@' + pre + 'keyframes ' + name + '{' +
71
+ '0%{opacity:' + z + '}' +
72
+ start + '%{opacity:' + alpha + '}' +
73
+ (start+0.01) + '%{opacity:1}' +
74
+ (start+trail) % 100 + '%{opacity:' + alpha + '}' +
75
+ '100%{opacity:' + z + '}' +
76
+ '}', sheet.cssRules.length)
77
+
78
+ animations[name] = 1
79
+ }
80
+
81
+ return name
82
+ }
83
+
84
+ /**
85
+ * Tries various vendor prefixes and returns the first supported property.
86
+ */
87
+ function vendor(el, prop) {
88
+ var s = el.style
89
+ , pp
90
+ , i
91
+
92
+ if(s[prop] !== undefined) return prop
93
+ prop = prop.charAt(0).toUpperCase() + prop.slice(1)
94
+ for(i=0; i<prefixes.length; i++) {
95
+ pp = prefixes[i]+prop
96
+ if(s[pp] !== undefined) return pp
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Sets multiple style properties at once.
102
+ */
103
+ function css(el, prop) {
104
+ for (var n in prop)
105
+ el.style[vendor(el, n)||n] = prop[n]
106
+
107
+ return el
108
+ }
109
+
110
+ /**
111
+ * Fills in default values.
112
+ */
113
+ function merge(obj) {
114
+ for (var i=1; i < arguments.length; i++) {
115
+ var def = arguments[i]
116
+ for (var n in def)
117
+ if (obj[n] === undefined) obj[n] = def[n]
118
+ }
119
+ return obj
120
+ }
121
+
122
+ /**
123
+ * Returns the absolute page-offset of the given element.
124
+ */
125
+ function pos(el) {
126
+ var o = { x:el.offsetLeft, y:el.offsetTop }
127
+ while((el = el.offsetParent))
128
+ o.x+=el.offsetLeft, o.y+=el.offsetTop
129
+
130
+ return o
131
+ }
132
+
133
+ // Built-in defaults
134
+
135
+ var defaults = {
136
+ lines: 12, // The number of lines to draw
137
+ length: 7, // The length of each line
138
+ width: 5, // The line thickness
139
+ radius: 10, // The radius of the inner circle
140
+ rotate: 0, // Rotation offset
141
+ corners: 1, // Roundness (0..1)
142
+ color: '#000', // #rgb or #rrggbb
143
+ direction: 1, // 1: clockwise, -1: counterclockwise
144
+ speed: 1, // Rounds per second
145
+ trail: 100, // Afterglow percentage
146
+ opacity: 1/4, // Opacity of the lines
147
+ fps: 20, // Frames per second when using setTimeout()
148
+ zIndex: 2e9, // Use a high z-index by default
149
+ className: 'spinner', // CSS class to assign to the element
150
+ top: 'auto', // center vertically
151
+ left: 'auto', // center horizontally
152
+ position: 'relative' // element position
153
+ }
154
+
155
+ /** The constructor */
156
+ function Spinner(o) {
157
+ if (typeof this == 'undefined') return new Spinner(o)
158
+ this.opts = merge(o || {}, Spinner.defaults, defaults)
159
+ }
160
+
161
+ // Global defaults that override the built-ins:
162
+ Spinner.defaults = {}
163
+
164
+ merge(Spinner.prototype, {
165
+
166
+ /**
167
+ * Adds the spinner to the given target element. If this instance is already
168
+ * spinning, it is automatically removed from its previous target b calling
169
+ * stop() internally.
170
+ */
171
+ spin: function(target) {
172
+ this.stop()
173
+
174
+ var self = this
175
+ , o = self.opts
176
+ , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
177
+ , mid = o.radius+o.length+o.width
178
+ , ep // element position
179
+ , tp // target position
180
+
181
+ if (target) {
182
+ target.insertBefore(el, target.firstChild||null)
183
+ tp = pos(target)
184
+ ep = pos(el)
185
+ css(el, {
186
+ left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
187
+ top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
188
+ })
189
+ }
190
+
191
+ el.setAttribute('role', 'progressbar')
192
+ self.lines(el, self.opts)
193
+
194
+ if (!useCssAnimations) {
195
+ // No CSS animation support, use setTimeout() instead
196
+ var i = 0
197
+ , start = (o.lines - 1) * (1 - o.direction) / 2
198
+ , alpha
199
+ , fps = o.fps
200
+ , f = fps/o.speed
201
+ , ostep = (1-o.opacity) / (f*o.trail / 100)
202
+ , astep = f/o.lines
203
+
204
+ ;(function anim() {
205
+ i++;
206
+ for (var j = 0; j < o.lines; j++) {
207
+ alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
208
+
209
+ self.opacity(el, j * o.direction + start, alpha, o)
210
+ }
211
+ self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
212
+ })()
213
+ }
214
+ return self
215
+ },
216
+
217
+ /**
218
+ * Stops and removes the Spinner.
219
+ */
220
+ stop: function() {
221
+ var el = this.el
222
+ if (el) {
223
+ clearTimeout(this.timeout)
224
+ if (el.parentNode) el.parentNode.removeChild(el)
225
+ this.el = undefined
226
+ }
227
+ return this
228
+ },
229
+
230
+ /**
231
+ * Internal method that draws the individual lines. Will be overwritten
232
+ * in VML fallback mode below.
233
+ */
234
+ lines: function(el, o) {
235
+ var i = 0
236
+ , start = (o.lines - 1) * (1 - o.direction) / 2
237
+ , seg
238
+
239
+ function fill(color, shadow) {
240
+ return css(createEl(), {
241
+ position: 'absolute',
242
+ width: (o.length+o.width) + 'px',
243
+ height: o.width + 'px',
244
+ background: color,
245
+ boxShadow: shadow,
246
+ transformOrigin: 'left',
247
+ transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
248
+ borderRadius: (o.corners * o.width>>1) + 'px'
249
+ })
250
+ }
251
+
252
+ for (; i < o.lines; i++) {
253
+ seg = css(createEl(), {
254
+ position: 'absolute',
255
+ top: 1+~(o.width/2) + 'px',
256
+ transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
257
+ opacity: o.opacity,
258
+ animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
259
+ })
260
+
261
+ if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
262
+
263
+ ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')))
264
+ }
265
+ return el
266
+ },
267
+
268
+ /**
269
+ * Internal method that adjusts the opacity of a single line.
270
+ * Will be overwritten in VML fallback mode below.
271
+ */
272
+ opacity: function(el, i, val) {
273
+ if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
274
+ }
275
+
276
+ })
277
+
278
+
279
+ function initVML() {
280
+
281
+ /* Utility function to create a VML tag */
282
+ function vml(tag, attr) {
283
+ return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
284
+ }
285
+
286
+ // No CSS transforms but VML support, add a CSS rule for VML elements:
287
+ sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
288
+
289
+ Spinner.prototype.lines = function(el, o) {
290
+ var r = o.length+o.width
291
+ , s = 2*r
292
+
293
+ function grp() {
294
+ return css(
295
+ vml('group', {
296
+ coordsize: s + ' ' + s,
297
+ coordorigin: -r + ' ' + -r
298
+ }),
299
+ { width: s, height: s }
300
+ )
301
+ }
302
+
303
+ var margin = -(o.width+o.length)*2 + 'px'
304
+ , g = css(grp(), {position: 'absolute', top: margin, left: margin})
305
+ , i
306
+
307
+ function seg(i, dx, filter) {
308
+ ins(g,
309
+ ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
310
+ ins(css(vml('roundrect', {arcsize: o.corners}), {
311
+ width: r,
312
+ height: o.width,
313
+ left: o.radius,
314
+ top: -o.width>>1,
315
+ filter: filter
316
+ }),
317
+ vml('fill', {color: o.color, opacity: o.opacity}),
318
+ vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
319
+ )
320
+ )
321
+ )
322
+ }
323
+
324
+ if (o.shadow)
325
+ for (i = 1; i <= o.lines; i++)
326
+ seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
327
+
328
+ for (i = 1; i <= o.lines; i++) seg(i)
329
+ return ins(el, g)
330
+ }
331
+
332
+ Spinner.prototype.opacity = function(el, i, val, o) {
333
+ var c = el.firstChild
334
+ o = o.shadow && o.lines || 0
335
+ if (c && i+o < c.childNodes.length) {
336
+ c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
337
+ if (c) c.opacity = val
338
+ }
339
+ }
340
+ }
341
+
342
+ var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
343
+
344
+ if (!vendor(probe, 'transform') && probe.adj) initVML()
345
+ else useCssAnimations = vendor(probe, 'animation')
346
+
347
+ return Spinner
348
+
349
+ }));
@@ -0,0 +1,535 @@
1
+ /*!
2
+ * Ladda
3
+ * http://lab.hakim.se/ladda
4
+ * MIT licensed
5
+ *
6
+ * Copyright (C) 2013 Hakim El Hattab, http://hakim.se
7
+ */
8
+
9
+
10
+ /*************************************
11
+ * CONFIG
12
+ */
13
+
14
+ $green: #2aca76;
15
+ $blue: #53b5e6;
16
+ $red: #ea8557;
17
+ $purple: #9973C2;
18
+ $mint: #16a085;
19
+
20
+ $spinnerSize: 32px;
21
+
22
+
23
+ /*************************************
24
+ * MIXINS
25
+ */
26
+
27
+ @mixin prefix ( $property, $value ) {
28
+ -webkit-#{$property}: $value;
29
+ -moz-#{$property}: $value;
30
+ -ms-#{$property}: $value;
31
+ -o-#{$property}: $value;
32
+ #{$property}: $value;
33
+ }
34
+
35
+ @mixin transition( $value ) {
36
+ @include prefix( transition, $value );
37
+ }
38
+
39
+ @mixin transform( $value ) {
40
+ @include prefix( transform, $value );
41
+ }
42
+
43
+ @mixin transform-origin( $value ) {
44
+ @include prefix( transform-origin, $value );
45
+ }
46
+
47
+ @mixin buttonColor( $name, $color ) {
48
+ &[data-color=#{$name}] {
49
+ background: $color;
50
+
51
+ &:hover {
52
+ background-color: lighten( $color, 5% );
53
+ }
54
+ }
55
+ }
56
+
57
+
58
+ /*************************************
59
+ * BUTTON BASE
60
+ */
61
+
62
+ .ladda-button {
63
+ position: relative;
64
+ background: #666;
65
+ border: 0;
66
+ padding: 14px 18px;
67
+ font-size: 18px;
68
+ cursor: pointer;
69
+ overflow: hidden;
70
+
71
+ color: #fff;
72
+ border-radius: 2px;
73
+ border: 1px solid transparent;
74
+
75
+ -webkit-appearance: none;
76
+ -webkit-font-smoothing: antialiased;
77
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
78
+
79
+ &:hover {
80
+ border-color: rgba( 0, 0, 0, 0.07 );
81
+ background-color: #888;
82
+ }
83
+
84
+ @include buttonColor( 'green', $green );
85
+ @include buttonColor( 'blue', $blue );
86
+ @include buttonColor( 'red', $red );
87
+ @include buttonColor( 'purple', $purple );
88
+ @include buttonColor( 'mint', $mint );
89
+
90
+ &[disabled],
91
+ &[data-loading] {
92
+ border-color: rgba( 0, 0, 0, 0.07 );
93
+ cursor: default;
94
+ background-color: #999;
95
+
96
+ &:hover {
97
+ cursor: default;
98
+ background-color: #999;
99
+ }
100
+ }
101
+
102
+ &[data-size=xs] {
103
+ padding: 4px 8px;
104
+
105
+ .ladda-label {
106
+ font-size: 0.7em;
107
+ }
108
+ }
109
+
110
+ &[data-size=s] {
111
+ padding: 6px 10px;
112
+
113
+ .ladda-label {
114
+ font-size: 0.9em;
115
+ }
116
+ }
117
+
118
+ &[data-size=l] .ladda-label {
119
+ font-size: 1.2em;
120
+ }
121
+
122
+ &[data-size=xl] .ladda-label {
123
+ font-size: 1.5em;
124
+ }
125
+ }
126
+
127
+
128
+ /* Spinner animation */
129
+ .ladda-button .ladda-spinner {
130
+ position: absolute;
131
+ z-index: 2;
132
+ display: inline-block;
133
+ width: $spinnerSize;
134
+ height: $spinnerSize;
135
+ top: 50%;
136
+ margin-top: -$spinnerSize/2;
137
+ opacity: 0;
138
+ }
139
+
140
+ /* Button label */
141
+ .ladda-button .ladda-label {
142
+ position: relative;
143
+ z-index: 3;
144
+ }
145
+
146
+ /* Progress bar */
147
+ .ladda-button .ladda-progress {
148
+ position: absolute;
149
+ width: 0;
150
+ height: 100%;
151
+ left: 0;
152
+ top: 0;
153
+ background: rgba( 0, 0, 0, 0.2 );
154
+
155
+ visibility: hidden;
156
+ opacity: 0;
157
+
158
+ @include transition( 0.1s linear all );
159
+ }
160
+ .ladda-button[data-loading] .ladda-progress {
161
+ opacity: 1;
162
+ visibility: visible;
163
+ }
164
+
165
+
166
+ /*************************************
167
+ * EASING
168
+ */
169
+
170
+ .ladda-button,
171
+ .ladda-button .ladda-spinner,
172
+ .ladda-button .ladda-label {
173
+ @include transition( 0.3s cubic-bezier(0.175, 0.885, 0.320, 1.275) all );
174
+ }
175
+
176
+ .ladda-button[data-style=zoom-in],
177
+ .ladda-button[data-style=zoom-in] .ladda-spinner,
178
+ .ladda-button[data-style=zoom-in] .ladda-label,
179
+ .ladda-button[data-style=zoom-out],
180
+ .ladda-button[data-style=zoom-out] .ladda-spinner,
181
+ .ladda-button[data-style=zoom-out] .ladda-label {
182
+ @include transition( 0.3s ease all );
183
+ }
184
+
185
+
186
+ /*************************************
187
+ * EXPAND LEFT
188
+ */
189
+
190
+ .ladda-button[data-style=expand-right] {
191
+ .ladda-spinner {
192
+ right: 14px;
193
+ }
194
+
195
+ &[data-size="s"] .ladda-spinner,
196
+ &[data-size="xs"] .ladda-spinner {
197
+ right: 4px;
198
+ }
199
+
200
+ &[data-loading] {
201
+ padding-right: 56px;
202
+
203
+ .ladda-spinner {
204
+ opacity: 1;
205
+ }
206
+
207
+ &[data-size="s"],
208
+ &[data-size="xs"] {
209
+ padding-right: 40px;
210
+ }
211
+ }
212
+ }
213
+
214
+
215
+ /*************************************
216
+ * EXPAND RIGHT
217
+ */
218
+
219
+ .ladda-button[data-style=expand-left] {
220
+ .ladda-spinner {
221
+ left: 14px;
222
+ }
223
+
224
+ &[data-size="s"] .ladda-spinner,
225
+ &[data-size="xs"] .ladda-spinner {
226
+ left: 4px;
227
+ }
228
+
229
+ &[data-loading] {
230
+ padding-left: 56px;
231
+
232
+ .ladda-spinner {
233
+ opacity: 1;
234
+ }
235
+
236
+ &[data-size="s"],
237
+ &[data-size="xs"] {
238
+ padding-left: 40px;
239
+ }
240
+ }
241
+ }
242
+
243
+
244
+ /*************************************
245
+ * EXPAND UP
246
+ */
247
+
248
+ .ladda-button[data-style=expand-up] {
249
+ overflow: hidden;
250
+
251
+ .ladda-spinner {
252
+ top: -$spinnerSize;
253
+ left: 50%;
254
+ margin-left: -$spinnerSize/2;
255
+ }
256
+
257
+ &[data-loading] {
258
+ padding-top: 54px;
259
+
260
+ .ladda-spinner {
261
+ opacity: 1;
262
+ top: 14px;
263
+ margin-top: 0;
264
+ }
265
+
266
+ &[data-size="s"],
267
+ &[data-size="xs"] {
268
+ padding-top: 32px;
269
+
270
+ .ladda-spinner {
271
+ top: 4px;
272
+ }
273
+ }
274
+ }
275
+ }
276
+
277
+
278
+ /*************************************
279
+ * EXPAND DOWN
280
+ */
281
+
282
+ .ladda-button[data-style=expand-down] {
283
+ overflow: hidden;
284
+
285
+ .ladda-spinner {
286
+ top: 62px;
287
+ left: 50%;
288
+ margin-left: -$spinnerSize/2;
289
+ }
290
+
291
+ &[data-size="s"] .ladda-spinner,
292
+ &[data-size="xs"] .ladda-spinner {
293
+ top: 40px;
294
+ }
295
+
296
+ &[data-loading] {
297
+ padding-bottom: 54px;
298
+
299
+ .ladda-spinner {
300
+ opacity: 1;
301
+ }
302
+
303
+ &[data-size="s"],
304
+ &[data-size="xs"] {
305
+ padding-bottom: 32px;
306
+ }
307
+ }
308
+ }
309
+
310
+
311
+ /*************************************
312
+ * SLIDE LEFT
313
+ */
314
+ .ladda-button[data-style=slide-left] {
315
+ overflow: hidden;
316
+
317
+ .ladda-label {
318
+ position: relative;
319
+ }
320
+ .ladda-spinner {
321
+ left: 100%;
322
+ margin-left: -$spinnerSize/2;
323
+ }
324
+
325
+ &[data-loading] {
326
+ .ladda-label {
327
+ opacity: 0;
328
+ left: -100%;
329
+ }
330
+ .ladda-spinner {
331
+ opacity: 1;
332
+ left: 50%;
333
+ }
334
+ }
335
+ }
336
+
337
+
338
+ /*************************************
339
+ * SLIDE RIGHT
340
+ */
341
+ .ladda-button[data-style=slide-right] {
342
+ overflow: hidden;
343
+
344
+ .ladda-label {
345
+ position: relative;
346
+ }
347
+ .ladda-spinner {
348
+ right: 100%;
349
+ margin-left: -$spinnerSize/2;
350
+ }
351
+
352
+ &[data-loading] {
353
+ .ladda-label {
354
+ opacity: 0;
355
+ left: 100%;
356
+ }
357
+ .ladda-spinner {
358
+ opacity: 1;
359
+ left: 50%;
360
+ }
361
+ }
362
+ }
363
+
364
+
365
+ /*************************************
366
+ * SLIDE UP
367
+ */
368
+ .ladda-button[data-style=slide-up] {
369
+ overflow: hidden;
370
+
371
+ .ladda-label {
372
+ position: relative;
373
+ }
374
+ .ladda-spinner {
375
+ left: 50%;
376
+ margin-left: -$spinnerSize/2;
377
+ margin-top: 1em;
378
+ }
379
+
380
+ &[data-loading] {
381
+ .ladda-label {
382
+ opacity: 0;
383
+ top: -1em;
384
+ }
385
+ .ladda-spinner {
386
+ opacity: 1;
387
+ margin-top: -$spinnerSize/2;
388
+ }
389
+ }
390
+ }
391
+
392
+
393
+ /*************************************
394
+ * SLIDE DOWN
395
+ */
396
+ .ladda-button[data-style=slide-down] {
397
+ overflow: hidden;
398
+
399
+ .ladda-label {
400
+ position: relative;
401
+ }
402
+ .ladda-spinner {
403
+ left: 50%;
404
+ margin-left: -$spinnerSize/2;
405
+ margin-top: -2em;
406
+ }
407
+
408
+ &[data-loading] {
409
+ .ladda-label {
410
+ opacity: 0;
411
+ top: 1em;
412
+ }
413
+ .ladda-spinner {
414
+ opacity: 1;
415
+ margin-top: -$spinnerSize/2;
416
+ }
417
+ }
418
+ }
419
+
420
+
421
+ /*************************************
422
+ * ZOOM-OUT
423
+ */
424
+
425
+ .ladda-button[data-style=zoom-out] {
426
+ overflow: hidden;
427
+ }
428
+ .ladda-button[data-style=zoom-out] .ladda-spinner {
429
+ left: 50%;
430
+ margin-left: -$spinnerSize/2;
431
+
432
+ @include transform( scale( 2.5 ) );
433
+ }
434
+ .ladda-button[data-style=zoom-out] .ladda-label {
435
+ position: relative;
436
+ display: inline-block;
437
+ }
438
+
439
+ .ladda-button[data-style=zoom-out][data-loading] .ladda-label {
440
+ opacity: 0;
441
+
442
+ @include transform( scale( 0.5 ) );
443
+ }
444
+ .ladda-button[data-style=zoom-out][data-loading] .ladda-spinner {
445
+ opacity: 1;
446
+
447
+ @include transform( none );
448
+ }
449
+
450
+
451
+ /*************************************
452
+ * ZOOM-IN
453
+ */
454
+
455
+ .ladda-button[data-style=zoom-in] {
456
+ overflow: hidden;
457
+ }
458
+ .ladda-button[data-style=zoom-in] .ladda-spinner {
459
+ left: 50%;
460
+ margin-left: -$spinnerSize/2;
461
+
462
+ @include transform( scale( 0.2 ) );
463
+ }
464
+ .ladda-button[data-style=zoom-in] .ladda-label {
465
+ position: relative;
466
+ display: inline-block;
467
+ }
468
+
469
+ .ladda-button[data-style=zoom-in][data-loading] .ladda-label {
470
+ opacity: 0;
471
+
472
+ @include transform( scale( 2.2 ) );
473
+ }
474
+ .ladda-button[data-style=zoom-in][data-loading] .ladda-spinner {
475
+ opacity: 1;
476
+
477
+ @include transform( none );
478
+ }
479
+
480
+
481
+ /*************************************
482
+ * CONTRACT
483
+ */
484
+
485
+ .ladda-button[data-style=contract] {
486
+ overflow: hidden;
487
+ width: 100px;
488
+ }
489
+ .ladda-button[data-style=contract] .ladda-spinner {
490
+ left: 50%;
491
+ margin-left: -16px;
492
+ }
493
+
494
+ .ladda-button[data-style=contract][data-loading] {
495
+ border-radius: 50%;
496
+ width: 52px;
497
+ }
498
+ .ladda-button[data-style=contract][data-loading] .ladda-label {
499
+ opacity: 0;
500
+ }
501
+ .ladda-button[data-style=contract][data-loading] .ladda-spinner {
502
+ opacity: 1;
503
+ }
504
+
505
+
506
+
507
+ /*************************************
508
+ * OVERLAY
509
+ */
510
+
511
+ .ladda-button[data-style=contract-overlay] {
512
+ overflow: hidden;
513
+ width: 100px;
514
+
515
+ box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0);
516
+ }
517
+ .ladda-button[data-style=contract-overlay] .ladda-spinner {
518
+ left: 50%;
519
+ margin-left: -16px;
520
+ }
521
+
522
+ .ladda-button[data-style=contract-overlay][data-loading] {
523
+ border-radius: 50%;
524
+ width: 52px;
525
+
526
+ /*outline: 10000px solid rgba( 0, 0, 0, 0.5 );*/
527
+ box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0.8);
528
+ }
529
+
530
+ .ladda-button[data-style=contract-overlay][data-loading] .ladda-label {
531
+ opacity: 0;
532
+ }
533
+ .ladda-button[data-style=contract-overlay][data-loading] .ladda-spinner {
534
+ opacity: 1;
535
+ }
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ladda_on_rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ladda_on_rails"
8
+ spec.version = LaddaOnRails::VERSION
9
+ spec.authors = ["Robbie Marcelo"]
10
+ spec.email = ["rbmrclo@hotmail.com"]
11
+ spec.description = %q{Ruby Gem of Ladda.js for Rails Asset Pipeline}
12
+ spec.summary = %q{Ruby Gem of Ladda.js for Rails Asset Pipeline}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,4 @@
1
+ module LaddaOnRails
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module LaddaOnRails
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require "ladda_on_rails/version"
2
+
3
+ module SpacersAndDividers
4
+ require "ladda_on_rails/engine"
5
+ require "ladda_on_rails/version"
6
+ end
7
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ladda_on_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Robbie Marcelo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Ruby Gem of Ladda.js for Rails Asset Pipeline
47
+ email:
48
+ - rbmrclo@hotmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - app/assets/javascripts/ladda.js
59
+ - app/assets/javascripts/spin.js
60
+ - app/assets/stylesheets/ladda.scss
61
+ - ladda_on_rails.gemspec
62
+ - lib/ladda_on_rails.rb
63
+ - lib/ladda_on_rails/engine.rb
64
+ - lib/ladda_on_rails/version.rb
65
+ homepage: ''
66
+ licenses:
67
+ - MIT
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.24
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Ruby Gem of Ladda.js for Rails Asset Pipeline
90
+ test_files: []