mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-01 13:36:55 +08:00
feat: notification
This commit is contained in:
parent
b342cd82e4
commit
6c1e292422
58
demo/components/notificationDemo.vue
Normal file
58
demo/components/notificationDemo.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div
|
||||
ref="doc"
|
||||
class="doc"
|
||||
>
|
||||
<h1>Message</h1>
|
||||
<hr>
|
||||
<h2>基本用法</h2>
|
||||
<button @click="emitMessage">
|
||||
爱你那么用力,却好像一场闹剧
|
||||
</button>
|
||||
<br><br>
|
||||
<textarea rows="5"><button @click="emitMessage">
|
||||
爱你那么用力,却好像一场闹剧
|
||||
</button>
|
||||
|
||||
<script>
|
||||
emitMessage () {
|
||||
this.$NMessage.error('Oops, here is a error')
|
||||
this.$NMessage.success('Cloned Successfully')
|
||||
}
|
||||
</script>
|
||||
|
||||
</textarea>
|
||||
<hr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import docCodeEditorMixin from './docCodeEditorMixin'
|
||||
export default {
|
||||
mixins: [docCodeEditorMixin],
|
||||
methods: {
|
||||
emitMessage () {
|
||||
this.$NNotification.notify({
|
||||
title: 'Notification',
|
||||
titleMeta: 'From Xingyue Feng',
|
||||
content: 'VTS has been edited by admin',
|
||||
meta: '2019-5-27 15:11',
|
||||
action: 'Mark as read',
|
||||
actionCallback: () => {}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.doc {
|
||||
width: 900px;
|
||||
margin: auto;
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 3em;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -14,7 +14,7 @@
|
||||
This is the contextual help
|
||||
</div>
|
||||
</n-tooltip>
|
||||
<br>
|
||||
<br><br>
|
||||
<textarea rows="5"><n-tooltip>
|
||||
<template v-slot:activator>
|
||||
scaffold
|
||||
|
@ -54,6 +54,10 @@
|
||||
<router-link to="/n-tooltip">
|
||||
帮助 / n-tooltip
|
||||
</router-link>
|
||||
<br>
|
||||
<router-link to="/n-notification">
|
||||
通知 / $NNotification
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -20,6 +20,7 @@ import Select from '../packages/common/Select'
|
||||
import Modal from '../packages/common/Modal'
|
||||
import Message from '../packages/common/Message'
|
||||
import Tooltip from '../packages/common/Tooltip'
|
||||
import Notification from '../packages/common/Notification'
|
||||
|
||||
import ServiceCard from 'packages/nimbus/ServiceCard'
|
||||
import HomeLayout from 'packages/nimbus/HomeLayout'
|
||||
@ -41,6 +42,7 @@ import modalDemo from './components/modalDemo'
|
||||
import nimbusFormCardDemo from './components/nimbusFormCardDemo'
|
||||
import messageDemo from './components/messageDemo'
|
||||
import tooltipDemo from './components/tooltipDemo'
|
||||
import notificationDemo from './components/notificationDemo'
|
||||
import demo from './demo'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
@ -67,6 +69,7 @@ Modal.install(Vue)
|
||||
NimbusFormCard.install(Vue)
|
||||
Message.install(Vue)
|
||||
Tooltip.install(Vue)
|
||||
Notification.install(Vue)
|
||||
|
||||
const routes = [
|
||||
{ path: '/', component: demo },
|
||||
@ -83,7 +86,8 @@ const routes = [
|
||||
{ path: '/n-modal', component: modalDemo },
|
||||
{ path: '/n-nimbus-form-card', component: nimbusFormCardDemo },
|
||||
{ path: '/n-message', component: messageDemo },
|
||||
{ path: '/n-tooltip', component: tooltipDemo }
|
||||
{ path: '/n-tooltip', component: tooltipDemo },
|
||||
{ path: '/n-notification', component: notificationDemo }
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
|
2
index.js
2
index.js
@ -13,6 +13,7 @@ import Switch from './packages/common/Switch'
|
||||
import Select from './packages/common/Select'
|
||||
import Modal from './packages/common/Modal'
|
||||
import Input from './packages/common/Input'
|
||||
import Message from './packages/common/Message'
|
||||
|
||||
import ServiceCard from './packages/nimbus/ServiceCard'
|
||||
import HomeLayout from './packages/nimbus/HomeLayout'
|
||||
@ -41,6 +42,7 @@ function installUiToVue (Vue) {
|
||||
Modal.install(Vue)
|
||||
NimbusFormCard.install(Vue)
|
||||
Input.install(Vue)
|
||||
Message.install(Vue)
|
||||
}
|
||||
|
||||
export default installUiToVue
|
||||
|
7
packages/common/Notification/index.js
Normal file
7
packages/common/Notification/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
import Notification from './src/main.js'
|
||||
|
||||
Notification.install = function (Vue) {
|
||||
Vue.prototype.$NNotification = Notification
|
||||
}
|
||||
|
||||
export default Notification
|
53
packages/common/Notification/src/MessageCell.vue
Normal file
53
packages/common/Notification/src/MessageCell.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div
|
||||
class="n-notification__cell"
|
||||
:class="{
|
||||
[`n-notification__cell--${type}`]: true
|
||||
}"
|
||||
>
|
||||
<div class="n-notification-cell__avator" />
|
||||
<div class="n-notification-cell__body">
|
||||
<div class="n-notification-cell__header">
|
||||
{{ notification.title }}
|
||||
</div>
|
||||
<div class="n-notification-cell__title-meta">
|
||||
{{ notification.titleMeta }}
|
||||
</div>
|
||||
<div class="n-notification-cell__content">
|
||||
{{ notification.content }}
|
||||
</div>
|
||||
<div class="n-notification-cell__footer">
|
||||
<div class="n-notification-cell__meta">
|
||||
{{ notification.meta }}
|
||||
</div>
|
||||
<div class="n-notification-cell__action">
|
||||
{{ notification.action }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NIcon from '../../Icon/index'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NIcon
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'success'
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
notification: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
57
packages/common/Notification/src/main.js
Normal file
57
packages/common/Notification/src/main.js
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
import Vue from 'vue'
|
||||
import NMessageCell from './MessageCell'
|
||||
|
||||
function attachMessageContainer () {
|
||||
let notificationContainer = document.querySelector('.n-notification.n-notification__container')
|
||||
console.log(notificationContainer)
|
||||
if (!notificationContainer) {
|
||||
notificationContainer = document.createElement('div')
|
||||
notificationContainer.classList.add('n-notification', 'n-notification__container')
|
||||
notificationContainer.style = `
|
||||
z-index: 300;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
`
|
||||
document.body.appendChild(notificationContainer)
|
||||
}
|
||||
return notificationContainer
|
||||
}
|
||||
|
||||
const defaultOptions = {
|
||||
timeout: 50000,
|
||||
emergeTransitionTimeout: 300,
|
||||
vanishTransitionTimeout: 300
|
||||
}
|
||||
|
||||
function registerMessageEl (container, el, option) {
|
||||
el.classList.add('is-going-to-emerge')
|
||||
container.appendChild(el)
|
||||
el.getBoundingClientRect()
|
||||
el.classList.remove('is-going-to-emerge')
|
||||
setTimeout(function () {
|
||||
setTimeout(function () {
|
||||
setTimeout(function () {
|
||||
container.removeChild(el)
|
||||
}, option.vanishTransitionTimeout)
|
||||
el.classList.add('is-vanishing')
|
||||
}, option.timeout)
|
||||
}, option.emergeTransitionTimeout)
|
||||
}
|
||||
|
||||
const NMessage = {
|
||||
notify (notification, type = 'success', option = defaultOptions) {
|
||||
const notificationContainer = attachMessageContainer()
|
||||
const notificationCell = (new Vue({ ...NMessageCell, propsData: { type, notification: notification } })).$mount()
|
||||
registerMessageEl(notificationContainer, notificationCell.$el, option)
|
||||
}
|
||||
}
|
||||
|
||||
export default NMessage
|
@ -44,10 +44,15 @@ export default {
|
||||
}
|
||||
this.isHidden = false
|
||||
this.hasEmerged = true
|
||||
this.$nextTick(() => {
|
||||
this.$el.getBoundingClientRect()
|
||||
this.hasEmerged = false
|
||||
})
|
||||
this
|
||||
.$nextTick()
|
||||
.then(vm => {
|
||||
vm.$el.getBoundingClientRect()
|
||||
return this.$nextTick()
|
||||
})
|
||||
.then(vm => {
|
||||
vm.hasEmerged = false
|
||||
})
|
||||
},
|
||||
handleMouseLeave (x) {
|
||||
this.isVanishing = true
|
||||
|
@ -131,8 +131,8 @@ export default {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.body {
|
||||
& {
|
||||
padding: 21px 48px;
|
||||
|
107
styles/Notification.scss
Normal file
107
styles/Notification.scss
Normal file
@ -0,0 +1,107 @@
|
||||
@import './mixins/mixins.scss';
|
||||
@import './theme/default.scss';
|
||||
|
||||
@include b(notification) {
|
||||
&.n-notification__container {
|
||||
.n-notification__cell {
|
||||
&.is-going-to-emerge {
|
||||
opacity: 0;
|
||||
transform: translateX(calc(100% + 15px));
|
||||
max-height: 0px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
& {
|
||||
position: relative;
|
||||
transform: translateX(0);
|
||||
display: flex;
|
||||
transition: opacity .3s $default-cubic-bezier, transform .3s $default-cubic-bezier, max-height .3s $default-cubic-bezier, margin-bottom .3s $default-cubic-bezier;
|
||||
opacity: 1;
|
||||
margin-bottom: 9px;
|
||||
width:365px;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
max-height: 400px;
|
||||
background:linear-gradient(225deg,rgba(91,197,161,1) 0%,rgba(116,127,157,1) 100%);
|
||||
box-shadow:0px 2px 25px 0px rgba(0,0,0,0.5);
|
||||
border-radius:6px;
|
||||
flex-shrink: 0;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
.n-notification-cell__avator {
|
||||
position: absolute;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 14px;
|
||||
background-color: #59C3B2FF;
|
||||
left: 15px;
|
||||
top: 15px;
|
||||
}
|
||||
.n-notification-cell__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 41px;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
color: #ffffff;
|
||||
.n-notification-cell__header {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.n-notification-cell__title-meta {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.n-notification-cell__title-meta, .n-notification-cell__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,.4);
|
||||
}
|
||||
.n-notification-cell__content {
|
||||
color: #ffffff;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
.n-notification-cell__action {
|
||||
cursor: pointer;
|
||||
color: #00FFA9FF;
|
||||
}
|
||||
.n-notification-cell__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
.n-notification-cell__icon {
|
||||
margin-right: 11px;
|
||||
display: inline-flex;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
align-items: center;
|
||||
i::before {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
&.n-notification__cell--success {
|
||||
background-color: #2F6C66FF;
|
||||
.n-notification-cell__icon {
|
||||
i::before {
|
||||
color: #63E2B7FF
|
||||
}
|
||||
}
|
||||
}
|
||||
&.n-notification__cell--error {
|
||||
background-color: #D03A52FF;
|
||||
.n-notification-cell__icon {
|
||||
i::before {
|
||||
color: #FF92A4FF
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.is-vanishing {
|
||||
opacity: 0;
|
||||
transform: translateX(calc(100% + 15px));
|
||||
max-height: 0px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,15 +10,15 @@
|
||||
display: none;
|
||||
}
|
||||
.n-tooltip__popup.has-emerged {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
opacity: .5;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
}
|
||||
.n-tooltip__popup {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
transform: translateX(-50%) translateY(0px);
|
||||
padding-top: 2px;
|
||||
opacity: 1;
|
||||
transition: opacity .3s $default-cubic-bezier, transform .3s $default-cubic-bezier;
|
||||
@ -33,5 +33,6 @@
|
||||
}
|
||||
.n-tooltip__popup.is-vanishing {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
}
|
||||
}
|
@ -15,5 +15,6 @@
|
||||
@import './Select.scss';
|
||||
@import './Message.scss';
|
||||
@import './Tooltip.scss';
|
||||
@import './Notification.scss';
|
||||
|
||||
@import './NimbusServiceLayout.scss';
|
Loading…
Reference in New Issue
Block a user