feat(spin): add spin component

This commit is contained in:
07akioni 2019-09-04 16:06:07 +08:00
parent ddaecaecc9
commit d2e9226b83
23 changed files with 606 additions and 35 deletions

View File

@ -79,10 +79,13 @@ Vue.use(naiveUi)
|Collapse|😍|||
|Cascader|😍|||
|Dropdown|😍|||
|Affix|🚧|||
|Transfer|🚧|||
|Carousel|🚧|||
|Transfer|😍|||
|Spin|😍|||
|Drawer|🚧|||
|Grid|🚧|||
|Layout|🚧|||
|Affix|🚧|||
|Carousel|🚧|||
|Card|🚧|||
|Anchor|🚧|||
|Statistic|🚧|||
@ -93,12 +96,18 @@ Vue.use(naiveUi)
|AutoComplete|🚧|||
|Slider|🚧|||
|TreeSelect|🚧|||
|Transfer|🚧|||
|Upload|🚧|||
|Empty|🚧|||
|Tree|🚧|||
|Spin|🚧|||
|Drawer|🚧|||
|LoadingBar|🚧|||
|Rating|🚧|||
|Time|🚧|||
|Avator|🚧|||
|Menu|🚧|||
|Typography|🚧|||
|Mentions|🚧|||
|Result|🚧|||
|Calendar|🚧|||
1. Z-index management on `Select` & `Tooltip` & `Modal`(Low Priority)
2. Full featured table component(Medium Priority)

View File

@ -0,0 +1,32 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
Drawer
</n-gradient-text>
</div>
<div class="n-doc-body">
<scaffold />
</div>
</div>
</template>
<script>
import scaffold from './scaffold.demo.vue'
export default {
components: {
scaffold
},
data () {
return {
}
},
methods: {
}
}
</script>

View File

@ -0,0 +1,31 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Scaffold
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-drawer v-model="active">
777
</n-drawer>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect"><n-button @click="active = !active">active</n-button></pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
active: false
}
}
}
</script>

View File

@ -0,0 +1,35 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
Spin / n-spin
</n-gradient-text>
</div>
<div class="n-doc-body">
<scaffold />
<wrap />
</div>
</div>
</template>
<script>
import scaffold from './scaffold.demo.vue'
import wrap from './wrap.demo.vue'
export default {
components: {
scaffold,
wrap
},
data () {
return {
}
},
methods: {
}
}
</script>

View File

@ -0,0 +1,28 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
BasicUsage
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-spin size="small" /> <n-spin size="medium" /> <n-spin size="large" />
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">Inspect some value here</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>

View File

@ -0,0 +1,60 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Wrap
</div>
<div
class="n-doc-section__view"
style="align-items: flex-start;"
>
<!--EXAMPLE_START-->
<n-spin
size="in-small"
:spinning="spinning"
>
<n-button size="small">
Small Spin
</n-button>
</n-spin>
<n-spin
size="in-medium"
:spinning="spinning"
>
<n-button size="medium">
Medium Spin
</n-button>
</n-spin>
<n-spin
size="in-large"
:spinning="spinning"
>
<n-button size="large">
Large Spin
</n-button>
</n-spin>
<n-spin :spinning="spinning">
<n-alert
title="Success Text"
type="success"
>
Leave it till tomorrow to unpack my case
</n-alert>
</n-spin>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect"><n-button @click="spinning = !spinning">spin</n-button></pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
spinning: false
}
}
}
</script>

View File

