create spinner #20 (#186)

This commit is contained in:
Marcos Moura 2016-12-12 02:56:44 -02:00 committed by GitHub
parent 88660316cb
commit bf06ffce6b
9 changed files with 429 additions and 6 deletions

View file

@ -101,6 +101,10 @@
<router-link exact to="/components/sidenav">Sidenav</router-link>
</md-list-item>
<md-list-item class="md-inset">
<router-link exact to="/components/spinner">Spinner</router-link>
</md-list-item>
<md-list-item class="md-inset">
<router-link exact to="/components/subheader">Subheader</router-link>
</md-list-item>

View file

@ -8,6 +8,10 @@ Vue.material.theme.registerAll({
primary: 'blue',
accent: 'pink'
},
blue: {
primary: 'blue',
accent: 'pink'
},
indigo: {
primary: 'indigo',
accent: 'pink'
@ -21,12 +25,8 @@ Vue.material.theme.registerAll({
accent: 'blue'
},
orange: {
primary: 'orange',
accent: 'green'
},
blue: {
primary: 'blue',
accent: 'pink'
primary: 'deep-orange',
accent: 'purple'
},
green: {
primary: 'green',

View file

@ -0,0 +1,225 @@
<template>
<page-content page-title="Components - Spinner">
<docs-component>
<div slot="description">
<p>Progress and activity indicators are visual indications of an app loading content.</p>
<p>The following classes can be applied to change the color palette:</p>
<ul class="md-body-2">
<li><code>md-accent</code></li>
<li><code>md-warn</code></li>
</ul>
</div>
<div slot="api">
<api-table name="md-spinner">
<md-table slot="properties">
<md-table-header>
<md-table-row>
<md-table-head>Name</md-table-head>
<md-table-head>Type</md-table-head>
<md-table-head>Description</md-table-head>
</md-table-row>
</md-table-header>
<md-table-body>
<md-table-row>
<md-table-cell>md-size</md-table-cell>
<md-table-cell><code>Number</code></md-table-cell>
<md-table-cell>The spinner size. Default <code>50</code></md-table-cell>
</md-table-row>
<md-table-row>
<md-table-cell>md-indeterminate</md-table-cell>
<md-table-cell><code>Boolean</code></md-table-cell>
<md-table-cell>Enable the indeterminate state. Default <code>false</code></md-table-cell>
</md-table-row>
<md-table-row>
<md-table-cell>md-progress</md-table-cell>
<md-table-cell><code>Number</code></md-table-cell>
<md-table-cell>Define the current progress of the spinner. Default <code>0</code></md-table-cell>
</md-table-row>
</md-table-body>
</md-table>
</api-table>
</div>
<div slot="example">
<example-box card-title="Determinate">
<div class="spinner-demo" slot="demo">
<md-button class="md-primary md-raised" @click.native="restartProgress">Restart</md-button>
<md-spinner :md-progress="progress" v-show="transition"></md-spinner>
<md-spinner :md-progress="progress" v-show="transition" class="md-accent"></md-spinner>
<md-spinner :md-progress="progress" v-show="transition" class="md-warn"></md-spinner>
</div>
<div slot="code">
<code-block lang="xml">
&lt;md-spinner :md-progress=&quot;progress&quot;&gt;&lt;/md-spinner&gt;
&lt;md-spinner :md-progress=&quot;progress&quot; class=&quot;md-accent&quot;&gt;&lt;/md-spinner&gt;
&lt;md-spinner :md-progress=&quot;progress&quot; class=&quot;md-warn&quot;&gt;&lt;/md-spinner&gt;
</code-block>
</div>
</example-box>
<example-box card-title="Indeterminate">
<div class="spinner-demo" slot="demo">
<md-spinner md-indeterminate></md-spinner>
<md-spinner md-indeterminate class="md-accent"></md-spinner>
<md-spinner md-indeterminate class="md-warn"></md-spinner>
</div>
<div slot="code">
<code-block lang="xml">
&lt;md-spinner md-indeterminate&gt;&lt;/md-spinner&gt;
&lt;md-spinner md-indeterminate class=&quot;md-accent&quot;&gt;&lt;/md-spinner&gt;
&lt;md-spinner md-indeterminate class=&quot;md-warn&quot;&gt;&lt;/md-spinner&gt;
</code-block>
</div>
</example-box>
<example-box card-title="Sizes">
<div class="spinner-demo" slot="demo">
<md-spinner :md-size="20" md-indeterminate class="md-accent"></md-spinner>
<md-spinner :md-size="60" md-indeterminate class="md-warn"></md-spinner>
<md-spinner :md-size="150" md-indeterminate></md-spinner>
</div>
<div slot="code">
<code-block lang="xml">
&lt;md-spinner :md-size=&quot;20&quot; md-indeterminate class=&quot;md-accent&quot;&gt;&lt;/md-spinner&gt;
&lt;md-spinner :md-size=&quot;60&quot; md-indeterminate class=&quot;md-warn&quot;&gt;&lt;/md-spinner&gt;
&lt;md-spinner :md-size=&quot;150&quot; md-indeterminate&gt;&lt;/md-spinner&gt;
</code-block>
</div>
</example-box>
<example-box card-title="Complete Example">
<div slot="demo">
<div class="complete-example" v-md-theme="'orange'">
<md-button class="md-fab" @click.native="restartProgress" :class="{ 'md-primary': done }">
<md-icon v-show="!done">cloud_upload</md-icon>
<md-icon v-show="done">done</md-icon>
</md-button>
<md-spinner :md-size="75" :md-progress="progress" v-show="transition && progress < 115"></md-spinner>
</div>
</div>
<div slot="code">
<code-block lang="xml">
&lt;div class=&quot;complete-example&quot; v-md-theme=&quot;&#039;orange&#039;&quot;&gt;
&lt;md-button class=&quot;md-fab&quot; @click.native=&quot;restartProgress&quot; :class=&quot;{ &#039;md-primary&#039;: done }&quot;&gt;
&lt;md-icon v-show=&quot;!done&quot;&gt;cloud_upload&lt;/md-icon&gt;
&lt;md-icon v-show=&quot;done&quot;&gt;done&lt;/md-icon&gt;
&lt;/md-button&gt;
&lt;md-spinner :md-size=&quot;75&quot; :md-progress=&quot;progress&quot; v-show=&quot;transition &amp;&amp; progress &lt; 115&quot;&gt;&lt;/md-spinner&gt;
&lt;/div&gt;
</code-block>
<code-block lang="javascript">
export default {
data: () => ({
progress: 0,
progressInterval: null,
done: false,
transition: true
}),
methods: {
startProgress() {
this.progressInterval = window.setInterval(() => {
this.progress += 3;
if (this.progress > 115) {
this.done = true;
window.clearInterval(this.progressInterval);
window.setTimeout(() => {
this.done = false;
}, 3000);
}
}, 100);
},
restartProgress() {
this.progress = 0;
this.transition = false;
this.done = false;
window.clearInterval(this.progressInterval);
window.setTimeout(() => {
this.transition = true;
this.startProgress();
}, 600);
}
}
};
</code-block>
</div>
</example-box>
</div>
</docs-component>
</page-content>
</template>
<style lang="scss" scoped>
.spinner-demo {
min-height: 55px;
}
.complete-example {
width: 56px;
height: 56px;
position: relative;
.md-fab {
margin: 0;
}
.md-spinner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
</style>
<script>
export default {
data: () => ({
progress: 0,
progressInterval: null,
done: false,
transition: true
}),
methods: {
startProgress() {
this.progressInterval = window.setInterval(() => {
this.progress += 3;
if (this.progress > 115) {
this.done = true;
window.clearInterval(this.progressInterval);
window.setTimeout(() => {
this.done = false;
}, 3000);
}
}, 100);
},
restartProgress() {
this.progress = 0;
this.transition = false;
this.done = false;
window.clearInterval(this.progressInterval);
window.setTimeout(() => {
this.transition = true;
this.startProgress();
}, 600);
}
},
mounted() {
this.startProgress();
}
};
</script>

View file

@ -21,6 +21,7 @@ import Radio from './pages/components/Radio';
import InkRipple from './pages/components/InkRipple';
import Select from './pages/components/Select';
import Sidenav from './pages/components/Sidenav';
import Spinner from './pages/components/Spinner';
import Subheader from './pages/components/Subheader';
import Switch from './pages/components/Switch';
import Table from './pages/components/Table';
@ -141,6 +142,11 @@ const components = [
name: 'components:sidenav',
component: Sidenav
},
{
path: '/components/spinner',
name: 'components:spinner',
component: Spinner
},
{
path: '/components/switch',
name: 'components:switch',

View file

@ -0,0 +1,8 @@
import mdSpinner from './mdSpinner.vue';
import mdSpinnerTheme from './mdSpinner.theme';
export default function install(Vue) {
Vue.component('md-spinner', Vue.extend(mdSpinner));
Vue.material.styles.push(mdSpinnerTheme);
}

View file

@ -0,0 +1,97 @@
@import '../../core/stylesheets/variables.scss';
.md-spinner {
display: inline-block;
position: relative;
pointer-events: none;
will-change: transform, opacity;
&.md-indeterminate {
.md-spinner-draw {
animation: spinner-rotate 1.9s linear infinite;
transform: rotate(0deg) translateZ(0);
}
.md-spinner-path {
stroke-dasharray: 2, 200;
animation: spinner-dash 1.425s ease-in-out infinite;
}
}
&.md-spinner-leave-active {
opacity: 0;
transform: scale(.9) translateZ(0);
transition: $swift-ease-out;
}
&:not(.md-indeterminate) {
&.md-spinner-enter-active {
transition-duration: 1.8s;
.md-spinner-draw {
animation: spinner-initial-rotate 1.79s $swift-ease-out-timing-function infinite;
}
}
}
}
.md-spinner-draw {
width: 100%;
height: 100%;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: rotate(270deg) translateZ(0);
transform-origin: center center;
will-change: transform, opacity;
}
.md-spinner-path {
fill: none;
stroke-dashoffset: 0;
stroke-miterlimit: 10;
stroke-width: 3.2;
transition: $swift-ease-out;
}
@keyframes spinner-rotate {
to {
transform: rotate(360deg) translateZ(0);
}
}
@keyframes spinner-initial-rotate {
0% {
opacity: 0;
transform: rotate(-90deg) translateZ(0);
}
10% {
opacity: 1;
}
100% {
opacity: 1;
transform: rotate(270deg) translateZ(0);
}
}
@keyframes spinner-dash {
0% {
stroke-dasharray: 2, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}

View file

@ -0,0 +1,20 @@
.THEME_NAME {
.md-spinner,
&.md-spinner {
.md-spinner-path {
stroke: #{'PRIMARY-COLOR'}
}
&.md-accent {
.md-spinner-path {
stroke: #{'ACCENT-COLOR'}
}
}
&.md-warn {
.md-spinner-path {
stroke: #{'WARN-COLOR'}
}
}
}
}

View file

@ -0,0 +1,61 @@
<template>
<transition name="md-spinner" appear>
<div class="md-spinner" :class="classes" :style="styles">
<svg class="md-spinner-draw" viewBox="25 25 50 50">
<circle class="md-spinner-path" cx="50" cy="50" r="20" :stroke-dasharray="dashProgress">
</svg>
</div>
</transition>
</template>
<style lang="scss" src="./mdSpinner.scss"></style>
<script>
export default {
props: {
mdSize: {
type: Number,
default: 50
},
mdIndeterminate: Boolean,
mdProgress: {
type: Number,
default: 0
}
},
computed: {
classes() {
return {
'md-indeterminate': this.mdIndeterminate
};
},
styles() {
const newSize = this.mdSize + 'px';
return {
width: newSize,
height: newSize
};
},
dashProgress() {
let progress = this.mdProgress * 125 / 100;
if (this.mdIndeterminate) {
return false;
}
if (progress >= 125) {
progress = 130;
}
return `${progress}, 200`;
}
},
data: () => ({
}),
methods: {
}
};
</script>

View file

@ -15,6 +15,7 @@ import MdMenu from './components/mdMenu';
import MdRadio from './components/mdRadio';
import MdSelect from './components/mdSelect';
import MdSidenav from './components/mdSidenav';
import MdSpinner from './components/mdSpinner';
import MdSubheader from './components/mdSubheader';
import MdSwitch from './components/mdSwitch';
import MdTable from './components/mdTable';
@ -41,6 +42,7 @@ const options = {
MdRadio,
MdSelect,
MdSidenav,
MdSpinner,
MdSubheader,
MdSwitch,
MdTable,