├── .gitignore
├── README.md
├── dist
└── vue-button-spinner.js
├── package-lock.json
├── package.json
├── src
└── VueButtonSpinner.vue
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 | /.idea/
3 | node_modules/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VueButtonSpinner
2 | [](https://badge.fury.io/js/vue-button-spinner)
3 |
4 | > Simple VUE 2 component to create a button spinner. The perfect solution for your submit buttons!
5 |
6 | 
7 |
8 | # Features
9 |
10 | - Show an css loader into the button to indicate the request status.
11 | - Add a custom html inside the component.
12 | - Pure CSS loaders, no fonts or images have been used.
13 | - Different styles for each state: loading, success, error.
14 | - Available props:
15 | * 'isLoading' (boolean) to show the spinner
16 | * 'status' (String | Boolean) allow 'success' or true and 'error' or false.
17 | - **Remember use the .native modifier for the events ([docs](https://vuejs.org/v2/guide/migration.html#Listening-for-Native-Events-on-Components-with-v-on-changed))**
18 |
19 | # Install
20 |
21 | ```npm install vue-button-spinner```
22 |
23 | # Usage
24 |
25 | ### Example:
26 |
27 | [Your .vue component (vue-loader with webpack or use vue-cli projects)]
28 | ```js
29 |
30 | import VueButtonSpinner from 'vue-button-spinner';
31 |
32 | export default {
33 | name: 'events-form',
34 | data() {
35 | return {
36 | isLoading: false,
37 | status: '',
38 | }
39 | },
40 | components: {
41 | VueButtonSpinner
42 | },
43 | methods: {
44 | onSubmit() {
45 | this.isLoading = true
46 | $someRequest('/url', 'GET')
47 | .then(response => {
48 | this.isLoading = false
49 | this.status = true // or success
50 | setTimeout(() => { this.status = '' }, 2000) // to clear the status :)
51 | })
52 | .catch(error => {
53 | console.error(error)
54 | this.isLoading = false
55 | this.status = false //or error
56 | })
57 | }
58 | }
59 | }
60 |
61 | ```
62 |
63 | [Your HTML code]
64 | ```html
65 |
66 |
70 | Submit
71 |
72 |
73 | ```
74 |
--------------------------------------------------------------------------------
/dist/vue-button-spinner.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("vue-button-spinner",[],t):"object"==typeof exports?exports["vue-button-spinner"]=t():e["vue-button-spinner"]=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";function r(e){n(1)}Object.defineProperty(t,"__esModule",{value:!0});var o=n(7),a=n.n(o),i=n(8),s=n(6),c=r,d=s(a.a,i.a,!1,c,"data-v-67fd4b98",null);t.default=d.exports},function(e,t,n){var r=n(2);"string"==typeof r&&(r=[[e.i,r,""]]),r.locals&&(e.exports=r.locals);n(4)("c43219ee",r,!0)},function(e,t,n){t=e.exports=n(3)(void 0),t.push([e.i,'.fade-enter-active[data-v-67fd4b98],.fade-leave-active[data-v-67fd4b98]{transition:opacity 1s}.fade-enter[data-v-67fd4b98],.fade-leave-active[data-v-67fd4b98]{opacity:0;will-change:opacity}@keyframes rotation-data-v-67fd4b98{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}.vue-btn[data-v-67fd4b98]{-moz-appearance:none;-webkit-appearance:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-radius:3px;-webkit-box-shadow:none;box-shadow:none;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;font-size:1rem;height:2.25em;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;line-height:1.5;padding-left:calc(.625em - 1px);padding-right:calc(.625em - 1px);position:relative;vertical-align:top;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;border:1px solid #dbdbdb;color:#363636;cursor:pointer;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:calc(.375em - 1px) .75em;text-align:center;white-space:nowrap;transition:all .3s ease}button.vue-btn-loader-error[data-v-67fd4b98]:not(.is-loading){width:48px;background-color:#f44336;color:#fff}button.vue-btn-loader-success[data-v-67fd4b98]:not(.is-loading){width:48px;background-color:#8bc34a;color:#fff}button.vue-btn[data-v-67fd4b98]:disabled{cursor:not-allowed}.spinner[data-v-67fd4b98]{height:10px;width:10px;margin-right:8px;opacity:1;filter:alpha(opacity=100);animation:rotation-data-v-67fd4b98 .7s infinite linear;border:4px solid rgba(0,0,0,.2);border-top-color:#9e9e9e;border-radius:100%;transition:all .3s ease}.check[data-v-67fd4b98]{display:inline-block;width:23px;height:24px;border-radius:50%;transform:rotate(45deg);color:#fff;will-change:transform}.check[data-v-67fd4b98]:before{content:"";position:absolute;width:3px;height:9px;background-color:#fff;left:11px;top:6px}.check[data-v-67fd4b98]:after{content:"";position:absolute;width:3px;height:3px;background-color:#fff;left:8px;top:12px}.cross[data-v-67fd4b98]{display:inline-block;width:17px;height:16px;position:relative}.cross[data-v-67fd4b98]:after,.cross[data-v-67fd4b98]:before{position:absolute;left:8px;content:" ";height:16px;width:2px;background-color:#fff}.cross[data-v-67fd4b98]:before{transform:rotate(45deg);will-change:transform}.cross[data-v-67fd4b98]:after{transform:rotate(-45deg);will-change:transform}',""])},function(e,t){function n(e,t){var n=e[1]||"",o=e[3];if(!o)return n;if(t&&"function"==typeof btoa){var a=r(o);return[n].concat(o.sources.map(function(e){return"/*# sourceURL="+o.sourceRoot+e+" */"})).concat([a]).join("\n")}return[n].join("\n")}function r(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var r=n(t,e);return t[2]?"@media "+t[2]+"{"+r+"}":r}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{for(var i=[],o=0;o
2 |
10 |
11 |
12 |
56 |
57 |
221 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const path = require("path");
3 | const PROD = process.env.NODE_ENV === "production";
4 |
5 | module.exports = {
6 | entry: path.resolve("./src/VueButtonSpinner.vue"),
7 |
8 | output: {
9 | path: path.resolve(__dirname, "dist"),
10 | filename: "vue-button-spinner.js",
11 |
12 | libraryTarget: "umd",
13 | library: "vue-button-spinner",
14 | umdNamedDefine: true
15 | },
16 |
17 | module: {
18 | loaders: [
19 | {
20 | test: /\.vue$/,
21 | loader: "vue-loader",
22 | options: {
23 | loaders: {
24 | js: {
25 | loader: "babel-loader",
26 | options: {
27 | presets: ["env"]
28 | }
29 | }
30 | }
31 | }
32 | }
33 | ]
34 | },
35 |
36 | plugins: [
37 | new webpack.optimize.UglifyJsPlugin({
38 | minimize: PROD ? true : false,
39 | sourceMap: PROD ? false : true,
40 | mangle: PROD ? true : false,
41 | compress: {
42 | warnings: PROD ? false : true
43 | }
44 | })
45 | ]
46 | };
47 |
--------------------------------------------------------------------------------