@ -102,6 +102,11 @@ export default {
{
name: 'Divider',
path: '/n-divider'
},
{
name: 'Drawer',
path: '/n-drawer'
},
{
name: 'Dropdown',
@ -171,6 +176,10 @@ export default {
name: 'Select',
path: '/n-select'
},
{
name: 'Spin',
path: '/n-spin'
},
{
name: 'Steps',
path: '/n-steps'

View File

@ -52,6 +52,8 @@ import popselectDemo from './components/popselectDemo'
import appDemo from './components/appDemo'
import advanceTableDemos from './components/advanceTableDemos'
import transferDemo from './components/transferDemo'
import spinDemo from './components/spinDemo'
import drawerDemo from './components/drawerDemo'
import demo from './demo'
@ -140,7 +142,9 @@ const routes = [
{ path: '/n-popselect', component: popselectDemo },
{ path: '/n-app', component: appDemo },
{ path: '/n-cancel-mark-debug', component: cancelMarkDebug },
{ path: '/n-transfer', component: transferDemo }
{ path: '/n-transfer', component: transferDemo },
{ path: '/n-spin', component: spinDemo },
{ path: '/n-drawer', component: drawerDemo }
]
},
{

View File

@ -237,19 +237,19 @@ Vue.use(naiveUi)
<td></td>
</tr>
<tr>
<td>Affix</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Transfer</td>
<td style="text-align:center;">😍</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Spin</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Carousel</td>
<td>Drawer</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
@ -261,6 +261,24 @@ Vue.use(naiveUi)
<td></td>
</tr>
<tr>
<td>Layout</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Affix</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Carousel</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Card</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
@ -321,12 +339,6 @@ Vue.use(naiveUi)
<td></td>
</tr>
<tr>
<td>Transfer</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Upload</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
@ -345,13 +357,55 @@ Vue.use(naiveUi)
<td></td>
</tr>
<tr>
<td>Spin</td>
<td>LoadingBar</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Drawer</td>
<td>Rating</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Time</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Avator</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Menu</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Typography</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Mentions</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Result</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Calendar</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>

View File

@ -52,6 +52,8 @@ import Popselect from './packages/common/Popselect'
import App from './packages/common/App'
import CancelMark from './packages/base/CancelMark'
import Transfer from './packages/common/Transfer'
import Spin from './packages/common/Spin'
import Drawer from './packages/common/Drawer'
function install (Vue) {
Card.install(Vue)
@ -108,6 +110,8 @@ function install (Vue) {
App.install(Vue)
CancelMark.install(Vue)
Transfer.install(Vue)
Spin.install(Vue)
Drawer.install(Vue)
}
export default {

View File

@ -1,6 +1,6 @@
{
"name": "naive-ui",
"version": "0.4.6",
"version": "0.4.10",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -2,13 +2,13 @@
<div class="n-base-loading">
<svg
viewBox="25 25 50 50"
class="circular"
class="n-base-loading-circular"
><circle
cx="50"
cy="50"
r="20"
fill="none"
class="path"
class="n-base-loading-circular-path"
/></svg>
</div>
</template>
@ -26,11 +26,11 @@ export default {
line-height: 1;
}
.circular {
.n-base-loading-circular {
height: 100%;
width: 100%;
animation: loading-rotate 2s linear infinite;
.path {
.n-base-loading-circular-path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90,150;
stroke-dashoffset: 0;

View File

@ -0,0 +1,8 @@
/* istanbul ignore file */
import Drawer from './src/main.vue'
Drawer.install = function (Vue) {
Vue.component(Drawer.name, Drawer)
}
export default Drawer

View File

@ -0,0 +1,102 @@
<template>
<n-base-portal>
<div class="n-detached-content-container">
<div
class="n-drawer-container"
:class="{
'n-drawer-container--active': containerActive
}"
>
<transition name="n-fade-in--transition">
<div
v-if="active"
class="n-drawer-overlay"
@click="handleOverlayClick"
/>
</transition>
<transition
name="n-slide-in-from-right"
@after-leave="handleAfterLeave"
>
<div
v-if="active"
class="n-drawer"
>
<slot />
</div>
</transition>
</div>
</div>
</n-base-portal>
</template>
<script>
import NBasePortal from '../../../base/Protal'
export default {
name: 'NDrawer',
components: {
NBasePortal
},
props: {
value: {
type: Boolean,
default: false
},
type: {
validator (type) {
return ['drawer', 'card'].includes(type)
},
default: 'drawer'
},
width: {
type: Number,
default: null
},
height: {
type: Number,
default: null
},
placement: {
validator (placement) {
return ['top', 'right', 'bottom', 'left'].includes(placement)
},
default: 'right'
},
maskClosable: {
type: Boolean,
default: true
}
},
data () {
return {
containerActive: false
}
},
computed: {
active () {
return this.value
}
},
watch: {
active (newActive) {
if (newActive) {
this.containerActive = true
}
}
},
created () {
this.containerActive = this.active
},
methods: {
handleAfterLeave () {
this.containerActive = false
},
handleOverlayClick () {
if (this.maskClosable) {
this.$emit('input', false)
}
}
}
}
</script>

View File

@ -0,0 +1,8 @@
/* istanbul ignore file */
import Spin from './src/main.vue'
Spin.install = function (Vue) {
Vue.component(Spin.name, Spin)
}
export default Spin

View File

@ -0,0 +1,55 @@
<template>
<div
v-if="$slots.default"
class="n-spin-container"
>
<transition name="n-spin--transition">
<n-base-loading
v-if="spinning"
class="n-spin"
:class="{
[`n-spin--${size}-size`]: true
}"
/>
</transition>
<div
class="n-spin-content"
:class="{
'n-spin-content--spinning': spinning
}"
>
<slot />
</div>
</div>
<n-base-loading
v-else
class="n-spin"
:class="{
[`n-spin--${size}-size`]: true
}"
/>
</template>
<script>
import NBaseLoading from '../../../base/Loading'
export default {
name: 'NSpin',
components: {
NBaseLoading
},
props: {
size: {
type: [String, Number],
default: 'medium'
},
spinning: {
type: Boolean,
default: true
}
},
methods: {
}
}
</script>

View File

@ -4,7 +4,6 @@
@include b(alert) {
color: rgba(255, 146, 164, 1);
border-radius: 12px;
margin-bottom: 12px;
position: relative;
.n-alert__icon {
position: absolute;
@ -39,7 +38,8 @@
}
}
&.n-alert--success {
background-color: rgba(99, 226, 183, 0.1);
background-color: rgba(99, 226, 183, 0.2);
box-shadow: inset 0 0 0 1.2px rgba(99, 226, 183, .5);
.n-icon {
color: rgba(99, 226, 183, 1);
}
@ -48,7 +48,8 @@
}
}
&.n-alert--info {
background-color: rgba(98,187,252,0.1);
background-color: rgba(98,187,252,0.2);
box-shadow: inset 0 0 0 1.2px rgba(98,187,252, .5);
.n-icon {
color: rgba(98, 187, 252, 1);
}
@ -57,7 +58,8 @@
}
}
&.n-alert--warning {
background-color: rgba(245, 166, 35, 0.1);
background-color: rgba(245, 166, 35, 0.2);
box-shadow: inset 0 0 0 1.2px rgba(245, 166, 35, .5);
.n-icon {
color: rgba(245, 166, 35, 1);
}
@ -66,7 +68,8 @@
}
}
&.n-alert--error {
background-color: rgba(255, 146, 164, 0.1);
background-color: rgba(255, 146, 164, 0.2);
box-shadow: inset 0 0 0 1.2px rgba(255, 146, 164, 0.5);
.n-icon {
color:rgba(255, 146, 164, 1);
}

View File

@ -5,7 +5,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: inset 0 0 0 1.5px $button-default-border-color;
box-shadow: inset 0 0 0 1.2px $button-default-border-color;
cursor: pointer;
user-select: none;
font-weight: 700;

33
styles/Drawer.scss Normal file
View File

@ -0,0 +1,33 @@
@import './mixins/mixins.scss';
@import './theme/default.scss';
@include b(drawer) {
@include slide-in-from-right-transition();
position: absolute;
top: 0;
bottom: 0;
right: 0;
background-color: rgba(111, 111, 111, 1);
}
@include b(drawer-overlay) {
@include fade-in-transition(fade-in);
background-color: rgba(0, 0, 0, .3);
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
@include b(drawer-container) {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
visibility: hidden;
@include m(active) {
visibility: visible;
}
}

66
styles/Spin.scss Normal file
View File

@ -0,0 +1,66 @@
@import './mixins/mixins.scss';
@import './theme/default.scss';
@include b(spin) {
display: inline-block;
@include fade-in-transition(spin);
@include m(in-small-size) {
width: 14px;
height: 14px;
@include b(base-loading-circular-path) {
stroke-width: 8!important;
}
}
@include m(in-medium-size) {
width: 16px;
height: 16px;
@include b(base-loading-circular-path) {
stroke-width: 7!important;
}
}
@include m(in-large-size) {
width: 18px;
height: 18px;
@include b(base-loading-circular-path) {
stroke-width: 6!important;
}
}
@include m(small-size) {
width: 28px;
height: 28px;
@include b(base-loading-circular-path) {
stroke-width: 6!important;
}
}
@include m(medium-size) {
width: 34px;
height: 34px;
@include b(base-loading-circular-path) {
stroke-width: 5!important;
}
}
@include m(large-size) {
width: 40px;
height: 40px;
@include b(base-loading-circular-path) {
stroke-width: 4.25!important;
}
}
}
@include b(spin-container) {
position: relative;
@include b(spin) {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
@include b(spin-content) {
opacity: 1;
transition: opacity .2s $default-cubic-bezier;
@include m(spinning) {
opacity: .5;
}
}
}

View File

@ -20,6 +20,10 @@
.n-tab-label {
box-sizing: border-box;
padding-bottom: 7px;
vertical-align: bottom;
.n-tab-label__label {
font-size: 16px;
}
&:hover {
.n-tab-label__label {
color: #63E2B7;
@ -30,7 +34,6 @@
}
&.n-tab-label--active {
.n-tab-label__label {
font-size: 16px;
color: #63E2B7;
}
}
@ -61,6 +64,10 @@
line-height: 34px;
padding: 0 16px;
position: relative;
vertical-align: bottom;
.n-tab-label__label {
font-size: 16px;
}
.n-tab-label__corner {
position: absolute;
height: 4px;

View File

@ -43,6 +43,8 @@
@import './BasePicker.scss';
@import './BaseSelectMenu.scss';
@import './Transfer.scss';
@import './Spin.scss';
@import './Drawer.scss';
@import "./NimbusServiceLayout.scss";
@import "./Popover.scss";

View File

@ -188,7 +188,7 @@ $scrollbar-color--hover: rgba(255,255,255,0.3);
}
}
@mixin fade-in-transition($block, $duration: .2s) {
@mixin fade-in-transition($block: "fade-in", $duration: .2s) {
&.#{$namespace}-#{$block}--transition-enter-active,
&.#{$namespace}-#{$block}--transition-leave-active {
opacity: 1;
@ -220,6 +220,27 @@ $scrollbar-color--hover: rgba(255,255,255,0.3);
}
}
@mixin slide-in-from-right-transition($duration: .3s) {
&.#{$namespace}-slide-in-from-right-leave-active {
transition: transform $duration cubic-bezier(.78, .14, .15, .86);
}
&.#{$namespace}-slide-in-from-right-enter-active {
transition: transform $duration cubic-bezier(.7, .3, .1, 1);
}
&.#{$namespace}-slide-in-from-right-enter-to {
transform: translateX(0);
}
&.#{$namespace}-slide-in-from-right-enter {
transform: translateX(100%);
}
&.#{$namespace}-slide-in-from-right-leave {
transform: translateX(0);
}
&.#{$namespace}-slide-in-from-right-leave-to {
transform: translateX(100%);
}
}
@mixin slide-right-transition($block, $duration: .3s, $delay: .3s) {
&.#{$namespace}-#{$block}--transition-leave-active {
transition: transform $duration $slow-out-cubic-bezier, max-height $duration $default-cubic-bezier $delay;