├── static
├── .gitkeep
├── example1.gif
├── example2.gif
├── example3.gif
└── example4.gif
├── .github
├── FUNDING.yml
└── workflows
│ ├── node.js.yml
│ └── deploy-on-merge.yml
├── public
├── favicon.ico
└── index.html
├── src
├── assets
│ └── logo.png
├── components
│ ├── css
│ │ ├── base.css
│ │ ├── dual-ring.css
│ │ ├── pulse.css
│ │ ├── ripple.css
│ │ ├── loadbar.css
│ │ ├── circle-solid-spin.css
│ │ ├── facebook.css
│ │ ├── hourglass.css
│ │ ├── clock.css
│ │ ├── hydrogen.css
│ │ ├── ring.css
│ │ ├── wordpress.css
│ │ ├── double-bounce.css
│ │ ├── rotating-plane.css
│ │ ├── three-bounce.css
│ │ ├── heart.css
│ │ ├── ellipsis.css
│ │ ├── wave.css
│ │ ├── chasing-dots.css
│ │ ├── grid.css
│ │ ├── fade-in.css
│ │ ├── circle-fade.css
│ │ ├── loaders-css.css
│ │ ├── cube-grid.css
│ │ ├── wandering-cubes.css
│ │ ├── roller.css
│ │ ├── moon.css
│ │ ├── folding-cube.css
│ │ ├── circle.css
│ │ ├── fading-circle.css
│ │ └── loaders.css
│ ├── Spinner.vue
│ └── spinners.js
├── main.js
├── index.js
└── Example.vue
├── babel.config.js
├── .npmignore
├── .gitignore
├── index.html
├── vite.example.config.js
├── .eslintrc.js
├── postcss.config.js
├── vite.config.js
├── LICENSE
├── test
└── smoke.js
├── package.json
├── postcss-plugins.js
└── README.md
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: tonpc64
2 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/static/example1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/static/example1.gif
--------------------------------------------------------------------------------
/static/example2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/static/example2.gif
--------------------------------------------------------------------------------
/static/example3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/static/example3.gif
--------------------------------------------------------------------------------
/static/example4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TonPC64/vue-spinkit/HEAD/static/example4.gif
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | ['@babel/preset-env', { targets: { node: 'current' } }]
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/css/base.css:
--------------------------------------------------------------------------------
1 | .sk-spinner {
2 | color: #333;
3 | }
4 |
5 | .sk-spinner > div {
6 | background-color: currentColor;
7 | }
8 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /public/
2 | /src/
3 | /build/
4 | /config/
5 | /static/
6 | .babelrc
7 | .editconfig
8 | .eslintignore
9 | .eslintrc.js
10 | .postcssrc.js
11 | bili.config.js
12 | index.html
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /build
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-spinkit (dev)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './Example.vue'
3 | // Import the library entry for its side-effects (injects CSS at runtime).
4 | // This keeps example styles working during dev without emitting a separate CSS file during library build.
5 | import './index.js'
6 |
7 | Vue.config.productionTip = false
8 |
9 | new Vue({
10 | render: h => h(App),
11 | }).$mount('#app')
12 |
--------------------------------------------------------------------------------
/vite.example.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import vue from '@vitejs/plugin-vue2'
3 |
4 | // This config builds the example app (index.html + src) into `dist/` for hosting.
5 | export default defineConfig({
6 | plugins: [vue()],
7 | root: process.cwd(),
8 | build: {
9 | outDir: 'dist',
10 | emptyOutDir: true,
11 | rollupOptions: {
12 | input: 'index.html'
13 | }
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/src/components/css/dual-ring.css:
--------------------------------------------------------------------------------
1 | .sk-dual-ring {
2 | display: inline-block;
3 | width: 64px;
4 | height: 64px;
5 | }
6 |
7 | .sk-dual-ring:after {
8 | content: " ";
9 | display: block;
10 | width: 46px;
11 | height: 46px;
12 | margin: 1px;
13 | border-radius: 50%;
14 | border: 5px solid currentColor;
15 | border-color: currentColor transparent currentColor transparent;
16 | animation: sk-dual-ring 1.2s linear infinite;
17 | }
18 |
19 | @keyframes sk-dual-ring {
20 | 0% {
21 | transform: rotate(0deg);
22 | }
23 | 100% {
24 | transform: rotate(360deg);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true,
5 | es6: true
6 | },
7 | extends: [
8 | 'eslint:recommended',
9 | 'plugin:vue/essential'
10 | ],
11 | parserOptions: {
12 | parser: '@babel/eslint-parser',
13 | ecmaVersion: 2020,
14 | sourceType: 'module',
15 | requireConfigFile: false,
16 | babelOptions: {
17 | presets: ['@babel/preset-env']
18 | }
19 | },
20 | rules: {
21 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
22 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
23 | 'vue/multi-word-component-names': 'off'
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/css/pulse.css:
--------------------------------------------------------------------------------
1 | .sk-pulse > div {
2 | width: 27px;
3 | height: 27px;
4 | background-color: currentColor;
5 | border-radius: 100%;
6 |
7 | -webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
8 | animation: sk-scaleout 1.0s infinite ease-in-out;
9 | }
10 |
11 | @-webkit-keyframes sk-scaleout {
12 | 0% { -webkit-transform: scale(0.0) }
13 | 100% {
14 | -webkit-transform: scale(1.0);
15 | opacity: 0;
16 | }
17 | }
18 |
19 | @keyframes sk-scaleout {
20 | 0% {
21 | transform: scale(0.0);
22 | -webkit-transform: scale(0.0);
23 | } 100% {
24 | transform: scale(1.0);
25 | -webkit-transform: scale(1.0);
26 | opacity: 0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/css/ripple.css:
--------------------------------------------------------------------------------
1 | .sk-ripple {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-ripple div {
8 | position: absolute;
9 | border: 4px solid currentColor;
10 | opacity: 1;
11 | border-radius: 50%;
12 | animation: sk-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
13 | }
14 | .sk-ripple div:nth-child(2) {
15 | animation-delay: -0.5s;
16 | }
17 | @keyframes sk-ripple {
18 | 0% {
19 | top: 28px;
20 | left: 28px;
21 | width: 0;
22 | height: 0;
23 | opacity: 1;
24 | }
25 | 100% {
26 | top: -1px;
27 | left: -1px;
28 | width: 58px;
29 | height: 58px;
30 | opacity: 0;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/css/loadbar.css:
--------------------------------------------------------------------------------
1 | .sk-loadbar {
2 | width: 50px;
3 | height: 18px;
4 | border: 1px currentColor solid;
5 | border-radius: 4px;
6 | background: linear-gradient(-60deg, transparent 0%, transparent 50%, currentColor 50%, currentColor 75%, transparent 75%, transparent);
7 | background-size: 20px 30px;
8 | background-position: 0px 0px;
9 | -webkit-animation: skLoadBar 0.8s infinite linear;
10 | animation: skLoadBar 0.8s infinite linear;
11 | }
12 | @-webkit-keyframes skLoadBar {
13 | from { background-position: 0px 0px; }
14 | to { background-position: -20px 0px; }
15 | }
16 | @keyframes skLoadBar {
17 | from { background-position: 0px 0px; }
18 | to { background-position: -20px 0px; }
19 | }
20 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | <%= htmlWebpackPlugin.options.title %>
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/components/css/circle-solid-spin.css:
--------------------------------------------------------------------------------
1 | .sk-circle-solid-spin {
2 | display: inline-block;
3 | transform: translateZ(1px);
4 | }
5 |
6 | .sk-circle-solid-spin > div {
7 | display: inline-block;
8 | width: 51px;
9 | height: 51px;
10 | margin: 6px;
11 | border-radius: 50%;
12 | animation: sk-circle-solid-spin 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite;
13 | }
14 |
15 | @keyframes sk-circle-solid-spin {
16 | 0%, 100% {
17 | animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5);
18 | }
19 | 0% {
20 | transform: rotateY(0deg);
21 | }
22 | 50% {
23 | transform: rotateY(1800deg);
24 | animation-timing-function: cubic-bezier(0, 0.5, 0.5, 1);
25 | }
26 | 100% {
27 | transform: rotateY(3600deg);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/components/css/facebook.css:
--------------------------------------------------------------------------------
1 | .sk-facebook {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-facebook div {
8 | display: inline-block;
9 | position: absolute;
10 | left: 6px;
11 | width: 13px;
12 | background: currentColor;
13 | animation: sk-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
14 | }
15 | .sk-facebook div:nth-child(1) {
16 | left: 6px;
17 | animation-delay: -0.24s;
18 | }
19 | .sk-facebook div:nth-child(2) {
20 | left: 26px;
21 | animation-delay: -0.12s;
22 | }
23 | .sk-facebook div:nth-child(3) {
24 | left: 45px;
25 | animation-delay: 0;
26 | }
27 | @keyframes sk-facebook {
28 | 0% {
29 | top: 6px;
30 | height: 51px;
31 | }
32 | 50%, 100% {
33 | top: 19px;
34 | height: 26px;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | name: Node.js CI
2 |
3 | on:
4 | pull_request:
5 | branches: [ master ]
6 |
7 | jobs:
8 | build:
9 |
10 | runs-on: ubuntu-latest
11 |
12 | strategy:
13 | matrix:
14 | node-version: [18.x, 20.x, 22.x]
15 |
16 | steps:
17 | - uses: actions/checkout@v4
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 | cache: 'npm'
23 | - name: Install dependencies
24 | run: npm ci
25 | - name: Run ESLint
26 | run: npm run lint
27 | - name: Build library
28 | run: npm run build
29 | - name: Build example (for deploy)
30 | run: npm run build:example
31 | - name: Run smoke test
32 | run: npm test
33 |
--------------------------------------------------------------------------------
/src/components/css/hourglass.css:
--------------------------------------------------------------------------------
1 | .sk-hourglass {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-hourglass:after {
8 | content: " ";
9 | display: block;
10 | border-radius: 50%;
11 | width: 0;
12 | height: 0;
13 | margin: 6px;
14 | box-sizing: border-box;
15 | border: 26px solid currentColor;
16 | border-color: currentColor transparent currentColor transparent;
17 | animation: sk-hourglass 1.2s infinite;
18 | }
19 | @keyframes sk-hourglass {
20 | 0% {
21 | transform: rotate(0);
22 | animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
23 | }
24 | 50% {
25 | transform: rotate(900deg);
26 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
27 | }
28 | 100% {
29 | transform: rotate(1800deg);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/css/clock.css:
--------------------------------------------------------------------------------
1 | .sk-clock {
2 | border: 1px currentColor solid;
3 | border-radius: 50%;
4 | position: relative;
5 | height: 30px;
6 | width: 30px;
7 | }
8 | .sk-clock:before {
9 | content:'';
10 | border-left: 1px currentColor solid;
11 | position: absolute;
12 | top: 2px;
13 | width: 1px;
14 | height: calc( 50% - 2px );
15 | -webkit-transform: rotate(0deg);
16 | transform: rotate(0deg);
17 | -ms-transform-origin: 0% 100%;
18 | -webkit-transform-origin: 0% 100%;
19 | transform-origin: 0% 100%;
20 | -webkit-animation: skClock 1s infinite linear;
21 | animation: skClock 1s infinite linear;
22 | }
23 | @-webkit-keyframes skClock {
24 | from { -webkit-transform: rotate(0deg); }
25 | to { -webkit-transform: rotate(359deg); }
26 | }
27 | @keyframes skClock {
28 | from { transform: rotate(0deg); }
29 | to { transform: rotate(359deg); }
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/css/hydrogen.css:
--------------------------------------------------------------------------------
1 | .sk-hydrogen {
2 | position: relative;
3 | border: 1px currentColor solid;
4 | border-radius: 50%;
5 | -webkit-animation: skHydro 0.6s infinite linear;
6 | animation: skHydro 0.6s infinite linear;
7 | height: 30px;
8 | width: 30px;
9 | }
10 | .sk-hydrogen:before, .sk-hydrogen:after {
11 | content: '';
12 | position: absolute;
13 | width: 10px;
14 | height: 10px;
15 | background-color: currentColor;
16 | border-radius: 50%;
17 | }
18 | .sk-hydrogen:before {
19 | top: calc( 50% - 5px );
20 | left: calc( 50% - 5px );
21 | }
22 | .sk-hydrogen:after {
23 | top: -1px;
24 | left: -1px;
25 | }
26 | @-webkit-keyframes skHydro {
27 | from { -webkit-transform: rotate(0deg); }
28 | to { -webkit-transform: rotate(359deg); }
29 | }
30 | @keyframes skHydro {
31 | from { transform: rotate(0deg); }
32 | to { transform: rotate(359deg); }
33 | }
34 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | // Modern PostCSS 8 plugins to replace deprecated ones
2 | const trimPlugin = () => {
3 | return {
4 | postcssPlugin: 'vue-scoped-trim',
5 | Once(root) {
6 | // Clean up empty rules and whitespace
7 | root.walkRules(rule => {
8 | if (rule.nodes && rule.nodes.length === 0) {
9 | rule.remove()
10 | }
11 | })
12 | }
13 | }
14 | }
15 | trimPlugin.postcss = true
16 |
17 | const addIdPlugin = () => {
18 | return {
19 | postcssPlugin: 'vue-scoped-id',
20 | Rule() {
21 | // Scoped CSS functionality - handled by Vue SFC compiler
22 | // This plugin is mainly a placeholder to prevent deprecated warnings
23 | }
24 | }
25 | }
26 | addIdPlugin.postcss = true
27 |
28 | module.exports = {
29 | plugins: [
30 | require('autoprefixer'),
31 | trimPlugin(),
32 | addIdPlugin()
33 | ]
34 | }
--------------------------------------------------------------------------------
/src/components/css/ring.css:
--------------------------------------------------------------------------------
1 | .sk-ring {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-ring div {
8 | background: transparent;
9 | box-sizing: border-box;
10 | display: block;
11 | position: absolute;
12 | width: 51px;
13 | height: 51px;
14 | margin: 6px;
15 | border: 6px solid currentColor;
16 | border-radius: 50%;
17 | animation: sk-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
18 | border-color: currentColor transparent transparent transparent;
19 | }
20 | .sk-ring div:nth-child(1) {
21 | animation-delay: -0.45s;
22 | }
23 | .sk-ring div:nth-child(2) {
24 | animation-delay: -0.3s;
25 | }
26 | .sk-ring div:nth-child(3) {
27 | animation-delay: -0.15s;
28 | }
29 | @keyframes sk-ring {
30 | 0% {
31 | transform: rotate(0deg);
32 | }
33 | 100% {
34 | transform: rotate(360deg);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/css/wordpress.css:
--------------------------------------------------------------------------------
1 | .sk-wordpress > div {
2 | width: 27px;
3 | height: 27px;
4 | background-color: currentColor;
5 | display: inline-block;
6 | border-radius: 27px;
7 | position: relative;
8 |
9 | -webkit-animation: sk-inner-circle 1s linear infinite;
10 | animation: sk-inner-circle 1s linear infinite;
11 | }
12 |
13 | .sk-wordpress > div::after {
14 | content: '';
15 | display: block;
16 | background-color: #fff;
17 | width: 8px;
18 | height: 8px;
19 | position: absolute;
20 | border-radius: 8px;
21 | top: 5px;
22 | left: 5px;
23 | }
24 |
25 | @-webkit-keyframes sk-inner-circle {
26 | 0% { -webkit-transform: rotate(0); }
27 | 100% { -webkit-transform: rotate(360deg); }
28 | }
29 |
30 | @keyframes sk-inner-circle {
31 | 0% { transform: rotate(0); -webkit-transform:rotate(0); }
32 | 100% { transform: rotate(360deg); -webkit-transform:rotate(360deg); }
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/css/double-bounce.css:
--------------------------------------------------------------------------------
1 | .sk-double-bounce {
2 | width: 27px;
3 | height: 27px;
4 | position: relative;
5 | }
6 |
7 | .sk-double-bounce > div {
8 | width: 100%;
9 | height: 100%;
10 | border-radius: 50%;
11 | background-color: currentColor;
12 | opacity: 0.6;
13 | position: absolute;
14 | top: 0;
15 | left: 0;
16 |
17 | -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
18 | animation: sk-bounce 2.0s infinite ease-in-out;
19 | }
20 |
21 | .sk-double-bounce > div:last-child {
22 | -webkit-animation-delay: -1.0s;
23 | animation-delay: -1.0s;
24 | }
25 |
26 | @-webkit-keyframes sk-bounce {
27 | 0%, 100% { -webkit-transform: scale(0.0) }
28 | 50% { -webkit-transform: scale(1.0) }
29 | }
30 |
31 | @keyframes sk-bounce {
32 | 0%, 100% {
33 | transform: scale(0.0);
34 | -webkit-transform: scale(0.0);
35 | } 50% {
36 | transform: scale(1.0);
37 | -webkit-transform: scale(1.0);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/css/rotating-plane.css:
--------------------------------------------------------------------------------
1 | .sk-rotating-plane > div {
2 | width: 27px;
3 | height: 27px;
4 | background-color: currentColor;
5 |
6 | -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
7 | animation: sk-rotateplane 1.2s infinite ease-in-out;
8 | }
9 |
10 | @-webkit-keyframes sk-rotateplane {
11 | 0% { -webkit-transform: perspective(120px) }
12 | 50% { -webkit-transform: perspective(120px) rotateY(180deg) }
13 | 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
14 | }
15 |
16 | @keyframes sk-rotateplane {
17 | 0% {
18 | transform: perspective(120px) rotateX(0deg) rotateY(0deg);
19 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
20 | } 50% {
21 | transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
22 | -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
23 | } 100% {
24 | transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
25 | -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import vue from '@vitejs/plugin-vue2'
3 |
4 | export default defineConfig({
5 | plugins: [vue()],
6 | css: {
7 | postcss: {
8 | plugins: [
9 | require('autoprefixer')
10 | ]
11 | }
12 | },
13 | build: {
14 | outDir: 'build',
15 | minify: 'terser',
16 | terserOptions: {
17 | compress: {
18 | drop_console: true,
19 | drop_debugger: true,
20 | pure_funcs: ['console.log']
21 | }
22 | },
23 | lib: {
24 | entry: 'src/index.js',
25 | name: 'VueSpinkit',
26 | fileName: 'vue-spinkit.common',
27 | formats: ['umd']
28 | },
29 | rollupOptions: {
30 | external: ['vue'],
31 | output: {
32 | inlineDynamicImports: true,
33 | // force a single filename for the library bundle so it matches package.json "main"
34 | entryFileNames: 'vue-spinkit.common.js',
35 | exports: 'named',
36 | globals: {
37 | vue: 'Vue'
38 | }
39 | }
40 | },
41 | cssCodeSplit: false
42 | }
43 | })
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Pongsatorn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/components/css/three-bounce.css:
--------------------------------------------------------------------------------
1 | .sk-three-bounce {
2 | height: 18px;
3 | }
4 |
5 | .sk-three-bounce > div {
6 | width: 18px;
7 | height: 18px;
8 | background-color: currentColor;
9 | border-radius: 100%;
10 | display: inline-block;
11 |
12 | -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out;
13 | animation: sk-bouncedelay 1.4s infinite ease-in-out;
14 | /* Prevent first frame from flickering when animation starts */
15 | -webkit-animation-fill-mode: both;
16 | animation-fill-mode: both;
17 | }
18 |
19 | .sk-three-bounce > div:first-child {
20 | -webkit-animation-delay: -0.32s;
21 | animation-delay: -0.32s;
22 | }
23 |
24 | .sk-three-bounce > div:nth-child(2) {
25 | -webkit-animation-delay: -0.16s;
26 | animation-delay: -0.16s;
27 | }
28 |
29 | @-webkit-keyframes sk-bouncedelay {
30 | 0%, 80%, 100% { -webkit-transform: scale(0.0) }
31 | 40% { -webkit-transform: scale(1.0) }
32 | }
33 |
34 | @keyframes sk-bouncedelay {
35 | 0%, 80%, 100% {
36 | transform: scale(0.0);
37 | -webkit-transform: scale(0.0);
38 | } 40% {
39 | transform: scale(1.0);
40 | -webkit-transform: scale(1.0);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/css/heart.css:
--------------------------------------------------------------------------------
1 | .sk-heart {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | transform: rotate(45deg);
7 | transform-origin: 32px 32px;
8 | }
9 | .sk-heart div {
10 | top: 23px;
11 | left: 19px;
12 | position: absolute;
13 | width: 26px;
14 | height: 26px;
15 | background: currentColor;
16 | animation: sk-heart 1.2s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
17 | }
18 | .sk-heart div:after,
19 | .sk-heart div:before {
20 | content: " ";
21 | position: absolute;
22 | display: block;
23 | width: 26px;
24 | height: 26px;
25 | background: currentColor;
26 | }
27 | .sk-heart div:before {
28 | left: -17px;
29 | border-radius: 50% 0 0 50%;
30 | }
31 | .sk-heart div:after {
32 | top: -17px;
33 | border-radius: 50% 50% 0 0;
34 | }
35 | @keyframes sk-heart {
36 | 0% {
37 | transform: scale(0.95);
38 | }
39 | 5% {
40 | transform: scale(1.1);
41 | }
42 | 39% {
43 | transform: scale(0.85);
44 | }
45 | 45% {
46 | transform: scale(1);
47 | }
48 | 60% {
49 | transform: scale(0.95);
50 | }
51 | 100% {
52 | transform: scale(0.9);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/css/ellipsis.css:
--------------------------------------------------------------------------------
1 | .sk-ellipsis {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-ellipsis div {
8 | position: absolute;
9 | top: 27px;
10 | width: 11px;
11 | height: 11px;
12 | border-radius: 50%;
13 | animation-timing-function: cubic-bezier(0, 1, 1, 0);
14 | }
15 | .sk-ellipsis div:nth-child(1) {
16 | left: 6px;
17 | animation: sk-ellipsis1 0.6s infinite;
18 | }
19 | .sk-ellipsis div:nth-child(2) {
20 | left: 6px;
21 | animation: sk-ellipsis2 0.6s infinite;
22 | }
23 | .sk-ellipsis div:nth-child(3) {
24 | left: 26px;
25 | animation: sk-ellipsis2 0.6s infinite;
26 | }
27 | .sk-ellipsis div:nth-child(4) {
28 | left: 45px;
29 | animation: sk-ellipsis3 0.6s infinite;
30 | }
31 | @keyframes sk-ellipsis1 {
32 | 0% {
33 | transform: scale(0);
34 | }
35 | 100% {
36 | transform: scale(1);
37 | }
38 | }
39 | @keyframes sk-ellipsis3 {
40 | 0% {
41 | transform: scale(1);
42 | }
43 | 100% {
44 | transform: scale(0);
45 | }
46 | }
47 | @keyframes sk-ellipsis2 {
48 | 0% {
49 | transform: translate(0, 0);
50 | }
51 | 100% {
52 | transform: translate(19px, 0);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/css/wave.css:
--------------------------------------------------------------------------------
1 | .sk-wave {
2 | width: 50px;
3 | height: 40px;
4 | text-align: center;
5 | font-size: 10px;
6 | }
7 |
8 | .sk-wave > div {
9 | background-color: currentColor;
10 | height: 100%;
11 | width: 6px;
12 | margin: 0 3px 0 0;
13 | display: inline-block;
14 |
15 | -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
16 | animation: sk-stretchdelay 1.2s infinite ease-in-out;
17 | }
18 |
19 | .sk-wave > div:nth-child(2) {
20 | -webkit-animation-delay: -1.1s;
21 | animation-delay: -1.1s;
22 | }
23 |
24 | .sk-wave > div:nth-child(3) {
25 | -webkit-animation-delay: -1.0s;
26 | animation-delay: -1.0s;
27 | }
28 |
29 | .sk-wave > div:nth-child(4) {
30 | -webkit-animation-delay: -0.9s;
31 | animation-delay: -0.9s;
32 | }
33 |
34 | .sk-wave > div:nth-child(5) {
35 | -webkit-animation-delay: -0.8s;
36 | animation-delay: -0.8s;
37 | }
38 |
39 | @-webkit-keyframes sk-stretchdelay {
40 | 0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
41 | 20% { -webkit-transform: scaleY(1.0) }
42 | }
43 |
44 | @keyframes sk-stretchdelay {
45 | 0%, 40%, 100% {
46 | transform: scaleY(0.4);
47 | -webkit-transform: scaleY(0.4);
48 | } 20% {
49 | transform: scaleY(1.0);
50 | -webkit-transform: scaleY(1.0);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/css/chasing-dots.css:
--------------------------------------------------------------------------------
1 | .sk-chasing-dots {
2 | width: 27px;
3 | height: 27px;
4 | position: relative;
5 |
6 | -webkit-animation: sk-rotate 2.0s infinite linear;
7 | animation: sk-rotate 2.0s infinite linear;
8 | }
9 |
10 | .sk-chasing-dots > div {
11 | width: 60%;
12 | height: 60%;
13 | display: inline-block;
14 | position: absolute;
15 | top: 0;
16 | background-color: currentColor;
17 | border-radius: 100%;
18 |
19 | -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
20 | animation: sk-bounce 2.0s infinite ease-in-out;
21 | }
22 |
23 | .sk-chasing-dots > div:last-child {
24 | top: auto;
25 | bottom: 0;
26 |
27 | -webkit-animation-delay: -1.0s;
28 | animation-delay: -1.0s;
29 | }
30 |
31 | @-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) }}
32 | @keyframes sk-rotate {
33 | 100% {
34 | transform: rotate(360deg);
35 | -webkit-transform: rotate(360deg);
36 | }
37 | }
38 |
39 | @-webkit-keyframes sk-bounce {
40 | 0%, 100% { -webkit-transform: scale(0.0) }
41 | 50% { -webkit-transform: scale(1.0) }
42 | }
43 |
44 | @keyframes sk-bounce {
45 | 0%, 100% {
46 | transform: scale(0.0);
47 | -webkit-transform: scale(0.0);
48 | } 50% {
49 | transform: scale(1.0);
50 | -webkit-transform: scale(1.0);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/css/grid.css:
--------------------------------------------------------------------------------
1 | .sk-grid {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-grid div {
8 | position: absolute;
9 | width: 13px;
10 | height: 13px;
11 | border-radius: 50%;
12 | animation: sk-grid 1.2s linear infinite;
13 | }
14 | .sk-grid div:nth-child(1) {
15 | top: 6px;
16 | left: 6px;
17 | animation-delay: 0s;
18 | }
19 | .sk-grid div:nth-child(2) {
20 | top: 6px;
21 | left: 26px;
22 | animation-delay: -0.4s;
23 | }
24 | .sk-grid div:nth-child(3) {
25 | top: 6px;
26 | left: 45px;
27 | animation-delay: -0.8s;
28 | }
29 | .sk-grid div:nth-child(4) {
30 | top: 26px;
31 | left: 6px;
32 | animation-delay: -0.4s;
33 | }
34 | .sk-grid div:nth-child(5) {
35 | top: 26px;
36 | left: 26px;
37 | animation-delay: -0.8s;
38 | }
39 | .sk-grid div:nth-child(6) {
40 | top: 26px;
41 | left: 45px;
42 | animation-delay: -1.2s;
43 | }
44 | .sk-grid div:nth-child(7) {
45 | top: 45px;
46 | left: 6px;
47 | animation-delay: -0.8s;
48 | }
49 | .sk-grid div:nth-child(8) {
50 | top: 45px;
51 | left: 26px;
52 | animation-delay: -1.2s;
53 | }
54 | .sk-grid div:nth-child(9) {
55 | top: 45px;
56 | left: 45px;
57 | animation-delay: -1.6s;
58 | }
59 | @keyframes sk-grid {
60 | 0%, 100% {
61 | opacity: 1;
62 | }
63 | 50% {
64 | opacity: 0.5;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/components/css/fade-in.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes sk-fade-in {
2 | 0% {
3 | opacity: 0;
4 | }
5 | 50% {
6 | opacity: 0;
7 | }
8 | 100% {
9 | opacity: 1;
10 | }
11 | }
12 |
13 | @-moz-keyframes sk-fade-in {
14 | 0% {
15 | opacity: 0;
16 | }
17 | 50% {
18 | opacity: 0;
19 | }
20 | 100% {
21 | opacity: 1;
22 | }
23 | }
24 |
25 | @-ms-keyframes sk-fade-in {
26 | 0% {
27 | opacity: 0;
28 | }
29 | 50% {
30 | opacity: 0;
31 | }
32 | 100% {
33 | opacity: 1;
34 | }
35 | }
36 |
37 | @keyframes sk-fade-in {
38 | 0% {
39 | opacity: 0;
40 | }
41 | 50% {
42 | opacity: 0;
43 | }
44 | 100% {
45 | opacity: 1;
46 | }
47 | }
48 |
49 | .sk-fade-in {
50 | -webkit-animation: sk-fade-in 2s;
51 | -moz-animation: sk-fade-in 2s;
52 | -o-animation: sk-fade-in 2s;
53 | -ms-animation: sk-fade-in 2s;
54 | animation: sk-fade-in 2s;
55 | }
56 |
57 | .sk-fade-in-half-second {
58 | -webkit-animation: sk-fade-in 1s;
59 | -moz-animation: sk-fade-in 1s;
60 | -o-animation: sk-fade-in 1s;
61 | -ms-animation: sk-fade-in 1s;
62 | animation: sk-fade-in 1s;
63 | }
64 |
65 | .sk-fade-in-quarter-second {
66 | -webkit-animation: sk-fade-in 0.5s;
67 | -moz-animation: sk-fade-in 0.5s;
68 | -o-animation: sk-fade-in 0.5s;
69 | -ms-animation: sk-fade-in 0.5s;
70 | animation: sk-fade-in 0.5s;
71 | }
72 |
--------------------------------------------------------------------------------
/src/components/css/circle-fade.css:
--------------------------------------------------------------------------------
1 | .sk-circle-fade {
2 | font-size: 10px;
3 | text-indent: -9999em;
4 | width: 32px;
5 | height: 32px;
6 | border-radius: 50%;
7 | background: currentColor;
8 | background: linear-gradient(to right, currentColor 10%, rgba(255, 255, 255, 0) 42%);
9 | position: relative;
10 | -webkit-animation: circleRotate 1.4s infinite linear;
11 | animation: circleRotate 1.4s infinite linear;
12 | -webkit-transform: translateZ(0);
13 | -ms-transform: translateZ(0);
14 | transform: translateZ(0);
15 | }
16 | .sk-circle-fade:before {
17 | width: 50%;
18 | height: 50%;
19 | background: currentColor;
20 | border-radius: 100% 0 0 0;
21 | position: absolute;
22 | top: 0;
23 | left: 0;
24 | content: '';
25 | }
26 | .sk-circle-fade:after {
27 | background: #fff;
28 | width: 75%;
29 | height: 75%;
30 | border-radius: 50%;
31 | content: '';
32 | margin: auto;
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | bottom: 0;
37 | right: 0;
38 | }
39 | @-webkit-keyframes circleRotate {
40 | 0% {
41 | -webkit-transform: rotate(0deg);
42 | transform: rotate(0deg);
43 | }
44 | 100% {
45 | -webkit-transform: rotate(360deg);
46 | transform: rotate(360deg);
47 | }
48 | }
49 | @keyframes circleRotate {
50 | 0% {
51 | -webkit-transform: rotate(0deg);
52 | transform: rotate(0deg);
53 | }
54 | 100% {
55 | -webkit-transform: rotate(360deg);
56 | transform: rotate(360deg);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/test/smoke.js:
--------------------------------------------------------------------------------
1 | // Simple smoke test to verify the built library can be loaded
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | console.log('🧪 Running smoke test...');
6 |
7 | // Check if build files exist
8 | const buildDir = path.join(__dirname, '..', 'build');
9 | const jsFile = path.join(buildDir, 'vue-spinkit.common.js');
10 |
11 | if (!fs.existsSync(jsFile)) {
12 | console.error('❌ Built JavaScript file not found:', jsFile);
13 | process.exit(1);
14 | }
15 |
16 | // A separate CSS file is optional because the library may inject CSS into the JS bundle.
17 | // If present, we'll report its size; if not, that's fine.
18 | const cssFile = path.join(buildDir, 'style.css');
19 |
20 | // Check if the JS file can be required
21 | try {
22 | const VueSpinkit = require(jsFile);
23 | if (VueSpinkit && (VueSpinkit.default || VueSpinkit.Spinner)) {
24 | console.log('✅ Built library loads successfully');
25 | console.log('✅ JS file size:', (fs.statSync(jsFile).size / 1024).toFixed(2), 'KB');
26 | if (fs.existsSync(cssFile)) {
27 | console.log('ℹ️ Found separate CSS file. Size:', (fs.statSync(cssFile).size / 1024).toFixed(2), 'KB');
28 | } else {
29 | console.log('ℹ️ No separate CSS file found (styles may be injected by the JS bundle)');
30 | }
31 | } else {
32 | console.error('❌ Built library does not export expected components');
33 | process.exit(1);
34 | }
35 | } catch (error) {
36 | console.error('❌ Failed to load built library:', error.message);
37 | process.exit(1);
38 | }
39 |
40 | console.log('🎉 Smoke test passed!');
--------------------------------------------------------------------------------
/src/components/css/loaders-css.css:
--------------------------------------------------------------------------------
1 | .ball-triangle-path > div,
2 | .ball-scale-ripple-multiple > div,
3 | .ball-scale-ripple > div {
4 | background-color: initial;
5 | border-color: currentColor;
6 | }
7 |
8 | .ball-clip-rotate > div {
9 | background-color: initial;
10 | border-top-color: currentColor;
11 | border-right-color: currentColor;
12 | border-left-color: currentColor;
13 | }
14 |
15 | .ball-clip-rotate-pulse > div:first-child {
16 | background-color: currentColor;
17 | }
18 | .ball-clip-rotate-pulse > div:last-child {
19 | background-color: initial;
20 | border-top-color: currentColor;
21 | border-bottom-color: currentColor;
22 | }
23 |
24 | .ball-clip-rotate-multiple > div:first-child {
25 | background-color: initial;
26 | border-right-color: currentColor;
27 | border-left-color: currentColor;
28 | }
29 | .ball-clip-rotate-multiple > div:last-child {
30 | background-color: initial;
31 | border-top-color: currentColor;
32 | border-bottom-color: currentColor;
33 | }
34 |
35 | .triangle-skew-spin > div {
36 | background-color: initial;
37 | border-bottom-color: currentColor;
38 | }
39 |
40 | .pacman > div:nth-child(1),
41 | .pacman > div:nth-child(2) {
42 | background-color: initial;
43 | border-top-color: currentColor;
44 | border-left-color: currentColor;
45 | border-bottom-color: currentColor;
46 | }
47 |
48 | .pacman > div:nth-child(3),
49 | .pacman > div:nth-child(4),
50 | .pacman > div:nth-child(5) {
51 | background-color: currentColor;
52 | }
53 |
54 | .square-spin > div {
55 | background: currentColor;
56 | border-color: currentColor;
57 | }
58 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-spinkit",
3 | "version": "2.1.5",
4 | "description": "A collection of loading indicators animated with CSS for VueJS",
5 | "author": "Chanwit Piromplad ",
6 | "scripts": {
7 | "serve": "vite",
8 | "dev": "vite",
9 | "build": "vite build",
10 | "build:example": "vite build --config vite.example.config.js",
11 | "deploy:surge": "surge dist vue-spinkit.surge.sh",
12 | "lint": "eslint --ext .js,.vue src",
13 | "test": "node test/smoke.js"
14 | },
15 | "main": "build/vue-spinkit.common.js",
16 | "files": [
17 | "build/vue-spinkit.common.js",
18 | "README.md",
19 | "LICENSE"
20 | ],
21 | "repository": {
22 | "type": "git",
23 | "url": "https://github.com/TonPC64/vue-spinkit.git"
24 | },
25 | "homepage": "http://vue-spinkit.surge.sh",
26 | "keywords": [
27 | "spinkit",
28 | "vue-spinkit",
29 | "loading",
30 | "vue-loading"
31 | ],
32 | "devDependencies": {
33 | "@babel/core": "^7.23.6",
34 | "@babel/eslint-parser": "^7.23.6",
35 | "@babel/preset-env": "^7.23.6",
36 | "@vitejs/plugin-vue2": "^2.3.3",
37 | "autoprefixer": "^10.4.21",
38 | "eslint": "^8.57.1",
39 | "eslint-plugin-vue": "^9.33.0",
40 | "prismjs": "^1.25.0",
41 | "randomcolor": "^0.6.2",
42 | "terser": "^5.44.0",
43 | "vite": "^6.3.6",
44 | "vue": "^2.7.16",
45 | "vue-template-compiler": "^2.7.16"
46 | },
47 | "engines": {
48 | "node": ">=16"
49 | },
50 | "browserslist": [
51 | "> 1%",
52 | "last 2 versions",
53 | "not dead"
54 | ],
55 | "license": "MIT"
56 | }
57 |
--------------------------------------------------------------------------------
/src/components/css/cube-grid.css:
--------------------------------------------------------------------------------
1 | .sk-cube-grid {
2 | width: 39px;
3 | height: 39px;
4 | }
5 |
6 | .sk-cube-grid > div {
7 | width: 33%;
8 | height: 33%;
9 | background-color: currentColor;
10 | float: left;
11 |
12 |
13 | -webkit-animation: sk-scaleDelay 1.3s infinite ease-in-out;
14 | animation: sk-scaleDelay 1.3s infinite ease-in-out;
15 | }
16 |
17 | /*
18 | * Spinner positions
19 | * 1 2 3
20 | * 4 5 6
21 | * 7 8 9
22 | */
23 |
24 | .sk-cube-grid > div:nth-child(1) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s }
25 | .sk-cube-grid > div:nth-child(2) { -webkit-animation-delay: 0.3s; animation-delay: 0.3s }
26 | .sk-cube-grid > div:nth-child(3) { -webkit-animation-delay: 0.4s; animation-delay: 0.4s }
27 | .sk-cube-grid > div:nth-child(4) { -webkit-animation-delay: 0.1s; animation-delay: 0.1s }
28 | .sk-cube-grid > div:nth-child(5) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s }
29 | .sk-cube-grid > div:nth-child(6) { -webkit-animation-delay: 0.3s; animation-delay: 0.3s }
30 | .sk-cube-grid > div:nth-child(7) { -webkit-animation-delay: 0.0s; animation-delay: 0.0s }
31 | .sk-cube-grid > div:nth-child(8) { -webkit-animation-delay: 0.1s; animation-delay: 0.1s }
32 | .sk-cube-grid > div:nth-child(9) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s }
33 |
34 | @-webkit-keyframes sk-scaleDelay {
35 | 0%, 70%, 100% { -webkit-transform:scale3D(1.0, 1.0, 1.0) }
36 | 35% { -webkit-transform:scale3D(0.0, 0.0, 1.0) }
37 | }
38 |
39 | @keyframes sk-scaleDelay {
40 | 0%, 70%, 100% { -webkit-transform:scale3D(1.0, 1.0, 1.0); transform:scale3D(1.0, 1.0, 1.0) }
41 | 35% { -webkit-transform:scale3D(0.0, 0.0, 1.0); transform:scale3D(0.0, 0.0, 1.0) }
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/css/wandering-cubes.css:
--------------------------------------------------------------------------------
1 | .sk-wandering-cubes {
2 | width: 52px;
3 | height: 52px;
4 | position: relative;
5 | }
6 |
7 | .sk-wandering-cubes > div {
8 | background-color: currentColor;
9 | width: 10px;
10 | height: 10px;
11 | position: absolute;
12 | top: 0;
13 | left: 0;
14 |
15 | -webkit-animation: sk-cubemove 1.8s infinite ease-in-out;
16 | animation: sk-cubemove 1.8s infinite ease-in-out;
17 | }
18 |
19 | .sk-wandering-cubes > div:last-child {
20 | -webkit-animation-delay: -0.9s;
21 | animation-delay: -0.9s;
22 | }
23 |
24 | @-webkit-keyframes sk-cubemove {
25 | 25% { -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5) }
26 | 50% { -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg) }
27 | 75% { -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5) }
28 | 100% { -webkit-transform: rotate(-360deg) }
29 | }
30 |
31 | @keyframes sk-cubemove {
32 | 25% {
33 | transform: translateX(42px) rotate(-90deg) scale(0.5);
34 | -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5);
35 | } 50% {
36 | /* Hack to make FF rotate in the right direction */
37 | transform: translateX(42px) translateY(42px) rotate(-179deg);
38 | -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg);
39 | } 50.1% {
40 | transform: translateX(42px) translateY(42px) rotate(-180deg);
41 | -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg);
42 | } 75% {
43 | transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5);
44 | -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5);
45 | } 100% {
46 | transform: rotate(-360deg);
47 | -webkit-transform: rotate(-360deg);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/components/css/roller.css:
--------------------------------------------------------------------------------
1 | .sk-roller {
2 | display: inline-block;
3 | position: relative;
4 | width: 64px;
5 | height: 64px;
6 | }
7 | .sk-roller div {
8 | animation: sk-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
9 | transform-origin: 32px 32px;
10 | }
11 | .sk-roller div:after {
12 | content: " ";
13 | display: block;
14 | position: absolute;
15 | width: 6px;
16 | height: 6px;
17 | border-radius: 50%;
18 | background: currentColor;
19 | margin: -3px 0 0 -3px;
20 | }
21 | .sk-roller div:nth-child(1) {
22 | animation-delay: -0.036s;
23 | }
24 | .sk-roller div:nth-child(1):after {
25 | top: 50px;
26 | left: 50px;
27 | }
28 | .sk-roller div:nth-child(2) {
29 | animation-delay: -0.072s;
30 | }
31 | .sk-roller div:nth-child(2):after {
32 | top: 54px;
33 | left: 45px;
34 | }
35 | .sk-roller div:nth-child(3) {
36 | animation-delay: -0.108s;
37 | }
38 | .sk-roller div:nth-child(3):after {
39 | top: 57px;
40 | left: 39px;
41 | }
42 | .sk-roller div:nth-child(4) {
43 | animation-delay: -0.144s;
44 | }
45 | .sk-roller div:nth-child(4):after {
46 | top: 58px;
47 | left: 32px;
48 | }
49 | .sk-roller div:nth-child(5) {
50 | animation-delay: -0.18s;
51 | }
52 | .sk-roller div:nth-child(5):after {
53 | top: 57px;
54 | left: 25px;
55 | }
56 | .sk-roller div:nth-child(6) {
57 | animation-delay: -0.216s;
58 | }
59 | .sk-roller div:nth-child(6):after {
60 | top: 54px;
61 | left: 19px;
62 | }
63 | .sk-roller div:nth-child(7) {
64 | animation-delay: -0.252s;
65 | }
66 | .sk-roller div:nth-child(7):after {
67 | top: 50px;
68 | left: 14px;
69 | }
70 | .sk-roller div:nth-child(8) {
71 | animation-delay: -0.288s;
72 | }
73 | .sk-roller div:nth-child(8):after {
74 | top: 45px;
75 | left: 10px;
76 | }
77 | @keyframes sk-roller {
78 | 0% {
79 | transform: rotate(0deg);
80 | }
81 | 100% {
82 | transform: rotate(360deg);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/components/css/moon.css:
--------------------------------------------------------------------------------
1 | .sk-moon {
2 | position: relative;
3 | width: 50px;
4 | height: 50px;
5 | overflow: hidden;
6 | margin:0px auto;
7 | }
8 |
9 | .sk-moon > div {
10 | margin: auto;
11 | position: absolute;
12 | top: 0;
13 | right: 0;
14 | bottom: 0;
15 | left: 0;
16 | width: 32px;
17 | height: 32px;
18 | background-color: transparent;
19 | box-sizing: border-box;
20 | -o-box-sizing: border-box;
21 | -ms-box-sizing: border-box;
22 | -webkit-box-sizing: border-box;
23 | -moz-box-sizing: border-box;
24 | box-shadow: 0 0 8px 1px currentColor;
25 | -o-box-shadow: 0 0 8px 1px currentColor;
26 | -ms-box-shadow: 0 0 8px 1px currentColor;
27 | -webkit-box-shadow: 0 0 8px 1px currentColor;
28 | -moz-box-shadow: 0 0 8px 1px currentColor;
29 | border-bottom: 10px solid currentColor;
30 | border-radius: 50%;
31 | -o-border-radius: 50%;
32 | -ms-border-radius: 50%;
33 | -webkit-border-radius: 50%;
34 | -moz-border-radius: 50%;
35 | animation: spin 1.15s ease infinite;
36 | -o-animation: spin 1.15s ease infinite;
37 | -ms-animation: spin 1.15s ease infinite;
38 | -webkit-animation: spin 1.15s ease infinite;
39 | -moz-animation: spin 1.15s ease infinite;
40 | }
41 |
42 |
43 | @keyframes spin {
44 | from {
45 | transform: rotate(0deg);
46 | }
47 | to {
48 | transform: rotate(360deg);
49 | }
50 | }
51 |
52 | @-o-keyframes spin {
53 | from {
54 | -o-transform: rotate(0deg);
55 | }
56 | to {
57 | -o-transform: rotate(360deg);
58 | }
59 | }
60 |
61 | @-ms-keyframes spin {
62 | from {
63 | -ms-transform: rotate(0deg);
64 | }
65 | to {
66 | -ms-transform: rotate(360deg);
67 | }
68 | }
69 |
70 | @-webkit-keyframes spin {
71 | from {
72 | -webkit-transform: rotate(0deg);
73 | }
74 | to {
75 | -webkit-transform: rotate(360deg);
76 | }
77 | }
78 |
79 | @-moz-keyframes spin {
80 | from {
81 | -moz-transform: rotate(0deg);
82 | }
83 | to {
84 | -moz-transform: rotate(360deg);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/components/Spinner.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
84 |
--------------------------------------------------------------------------------
/src/components/css/folding-cube.css:
--------------------------------------------------------------------------------
1 | .sk-folding-cube {
2 | width: 40px;
3 | height: 40px;
4 | position: relative;
5 |
6 | -webkit-transform: rotateZ(45deg);
7 | transform: rotateZ(45deg);
8 | }
9 |
10 | .sk-folding-cube > div {
11 | background-color: initial;
12 | float: left;
13 | width: 50%;
14 | height: 50%;
15 | position: relative;
16 |
17 | -webkit-transform: scale(1.1);
18 | -ms-transform: scale(1.1);
19 | transform: scale(1.1);
20 | }
21 | .sk-folding-cube > div::before {
22 | content: '';
23 | position: absolute;
24 | top: 0;
25 | left: 0;
26 | width: 100%;
27 | height: 100%;
28 | background-color: currentColor;
29 |
30 | -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
31 | animation: sk-foldCubeAngle 2.4s infinite linear both;
32 | -webkit-transform-origin: 100% 100%;
33 | -ms-transform-origin: 100% 100%;
34 | transform-origin: 100% 100%;
35 | }
36 | .sk-folding-cube > div:nth-child(2) {
37 | -webkit-transform: scale(1.1) rotateZ(90deg);
38 | transform: scale(1.1) rotateZ(90deg);
39 | }
40 | .sk-folding-cube > div:nth-child(4) {
41 | -webkit-transform: scale(1.1) rotateZ(180deg);
42 | transform: scale(1.1) rotateZ(180deg);
43 | }
44 | .sk-folding-cube > div:nth-child(3) {
45 | -webkit-transform: scale(1.1) rotateZ(270deg);
46 | transform: scale(1.1) rotateZ(270deg);
47 | }
48 | .sk-folding-cube > div:nth-child(2)::before {
49 | -webkit-animation-delay: 0.3s;
50 | animation-delay: 0.3s;
51 | }
52 | .sk-folding-cube > div:nth-child(4)::before {
53 | -webkit-animation-delay: 0.6s;
54 | animation-delay: 0.6s;
55 | }
56 | .sk-folding-cube > div:nth-child(3)::before {
57 | -webkit-animation-delay: 0.9s;
58 | animation-delay: 0.9s;
59 | }
60 | @-webkit-keyframes sk-foldCubeAngle {
61 | 0%, 10% {
62 | -webkit-transform: perspective(140px) rotateX(-180deg);
63 | transform: perspective(140px) rotateX(-180deg);
64 | opacity: 0;
65 | } 25%, 75% {
66 | -webkit-transform: perspective(140px) rotateX(0deg);
67 | transform: perspective(140px) rotateX(0deg);
68 | opacity: 1;
69 | } 90%, 100% {
70 | -webkit-transform: perspective(140px) rotateY(180deg);
71 | transform: perspective(140px) rotateY(180deg);
72 | opacity: 0;
73 | }
74 | }
75 |
76 | @keyframes sk-foldCubeAngle {
77 | 0%, 10% {
78 | -webkit-transform: perspective(140px) rotateX(-180deg);
79 | transform: perspective(140px) rotateX(-180deg);
80 | opacity: 0;
81 | } 25%, 75% {
82 | -webkit-transform: perspective(140px) rotateX(0deg);
83 | transform: perspective(140px) rotateX(0deg);
84 | opacity: 1;
85 | } 90%, 100% {
86 | -webkit-transform: perspective(140px) rotateY(180deg);
87 | transform: perspective(140px) rotateY(180deg);
88 | opacity: 0;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/components/spinners.js:
--------------------------------------------------------------------------------
1 | const spinkitSpinners = {
2 | 'circle': { className: 'sk-circle', divCount: 12 },
3 | 'cube-grid': { className: 'sk-cube-grid', divCount: 9 },
4 | 'wave': { className: 'sk-wave', divCount: 5 },
5 | 'folding-cube': { className: 'sk-folding-cube', divCount: 4 },
6 | 'three-bounce': { className: 'sk-three-bounce', divCount: 3 },
7 | 'double-bounce': { className: 'sk-double-bounce', divCount: 2 },
8 | 'wandering-cubes': { className: 'sk-wandering-cubes', divCount: 2 },
9 | 'chasing-dots': { className: 'sk-chasing-dots', divCount: 2 },
10 | 'rotating-plane': { className: 'sk-rotating-plane', divCount: 1 },
11 | 'pulse': { className: 'sk-pulse', divCount: 1 },
12 | 'wordpress': { className: 'sk-wordpress', divCount: 1 },
13 | 'fading-circle': { className: 'sk-fading-circle', divCount: 12 }
14 | }
15 |
16 | const loadersCssSpinners = {
17 | 'square-spin': { divCount: 1 },
18 | 'ball-grid-beat': { divCount: 9 },
19 | 'ball-grid-pulse': { divCount: 9 },
20 | 'line-spin-fade-loader': { divCount: 8 },
21 | 'ball-spin-fade-loader': { divCount: 8 },
22 | 'ball-pulse-rise': { divCount: 5 },
23 | 'line-scale': { divCount: 5 },
24 | 'line-scale-pulse-out': { divCount: 5 },
25 | 'line-scale-pulse-out-rapid': { divCount: 5 },
26 | 'pacman': { divCount: 5 },
27 | 'line-scale-party': { divCount: 4 },
28 | 'ball-triangle-path': { divCount: 3 },
29 | 'ball-scale-multiple': { divCount: 3 },
30 | 'ball-scale-ripple-multiple': { divCount: 3 },
31 | 'ball-pulse-sync': { divCount: 3 },
32 | 'ball-pulse': { divCount: 3 },
33 | 'ball-beat': { divCount: 3 },
34 | 'ball-zig-zag': { divCount: 2 },
35 | 'ball-zig-zag-deflect': { divCount: 2 },
36 | 'ball-clip-rotate-pulse': { divCount: 2 },
37 | 'ball-clip-rotate-multiple': { divCount: 2 },
38 | 'ball-clip-rotate': { divCount: 1 },
39 | 'ball-scale-ripple': { divCount: 1 },
40 | 'triangle-skew-spin': { divCount: 1 }
41 | }
42 |
43 | const loadingIOSpinners = {
44 | 'circle-solid-spin': { className: 'sk-circle-solid-spin', divCount: 1 },
45 | 'dual-ring': { className: 'sk-dual-ring', divCount: 0 },
46 | 'facebook': { className: 'sk-facebook', divCount: 3 },
47 | 'heart': { className: 'sk-heart', divCount: 1 },
48 | 'ring': { className: 'sk-ring', divCount: 4 },
49 | 'roller': { className: 'sk-roller', divCount: 8 },
50 | 'ellipsis': { className: 'sk-ellipsis', divCount: 4 },
51 | 'grid': { className: 'sk-grid', divCount: 9 },
52 | 'hourglass': { className: 'sk-hourglass', divCount: 0 },
53 | 'ripple': { className: 'sk-ripple', divCount: 2 }
54 | }
55 |
56 | const awesomeSpinners = {
57 | 'loadbar': { className: 'sk-loadbar', divCount: 0 },
58 | 'hydrogen': { className: 'sk-hydrogen', divCount: 0 },
59 | 'clock': { className: 'sk-clock', divCount: 0 },
60 | 'circle-fade': { className: 'sk-circle-fade', divCount: 0 },
61 | 'moon': { className: 'sk-moon', divCount: 1 }
62 | }
63 |
64 | export default {
65 | spinkitSpinners,
66 | loadersCssSpinners,
67 | loadingIOSpinners,
68 | awesomeSpinners,
69 | allSpinners: {
70 | ...spinkitSpinners,
71 | ...loadersCssSpinners,
72 | ...loadingIOSpinners,
73 | ...awesomeSpinners
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // Library entrypoint for vue-spinkit
2 | import Spinner from './components/Spinner.vue'
3 |
4 | // Import CSS files as raw text and inject at runtime so Vite doesn't emit a separate CSS asset.
5 | // This keeps the final build as a single JS file containing both JS and CSS.
6 | import baseCss from './components/css/base.css?raw'
7 | import fadeInCss from './components/css/fade-in.css?raw'
8 | import rotatingPlaneCss from './components/css/rotating-plane.css?raw'
9 | import doubleBounceCss from './components/css/double-bounce.css?raw'
10 | import waveCss from './components/css/wave.css?raw'
11 | import wanderingCubesCss from './components/css/wandering-cubes.css?raw'
12 | import pulseCss from './components/css/pulse.css?raw'
13 | import chasingDotsCss from './components/css/chasing-dots.css?raw'
14 | import threeBounceCss from './components/css/three-bounce.css?raw'
15 | import circleCss from './components/css/circle.css?raw'
16 | import cubeGridCss from './components/css/cube-grid.css?raw'
17 | import fadingCircleCss from './components/css/fading-circle.css?raw'
18 | import foldingCubeCss from './components/css/folding-cube.css?raw'
19 | import wordpressCss from './components/css/wordpress.css?raw'
20 | import loadersCss from './components/css/loaders.css?raw'
21 | import loadersCssExtra from './components/css/loaders-css.css?raw'
22 | import circleSolidSpinCss from './components/css/circle-solid-spin.css?raw'
23 | import dualRingCss from './components/css/dual-ring.css?raw'
24 | import ellipsisCss from './components/css/ellipsis.css?raw'
25 | import facebookCss from './components/css/facebook.css?raw'
26 | import gridCss from './components/css/grid.css?raw'
27 | import heartCss from './components/css/heart.css?raw'
28 | import hourglassCss from './components/css/hourglass.css?raw'
29 | import ringCss from './components/css/ring.css?raw'
30 | import rippleCss from './components/css/ripple.css?raw'
31 | import rollerCss from './components/css/roller.css?raw'
32 | import clockCss from './components/css/clock.css?raw'
33 | import hydrogenCss from './components/css/hydrogen.css?raw'
34 | import loadbarCss from './components/css/loadbar.css?raw'
35 | import circleFadeCss from './components/css/circle-fade.css?raw'
36 | import moonCss from './components/css/moon.css?raw'
37 |
38 | const __injectedCss = [
39 | baseCss,
40 | fadeInCss,
41 | rotatingPlaneCss,
42 | doubleBounceCss,
43 | waveCss,
44 | wanderingCubesCss,
45 | pulseCss,
46 | chasingDotsCss,
47 | threeBounceCss,
48 | circleCss,
49 | cubeGridCss,
50 | fadingCircleCss,
51 | foldingCubeCss,
52 | wordpressCss,
53 | loadersCss,
54 | loadersCssExtra,
55 | circleSolidSpinCss,
56 | dualRingCss,
57 | ellipsisCss,
58 | facebookCss,
59 | gridCss,
60 | heartCss,
61 | hourglassCss,
62 | ringCss,
63 | rippleCss,
64 | rollerCss,
65 | clockCss,
66 | hydrogenCss,
67 | loadbarCss,
68 | circleFadeCss,
69 | moonCss
70 | ].join('\n')
71 |
72 | if (typeof document !== 'undefined') {
73 | const style = document.createElement('style')
74 | style.setAttribute('data-vue-spinkit', '')
75 | style.appendChild(document.createTextNode(__injectedCss))
76 | document.head.appendChild(style)
77 | }
78 |
79 | // For CommonJS build, export the component
80 | export { Spinner }
81 | export default Spinner
82 |
--------------------------------------------------------------------------------
/src/components/css/circle.css:
--------------------------------------------------------------------------------
1 | .sk-circle {
2 | width: 40px;
3 | height: 40px;
4 | position: relative;
5 | }
6 |
7 | .sk-circle > div {
8 | background-color: initial;
9 | width: 100%;
10 | height: 100%;
11 | position: absolute;
12 | left: 0;
13 | top: 0;
14 | }
15 |
16 | .sk-circle > div::before {
17 | content: '';
18 | display: block;
19 | margin: 0 auto;
20 | width: 20%;
21 | height: 20%;
22 | background-color: currentColor;
23 | border-radius: 100%;
24 |
25 | -webkit-animation: sk-bouncedelay 1.2s infinite ease-in-out;
26 | animation: sk-bouncedelay 1.2s infinite ease-in-out;
27 | /* Prevent first frame from flickering when animation starts */
28 | -webkit-animation-fill-mode: both;
29 | animation-fill-mode: both;
30 | }
31 |
32 | .sk-circle > div:nth-child(2) { -webkit-transform: rotate(30deg); transform: rotate(30deg) }
33 | .sk-circle > div:nth-child(3) { -webkit-transform: rotate(60deg); transform: rotate(60deg) }
34 | .sk-circle > div:nth-child(4) { -webkit-transform: rotate(90deg); transform: rotate(90deg) }
35 | .sk-circle > div:nth-child(5) { -webkit-transform: rotate(120deg); transform: rotate(120deg) }
36 | .sk-circle > div:nth-child(6) { -webkit-transform: rotate(150deg); transform: rotate(150deg) }
37 | .sk-circle > div:nth-child(7) { -webkit-transform: rotate(180deg); transform: rotate(180deg) }
38 | .sk-circle > div:nth-child(8) { -webkit-transform: rotate(210deg); transform: rotate(210deg) }
39 | .sk-circle > div:nth-child(9) { -webkit-transform: rotate(240deg); transform: rotate(240deg) }
40 | .sk-circle > div:nth-child(10) { -webkit-transform: rotate(270deg); transform: rotate(270deg) }
41 | .sk-circle > div:nth-child(11) { -webkit-transform: rotate(300deg); transform: rotate(300deg) }
42 | .sk-circle > div:nth-child(12) { -webkit-transform: rotate(330deg); transform: rotate(330deg) }
43 |
44 | .sk-circle > div:nth-child(2)::before { -webkit-animation-delay: -1.1s; animation-delay: -1.1s }
45 | .sk-circle > div:nth-child(3)::before { -webkit-animation-delay: -1.0s; animation-delay: -1.0s }
46 | .sk-circle > div:nth-child(4)::before { -webkit-animation-delay: -0.9s; animation-delay: -0.9s }
47 | .sk-circle > div:nth-child(5)::before { -webkit-animation-delay: -0.8s; animation-delay: -0.8s }
48 | .sk-circle > div:nth-child(6)::before { -webkit-animation-delay: -0.7s; animation-delay: -0.7s }
49 | .sk-circle > div:nth-child(7)::before { -webkit-animation-delay: -0.6s; animation-delay: -0.6s }
50 | .sk-circle > div:nth-child(8)::before { -webkit-animation-delay: -0.5s; animation-delay: -0.5s }
51 | .sk-circle > div:nth-child(9)::before { -webkit-animation-delay: -0.4s; animation-delay: -0.4s }
52 | .sk-circle > div:nth-child(10)::before { -webkit-animation-delay: -0.3s; animation-delay: -0.3s }
53 | .sk-circle > div:nth-child(11)::before { -webkit-animation-delay: -0.2s; animation-delay: -0.2s }
54 | .sk-circle > div:nth-child(12)::before { -webkit-animation-delay: -0.1s; animation-delay: -0.1s }
55 |
56 | @-webkit-keyframes sk-bouncedelay {
57 | 0%, 80%, 100% { -webkit-transform: scale(0.0) }
58 | 40% { -webkit-transform: scale(1.0) }
59 | }
60 |
61 | @keyframes sk-bouncedelay {
62 | 0%, 80%, 100% {
63 | -webkit-transform: scale(0.0);
64 | transform: scale(0.0);
65 | } 40% {
66 | -webkit-transform: scale(1.0);
67 | transform: scale(1.0);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/components/css/fading-circle.css:
--------------------------------------------------------------------------------
1 | .sk-fading-circle {
2 | width: 40px;
3 | height: 40px;
4 | position: relative;
5 | }
6 | .sk-fading-circle > div {
7 | background-color: initial;
8 | width: 100%;
9 | height: 100%;
10 | position: absolute;
11 | left: 0;
12 | top: 0;
13 | }
14 |
15 | .sk-fading-circle > div::before {
16 | content: '';
17 | display: block;
18 | margin: 0 auto;
19 | width: 15%;
20 | height: 15%;
21 | background-color: currentColor;
22 | border-radius: 100%;
23 | -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
24 | animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
25 | }
26 | .sk-fading-circle > div:nth-child(2) {
27 | -webkit-transform: rotate(30deg);
28 | -ms-transform: rotate(30deg);
29 | transform: rotate(30deg); }
30 | .sk-fading-circle > div:nth-child(3) {
31 | -webkit-transform: rotate(60deg);
32 | -ms-transform: rotate(60deg);
33 | transform: rotate(60deg); }
34 | .sk-fading-circle > div:nth-child(4) {
35 | -webkit-transform: rotate(90deg);
36 | -ms-transform: rotate(90deg);
37 | transform: rotate(90deg); }
38 | .sk-fading-circle > div:nth-child(5) {
39 | -webkit-transform: rotate(120deg);
40 | -ms-transform: rotate(120deg);
41 | transform: rotate(120deg); }
42 | .sk-fading-circle > div:nth-child(6) {
43 | -webkit-transform: rotate(150deg);
44 | -ms-transform: rotate(150deg);
45 | transform: rotate(150deg); }
46 | .sk-fading-circle > div:nth-child(7) {
47 | -webkit-transform: rotate(180deg);
48 | -ms-transform: rotate(180deg);
49 | transform: rotate(180deg); }
50 | .sk-fading-circle > div:nth-child(8) {
51 | -webkit-transform: rotate(210deg);
52 | -ms-transform: rotate(210deg);
53 | transform: rotate(210deg); }
54 | .sk-fading-circle > div:nth-child(9) {
55 | -webkit-transform: rotate(240deg);
56 | -ms-transform: rotate(240deg);
57 | transform: rotate(240deg); }
58 | .sk-fading-circle > div:nth-child(10) {
59 | -webkit-transform: rotate(270deg);
60 | -ms-transform: rotate(270deg);
61 | transform: rotate(270deg); }
62 | .sk-fading-circle > div:nth-child(11) {
63 | -webkit-transform: rotate(300deg);
64 | -ms-transform: rotate(300deg);
65 | transform: rotate(300deg); }
66 | .sk-fading-circle > div:nth-child(12) {
67 | -webkit-transform: rotate(330deg);
68 | -ms-transform: rotate(330deg);
69 | transform: rotate(330deg); }
70 | .sk-fading-circle > div:nth-child(2)::before {
71 | -webkit-animation-delay: -1.1s;
72 | animation-delay: -1.1s; }
73 | .sk-fading-circle > div:nth-child(3)::before {
74 | -webkit-animation-delay: -1s;
75 | animation-delay: -1s; }
76 | .sk-fading-circle > div:nth-child(4)::before {
77 | -webkit-animation-delay: -0.9s;
78 | animation-delay: -0.9s; }
79 | .sk-fading-circle > div:nth-child(5)::before {
80 | -webkit-animation-delay: -0.8s;
81 | animation-delay: -0.8s; }
82 | .sk-fading-circle > div:nth-child(6)::before {
83 | -webkit-animation-delay: -0.7s;
84 | animation-delay: -0.7s; }
85 | .sk-fading-circle > div:nth-child(7)::before {
86 | -webkit-animation-delay: -0.6s;
87 | animation-delay: -0.6s; }
88 | .sk-fading-circle > div:nth-child(8)::before {
89 | -webkit-animation-delay: -0.5s;
90 | animation-delay: -0.5s; }
91 | .sk-fading-circle > div:nth-child(9)::before {
92 | -webkit-animation-delay: -0.4s;
93 | animation-delay: -0.4s; }
94 | .sk-fading-circle > div:nth-child(10)::before {
95 | -webkit-animation-delay: -0.3s;
96 | animation-delay: -0.3s; }
97 | .sk-fading-circle > div:nth-child(11)::before {
98 | -webkit-animation-delay: -0.2s;
99 | animation-delay: -0.2s; }
100 | .sk-fading-circle > div:nth-child(12)::before {
101 | -webkit-animation-delay: -0.1s;
102 | animation-delay: -0.1s; }
103 |
104 | @-webkit-keyframes sk-circleFadeDelay {
105 | 0%, 39%, 100% {
106 | opacity: 0; }
107 | 40% {
108 | opacity: 1; } }
109 |
110 | @keyframes sk-circleFadeDelay {
111 | 0%, 39%, 100% {
112 | opacity: 0; }
113 | 40% {
114 | opacity: 1; } }
--------------------------------------------------------------------------------
/src/Example.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Example Vue Spinkit
5 |
11 |
12 |
13 |
14 |
{{spinner.name}}
15 |
21 |
22 |
23 |
24 |
25 |
83 |
84 |
141 |
--------------------------------------------------------------------------------
/postcss-plugins.js:
--------------------------------------------------------------------------------
1 | // PostCSS 8 compatible plugins to replace deprecated ones in @vue/component-compiler-utils
2 |
3 | // Replacement for the 'trim' plugin
4 | const trimPlugin = () => {
5 | return {
6 | postcssPlugin: 'trim',
7 | Once(css) {
8 | css.walk(({ type, raws }) => {
9 | if (type === 'rule' || type === 'atrule') {
10 | if (raws.before) raws.before = '\n';
11 | if (raws.after) raws.after = '\n';
12 | }
13 | });
14 | }
15 | };
16 | };
17 | trimPlugin.postcss = true;
18 |
19 | // Replacement for the 'add-id' plugin
20 | const addIdPlugin = (options) => {
21 | return {
22 | postcssPlugin: 'add-id',
23 | Once(root) {
24 | const selectorParser = require('postcss-selector-parser');
25 | const id = options;
26 | const keyframes = Object.create(null);
27 |
28 | root.each(function rewriteSelector(node) {
29 | if (!node.selector) {
30 | // handle media queries
31 | if (node.type === 'atrule') {
32 | if (node.name === 'media' || node.name === 'supports') {
33 | node.each(rewriteSelector);
34 | } else if (/-?keyframes$/.test(node.name)) {
35 | // register keyframes
36 | keyframes[node.params] = node.params = node.params + '-' + id;
37 | }
38 | }
39 | return;
40 | }
41 |
42 | node.selector = selectorParser((selectors) => {
43 | selectors.each((selector) => {
44 | let node = null;
45 | // find the last child node to insert attribute selector
46 | selector.each((n) => {
47 | // ">>>" combinator
48 | // and /deep/ alias for >>>, since >>> doesn't work in SASS
49 | if (n.type === 'combinator' &&
50 | (n.value === '>>>' || n.value === '/deep/')) {
51 | n.value = ' ';
52 | n.spaces.before = n.spaces.after = '';
53 | return false;
54 | }
55 | // in newer versions of sass, /deep/ support is also dropped, so add a ::v-deep alias
56 | if (n.type === 'pseudo' && n.value === '::v-deep') {
57 | n.value = n.spaces.before = n.spaces.after = '';
58 | return false;
59 | }
60 | if (n.type !== 'pseudo' && n.type !== 'combinator') {
61 | node = n;
62 | }
63 | });
64 |
65 | if (node) {
66 | node.spaces.after = '';
67 | } else {
68 | // For deep selectors & standalone pseudo selectors,
69 | // the attribute selectors are prepended rather than appended.
70 | // So all leading spaces must be eliminated to avoid problems.
71 | selector.first.spaces.before = '';
72 | }
73 | selector.insertAfter(node, selectorParser.attribute({
74 | attribute: id
75 | }));
76 | });
77 | }).processSync(node.selector);
78 | });
79 |
80 | // If keyframes are found in this