ladda-sprockets 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ module Ladda
2
+ module Sprockets
3
+ def self.load!
4
+
5
+ if rails?
6
+ require "ladda-sprockets/engine"
7
+ end
8
+
9
+ stylesheets = File.expand_path(File.join("..", "vendor", "assets", "stylesheets"), File.dirname(__FILE__))
10
+ ::Sass.load_paths << stylesheets
11
+
12
+ end
13
+
14
+ private
15
+
16
+ def self.rails?
17
+ defined?(::Rails)
18
+ end
19
+ end
20
+ end
21
+
22
+ Ladda::Sprockets.load!
@@ -0,0 +1,6 @@
1
+ module Ladda
2
+ module Sprockets
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,314 @@
1
+ /*!
2
+ * Ladda 0.7.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
+ console.warn( "Ladda button target must be defined." );
41
+ return;
42
+ }
43
+
44
+ // The text contents must be wrapped in a ladda-label
45
+ // element, create one if it doesn't already exist
46
+ if( !button.querySelector( '.ladda-label' ) ) {
47
+ button.innerHTML = '<span class="ladda-label">'+ button.innerHTML +'</span>';
48
+ }
49
+
50
+ // Create the spinner
51
+ var spinner = createSpinner( button );
52
+
53
+ // Wrapper element for the spinner
54
+ var spinnerWrapper = document.createElement( 'span' );
55
+ spinnerWrapper.className = 'ladda-spinner';
56
+ button.appendChild( spinnerWrapper );
57
+
58
+ // Timer used to delay starting/stopping
59
+ var timer;
60
+
61
+ var instance = {
62
+
63
+ /**
64
+ * Enter the loading state.
65
+ */
66
+ start: function() {
67
+
68
+ button.setAttribute( 'disabled', '' );
69
+ button.setAttribute( 'data-loading', '' );
70
+
71
+ clearTimeout( timer );
72
+ spinner.spin( spinnerWrapper );
73
+
74
+ this.setProgress( 0 );
75
+
76
+ return this; // chain
77
+
78
+ },
79
+
80
+ /**
81
+ * Enter the loading state, after a delay.
82
+ */
83
+ startAfter: function( delay ) {
84
+
85
+ clearTimeout( timer );
86
+ timer = setTimeout( function() { instance.start(); }, delay );
87
+
88
+ return this; // chain
89
+
90
+ },
91
+
92
+ /**
93
+ * Exit the loading state.
94
+ */
95
+ stop: function() {
96
+
97
+ button.removeAttribute( 'disabled' );
98
+ button.removeAttribute( 'data-loading' );
99
+
100
+ // Kill the animation after a delay to make sure it
101
+ // runs for the duration of the button transition
102
+ clearTimeout( timer );
103
+ timer = setTimeout( function() { spinner.stop(); }, 1000 );
104
+
105
+ return this; // chain
106
+
107
+ },
108
+
109
+ /**
110
+ * Toggle the loading state on/off.
111
+ */
112
+ toggle: function() {
113
+
114
+ if( this.isLoading() ) {
115
+ this.stop();
116
+ }
117
+ else {
118
+ this.start();
119
+ }
120
+
121
+ return this; // chain
122
+
123
+ },
124
+
125
+ /**
126
+ * Sets the width of the visual progress bar inside of
127
+ * this Ladda button
128
+ *
129
+ * @param {Number} progress in the range of 0-1
130
+ */
131
+ setProgress: function( progress ) {
132
+
133
+ // Cap it
134
+ progress = Math.max( Math.min( progress, 1 ), 0 );
135
+
136
+ var progressElement = button.querySelector( '.ladda-progress' );
137
+
138
+ // Remove the progress bar if we're at 0 progress
139
+ if( progress === 0 && progressElement && progressElement.parentNode ) {
140
+ progressElement.parentNode.removeChild( progressElement );
141
+ }
142
+ else {
143
+ if( !progressElement ) {
144
+ progressElement = document.createElement( 'div' );
145
+ progressElement.className = 'ladda-progress';
146
+ button.appendChild( progressElement );
147
+ }
148
+
149
+ progressElement.style.width = ( ( progress || 0 ) * button.offsetWidth ) + 'px';
150
+ }
151
+
152
+ },
153
+
154
+ enable: function() {
155
+
156
+ this.stop();
157
+
158
+ return this; // chain
159
+
160
+ },
161
+
162
+ disable: function () {
163
+
164
+ this.stop();
165
+ button.setAttribute( 'disabled', '' );
166
+
167
+ return this; // chain
168
+
169
+ },
170
+
171
+ isLoading: function() {
172
+
173
+ return button.hasAttribute( 'data-loading' );
174
+
175
+ }
176
+
177
+ };
178
+
179
+ ALL_INSTANCES.push( instance );
180
+
181
+ return instance;
182
+
183
+ }
184
+
185
+ /**
186
+ * Binds the target buttons to automatically enter the
187
+ * loading state when clicked.
188
+ *
189
+ * @param target Either an HTML element or a CSS selector.
190
+ * @param options
191
+ * - timeout Number of milliseconds to wait before
192
+ * automatically cancelling the animation.
193
+ */
194
+ function bind( target, options ) {
195
+
196
+ options = options || {};
197
+
198
+ var targets = [];
199
+
200
+ if( typeof target === 'string' ) {
201
+ targets = toArray( document.querySelectorAll( target ) );
202
+ }
203
+ else if( typeof target === 'object' && typeof target.nodeName === 'string' ) {
204
+ targets = [ target ];
205
+ }
206
+
207
+ for( var i = 0, len = targets.length; i < len; i++ ) {
208
+
209
+ (function() {
210
+ var element = targets[i];
211
+
212
+ // Make sure we're working with a DOM element
213
+ if( typeof element.addEventListener === 'function' ) {
214
+ var instance = create( element );
215
+ var timeout = -1;
216
+
217
+ element.addEventListener( 'click', function() {
218
+
219
+ // This is asynchronous to avoid an issue where setting
220
+ // the disabled attribute on the button prevents forms
221
+ // from submitting
222
+ instance.startAfter( 1 );
223
+
224
+ // Set a loading timeout if one is specified
225
+ if( typeof options.timeout === 'number' ) {
226
+ clearTimeout( timeout );
227
+ timeout = setTimeout( instance.stop, options.timeout );
228
+ }
229
+
230
+ // Invoke callbacks
231
+ if( typeof options.callback === 'function' ) {
232
+ options.callback.apply( null, [ instance ] );
233
+ }
234
+
235
+ }, false );
236
+ }
237
+ })();
238
+
239
+ }
240
+
241
+ }
242
+
243
+ /**
244
+ * Stops ALL current loading animations.
245
+ */
246
+ function stopAll() {
247
+
248
+ for( var i = 0, len = ALL_INSTANCES.length; i < len; i++ ) {
249
+ ALL_INSTANCES[i].stop();
250
+ }
251
+
252
+ }
253
+
254
+ function createSpinner( button ) {
255
+
256
+ var height = button.offsetHeight,
257
+ spinnerColor;
258
+
259
+ // If the button is tall we can afford some padding
260
+ if( height > 32 ) {
261
+ height *= 0.8;
262
+ }
263
+
264
+ // Prefer an explicit height if one is defined
265
+ if( button.hasAttribute( 'data-spinner-size' ) ) {
266
+ height = parseInt( button.getAttribute( 'data-spinner-size' ), 10 );
267
+ }
268
+
269
+ // Allow buttons to specify the color of the spinner element
270
+ if (button.hasAttribute('data-spinner-color' ) ) {
271
+ spinnerColor = button.getAttribute( 'data-spinner-color' );
272
+ }
273
+
274
+ var lines = 12,
275
+ radius = height * 0.2,
276
+ length = radius * 0.6,
277
+ width = radius < 7 ? 2 : 3;
278
+
279
+ return new Spinner( {
280
+ color: spinnerColor || '#fff',
281
+ lines: lines,
282
+ radius: radius,
283
+ length: length,
284
+ width: width,
285
+ zIndex: 'auto',
286
+ top: 'auto',
287
+ left: 'auto',
288
+ className: ''
289
+ } );
290
+
291
+ }
292
+
293
+ function toArray( nodes ) {
294
+
295
+ var a = [];
296
+
297
+ for ( var i = 0; i < nodes.length; i++ ) {
298
+ a.push( nodes[ i ] );
299
+ }
300
+
301
+ return a;
302
+
303
+ }
304
+
305
+ // Public API
306
+ return {
307
+
308
+ bind: bind,
309
+ create: create,
310
+ stopAll: stopAll
311
+
312
+ };
313
+
314
+ }));
@@ -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,80 @@
1
+ /** Contains the default Ladda button theme styles */
2
+
3
+
4
+ /*************************************
5
+ * CONFIG
6
+ */
7
+
8
+ $green: #2aca76;
9
+ $blue: #53b5e6;
10
+ $red: #ea8557;
11
+ $purple: #9973C2;
12
+ $mint: #16a085;
13
+
14
+
15
+ /*************************************
16
+ * BUTTON THEME
17
+ */
18
+
19
+ .ladda-button {
20
+ background: #666;
21
+ border: 0;
22
+ padding: 14px 18px;
23
+ font-size: 18px;
24
+ cursor: pointer;
25
+
26
+ color: #fff;
27
+ border-radius: 2px;
28
+ border: 1px solid transparent;
29
+
30
+ -webkit-appearance: none;
31
+ -webkit-font-smoothing: antialiased;
32
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
33
+
34
+ &:hover {
35
+ border-color: rgba( 0, 0, 0, 0.07 );
36
+ background-color: #888;
37
+ }
38
+
39
+ @include buttonColor( 'green', $green );
40
+ @include buttonColor( 'blue', $blue );
41
+ @include buttonColor( 'red', $red );
42
+ @include buttonColor( 'purple', $purple );
43
+ @include buttonColor( 'mint', $mint );
44
+
45
+ &[disabled],
46
+ &[data-loading] {
47
+ border-color: rgba( 0, 0, 0, 0.07 );
48
+ cursor: default;
49
+ background-color: #999;
50
+
51
+ &:hover {
52
+ cursor: default;
53
+ background-color: #999;
54
+ }
55
+ }
56
+
57
+ &[data-size=xs] {
58
+ padding: 4px 8px;
59
+
60
+ .ladda-label {
61
+ font-size: 0.7em;
62
+ }
63
+ }
64
+
65
+ &[data-size=s] {
66
+ padding: 6px 10px;
67
+
68
+ .ladda-label {
69
+ font-size: 0.9em;
70
+ }
71
+ }
72
+
73
+ &[data-size=l] .ladda-label {
74
+ font-size: 1.2em;
75
+ }
76
+
77
+ &[data-size=xl] .ladda-label {
78
+ font-size: 1.5em;
79
+ }
80
+ }
@@ -0,0 +1,483 @@
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
+ $spinnerSize: 32px;
15
+
16
+
17
+ /*************************************
18
+ * MIXINS
19
+ */
20
+
21
+ @mixin prefix ( $property, $value ) {
22
+ -webkit-#{$property}: $value;
23
+ -moz-#{$property}: $value;
24
+ -ms-#{$property}: $value;
25
+ -o-#{$property}: $value;
26
+ #{$property}: $value;
27
+ }
28
+
29
+ @mixin transition( $value ) {
30
+ -webkit-transition: $value !important; // important to override bootstrap
31
+ -moz-transition: $value !important;
32
+ -ms-transition: $value !important;
33
+ -o-transition: $value !important;
34
+ transition: $value !important;
35
+ }
36
+
37
+ @mixin transform( $value ) {
38
+ @include prefix( transform, $value );
39
+ }
40
+
41
+ @mixin transform-origin( $value ) {
42
+ @include prefix( transform-origin, $value );
43
+ }
44
+
45
+ @mixin buttonColor( $name, $color ) {
46
+ &[data-color=#{$name}] {
47
+ background: $color;
48
+
49
+ &:hover {
50
+ background-color: lighten( $color, 5% );
51
+ }
52
+ }
53
+ }
54
+
55
+
56
+ /*************************************
57
+ * BUTTON BASE
58
+ */
59
+
60
+ .ladda-button {
61
+ position: relative;
62
+ }
63
+
64
+
65
+ /* Spinner animation */
66
+ .ladda-button .ladda-spinner {
67
+ position: absolute;
68
+ z-index: 2;
69
+ display: inline-block;
70
+ width: $spinnerSize;
71
+ height: $spinnerSize;
72
+ top: 50%;
73
+ margin-top: -$spinnerSize/2;
74
+ opacity: 0;
75
+ pointer-events: none;
76
+ }
77
+
78
+ /* Button label */
79
+ .ladda-button .ladda-label {
80
+ position: relative;
81
+ z-index: 3;
82
+ }
83
+
84
+ /* Progress bar */
85
+ .ladda-button .ladda-progress {
86
+ position: absolute;
87
+ width: 0;
88
+ height: 100%;
89
+ left: 0;
90
+ top: 0;
91
+ background: rgba( 0, 0, 0, 0.2 );
92
+
93
+ visibility: hidden;
94
+ opacity: 0;
95
+
96
+ @include transition( 0.1s linear all );
97
+ }
98
+ .ladda-button[data-loading] .ladda-progress {
99
+ opacity: 1;
100
+ visibility: visible;
101
+ }
102
+
103
+
104
+ /*************************************
105
+ * EASING
106
+ */
107
+
108
+ .ladda-button,
109
+ .ladda-button .ladda-spinner,
110
+ .ladda-button .ladda-label {
111
+ @include transition( 0.3s cubic-bezier(0.175, 0.885, 0.320, 1.275) all );
112
+ }
113
+
114
+ .ladda-button[data-style=zoom-in],
115
+ .ladda-button[data-style=zoom-in] .ladda-spinner,
116
+ .ladda-button[data-style=zoom-in] .ladda-label,
117
+ .ladda-button[data-style=zoom-out],
118
+ .ladda-button[data-style=zoom-out] .ladda-spinner,
119
+ .ladda-button[data-style=zoom-out] .ladda-label {
120
+ @include transition( 0.3s ease all );
121
+ }
122
+
123
+
124
+ /*************************************
125
+ * EXPAND LEFT
126
+ */
127
+
128
+ .ladda-button[data-style=expand-right] {
129
+ .ladda-spinner {
130
+ right: 14px;
131
+ }
132
+
133
+ &[data-size="s"] .ladda-spinner,
134
+ &[data-size="xs"] .ladda-spinner {
135
+ right: 4px;
136
+ }
137
+
138
+ &[data-loading] {
139
+ padding-right: 56px;
140
+
141
+ .ladda-spinner {
142
+ opacity: 1;
143
+ }
144
+
145
+ &[data-size="s"],
146
+ &[data-size="xs"] {
147
+ padding-right: 40px;
148
+ }
149
+ }
150
+ }
151
+
152
+
153
+ /*************************************
154
+ * EXPAND RIGHT
155
+ */
156
+
157
+ .ladda-button[data-style=expand-left] {
158
+ .ladda-spinner {
159
+ left: 14px;
160
+ }
161
+
162
+ &[data-size="s"] .ladda-spinner,
163
+ &[data-size="xs"] .ladda-spinner {
164
+ left: 4px;
165
+ }
166
+
167
+ &[data-loading] {
168
+ padding-left: 56px;
169
+
170
+ .ladda-spinner {
171
+ opacity: 1;
172
+ }
173
+
174
+ &[data-size="s"],
175
+ &[data-size="xs"] {
176
+ padding-left: 40px;
177
+ }
178
+ }
179
+ }
180
+
181
+
182
+ /*************************************
183
+ * EXPAND UP
184
+ */
185
+
186
+ .ladda-button[data-style=expand-up] {
187
+ overflow: hidden;
188
+
189
+ .ladda-spinner {
190
+ top: -$spinnerSize;
191
+ left: 50%;
192
+ margin-left: -$spinnerSize/2;
193
+ }
194
+
195
+ &[data-loading] {
196
+ padding-top: 54px;
197
+
198
+ .ladda-spinner {
199
+ opacity: 1;
200
+ top: 14px;
201
+ margin-top: 0;
202
+ }
203
+
204
+ &[data-size="s"],
205
+ &[data-size="xs"] {
206
+ padding-top: 32px;
207
+
208
+ .ladda-spinner {
209
+ top: 4px;
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+
216
+ /*************************************
217
+ * EXPAND DOWN
218
+ */
219
+
220
+ .ladda-button[data-style=expand-down] {
221
+ overflow: hidden;
222
+
223
+ .ladda-spinner {
224
+ top: 62px;
225
+ left: 50%;
226
+ margin-left: -$spinnerSize/2;
227
+ }
228
+
229
+ &[data-size="s"] .ladda-spinner,
230
+ &[data-size="xs"] .ladda-spinner {
231
+ top: 40px;
232
+ }
233
+
234
+ &[data-loading] {
235
+ padding-bottom: 54px;
236
+
237
+ .ladda-spinner {
238
+ opacity: 1;
239
+ }
240
+
241
+ &[data-size="s"],
242
+ &[data-size="xs"] {
243
+ padding-bottom: 32px;
244
+ }
245
+ }
246
+ }
247
+
248
+
249
+ /*************************************
250
+ * SLIDE LEFT
251
+ */
252
+ .ladda-button[data-style=slide-left] {
253
+ overflow: hidden;
254
+
255
+ .ladda-label {
256
+ position: relative;
257
+ }
258
+ .ladda-spinner {
259
+ left: 100%;
260
+ margin-left: -$spinnerSize/2;
261
+ }
262
+
263
+ &[data-loading] {
264
+ .ladda-label {
265
+ opacity: 0;
266
+ left: -100%;
267
+ }
268
+ .ladda-spinner {
269
+ opacity: 1;
270
+ left: 50%;
271
+ }
272
+ }
273
+ }
274
+
275
+
276
+ /*************************************
277
+ * SLIDE RIGHT
278
+ */
279
+ .ladda-button[data-style=slide-right] {
280
+ overflow: hidden;
281
+
282
+ .ladda-label {
283
+ position: relative;
284
+ }
285
+ .ladda-spinner {
286
+ right: 100%;
287
+ margin-left: -$spinnerSize/2;
288
+ }
289
+
290
+ &[data-loading] {
291
+ .ladda-label {
292
+ opacity: 0;
293
+ left: 100%;
294
+ }
295
+ .ladda-spinner {
296
+ opacity: 1;
297
+ left: 50%;
298
+ }
299
+ }
300
+ }
301
+
302
+
303
+ /*************************************
304
+ * SLIDE UP
305
+ */
306
+ .ladda-button[data-style=slide-up] {
307
+ overflow: hidden;
308
+
309
+ .ladda-label {
310
+ position: relative;
311
+ }
312
+ .ladda-spinner {
313
+ left: 50%;
314
+ margin-left: -$spinnerSize/2;
315
+ margin-top: 1em;
316
+ }
317
+
318
+ &[data-loading] {
319
+ .ladda-label {
320
+ opacity: 0;
321
+ top: -1em;
322
+ }
323
+ .ladda-spinner {
324
+ opacity: 1;
325
+ margin-top: -$spinnerSize/2;
326
+ }
327
+ }
328
+ }
329
+
330
+
331
+ /*************************************
332
+ * SLIDE DOWN
333
+ */
334
+ .ladda-button[data-style=slide-down] {
335
+ overflow: hidden;
336
+
337
+ .ladda-label {
338
+ position: relative;
339
+ }
340
+ .ladda-spinner {
341
+ left: 50%;
342
+ margin-left: -$spinnerSize/2;
343
+ margin-top: -2em;
344
+ }
345
+
346
+ &[data-loading] {
347
+ .ladda-label {
348
+ opacity: 0;
349
+ top: 1em;
350
+ }
351
+ .ladda-spinner {
352
+ opacity: 1;
353
+ margin-top: -$spinnerSize/2;
354
+ }
355
+ }
356
+ }
357
+
358
+
359
+ /*************************************
360
+ * ZOOM-OUT
361
+ */
362
+
363
+ .ladda-button[data-style=zoom-out] {
364
+ overflow: hidden;
365
+ }
366
+ .ladda-button[data-style=zoom-out] .ladda-spinner {
367
+ left: 50%;
368
+ margin-left: -$spinnerSize/2;
369
+
370
+ @include transform( scale( 2.5 ) );
371
+ }
372
+ .ladda-button[data-style=zoom-out] .ladda-label {
373
+ position: relative;
374
+ display: inline-block;
375
+ }
376
+
377
+ .ladda-button[data-style=zoom-out][data-loading] .ladda-label {
378
+ opacity: 0;
379
+
380
+ @include transform( scale( 0.5 ) );
381
+ }
382
+ .ladda-button[data-style=zoom-out][data-loading] .ladda-spinner {
383
+ opacity: 1;
384
+
385
+ @include transform( none );
386
+ }
387
+
388
+
389
+ /*************************************
390
+ * ZOOM-IN
391
+ */
392
+
393
+ .ladda-button[data-style=zoom-in] {
394
+ overflow: hidden;
395
+ }
396
+ .ladda-button[data-style=zoom-in] .ladda-spinner {
397
+ left: 50%;
398
+ margin-left: -$spinnerSize/2;
399
+
400
+ @include transform( scale( 0.2 ) );
401
+ }
402
+ .ladda-button[data-style=zoom-in] .ladda-label {
403
+ position: relative;
404
+ display: inline-block;
405
+ }
406
+
407
+ .ladda-button[data-style=zoom-in][data-loading] .ladda-label {
408
+ opacity: 0;
409
+
410
+ @include transform( scale( 2.2 ) );
411
+ }
412
+ .ladda-button[data-style=zoom-in][data-loading] .ladda-spinner {
413
+ opacity: 1;
414
+
415
+ @include transform( none );
416
+ }
417
+
418
+
419
+ /*************************************
420
+ * CONTRACT
421
+ */
422
+
423
+ .ladda-button[data-style=contract] {
424
+ overflow: hidden;
425
+ width: 100px;
426
+ }
427
+ .ladda-button[data-style=contract] .ladda-spinner {
428
+ left: 50%;
429
+ margin-left: -16px;
430
+ }
431
+
432
+ .ladda-button[data-style=contract][data-loading] {
433
+ border-radius: 50%;
434
+ width: 52px;
435
+ }
436
+ .ladda-button[data-style=contract][data-loading] .ladda-label {
437
+ opacity: 0;
438
+ }
439
+ .ladda-button[data-style=contract][data-loading] .ladda-spinner {
440
+ opacity: 1;
441
+ }
442
+
443
+
444
+
445
+ /*************************************
446
+ * OVERLAY
447
+ */
448
+
449
+ .ladda-button[data-style=contract-overlay] {
450
+ overflow: hidden;
451
+ width: 100px;
452
+
453
+ box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0);
454
+ }
455
+ .ladda-button[data-style=contract-overlay] .ladda-spinner {
456
+ left: 50%;
457
+ margin-left: -16px;
458
+ }
459
+
460
+ .ladda-button[data-style=contract-overlay][data-loading] {
461
+ border-radius: 50%;
462
+ width: 52px;
463
+
464
+ /*outline: 10000px solid rgba( 0, 0, 0, 0.5 );*/
465
+ box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0.8);
466
+ }
467
+ .ladda-button[data-style=contract-overlay][data-loading] .ladda-label {
468
+ opacity: 0;
469
+ }
470
+ .ladda-button[data-style=contract-overlay][data-loading] .ladda-spinner {
471
+ opacity: 1;
472
+ }
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ladda-sprockets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - shelling
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sprockets
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description:
31
+ email:
32
+ - navyblueshellingford@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/ladda-sprockets/engine.rb
38
+ - lib/ladda-sprockets.rb
39
+ - vendor/assets/javascripts/spin.js
40
+ - vendor/assets/javascripts/ladda.js
41
+ - vendor/assets/stylesheets/ladda-theme.scss
42
+ - vendor/assets/stylesheets/ladda.scss
43
+ homepage: http://github.com/shelling/ladda-sprockets
44
+ licenses:
45
+ - MIT
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.24
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: the ladda button effect assets
68
+ test_files: []