add modal
parent
0346b11868
commit
c67e4103f4
|
@ -60,12 +60,9 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
render () {
|
render () {
|
||||||
console.log(props)
|
|
||||||
return getComponent(props)
|
return getComponent(props)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
this._component.$forceUpdate()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -111,7 +111,11 @@ export function getClass (ele) {
|
||||||
} else if (ele.$vnode && ele.$vnode.data) {
|
} else if (ele.$vnode && ele.$vnode.data) {
|
||||||
data = ele.$vnode.data
|
data = ele.$vnode.data
|
||||||
}
|
}
|
||||||
return data.class || data.staticClass
|
let cls = data.class || data.staticClass || {}
|
||||||
|
if (typeof cls === 'string') {
|
||||||
|
cls = cls.split(' ').forEach(c => { cls[c.trim()] = true })
|
||||||
|
}
|
||||||
|
return cls
|
||||||
}
|
}
|
||||||
export function getStyle (ele) {
|
export function getStyle (ele) {
|
||||||
let data = {}
|
let data = {}
|
||||||
|
@ -138,6 +142,10 @@ export function isEmptyElement (ele) {
|
||||||
export function filterEmpty (children = []) {
|
export function filterEmpty (children = []) {
|
||||||
return children.filter(c => c.tag || c.text.trim() !== '')
|
return children.filter(c => c.tag || c.text.trim() !== '')
|
||||||
}
|
}
|
||||||
|
const initDefaultProps = (propTypes, defaultProps) => {
|
||||||
|
Object.keys(defaultProps).forEach(k => { propTypes[k] = propTypes[k].def(defaultProps[k]) })
|
||||||
|
return propTypes
|
||||||
|
}
|
||||||
export {
|
export {
|
||||||
hasProp,
|
hasProp,
|
||||||
filterProps,
|
filterProps,
|
||||||
|
@ -150,5 +158,6 @@ export {
|
||||||
getAttrs,
|
getAttrs,
|
||||||
getValueByProp,
|
getValueByProp,
|
||||||
parseStyleText,
|
parseStyleText,
|
||||||
|
initDefaultProps,
|
||||||
}
|
}
|
||||||
export default hasProp
|
export default hasProp
|
||||||
|
|
|
@ -93,4 +93,5 @@ export { default as Affix } from './affix'
|
||||||
|
|
||||||
export { default as Cascader } from './cascader'
|
export { default as Cascader } from './cascader'
|
||||||
export { default as BackTop } from './back-top'
|
export { default as BackTop } from './back-top'
|
||||||
|
export { default as Modal } from './modal'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
<script>
|
||||||
|
import PropTypes from '../_util/vue-types'
|
||||||
|
import Button from '../button'
|
||||||
|
import BaseMixin from '../_util/BaseMixin'
|
||||||
|
import buttonTypes from '../button/buttonTypes'
|
||||||
|
const ButtonType = buttonTypes().type
|
||||||
|
const ActionButtonProps = {
|
||||||
|
type: ButtonType,
|
||||||
|
actionFn: PropTypes.func,
|
||||||
|
closeModal: PropTypes.func,
|
||||||
|
autoFocus: PropTypes.bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [BaseMixin],
|
||||||
|
props: ActionButtonProps,
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
if (this.autoFocus) {
|
||||||
|
this.timeoutId = setTimeout(() => this.$el.focus())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
clearTimeout(this.timeoutId)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick () {
|
||||||
|
const { actionFn, closeModal } = this
|
||||||
|
if (actionFn) {
|
||||||
|
let ret
|
||||||
|
if (actionFn.length) {
|
||||||
|
ret = actionFn(closeModal)
|
||||||
|
} else {
|
||||||
|
ret = actionFn()
|
||||||
|
if (!ret) {
|
||||||
|
closeModal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret && ret.then) {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
ret.then((...args) => {
|
||||||
|
// It's unnecessary to set loading=false, for the Modal will be unmounted after close.
|
||||||
|
// this.setState({ loading: false });
|
||||||
|
closeModal(...args)
|
||||||
|
}, () => {
|
||||||
|
// See: https://github.com/ant-design/ant-design/issues/6183
|
||||||
|
this.setState({ loading: false })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
closeModal()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { type, $slots, loading } = this
|
||||||
|
return (
|
||||||
|
<Button type={type} onClick={this.onClick} loading={loading}>
|
||||||
|
{$slots.default}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script>
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import Icon from '../icon'
|
||||||
|
import Dialog from './Modal'
|
||||||
|
import ActionButton from './ActionButton'
|
||||||
|
import { getConfirmLocale } from './locale'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
functional: true,
|
||||||
|
render () {
|
||||||
|
const { onCancel, onOk, close, zIndex, afterClose, visible } = this.$props
|
||||||
|
const props = this.$props
|
||||||
|
const iconType = props.iconType || 'question-circle'
|
||||||
|
const okType = props.okType || 'primary'
|
||||||
|
const prefixCls = props.prefixCls || 'ant-confirm'
|
||||||
|
// 默认为 true,保持向下兼容
|
||||||
|
const okCancel = ('okCancel' in props) ? props.okCancel : true
|
||||||
|
const width = props.width || 416
|
||||||
|
const style = props.style || {}
|
||||||
|
// 默认为 false,保持旧版默认行为
|
||||||
|
const maskClosable = props.maskClosable === undefined ? false : props.maskClosable
|
||||||
|
const runtimeLocale = getConfirmLocale()
|
||||||
|
const okText = props.okText ||
|
||||||
|
(okCancel ? runtimeLocale.okText : runtimeLocale.justOkText)
|
||||||
|
const cancelText = props.cancelText || runtimeLocale.cancelText
|
||||||
|
|
||||||
|
const classString = classNames(
|
||||||
|
prefixCls,
|
||||||
|
`${prefixCls}-${props.type}`,
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
|
|
||||||
|
const cancelButton = okCancel && (
|
||||||
|
<ActionButton actionFn={onCancel} closeModal={close}>
|
||||||
|
{cancelText}
|
||||||
|
</ActionButton>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
class={classString}
|
||||||
|
onCancel={(e) => close({ triggerCancel: true }, e)}
|
||||||
|
visible={visible}
|
||||||
|
title=''
|
||||||
|
transitionName='zoom'
|
||||||
|
footer=''
|
||||||
|
maskTransitionName='fade'
|
||||||
|
maskClosable={maskClosable}
|
||||||
|
style={style}
|
||||||
|
width={width}
|
||||||
|
zIndex={zIndex}
|
||||||
|
afterClose={afterClose}
|
||||||
|
>
|
||||||
|
<div class={`${prefixCls}-body-wrapper`}>
|
||||||
|
<div class={`${prefixCls}-body`}>
|
||||||
|
<Icon type={iconType} />
|
||||||
|
<span class={`${prefixCls}-title`}>{props.title}</span>
|
||||||
|
<div class={`${prefixCls}-content`}>{props.content}</div>
|
||||||
|
</div>
|
||||||
|
<div class={`${prefixCls}-btns`}>
|
||||||
|
{cancelButton}
|
||||||
|
<ActionButton type={okType} actionFn={onOk} closeModal={close} autoFocus>
|
||||||
|
{okText}
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,149 @@
|
||||||
|
<script>
|
||||||
|
import Dialog from '../vc-dialog'
|
||||||
|
import PropTypes from '../_util/vue-types'
|
||||||
|
import addEventListener from '../_util/Dom/addEventListener'
|
||||||
|
import Button from '../button'
|
||||||
|
import buttonTypes from '../button/buttonTypes'
|
||||||
|
const ButtonType = buttonTypes().type
|
||||||
|
import LocaleReceiver from '../locale-provider/LocaleReceiver'
|
||||||
|
import { getConfirmLocale } from './locale'
|
||||||
|
import { initDefaultProps, getComponentFromProp } from '../_util/props-util'
|
||||||
|
|
||||||
|
let mousePosition = null
|
||||||
|
let mousePositionEventBinded = false
|
||||||
|
function noop () {}
|
||||||
|
const modalProps = (defaultProps = {}) => {
|
||||||
|
const props = {
|
||||||
|
prefixCls: PropTypes.string,
|
||||||
|
/** 对话框是否可见*/
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
/** 确定按钮 loading*/
|
||||||
|
confirmLoading: PropTypes.bool,
|
||||||
|
/** 标题*/
|
||||||
|
title: PropTypes.any,
|
||||||
|
/** 是否显示右上角的关闭按钮*/
|
||||||
|
closable: PropTypes.bool,
|
||||||
|
/** 点击确定回调*/
|
||||||
|
// onOk: (e: React.MouseEvent<any>) => void,
|
||||||
|
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/
|
||||||
|
// onCancel: (e: React.MouseEvent<any>) => void,
|
||||||
|
afterClose: PropTypes.func.def(noop),
|
||||||
|
/** 宽度*/
|
||||||
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
|
/** 底部内容*/
|
||||||
|
footer: PropTypes.any,
|
||||||
|
/** 确认按钮文字*/
|
||||||
|
okText: PropTypes.string,
|
||||||
|
/** 确认按钮类型*/
|
||||||
|
okType: ButtonType,
|
||||||
|
/** 取消按钮文字*/
|
||||||
|
cancelText: PropTypes.string,
|
||||||
|
/** 点击蒙层是否允许关闭*/
|
||||||
|
maskClosable: PropTypes.bool,
|
||||||
|
destroyOnClose: PropTypes.bool,
|
||||||
|
wrapClassName: PropTypes.string,
|
||||||
|
maskTransitionName: PropTypes.string,
|
||||||
|
transitionName: PropTypes.string,
|
||||||
|
getContainer: PropTypes.func,
|
||||||
|
zIndex: PropTypes.number,
|
||||||
|
bodyStyle: PropTypes.object,
|
||||||
|
maskStyle: PropTypes.object,
|
||||||
|
mask: PropTypes.bool,
|
||||||
|
}
|
||||||
|
return initDefaultProps(props, defaultProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: modalProps({
|
||||||
|
prefixCls: 'ant-modal',
|
||||||
|
width: 520,
|
||||||
|
transitionName: 'zoom',
|
||||||
|
maskTransitionName: 'fade',
|
||||||
|
confirmLoading: false,
|
||||||
|
visible: false,
|
||||||
|
okType: 'primary',
|
||||||
|
}),
|
||||||
|
// static info: ModalFunc;
|
||||||
|
// static success: ModalFunc;
|
||||||
|
// static error: ModalFunc;
|
||||||
|
// static warn: ModalFunc;
|
||||||
|
// static warning: ModalFunc;
|
||||||
|
// static confirm: ModalFunc;
|
||||||
|
methods: {
|
||||||
|
handleCancel (e) {
|
||||||
|
this.$emit('cancel', e)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleOk (e) {
|
||||||
|
this.$emit('ok', e)
|
||||||
|
},
|
||||||
|
renderFooter (locale) {
|
||||||
|
const { okType, confirmLoading } = this
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={this.handleCancel}
|
||||||
|
>
|
||||||
|
{getComponentFromProp(this, 'cancelText') || locale.cancelText}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type={okType}
|
||||||
|
loading={confirmLoading}
|
||||||
|
onClick={this.handleOk}
|
||||||
|
>
|
||||||
|
{getComponentFromProp(this, 'okText') || locale.okText}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
if (mousePositionEventBinded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 只有点击事件支持从鼠标位置动画展开
|
||||||
|
addEventListener(document.documentElement, 'click', (e) => {
|
||||||
|
mousePosition = {
|
||||||
|
x: e.pageX,
|
||||||
|
y: e.pageY,
|
||||||
|
}
|
||||||
|
// 100ms 内发生过点击事件,则从点击位置动画展示
|
||||||
|
// 否则直接 zoom 展示
|
||||||
|
// 这样可以兼容非点击方式展开
|
||||||
|
setTimeout(() => { mousePosition = null }, 100)
|
||||||
|
})
|
||||||
|
mousePositionEventBinded = true
|
||||||
|
},
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { visible, $listeners, $slots } = this
|
||||||
|
|
||||||
|
const defaultFooter = (
|
||||||
|
<LocaleReceiver
|
||||||
|
componentName='Modal'
|
||||||
|
defaultLocale={getConfirmLocale()}
|
||||||
|
children={this.renderFooter}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
const dialogProps = {
|
||||||
|
props: {
|
||||||
|
...this.$props,
|
||||||
|
title: getComponentFromProp(this, 'title'),
|
||||||
|
footer: getComponentFromProp(this, 'footer') || defaultFooter,
|
||||||
|
visible: visible,
|
||||||
|
mousePosition,
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
...$listeners,
|
||||||
|
close: this.handleCancel,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Dialog {...dialogProps}>
|
||||||
|
{$slots.default}
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
|
@ -0,0 +1,39 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import ConfirmDialog from './ConfirmDialog'
|
||||||
|
export default function confirm (config) {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
document.body.appendChild(div)
|
||||||
|
let confirmDialogInstance = null
|
||||||
|
function close (...args) {
|
||||||
|
destroy(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy (...args) {
|
||||||
|
if (confirmDialogInstance && div.parentNode) {
|
||||||
|
confirmDialogInstance.$destroy()
|
||||||
|
confirmDialogInstance = null
|
||||||
|
div.parentNode.removeChild(div)
|
||||||
|
}
|
||||||
|
const triggerCancel = args && args.length &&
|
||||||
|
args.some(param => param && param.triggerCancel)
|
||||||
|
if (config.onCancel && triggerCancel) {
|
||||||
|
config.onCancel(...args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function render (props) {
|
||||||
|
return new Vue({
|
||||||
|
el: div,
|
||||||
|
render () {
|
||||||
|
return <ConfirmDialog {...props} />
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmDialogInstance = render({ ...config, visible: true, close })
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy: close,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
<cn>
|
||||||
|
#### 基本
|
||||||
|
第一个对话框。
|
||||||
|
</cn>
|
||||||
|
|
||||||
|
<us>
|
||||||
|
#### Basic
|
||||||
|
Basic modal.
|
||||||
|
</us>
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" @click="showModal">Open</a-button>
|
||||||
|
<a-modal
|
||||||
|
title="Basic Modal"
|
||||||
|
:visible="visible"
|
||||||
|
@ok="handleOk"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showModal() {
|
||||||
|
this.visible = true
|
||||||
|
},
|
||||||
|
handleOk(e) {
|
||||||
|
console.log(e);
|
||||||
|
this.visible = false
|
||||||
|
},
|
||||||
|
handleCancel(e) {
|
||||||
|
console.log(e);
|
||||||
|
this.visible = false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import Modal from './Modal'
|
||||||
|
import confirm from './confirm'
|
||||||
|
|
||||||
|
// export { ActionButtonProps } from './ActionButton'
|
||||||
|
// export { ModalProps, ModalFuncProps } from './Modal'
|
||||||
|
|
||||||
|
Modal.info = function (props) {
|
||||||
|
const config = {
|
||||||
|
type: 'info',
|
||||||
|
iconType: 'info-circle',
|
||||||
|
okCancel: false,
|
||||||
|
...props,
|
||||||
|
}
|
||||||
|
return confirm(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.success = function (props) {
|
||||||
|
const config = {
|
||||||
|
type: 'success',
|
||||||
|
iconType: 'check-circle',
|
||||||
|
okCancel: false,
|
||||||
|
...props,
|
||||||
|
}
|
||||||
|
return confirm(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.error = function (props) {
|
||||||
|
const config = {
|
||||||
|
type: 'error',
|
||||||
|
iconType: 'cross-circle',
|
||||||
|
okCancel: false,
|
||||||
|
...props,
|
||||||
|
}
|
||||||
|
return confirm(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.warning = Modal.warn = function (props) {
|
||||||
|
const config = {
|
||||||
|
type: 'warning',
|
||||||
|
iconType: 'exclamation-circle',
|
||||||
|
okCancel: false,
|
||||||
|
...props,
|
||||||
|
}
|
||||||
|
return confirm(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.confirm = function (props) {
|
||||||
|
const config = {
|
||||||
|
type: 'confirm',
|
||||||
|
okCancel: true,
|
||||||
|
...props,
|
||||||
|
}
|
||||||
|
return confirm(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Modal
|
|
@ -0,0 +1,28 @@
|
||||||
|
import defaultLocale from '../locale-provider/default'
|
||||||
|
|
||||||
|
// export interface ModalLocale {
|
||||||
|
// okText: string;
|
||||||
|
// cancelText: string;
|
||||||
|
// justOkText: string;
|
||||||
|
// }
|
||||||
|
|
||||||
|
let runtimeLocale = {
|
||||||
|
...defaultLocale.Modal,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeConfirmLocale (newLocale) {
|
||||||
|
if (newLocale) {
|
||||||
|
runtimeLocale = {
|
||||||
|
...runtimeLocale,
|
||||||
|
...newLocale,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runtimeLocale = {
|
||||||
|
...defaultLocale.Modal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getConfirmLocale () {
|
||||||
|
return runtimeLocale
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
@import "../../style/mixins/index";
|
||||||
|
|
||||||
|
@confirm-prefix-cls: ~"@{ant-prefix}-confirm";
|
||||||
|
|
||||||
|
.@{confirm-prefix-cls} {
|
||||||
|
.@{ant-prefix}-modal-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-modal-close {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-modal-body {
|
||||||
|
padding: 32px 32px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body-wrapper {
|
||||||
|
.clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
.@{confirm-prefix-cls}-title {
|
||||||
|
color: @heading-color;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: @font-size-lg;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{confirm-prefix-cls}-content {
|
||||||
|
margin-left: 38px;
|
||||||
|
font-size: @font-size-base;
|
||||||
|
color: @text-color;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .@{iconfont-css-prefix} {
|
||||||
|
font-size: 22px;
|
||||||
|
margin-right: 16px;
|
||||||
|
float: left;
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{confirm-prefix-cls}-btns {
|
||||||
|
margin-top: 24px;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
button + button {
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-error &-body > .@{iconfont-css-prefix} {
|
||||||
|
color: @error-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-warning &-body > .@{iconfont-css-prefix},
|
||||||
|
&-confirm &-body > .@{iconfont-css-prefix} {
|
||||||
|
color: @warning-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-info &-body > .@{iconfont-css-prefix} {
|
||||||
|
color: @info-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-success &-body > .@{iconfont-css-prefix} {
|
||||||
|
color: @success-color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import '../../style/index.less'
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
// style dependencies
|
||||||
|
import '../../button/style'
|
|
@ -0,0 +1,4 @@
|
||||||
|
@import "../../style/themes/default";
|
||||||
|
@import "../../style/mixins/index";
|
||||||
|
@import "./modal";
|
||||||
|
@import "./confirm";
|
|
@ -0,0 +1,146 @@
|
||||||
|
@dialog-prefix-cls: ~"@{ant-prefix}-modal";
|
||||||
|
|
||||||
|
.@{dialog-prefix-cls} {
|
||||||
|
.reset-component;
|
||||||
|
position: relative;
|
||||||
|
width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
top: 100px;
|
||||||
|
padding-bottom: 24px;
|
||||||
|
|
||||||
|
&-wrap {
|
||||||
|
position: fixed;
|
||||||
|
overflow: auto;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: @zindex-modal;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: @font-size-lg;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: @heading-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
position: relative;
|
||||||
|
background-color: @component-background;
|
||||||
|
border: 0;
|
||||||
|
border-radius: @border-radius-base;
|
||||||
|
background-clip: padding-box;
|
||||||
|
box-shadow: @shadow-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color .3s;
|
||||||
|
color: @text-color-secondary;
|
||||||
|
outline: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&-x {
|
||||||
|
display: block;
|
||||||
|
font-style: normal;
|
||||||
|
vertical-align: baseline;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: none;
|
||||||
|
text-rendering: auto;
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
line-height: 56px;
|
||||||
|
font-size: @font-size-lg;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "\e633";
|
||||||
|
display: block;
|
||||||
|
font-family: "anticon" !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: #444;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
padding: 16px 24px;
|
||||||
|
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||||
|
background: @component-background;
|
||||||
|
color: @text-color;
|
||||||
|
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
padding: 24px;
|
||||||
|
font-size: @font-size-base;
|
||||||
|
line-height: @line-height-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer {
|
||||||
|
border-top: @border-width-base @border-style-base @border-color-split;
|
||||||
|
padding: 10px 16px;
|
||||||
|
text-align: right;
|
||||||
|
border-radius: 0 0 @border-radius-base @border-radius-base;
|
||||||
|
button + button {
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.zoom-enter,
|
||||||
|
&.zoom-appear {
|
||||||
|
animation-duration: @animation-duration-slow;
|
||||||
|
transform: none; // reset scale avoid mousePosition bug
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #373737;
|
||||||
|
background-color: @modal-mask-bg; // lesshint duplicateProperty: false
|
||||||
|
height: 100%;
|
||||||
|
z-index: @zindex-modal-mask;
|
||||||
|
filter: ~"alpha(opacity=50)";
|
||||||
|
|
||||||
|
&-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: @screen-md) {
|
||||||
|
.@{dialog-prefix-cls} {
|
||||||
|
width: auto !important;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.vertical-center-modal {
|
||||||
|
.@{dialog-prefix-cls} {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,3 +27,4 @@ import './auto-complete/style'
|
||||||
import './affix/style'
|
import './affix/style'
|
||||||
import './cascader/style'
|
import './cascader/style'
|
||||||
import './back-top/style'
|
import './back-top/style'
|
||||||
|
import './modal/style'
|
||||||
|
|
|
@ -218,11 +218,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { destroyPopup, getMaskElement, getPopupElement } = this
|
const { destroyPopup, getMaskElement, getPopupElement, visible } = this
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{getMaskElement()}
|
{getMaskElement()}
|
||||||
{ destroyPopup ? null : getPopupElement()}
|
{(visible || !destroyPopup) ? getPopupElement() : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,6 +62,11 @@ export default {
|
||||||
prefixCls: 'rc-dialog',
|
prefixCls: 'rc-dialog',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
destroyPopup: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// private inTransition: boolean;
|
// private inTransition: boolean;
|
||||||
// private titleId: string;
|
// private titleId: string;
|
||||||
|
@ -88,10 +93,13 @@ export default {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.updatedCallback(val)
|
this.updatedCallback(val)
|
||||||
})
|
})
|
||||||
|
if (val) {
|
||||||
|
this.destroyPopup = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
if (this.props.visible || this.inTransition) {
|
if (this.visible || this.inTransition) {
|
||||||
this.removeScrollingEffect()
|
this.removeScrollingEffect()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -127,12 +135,15 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onAnimateLeave () {
|
onAnimateLeave () {
|
||||||
const { afterClose } = this
|
const { afterClose, destroyOnClose } = this
|
||||||
// need demo?
|
// need demo?
|
||||||
// https://github.com/react-component/dialog/pull/28
|
// https://github.com/react-component/dialog/pull/28
|
||||||
if (this.$refs.wrap) {
|
if (this.$refs.wrap) {
|
||||||
this.$refs.wrap.style.display = 'none'
|
this.$refs.wrap.style.display = 'none'
|
||||||
}
|
}
|
||||||
|
if (destroyOnClose) {
|
||||||
|
this.destroyPopup = true
|
||||||
|
}
|
||||||
this.inTransition = false
|
this.inTransition = false
|
||||||
this.removeScrollingEffect()
|
this.removeScrollingEffect()
|
||||||
if (afterClose) {
|
if (afterClose) {
|
||||||
|
@ -149,6 +160,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onKeydown (e) {
|
onKeydown (e) {
|
||||||
|
console.log('keydown')
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
if (props.keyboard && e.keyCode === KeyCode.ESC) {
|
if (props.keyboard && e.keyCode === KeyCode.ESC) {
|
||||||
this.close(e)
|
this.close(e)
|
||||||
|
@ -169,32 +181,31 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDialogElement () {
|
getDialogElement () {
|
||||||
const props = this.$props
|
const { closable, prefixCls, width, height,
|
||||||
const closable = props.closable
|
title, footer: tempFooter, bodyStyle, visible, bodyProps } = this
|
||||||
const prefixCls = props.prefixCls
|
|
||||||
const dest = {}
|
const dest = {}
|
||||||
if (props.width !== undefined) {
|
if (width !== undefined) {
|
||||||
dest.width = props.width
|
dest.width = typeof width === 'number' ? `${width}px` : width
|
||||||
}
|
}
|
||||||
if (props.height !== undefined) {
|
if (height !== undefined) {
|
||||||
dest.height = props.height
|
dest.height = typeof height === 'number' ? `${height}px` : height
|
||||||
}
|
}
|
||||||
|
|
||||||
let footer
|
let footer
|
||||||
if (props.footer) {
|
if (tempFooter) {
|
||||||
footer = (
|
footer = (
|
||||||
<div class={`${prefixCls}-footer`} ref='footer'>
|
<div class={`${prefixCls}-footer`} ref='footer'>
|
||||||
{props.footer}
|
{tempFooter}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let header
|
let header
|
||||||
if (props.title) {
|
if (title) {
|
||||||
header = (
|
header = (
|
||||||
<div class={`${prefixCls}-header`} ref='header'>
|
<div class={`${prefixCls}-header`} ref='header'>
|
||||||
<div class={`${prefixCls}-title`} id={this.titleId}>
|
<div class={`${prefixCls}-title`} id={this.titleId}>
|
||||||
{props.title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -213,25 +224,29 @@ export default {
|
||||||
</button>)
|
</button>)
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = { ...dest }
|
const style = { ...this.dialogStyle, ...dest }
|
||||||
|
const cls = {
|
||||||
|
[prefixCls]: true,
|
||||||
|
...this.dialogClass,
|
||||||
|
}
|
||||||
const transitionName = this.getTransitionName()
|
const transitionName = this.getTransitionName()
|
||||||
const dialogElement = (
|
const dialogElement = (
|
||||||
<LazyRenderBox
|
<LazyRenderBox
|
||||||
v-show={props.visible}
|
v-show={visible}
|
||||||
key='dialog-element'
|
key='dialog-element'
|
||||||
role='document'
|
role='document'
|
||||||
ref='dialog'
|
ref='dialog'
|
||||||
style={style}
|
style={style}
|
||||||
class={prefixCls}
|
class={cls}
|
||||||
>
|
>
|
||||||
<div class={`${prefixCls}-content`}>
|
<div class={`${prefixCls}-content`}>
|
||||||
{closer}
|
{closer}
|
||||||
{header}
|
{header}
|
||||||
<div
|
<div
|
||||||
class={`${prefixCls}-body`}
|
class={`${prefixCls}-body`}
|
||||||
style={props.bodyStyle}
|
style={bodyStyle}
|
||||||
ref='body'
|
ref='body'
|
||||||
{...props.bodyProps}
|
{...bodyProps}
|
||||||
>
|
>
|
||||||
{this.$slots.default}
|
{this.$slots.default}
|
||||||
</div>
|
</div>
|
||||||
|
@ -250,7 +265,7 @@ export default {
|
||||||
key='dialog'
|
key='dialog'
|
||||||
{...dialogTransitionProps}
|
{...dialogTransitionProps}
|
||||||
>
|
>
|
||||||
{(props.visible || !props.destroyOnClose) ? dialogElement : null}
|
{(visible || !this.destroyPopup) ? dialogElement : null}
|
||||||
</transition>
|
</transition>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import Dialog from './Dialog'
|
import Dialog from './Dialog'
|
||||||
import ContainerRender from '../_util/ContainerRender'
|
import ContainerRender from '../_util/ContainerRender'
|
||||||
import getDialogPropTypes from './IDialogPropTypes'
|
import getDialogPropTypes from './IDialogPropTypes'
|
||||||
|
import { getStyle, getClass } from '../_util/props-util'
|
||||||
const IDialogPropTypes = getDialogPropTypes()
|
const IDialogPropTypes = getDialogPropTypes()
|
||||||
const DialogWrap = {
|
const DialogWrap = {
|
||||||
props: {
|
props: {
|
||||||
|
@ -29,16 +30,22 @@ const DialogWrap = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getComponent (extra = {}) {
|
getComponent (extra = {}) {
|
||||||
|
const { $attrs, $listeners, $props, $slots } = this
|
||||||
|
|
||||||
const dialogProps = {
|
const dialogProps = {
|
||||||
props: {
|
props: {
|
||||||
...this.$props,
|
...$props,
|
||||||
|
dialogClass: getClass(this),
|
||||||
|
dialogStyle: getStyle(this),
|
||||||
...extra,
|
...extra,
|
||||||
},
|
},
|
||||||
|
attrs: $attrs,
|
||||||
ref: '_component',
|
ref: '_component',
|
||||||
key: 'dialog',
|
key: 'dialog',
|
||||||
|
on: $listeners,
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Dialog {...dialogProps}>{this.$slots.default}</Dialog>
|
<Dialog {...dialogProps}>{$slots.default}</Dialog>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,15 @@ function IDialogPropTypes () {
|
||||||
maskStyle: PropTypes.object,
|
maskStyle: PropTypes.object,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
wrapClassName: PropTypes.string,
|
wrapClassName: PropTypes.string,
|
||||||
width: PropTypes.number,
|
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
height: PropTypes.number,
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
zIndex: PropTypes.number,
|
zIndex: PropTypes.number,
|
||||||
bodyProps: PropTypes.any,
|
bodyProps: PropTypes.any,
|
||||||
maskProps: PropTypes.any,
|
maskProps: PropTypes.any,
|
||||||
wrapProps: PropTypes.any,
|
wrapProps: PropTypes.any,
|
||||||
getContainer: PropTypes.func,
|
getContainer: PropTypes.func,
|
||||||
|
dialogStyle: PropTypes.object.def({}),
|
||||||
|
dialogClass: PropTypes.object.def({}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import '../assets/index.less'
|
import '../assets/index.less'
|
||||||
// use import Dialog from 'rc-dialog'
|
// use import Dialog from 'rc-dialog'
|
||||||
import Dialog from '../DialogWrap'
|
import Dialog from '../index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
|
@ -34,7 +34,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
changeWidth (e) {
|
changeWidth (e) {
|
||||||
console.log(e)
|
|
||||||
this.width = this.width === 600 ? 800 : 600
|
this.width = this.width === 600 ? 800 : 600
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
import DialogWrap from './DialogWrap'
|
||||||
|
export default DialogWrap
|
|
@ -3,7 +3,7 @@ const AsyncComp = () => {
|
||||||
const hashs = window.location.hash.split('/')
|
const hashs = window.location.hash.split('/')
|
||||||
const d = hashs[hashs.length - 1]
|
const d = hashs[hashs.length - 1]
|
||||||
return {
|
return {
|
||||||
component: import(`../components/vc-dialog/demo/${d}.vue`),
|
component: import(`../components/modal/demo/${d}`),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default [
|
export default [
|
||||||
|
|
Loading…
Reference in New Issue