-
-
-
-
+
+
+
+
-
+
diff --git a/src/notification/src/NotificationPlugin.js b/src/notification/src/NotificationPlugin.js
deleted file mode 100644
index d1fb8270e..000000000
--- a/src/notification/src/NotificationPlugin.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import NNotificationEnvironment from './NotificationEnvironment'
-import NNotificationContainer from './NotificationContainer'
-
-function mountNotificationContainer () {
- let container = Notification.container
- if (!container) {
- container = new Notification.Vue(Object.assign(NNotificationContainer, {
- propsData: {
- scrollable: Notification.scrollable
- }
- }))
- container.$mount()
- Notification.container = container
- document.body.appendChild(container.$el)
- }
- return container
-}
-
-function unmountNotificationContainer () {
- const container = Notification.container
- if (Notification.instances.size) {
- const instances = Array.from(Notification.instances)
- instances.forEach(unmountNotification)
- }
- if (container) {
- const el = container.$el
- if (el && el.parentElement) {
- el.parentElement.removeChild(el)
- }
- container.$destroy()
- Notification.container = null
- }
-}
-
-function createNotification (option) {
- const instance = new Notification.Vue(Object.assign(
- NNotificationEnvironment,
- {
- propsData: {
- onDestroy: unmountNotification,
- duration: option.duration
- }
- }
- ))
- updateNotification(instance, option)
- return instance
-}
-
-function mountNotification (instance) {
- if (!Notification.container) {
- throw new Error('[naive-ui/notification]: container not exist when try to mount notification')
- }
- Notification.instances.add(instance)
- instance.$mount()
- const el = instance.$el
- if (Notification.scrollable) {
- const slot = Notification.container.$refs.scrollbar.$refs.scrollContent
- slot.appendChild(el)
- } else {
- const slot = Notification.container.$el
- slot.appendChild(el)
- }
-}
-
-function unmountNotification (instance) {
- Notification.instances.delete(instance)
- const el = instance.$el
- if (el && el.parentElement) {
- el.parentElement.removeChild(el)
- }
- instance.$destroy()
- if (!Notification.instances.size) {
- unmountNotificationContainer()
- }
-}
-
-function updateNotification (instance, option) {
- Object.keys(option).forEach(key => {
- if (instance.hasOwnProperty(key)) {
- instance[key] = option[key]
- }
- })
-}
-
-const Notification = {
- theme: null,
- inheritedTheme: null,
- instances: new Set(),
- container: null,
- _scrollable: false,
- get scrollable () {
- return Notification._scrollable
- },
- set scrollable (value) {
- if (value !== Notification._scrollable) {
- Notification._scrollable = value
- unmountNotificationContainer()
- }
- },
- handleThemeChange (theme) {
- const container = Notification.container
- Notification.inheritedTheme = theme
- const syntheticTheme = Notification.theme || Notification.inheritedTheme
- if (container) {
- container.theme = syntheticTheme
- }
- Notification.instances.forEach(instance => {
- instance.inheritedTheme = syntheticTheme
- })
- },
- open (options, type = 'default') {
- mountNotificationContainer()
- const syntheticTheme = Notification.theme || Notification.inheritedTheme
- if (Notification.container && syntheticTheme) {
- Notification.container.theme = syntheticTheme
- }
- const notificationOptions = { type, ...options, inheritedTheme: syntheticTheme }
- const instance = createNotification(notificationOptions)
- mountNotification(instance)
- return instance
- },
- success (option) {
- return this.open(option, 'success')
- },
- info (option) {
- return this.open(option, 'info')
- },
- warning (option) {
- return this.open(option, 'warning')
- },
- error (option) {
- return this.open(option, 'error')
- }
-}
-
-export default Notification
diff --git a/src/notification/src/NotificationProvider.js b/src/notification/src/NotificationProvider.js
new file mode 100644
index 000000000..28df27b59
--- /dev/null
+++ b/src/notification/src/NotificationProvider.js
@@ -0,0 +1,92 @@
+import { Fragment, h, Teleport, reactive, ref } from 'vue'
+import createId from '../../_utils/vue/createId'
+import NotificationContainer from './NotificationContainer'
+import NotificationEnvironment from './NotificationEnvironment'
+import omit from '../../_utils/vue/omit'
+
+export default {
+ name: 'NotificationProvider',
+ provide () {
+ return {
+ notification: {
+ create: this.create,
+ info: this.info,
+ success: this.success,
+ warning: this.warning,
+ error: this.error
+ }
+ }
+ },
+ props: {
+ to: {
+ type: [String, Object],
+ default: 'body'
+ },
+ scrollable: {
+ type: Boolean,
+ default: true
+ }
+ },
+ setup () {
+ const notificationListRef = ref([])
+ return {
+ notificationList: notificationListRef
+ }
+ },
+ methods: {
+ create (options) {
+ const key = createId()
+ const notificationReactive = reactive({
+ ...options,
+ key,
+ destroy: () => this.$refs[`n-notification-${key}`].hide()
+ })
+ this.notificationList.push(notificationReactive)
+ return notificationReactive
+ },
+ ...[
+ 'info',
+ 'success',
+ 'warning',
+ 'error'
+ ].reduce((api, type) => {
+ api[type] = function (options) {
+ return this.create({ ...options, type })
+ }
+ return api
+ }, {}),
+ handleAfterLeave (key) {
+ const { notificationList } = this
+ notificationList.splice(
+ notificationList.findIndex(notification => notification.key === key),
+ 1
+ )
+ },
+ // deprecated
+ open (...args) {
+ return this.create(...args)
+ }
+ },
+ render () {
+ return h(Fragment, null, [
+ h(Teleport, {
+ to: this.to
+ }, [
+ this.notificationList.length ? h(NotificationContainer, {
+ scrollable: this.scrollable
+ }, {
+ default: () => {
+ return this.notificationList.map(
+ notification => h(NotificationEnvironment, {
+ ref: `n-notification-${notification.key}`,
+ ...omit(notification, ['destroy']),
+ onInternalAfterLeave: this.handleAfterLeave
+ })
+ )
+ }
+ }) : null
+ ]),
+ this.$slots.default()
+ ])
+ }
+}
diff --git a/src/notification/src/styles/themed-base.cssr.js b/src/notification/src/styles/themed-base.cssr.js
index a61f48981..8e9ac9bd5 100644
--- a/src/notification/src/styles/themed-base.cssr.js
+++ b/src/notification/src/styles/themed-base.cssr.js
@@ -109,24 +109,24 @@ export default c([
// TODO: refactor type styles & transition
['success', 'info', 'warning', 'error', 'default']
.map(type => typeStyle(type, props.$local[createKey('iconColor', type)])),
- c('&-transition-enter, &-transition-leave-to', {
+ c('&-transition-enter-from, &-transition-leave-to', {
raw: `
opacity: 0;
margin-bottom: 0;
transform: translateX(calc(100% + 16px));
`
}),
- c('&-transition-leave, &-transition-enter-to', {
+ c('&-transition-leave-from, &-transition-enter-to', {
raw: `
opacity: 1;
transform: translateX(0);
`
}),
- cM('no-avatar', [
+ cM('show-avatar', [
cB('notification-main', {
raw: `
- margin-left: 8px;
- width: calc(100% - 8px);
+ margin-left: 40px;
+ width: calc(100% - 40px);
`
})
]),
@@ -188,8 +188,8 @@ export default c([
box-sizing: border-box;
display: flex;
flex-direction: column;
- margin-left: 40px;
- width: calc(100% - 40px);
+ margin-left: 8px;
+ width: calc(100% - 8px);
`
}, [
cB('notification-main-footer', {
diff --git a/vue3.md b/vue3.md
index 4070f710b..2fc2ca5a6 100644
--- a/vue3.md
+++ b/vue3.md
@@ -52,7 +52,7 @@ placeable 进行了大调整
- deprecate `onAfterHide`, new `onAfterLeave`
- remove `hide` on message instance, new `destroy`
- TODO: update enUS docs
-- [ ] modal
+- [x] modal
- rewrite with teleport
- deprecate v-model show hide
- add prop `display-directive`
@@ -60,6 +60,10 @@ placeable 进行了大调整
- deprecate `overlay-style`, use `body-style`
- TODO: update docs, scrollbar mouseup
- [ ] notification
+ - deprecate `open`, use `create`
+ - deprecate `onHide`, use `onLeave`
+ - deprecate `onAfterShow`, use `onAfterEnter`
+ - deprecate `onAfterHide`, use `onAfterHide`
- [ ] pagination
- [ ] popconfirm
- [ ] popover