refactor(dialog): support vue3

This commit is contained in:
07akioni 2020-09-27 13:53:16 +08:00
parent a65b88f3b2
commit 4e0e80992c
35 changed files with 384 additions and 344 deletions

View File

@ -15,7 +15,8 @@ module.exports = {
}
],
'vue/no-template-key': 0,
'vue/valid-template-root': 0
'vue/valid-template-root': 0,
'vue/valid-v-model': 0
},
overrides: [
{

View File

@ -7,17 +7,19 @@
>
<n-message-provider>
<n-notification-provider>
<n-layout position="absolute" class="root-layout">
<doc-header
:lang="lang"
:items="flattenedItems"
:env="env"
@lang-change="handleLangChange"
/>
<n-layout class="home-layout" style="top: 64px; overflow: hidden;" position="absolute">
<router-view />
<n-dialog-provider>
<n-layout position="absolute" class="root-layout">
<doc-header
:lang="lang"
:items="flattenedItems"
:env="env"
@lang-change="handleLangChange"
/>
<n-layout class="home-layout" style="top: 64px; overflow: hidden;" position="absolute">
<router-view />
</n-layout>
</n-layout>
</n-layout>
</n-dialog-provider>
</n-notification-provider>
</n-message-provider>
</n-config-provider>

View File

@ -75,7 +75,7 @@
<n-tag
v-if="env==='development'"
class="nav-picker"
@click.native="handleModeChange"
@click="handleModeChange"
>
{{ modeOptions[mode].label }}
</n-tag>
@ -165,7 +165,7 @@ export default {
},
zIndex () {
const path = this.$route.path
return (path.endsWith('n-modal') || path.endsWith('n-drawer') || path.endsWith('n-confirm')) ? null : 3000
return (path.endsWith('n-modal') || path.endsWith('n-drawer') || path.endsWith('n-dialog')) ? null : 3000
},
theme () {
return 'light'

View File

@ -1,33 +0,0 @@
# 异步
确认可以异步。
```html
<n-button @click="handleClick">
成功
</n-button>
```
```css
.n-button {
margin: 0 12px 8px 0;
}
```
```js
export default {
methods: {
handleClick(e) {
const confirmInstance = this.$NConfirm.success({
title: '异步',
content:
'点击,倒计时 3 秒',
positiveText: '确认',
onPositiveClick: () => {
confirmInstance.loading = true
this.$NMessage.success('倒计时 3 秒')
return new Promise(resolve => window.setTimeout(() => resolve(true), 3000))
}
})
}
}
}
```

View File

@ -0,0 +1,44 @@
# 异步
对话框可以异步。
```html
<n-button @click="handleClick">
成功
</n-button>
```
```css
.n-button {
margin: 0 12px 8px 0;
}
```
```js
const sleep = () => new Promise(resolve => setTimeout(resolve, 1000))
const countDown = second => `倒计时 ${second} 秒`
export default {
inject: [
'dialog'
],
methods: {
handleClick(e) {
const dialog = this.dialog.success({
title: '异步',
content:
'点击,倒计时 3 秒',
positiveText: '确认',
onPositiveClick: () => {
dialog.loading = true
return new Promise(resolve => {
sleep()
.then(() => { dialog.content = countDown(2); return sleep() })
.then(() => { dialog.content = countDown(1); return sleep() })
.then(() => { dialog.content = countDown(0) })
.then(resolve)
})
}
})
}
}
}
```

View File

@ -1,5 +1,5 @@
# 基础用法
使用 `$NConfirm` 来创建一个确认弹框。
注入 `dialog` 来创建一个弹框。
```html
<n-button @click="handleConfirm">
警告
@ -18,39 +18,43 @@
```
```js
export default {
inject: [
'dialog',
'message'
],
methods: {
handleConfirm (e) {
const confirmInstance = this.$NConfirm.warning({
this.dialog.warning({
title: '警告',
content: '你确定?',
positiveText: '确定',
negativeText: '不确定',
onPositiveClick: () => {
this.$NMessage.success('确定')
this.message.success('确定')
},
onNegativeClick: () => {
this.$NMessage.error('不确定')
this.message.error('不确定')
}
})
},
handleSuccess (e) {
const confirmInstance = this.$NConfirm.success({
this.dialog.success({
title: '成功',
content:
'厉害',
positiveText: '哇',
onPositiveClick: () => {
this.$NMessage.success('耶!')
this.message.success('耶!')
}
})
},
handleError(e) {
const confirmInstance = this.$NConfirm.error({
handleError (e) {
this.dialog.error({
title: '错误',
content: '错了',
positiveText: '啊',
onPositiveClick: () => {
this.$NMessage.success('我就知道')
this.message.success('我就知道')
}
})
}

View File

@ -1,4 +1,4 @@
# 确认 Confirm
# 对话框 Dialog
执行之前,请确认。
## 演示
@ -7,16 +7,17 @@ basic
async
use-component
```
## API
### $NConfirm API
### Dialog Injection API
|名称|类型|说明|
|-|-|-|
|warning|`(options: ConfirmOption) => ConfirmEnvironment`||
|success|`(options: ConfirmOption) => ConfirmEnvironment`||
|error|`(options: ConfirmOption) => ConfirmEnvironment`||
|warning|`(options: DialogOption) => DialogReactive`||
|success|`(options: DialogOption) => DialogReactive`||
|error|`(options: DialogOption) => DialogReactive`||
|destroyAll|`() => void`||
### ConfirmOption API
### DialogOption API
|名称|类型|默认值|说明|
|-|-|-|-|
|theme|`'light' \| 'dark' \| null \| string`|`null`||
@ -34,8 +35,8 @@ use-component
|onNegativeClick|`() => boolean \| Promise<boolean> \| any`|`() => true`|默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为|
|onClose|`() => boolean \| Promise<boolean> \| any`|`() => true`|默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为|
### ConfirmEnvironment API
#### ConfirmEnvironment Properties
### DialogReactive API
#### DialogReactive Properties
下列属性都可以被动态修改。
|名称|类型|说明|
@ -55,13 +56,13 @@ use-component
|onNegativeClick|`() => boolean \| Promise<boolean> \| any`||
|onClose|`() => boolean \| Promise<boolean> \| any`||
#### ConfirmEnvironment Methods
#### DialogReactive Methods
|名称|类型|说明|
|-|-|-|
|hide|`()`|关闭 Confirm|
|destroy|`()`|关闭 Dialog|
## Props
### Confirm Props
### Dialog Props
|名称|类型|默认值|说明|
|-|-|-|-|
|type|`'error \| 'success' \| 'warning'`|`'warning'`||
@ -74,6 +75,9 @@ use-component
|show-icon|`boolean`|`true`||
|loading|`boolean`|`false`||
|bordered|`boolean`|`false`||
|on-positive-click|`() => any`||
|on-negative-click|`() => any`||
|on-close|`() => any`||
## Events
### Confirm Events

View File

@ -1,7 +1,7 @@
# 使用组件
有的时候你可能想把它用作一个组件
有的时候你可能想把它用作一个组件
```html
<n-confirm
<n-dialog
title="确认"
content="你确定"
:closable="false"
@ -13,14 +13,13 @@
```
```js
export default {
inject: ['message'],
methods: {
handleNegativeClick () {
this.$NMessage.warning('取消')
this.isActive = false
this.message.warning('取消')
},
handlePositiveClick () {
this.$NMessage.success('确认')
this.isActive = false
this.message.success('确认')
}
}
}

View File

@ -27,8 +27,8 @@ preset-confirm-slot
### Modal with Preset Card
See [Card props](n-card#Props)
### Modal with Preset Confirm
See [Confirm props](n-confirm#Props)
### Modal with Preset Dialog
See [Dialog props](n-dialog#Props)
## Slots
### Modal without Preset
@ -38,8 +38,8 @@ See [Confirm props](n-confirm#Props)
### Modal with Preset Card
See [Card slots](n-card#Slots)
### Modal with Preset Confirm
See [Confirm slots](n-confirm#Slots)
### Modal with Preset Dialog
See [Dialog slots](n-dialog#Slots)
## Events
### Modal
@ -49,5 +49,5 @@ See [Confirm slots](n-confirm#Slots)
### Modal with Preset Card
See [Card events](n-card#Events)
### Modal with Preset Confirm
See [Confirm events](n-confirm#Events)
### Modal with Preset Dialog
See [Dialog events](n-dialog#Events)

View File

@ -23,15 +23,15 @@ drawer-debug
|display-directive|`'if' \| 'show'`|`'if'`|使用何种指令控制模态框主体的条件渲染|
|mask-closable|`boolean`|`true`|点击遮罩时是否发出 `update:show` 事件|
|body-style|`Object \| null`|`null`|当使用 `preset` 时候主体的样式|
|preset|`'card' \| 'confirm' \| null`|`null`|模态框使用何种预设|
|preset|`'card' \| 'dialog' \| null`|`null`|模态框使用何种预设|
|show|`boolean`|`false`|是否展示 Modal|
|theme|`'light' \| 'dark' \| null \| string`|`null`||
|on-update:show|`(value: boolean) => any`||模态框更新是否展示状态的回调|
### ModalCard 预设)
参考 [Card props](n-card#Props)
### ModalConfirm 预设)
参考 [Confirm props](n-confirm#Props)
### ModalDialog 预设)
参考 [Dialog props](n-dialog#Props)
## Slots
### Modal无预设
@ -41,10 +41,5 @@ drawer-debug
### ModalCard 预设)
参考 [Card slots](n-card#Slots)
### ModalConfirm 预设)
参考 [Confirm slots](n-confirm#Slots)
### ModalCard 预设)
参考 [Card events](n-card#Events)
### ModalConfirm 预设)
参考 [Confirm events](n-confirm#Events)
### ModalDialog 预设)
参考 [Dialog slots](n-dialog#Slots)

View File

@ -12,13 +12,11 @@ no-icon
## Props
|名称|类型|默认值|说明|
|-|-|-|-|
|leave-on-negative-click|`boolean`|`true`||
|leave-on-positive-click|`boolean`|`true`||
|negative-text|`string`|`'取消'`||
|positive-text|`string`|`'确认'`||
|show-icon|`boolean`|`true`||
|on-positive-click|`() => any`|`undefined`||
|on-negative-click|`() => any`|`undefined`||
|on-positive-click|`() => boolean \| Promise<boolean> \| any`|`() => true`||
|on-negative-click|`() => boolean \| Promise<boolean> \| any`|`() => true`||
更多 props 请参考 [Popover](n-popover#Props).

View File

@ -434,10 +434,10 @@ export default function (instance) {
path: `/${lang}/${theme}/doc` + '/n-badge'
},
{
name: 'Confirm',
name: 'Dialog',
title: '确认',
titleExtra: 'Confirm',
path: `/${lang}/${theme}/doc` + '/n-confirm'
titleExtra: 'Dialog',
path: `/${lang}/${theme}/doc` + '/n-dialog'
},
{
name: 'Drawer',
@ -783,8 +783,8 @@ export default function (instance) {
path: `/${lang}/${theme}/doc` + '/n-badge'
},
{
name: 'Confirm',
path: `/${lang}/${theme}/doc` + '/n-confirm'
name: 'Dialog',
path: `/${lang}/${theme}/doc` + '/n-dialog'
},
{
name: 'Drawer',

View File

@ -29,7 +29,7 @@ import radio from '../documentation/components/radio'
import form from '../documentation/components/form'
import tabs from '../documentation/components/tabs'
import timePicker from '../documentation/components/time-picker'
import confirm from '../documentation/components/confirm'
import dialog from '../documentation/components/dialog'
import backTop from '../documentation/components/back-top'
import dropdown from '../documentation/components/dropdown'
import badge from '../documentation/components/badge'
@ -112,7 +112,7 @@ export const childRoutes = withPrefix('/:lang/:theme/doc', [
{ path: '/n-form', component: form },
{ path: '/n-tabs', component: tabs },
{ path: '/n-time-picker', component: timePicker },
{ path: '/n-confirm', component: confirm },
{ path: '/n-dialog', component: dialog },
{ path: '/n-badge', component: badge },
{ path: '/n-steps', component: steps },
{ path: '/n-collapse', component: collapse },

View File

@ -1,14 +0,0 @@
import ConfirmPlugin from './src/ConfirmPlugin.js'
import Confirm from './src/Confirm'
import { install } from '../_utils/naive/installThemeAwarableProperty'
ConfirmPlugin.install = function (app, naive) {
ConfirmPlugin.Vue = app
install(app, ConfirmPlugin, '$NConfirm')
app.component(naive.componentPrefix + Confirm.name, Confirm)
/** deprecated names */
app.component('NNimbusConfirmCard', Confirm)
install(app, ConfirmPlugin, '$NModal')
}
export default ConfirmPlugin

View File

@ -1,83 +0,0 @@
import ConfirmEnvironment from './ConfirmEnvironment.vue'
function updateConfirm (data, instance) {
for (const key of Object.keys(data)) {
if (key in instance.$data) {
instance.$data[key] = data[key]
}
}
}
export default {
name: 'NConfirm',
theme: null,
inheritedTheme: null,
instances: new Set(),
handleThemeChange (theme) {
this.inheritedTheme = theme
const syntheticTheme = this.theme || this.inheritedTheme
for (const instance of this.instances) {
instance.inheritedTheme = syntheticTheme
}
},
createInstance () {
const instance = new this.Vue(ConfirmEnvironment)
instance.$mount()
this.instances.add(instance)
instance.instances = this.instances
return instance
},
confirm (options) {
this.open.bind(this)(options)
},
open (options) {
this.warning(options)
},
warning (options) {
const instance = this.createInstance()
const syntheticTheme = this.theme || this.inheritedTheme
updateConfirm(
{
type: 'warning',
active: true,
...options,
inheritedTheme: syntheticTheme
},
instance
)
return instance
},
error (options) {
const instance = this.createInstance()
const syntheticTheme = this.theme || this.inheritedTheme
updateConfirm(
{
type: 'error',
active: true,
...options,
inheritedTheme: syntheticTheme
},
instance
)
return instance
},
success (options) {
const instance = this.createInstance()
const syntheticTheme = this.theme || this.inheritedTheme
updateConfirm(
{
type: 'success',
active: true,
...options,
inheritedTheme: syntheticTheme
},
instance
)
return instance
},
destroyAll () {
this.instances.forEach(instance => {
instance.active = false
})
}
}

12
src/dialog/index.js Normal file
View File

@ -0,0 +1,12 @@
import Dialog from './src/Dialog'
import DialogProvider from './src/DialogProvider'
DialogProvider.install = function (app, naive) {
app.component(naive.componentPrefix + DialogProvider.name, DialogProvider)
app.component(naive.componentPrefix + Dialog.name, Dialog)
// deprecated
app.component('NNimbusConfirmCard', Dialog)
app.component(naive.componentPrefix + 'Confirm', Dialog)
}
export default DialogProvider

View File

@ -29,12 +29,11 @@
<n-icon
v-if="closable"
class="n-confirm-title__close"
type="md-close"
size="22"
style="cursor:pointer;"
@click="handleCloseClick"
>
<md-close />
<close-icon />
</n-icon>
</div>
<div class="n-confirm__content">
@ -67,36 +66,40 @@
</div>
</div>
</template>
<script>
import NIcon from '../../icon'
import NButton from '../../button'
import iosCheckmarkCircle from '../../_icons/ios-checkmark-circle'
import mdClose from '../../_icons/md-close'
import iosHelpCircle from '../../_icons/ios-help-circle'
import iosCloseCircle from '../../_icons/ios-close-circle'
import withapp from '../../_mixins/withapp'
import themeable from '../../_mixins/themeable'
import render from '../../_utils/vue/render'
import asthemecontext from '../../_mixins/asthemecontext'
import usecssr from '../../_mixins/usecssr'
import NIcon from '../../icon'
import NButton from '../../button'
import SuccessIcon from '../../_icons/ios-checkmark-circle'
import CloseIcon from '../../_icons/md-close'
import WarningIcon from '../../_icons/ios-help-circle'
import ErrorIcon from '../../_icons/ios-close-circle'
import styles from './styles/index.js'
export default {
name: 'Confirm',
name: 'Dialog',
components: {
NIcon,
NButton,
mdClose,
iosHelpCircle,
iosCheckmarkCircle,
iosCloseCircle,
CloseIcon,
WarningIcon,
SuccessIcon,
ErrorIcon,
render
},
mixins: [withapp, themeable, asthemecontext, usecssr(styles)],
mixins: [
withapp,
themeable,
usecssr(styles)
],
props: {
icon: {
type: Function,
default: null
default: undefined
},
type: {
type: String,
@ -104,7 +107,7 @@ export default {
},
title: {
type: [String, Function],
default: null
default: undefined
},
closable: {
type: Boolean,
@ -112,15 +115,15 @@ export default {
},
negativeText: {
type: String,
default: null
default: undefined
},
positiveText: {
type: String,
default: null
default: undefined
},
content: {
type: [String, Function],
default: null
default: undefined
},
showIcon: {
type: Boolean,
@ -134,30 +137,41 @@ export default {
type: Boolean,
default: false
},
themeContextActivated: {
type: Boolean,
default: false
onPositiveClick: {
type: Function,
default: undefined
},
onNegativeClick: {
type: Function,
default: undefined
},
onClose: {
type: Function,
default: undefined
}
},
computed: {
iconType () {
const colors = {
error: 'ios-close-circle',
warning: 'ios-help-circle',
success: 'ios-checkmark-circle'
const iconName = {
error: 'error-icon',
warning: 'warning-icon',
success: 'success-icon'
}
return colors[this.type]
return iconName[this.type]
}
},
methods: {
handlePositiveClick () {
this.$emit('positive-click')
const { onPositiveClick } = this
if (onPositiveClick) onPositiveClick()
},
handleNegativeClick () {
this.$emit('negative-click')
const { onNegativeClick } = this
if (onNegativeClick) onNegativeClick()
},
handleCloseClick () {
this.$emit('close')
const { onClose } = this
if (onClose) onClose()
}
}
}

View File

@ -1,13 +1,12 @@
<template>
<n-modal
v-model="active"
:theme="syntheticTheme"
:activate-event="event"
v-model:show="show"
appear
:to="to"
:mask-closable="maskClosable"
@after-hide="handleAfterHide"
@after-leave="handleAfterHide"
>
<n-confirm
:theme="syntheticTheme"
<n-dialog
:type="type"
:content="content"
:positive-text="positiveText"
@ -17,7 +16,6 @@
:closable="closable"
:show-icon="showIcon"
:bordered="bordered"
theme-context-activated
@close="handleCloseClick"
@negative-click="handleNegativeClick"
@positive-click="handlePositiveClick"
@ -27,46 +25,50 @@
<script>
import NModal from '../../modal'
import NConfirm from './Confirm'
import NDialog from './Dialog'
export default {
name: 'NConfirm',
name: 'DialogEnvironment',
components: {
NModal,
NConfirm
NDialog
},
props: {
...NDialog.props,
maskClosable: {
type: Boolean,
default: true
},
onPositiveClick: {
type: Function,
default: () => true
},
onNegativeClick: {
type: Function,
default: () => true
},
onClose: {
type: Function,
default: () => true
},
to: {
type: [String, Object],
default: undefined
},
// private
onInternalAfterLeave: {
type: Function,
required: true
}
},
data () {
return {
theme: null,
inheritedTheme: null,
maskClosable: true,
active: false,
content: null,
icon: null,
positiveText: null,
negativeText: null,
type: 'warning',
title: null,
loading: false,
event: null,
onPositiveClick: () => true,
onNegativeClick: () => true,
onClose: () => true,
instances: null,
closable: true,
showIcon: true,
bordered: false
}
},
computed: {
syntheticTheme () {
return this.theme || this.inheritedTheme
show: true
}
},
methods: {
handleAfterHide () {
this.instances.delete(this)
this.$destroy()
this.onInternalAfterLeave(this._.vnode.key)
},
handlePositiveClick () {
Promise.resolve(
@ -76,7 +78,6 @@ export default {
if (result === false) return
this.hide()
})
.catch(err => console.error(err))
},
handleNegativeClick () {
Promise.resolve(
@ -86,7 +87,6 @@ export default {
if (result === false) return
this.hide()
})
.catch(err => console.error(err))
},
handleCloseClick () {
Promise.resolve(
@ -96,10 +96,9 @@ export default {
if (result === false) return
this.hide()
})
.catch(err => console.error(err))
},
hide () {
this.active = false
this.show = false
}
}
}

View File

@ -0,0 +1,76 @@
import { Fragment, ref, h, reactive } from 'vue'
import { createId, omit } from '../../_utils/vue'
import DialogEnvironment from './DialogEnvironment.vue'
export default {
name: 'DialogProvider',
props: {
to: {
type: [String, Object],
default: 'body'
}
},
provide () {
return {
dialog: {
create: this.create,
success: this.success,
warning: this.warning,
error: this.error
}
}
},
setup () {
const dialogListRef = ref([])
return {
dialogList: dialogListRef
}
},
methods: {
create (options = {}) {
const key = createId()
const dialogReactive = reactive({
...options,
key,
destroy: () => {
this.$refs[`n-dialog-${key}`].hide()
}
})
this.dialogList.push(dialogReactive)
return dialogReactive
},
...[
'success',
'warning',
'error'
].reduce((api, type) => {
api[type] = function (options) {
return this.create({ ...options, type })
}
return api
}, {}),
handleAfterLeave (key) {
const { dialogList } = this
dialogList.splice(
dialogList.findIndex(dialog => dialog.key === key),
1
)
}
},
render () {
return h(Fragment, null,
[
this.dialogList.map(dialog => h(DialogEnvironment, omit(
dialog,
['destroy'],
{
to: dialog.to ?? this.to,
ref: `n-dialog-${dialog.key}`,
onInternalAfterLeave: this.handleAfterLeave
}
))),
this.$slots.default()
]
)
}
}

View File

@ -2,7 +2,7 @@ import create from '../../styles/_utils/create-component-base'
export default create({
theme: 'dark',
name: 'Confirm',
name: 'Dialog',
getDerivedVariables ({ base, derived }) {
const {
textColorPrimaryOverlay,

View File

@ -2,7 +2,7 @@ import create from '../../styles/_utils/create-component-base'
export default create({
theme: 'light',
name: 'Confirm',
name: 'Dialog',
getDerivedVariables ({ base, derived }) {
const {
textColorPrimary,

View File

@ -15,7 +15,7 @@ import Code from './code'
import Collapse from './collapse'
import ConfigConsumer from './config-consumer'
import ConfigProvider from './config-provider'
// import ConfirmPlugin from './confirm'
import Dialog from './dialog'
import DataTable from './data-table'
import DatePicker from './date-picker'
import Descriptions from './descriptions'
@ -98,8 +98,8 @@ import codeDarkStyle from './code/styles/dark'
import codeLightStyle from './code/styles/light'
import collapseDarkStyle from './collapse/styles/dark'
import collapseLightStyle from './collapse/styles/light'
import confirmDarkStyle from './confirm/styles/dark'
import confirmLightStyle from './confirm/styles/light'
import dialogDarkStyle from './dialog/styles/dark'
import dialogLightStyle from './dialog/styles/light'
import dataTableDarkStyle from './data-table/styles/dark'
import dataTableLightStyle from './data-table/styles/light'
import datePickerDarkStyle from './date-picker/styles/dark'
@ -249,7 +249,7 @@ export default create({
TimePicker,
Scrollbar,
Steps,
// ConfirmPlugin,
Dialog,
Progress,
Badge,
Tag,
@ -353,8 +353,8 @@ export default create({
dividerDarkStyle,
dynamicInputLightStyle,
dynamicInputDarkStyle,
confirmLightStyle,
confirmDarkStyle,
dialogLightStyle,
dialogDarkStyle,
gradientTextLightStyle,
gradientTextDarkStyle,
listDarkStyle,

View File

@ -13,25 +13,25 @@ export default {
},
onClose: {
type: Function,
default: () => {}
default: undefined
},
onAfterLeave: {
type: Function,
default: () => {}
default: undefined
},
// private
onInternalAfterLeave: {
type: Function,
default: () => {}
default: undefined
},
// deprecated
onHide: {
type: Function,
default: () => {}
default: undefined
},
onAfterHide: {
type: Function,
default: () => {}
default: undefined
}
},
data () {
@ -50,18 +50,20 @@ export default {
hide () {
const {
timerId,
onClose,
onHide
} = this
this.show = false
if (timerId) {
window.clearTimeout(timerId)
}
onClose()
// deprecated
onHide()
if (onHide) onHide()
},
handleClose () {
const {
onClose
} = this
if (onClose) onClose()
this.hide()
},
handleAfterLeave () {
@ -70,10 +72,10 @@ export default {
onInternalAfterLeave,
onAfterHide
} = this
onAfterLeave()
onInternalAfterLeave(this._.vnode.key)
if (onAfterLeave) onAfterLeave()
if (onInternalAfterLeave) onInternalAfterLeave(this._.vnode.key)
// deprecated
onAfterHide()
if (onAfterHide) onAfterHide()
},
// deprecated
deactivate () {

View File

@ -1,7 +1,6 @@
import { Fragment, Teleport, ref, h, reactive } from 'vue'
import { createId } from '../../_utils/vue'
import { createId, omit } from '../../_utils/vue'
import MessageEnvironment from './MessageEnvironment.js'
import omit from '../../_utils/vue/omit'
export default {
name: 'MessageProvider',

View File

@ -7,7 +7,7 @@
<n-scrollbar ref="scrollbar">
<transition
name="n-fade-in-scale-up-transition"
:appear="NModal.isMounted"
:appear="NModal.appear ?? NModal.isMounted"
@enter="handleEnter"
@after-leave="handleAfterLeave"
@before-leave="handleBeforeLeave"
@ -20,9 +20,8 @@
[`n-${theme}-theme`]: theme,
}"
>
<n-confirm
v-if="preset === 'confirm'"
ref="confirm"
<n-dialog
v-if="preset === 'confirm' || preset === 'dialog'"
:style="compitableBodyStyle"
:theme="theme"
:title="title"
@ -44,7 +43,7 @@
<template v-if="$slots.action" v-slot:action>
<slot name="action" />
</template>
</n-confirm>
</n-dialog>
<n-card
v-else-if="preset === 'card'"
:theme="theme"
@ -80,7 +79,7 @@
<script>
import { nextTick, reactive, toRefs, toRef, watch } from 'vue'
import NScrollbar from '../../scrollbar'
import NConfirm from '../../confirm/src/Confirm'
import NDialog from '../../dialog/src/Dialog'
import NCard from '../../card'
import themeable from '../../_mixins/themeable'
import presetProps from './presetProps'
@ -94,7 +93,7 @@ export default {
},
components: {
NScrollbar,
NConfirm,
NDialog,
NCard
},
mixins: [

View File

@ -5,7 +5,8 @@ import themeable from '../../_mixins/themeable'
import presetProps from './presetProps'
import usecssr from '../../_mixins/usecssr'
import { useIsMounted } from '../../_utils/composition'
import omit from '../../_utils/vue/omit'
import { warn } from '../../_utils/naive/warn'
import { omit } from '../../_utils/vue'
import NLazyTeleport from '../../_base/lazy-teleport'
import NModalMask from './Mask'
import NModalBodyWrapper from './BodyWrapper'
@ -50,41 +51,54 @@ export default {
// events
'onUpdate:show': {
type: Function,
default: () => {}
default: undefined
},
onPositiveClick: {
type: Function,
default: () => {}
default: undefined
},
onNegativeClick: {
type: Function,
default: () => {}
default: undefined
},
onClose: {
type: Function,
default: () => {}
default: undefined
},
// private
onBeforeLeave: {
type: Function,
default: () => {}
default: undefined
},
onAfterLeave: {
type: Function,
default: () => {}
default: undefined
},
appear: {
type: Boolean,
default: undefined
},
// deprecated
onBeforeHide: {
type: Function,
default: () => {}
validator () {
if (__DEV__) warn('modal', '`on-before-hide` is deprecated, please use `on-before-leave` instead.')
return true
},
default: undefined
},
onAfterHide: {
type: Function,
default: () => {}
validator () {
if (__DEV__) warn('modal', '`on-after-hide` is deprecated, please use `on-after-leave` instead.')
return true
},
default: undefined
},
onHide: {
type: Function,
default: () => {}
validator () {
if (__DEV__) warn('modal', '`on-hide` is deprecated.')
return true
},
default: undefined
}
},
setup () {
@ -94,9 +108,13 @@ export default {
},
methods: {
hide () {
this['onUpdate:show'](false)
// legacy
this.onHide(false)
const {
'onUpdate:show': onUpdateShow,
onHide
} = this
if (onUpdateShow) onUpdateShow(false)
// deprecated
if (onHide) onHide(false)
}
},
render () {
@ -119,7 +137,7 @@ export default {
h(Transition, {
name: 'n-fade-in-transition',
key: 'mask',
appear: this.isMounted
appear: this.appear ?? this.isMounted
}, {
default: () => {
return this.show ? [ h(NModalMask) ] : null
@ -132,23 +150,34 @@ export default {
theme: this.syntheticTheme,
show: this.show,
onClose: () => {
this.onClose()
const { onClose } = this
if (onClose) onClose()
},
onNegativeClick: () => {
this.onNegativeClick()
const { onNegativeClick } = this
if (onNegativeClick) onNegativeClick()
},
onPositiveClick: () => {
this.onPositiveClick()
const { onPositiveClick } = this
if (onPositiveClick) onPositiveClick()
},
onBeforeLeave: () => {
this.onBeforeLeave()
const {
onBeforeLeave,
onBeforeHide
} = this
if (onBeforeLeave) onBeforeLeave()
// deprecated
this.onBeforeHide()
if (onBeforeHide) onBeforeHide()
},
onAfterLeave: () => {
this.onAfterLeave()
const {
onAfterLeave,
onAfterHide
} = this
if (onAfterLeave) onAfterLeave()
// deprecated
this.onAfterHide()
if (onAfterHide) onAfterHide()
},
onClickoutside: () => {
if (this.maskClosable) {

View File

@ -8,9 +8,7 @@ const panelProps = [
'negativeText',
'showIcon',
'onPositiveClick',
'onNegativeClick',
'leaveOnNegativeClick',
'leaveOnPositiveClick'
'onNegativeClick'
]
export default {
@ -33,21 +31,13 @@ export default {
type: String,
default: 'click'
},
leaveOnPositiveClick: {
type: Boolean,
default: true
},
leaveOnNegativeClick: {
type: Boolean,
default: true
},
onPositiveClick: {
type: Function,
default: undefined
default: () => true
},
onNegativeClick: {
type: Function,
default: undefined
default: () => true
}
},
render () {
@ -67,26 +57,28 @@ export default {
onPositiveClick: () => {
const {
onPositiveClick,
leaveOnPositiveClick,
'onUpdate:show': onUpdateShow
} = this
if (onPositiveClick) onPositiveClick()
if (leaveOnPositiveClick) {
Promise.resolve(
onPositiveClick()
).then(value => {
if (!value) return
this.$refs.popover.setShow(false)
onUpdateShow(false)
}
})
},
onNegativeClick: () => {
const {
onNegativeClick,
leaveOnNegativeClick,
'onUpdate:show': onUpdateShow
} = this
if (onNegativeClick) onNegativeClick()
if (leaveOnNegativeClick) {
Promise.resolve(
onNegativeClick()
).then(value => {
if (!value) return
this.$refs.popover.setShow(false)
onUpdateShow(false)
}
})
}
}, {
action: slots.action,

View File

@ -44,7 +44,11 @@ placeable 进行了大调整
- `as` => `tag`
- new
- provide `useOsTheme` hook
- [ ] confirm
- [ ] confirm => `dialog`
- break
- rename `confirm` to `dialog`
- remove
- `$NConfirm`, `$NModal` => `inject.dialog`
- [ ] data-table
- [ ] date-picker
- [x] descriptions
@ -122,9 +126,6 @@ placeable 进行了大调整
- `on-change` => `on-update:page`
- `on-page-size-change` => `on-update:page-size`
- [x] popconfirm
- new
- `leave-on-positive-click`
- `leave-on-negative-click`
- [x] popover
- new
- `default-show`