add Modal component
add Modal component
This commit is contained in:
parent
39e6e96563
commit
be966e9f49
20 changed files with 763 additions and 49 deletions
169
components/modal/confirm.js
Normal file
169
components/modal/confirm.js
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Modal from './modal.vue';
|
||||||
|
import Icon from '../icon/icon.vue';
|
||||||
|
import Button from '../button/button.vue';
|
||||||
|
import { camelcaseToHyphen } from '../../utils/assist';
|
||||||
|
|
||||||
|
const prefixCls = 'ivu-modal-confirm';
|
||||||
|
|
||||||
|
Modal.newInstance = properties => {
|
||||||
|
const _props = properties || {};
|
||||||
|
|
||||||
|
let props = '';
|
||||||
|
Object.keys(_props).forEach(prop => {
|
||||||
|
props += ' :' + camelcaseToHyphen(prop) + '=' + prop;
|
||||||
|
});
|
||||||
|
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = `
|
||||||
|
<Modal${props} :visible.sync="visible" :width="width">
|
||||||
|
<div class="${prefixCls}">
|
||||||
|
<div class="${prefixCls}-head">
|
||||||
|
<div :class="iconTypeCls"><i :class="iconNameCls"></i></div>
|
||||||
|
<div class="${prefixCls}-head-title">{{{ title }}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="${prefixCls}-body">
|
||||||
|
{{{ body }}}
|
||||||
|
</div>
|
||||||
|
<div class="${prefixCls}-footer">
|
||||||
|
<Button type="ghost" size="large" v-if="showCancel" @click="cancel">{{ cancelText }}</Button>
|
||||||
|
<Button type="primary" size="large" :loading="buttonLoading" @click="ok">{{ okText }}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(div);
|
||||||
|
|
||||||
|
const modal = new Vue({
|
||||||
|
el: div,
|
||||||
|
components: { Modal, Button, Icon },
|
||||||
|
data: Object.assign(_props, {
|
||||||
|
visible: false,
|
||||||
|
width: 416,
|
||||||
|
title: '',
|
||||||
|
body: '',
|
||||||
|
iconType: '',
|
||||||
|
iconName: '',
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
showCancel: false,
|
||||||
|
loading: false,
|
||||||
|
buttonLoading: false
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
iconTypeCls () {
|
||||||
|
return [
|
||||||
|
`${prefixCls}-head-icon`,
|
||||||
|
`${prefixCls}-head-icon-${this.iconType}`
|
||||||
|
]
|
||||||
|
},
|
||||||
|
iconNameCls () {
|
||||||
|
return [
|
||||||
|
'ivu-icon',
|
||||||
|
`ivu-icon-${this.iconName}`
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cancel () {
|
||||||
|
this.visible = false;
|
||||||
|
this.buttonLoading = false;
|
||||||
|
this.onCancel();
|
||||||
|
this.remove();
|
||||||
|
},
|
||||||
|
ok () {
|
||||||
|
if (this.loading) {
|
||||||
|
this.buttonLoading = true;
|
||||||
|
} else {
|
||||||
|
this.visible = false;
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
|
this.onOk();
|
||||||
|
},
|
||||||
|
remove () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.destroy();
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
destroy () {
|
||||||
|
this.$destroy();
|
||||||
|
document.body.removeChild(div);
|
||||||
|
this.onRemove();
|
||||||
|
},
|
||||||
|
onOk () {},
|
||||||
|
onCancel () {},
|
||||||
|
onRemove () {}
|
||||||
|
}
|
||||||
|
}).$children[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
show (props) {
|
||||||
|
modal.$parent.showCancel = props.showCancel;
|
||||||
|
modal.$parent.iconType = props.icon;
|
||||||
|
|
||||||
|
switch (props.icon) {
|
||||||
|
case 'info':
|
||||||
|
modal.$parent.iconName = 'information-circled';
|
||||||
|
break;
|
||||||
|
case 'success':
|
||||||
|
modal.$parent.iconName = 'checkmark-circled';
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
modal.$parent.iconName = 'android-alert';
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
modal.$parent.iconName = 'close-circled';
|
||||||
|
break;
|
||||||
|
case 'confirm':
|
||||||
|
modal.$parent.iconName = 'help-circled';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('width' in props) {
|
||||||
|
modal.$parent.width = props.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('title' in props) {
|
||||||
|
modal.$parent.title = props.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('content' in props) {
|
||||||
|
modal.$parent.body = props.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('okText' in props) {
|
||||||
|
modal.$parent.okText = props.okText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('cancelText' in props) {
|
||||||
|
modal.$parent.cancelText = props.cancelText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('onCancel' in props) {
|
||||||
|
modal.$parent.onCancel = props.onCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('onOk' in props) {
|
||||||
|
modal.$parent.onOk = props.onOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// async for ok
|
||||||
|
if ('loading' in props) {
|
||||||
|
modal.$parent.loading = props.loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// notice when component destroy
|
||||||
|
modal.$parent.onRemove = props.onRemove;
|
||||||
|
|
||||||
|
modal.visible = true;
|
||||||
|
},
|
||||||
|
remove () {
|
||||||
|
modal.visible = false;
|
||||||
|
modal.$parent.buttonLoading = false;
|
||||||
|
modal.$parent.remove();
|
||||||
|
},
|
||||||
|
component: modal
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
65
components/modal/index.js
Normal file
65
components/modal/index.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import Modal from './confirm';
|
||||||
|
|
||||||
|
let modalInstance;
|
||||||
|
|
||||||
|
function getModalInstance () {
|
||||||
|
modalInstance = modalInstance || Modal.newInstance({
|
||||||
|
closable: false,
|
||||||
|
maskClosable: false,
|
||||||
|
footerHide: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return modalInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirm (options) {
|
||||||
|
let instance = getModalInstance();
|
||||||
|
|
||||||
|
options.onRemove = function () {
|
||||||
|
modalInstance = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
instance.show(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.info = function (props = {}) {
|
||||||
|
props.icon = 'info';
|
||||||
|
props.showCancel = false;
|
||||||
|
return confirm(props);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.success = function (props = {}) {
|
||||||
|
props.icon = 'success';
|
||||||
|
props.showCancel = false;
|
||||||
|
return confirm(props);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.warning = function (props = {}) {
|
||||||
|
props.icon = 'warning';
|
||||||
|
props.showCancel = false;
|
||||||
|
return confirm(props);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.error = function (props = {}) {
|
||||||
|
props.icon = 'error';
|
||||||
|
props.showCancel = false;
|
||||||
|
return confirm(props);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.confirm = function (props = {}) {
|
||||||
|
props.icon = 'confirm';
|
||||||
|
props.showCancel = true;
|
||||||
|
return confirm(props);
|
||||||
|
};
|
||||||
|
|
||||||
|
Modal.remove = function () {
|
||||||
|
if (!modalInstance) { // at loading status, remove after Cancel
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = getModalInstance();
|
||||||
|
|
||||||
|
instance.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Modal;
|
205
components/modal/modal.vue
Normal file
205
components/modal/modal.vue
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
<template>
|
||||||
|
<div :class="wrapClasses">
|
||||||
|
<div :class="maskClasses" v-show="visible" @click="mask" transition="fade"></div>
|
||||||
|
<div :class="classes" :style="styles" v-show="visible" transition="ease">
|
||||||
|
<div :class="[`${prefixCls}-content`]">
|
||||||
|
<a :class="[`${prefixCls}-close`]" v-if="closable" @click="close">
|
||||||
|
<slot name="close">
|
||||||
|
<Icon type="ios-close-empty"></Icon>
|
||||||
|
</slot>
|
||||||
|
</a>
|
||||||
|
<div :class="[`${prefixCls}-header`]" v-if="showHead" v-el:head><slot name="header"><p>{{ title }}</p></slot></div>
|
||||||
|
<div :class="[`${prefixCls}-body`]"><slot></slot></div>
|
||||||
|
<div :class="[`${prefixCls}-footer`]" v-if="!footerHide">
|
||||||
|
<slot name="footer">
|
||||||
|
<Button type="ghost" size="large" @click="cancel">{{ cancelText }}</Button>
|
||||||
|
<Button type="primary" size="large" :loading="buttonLoading" @click="ok">{{ okText }}</Button>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Icon from '../icon';
|
||||||
|
import Button from '../button';
|
||||||
|
import { getScrollBarSize } from '../../utils/assist';
|
||||||
|
|
||||||
|
const prefixCls = 'ivu-modal';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Icon, Button },
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
closable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
maskClosable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 520
|
||||||
|
},
|
||||||
|
okText: {
|
||||||
|
type: String,
|
||||||
|
default: '确定'
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: '取消'
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
// for instance
|
||||||
|
footerHide: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
prefixCls: prefixCls,
|
||||||
|
wrapShow: false,
|
||||||
|
showHead: true,
|
||||||
|
buttonLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
wrapClasses () {
|
||||||
|
return [
|
||||||
|
`${prefixCls}-wrap`,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-hidden`]: !this.wrapShow,
|
||||||
|
[`${this.className}`]: !!this.className
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
maskClasses () {
|
||||||
|
return `${prefixCls}-mask`;
|
||||||
|
},
|
||||||
|
classes () {
|
||||||
|
return `${prefixCls}`;
|
||||||
|
},
|
||||||
|
styles () {
|
||||||
|
let style = {};
|
||||||
|
|
||||||
|
const styleWidth = {
|
||||||
|
width: `${this.width}px`
|
||||||
|
};
|
||||||
|
|
||||||
|
const customStyle = !!this.style ? this.style : {};
|
||||||
|
|
||||||
|
Object.assign(style, styleWidth, customStyle);
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close () {
|
||||||
|
this.visible = false;
|
||||||
|
this.$emit('on-cancel');
|
||||||
|
},
|
||||||
|
mask () {
|
||||||
|
if (this.maskClosable) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel () {
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
ok () {
|
||||||
|
if (this.loading) {
|
||||||
|
this.buttonLoading = true;
|
||||||
|
} else {
|
||||||
|
this.visible = false;
|
||||||
|
}
|
||||||
|
this.$emit('on-ok');
|
||||||
|
},
|
||||||
|
EscClose (e) {
|
||||||
|
if (this.visible && this.closable) {
|
||||||
|
if (e.keyCode === 27) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkScrollBar () {
|
||||||
|
let fullWindowWidth = window.innerWidth;
|
||||||
|
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
|
||||||
|
const documentElementRect = document.documentElement.getBoundingClientRect();
|
||||||
|
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
|
||||||
|
}
|
||||||
|
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
|
||||||
|
if (this.bodyIsOverflowing) {
|
||||||
|
this.scrollBarWidth = getScrollBarSize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setScrollBar () {
|
||||||
|
if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) {
|
||||||
|
document.body.style.paddingRight = `${this.scrollBarWidth}px`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetScrollBar () {
|
||||||
|
document.body.style.paddingRight = '';
|
||||||
|
},
|
||||||
|
addScrollEffect () {
|
||||||
|
this.checkScrollBar();
|
||||||
|
this.setScrollBar();
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
},
|
||||||
|
removeScrollEffect() {
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
this.resetScrollBar();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ready () {
|
||||||
|
if (this.visible) {
|
||||||
|
this.wrapShow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let showHead = true;
|
||||||
|
|
||||||
|
if (this.$els.head.innerHTML == '<p></p>' && !this.title) {
|
||||||
|
showHead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showHead = showHead;
|
||||||
|
|
||||||
|
// ESC close
|
||||||
|
document.addEventListener('keydown', this.EscClose);
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
document.removeEventListener('keydown', this.EscClose);
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible (val) {
|
||||||
|
if (val === false) {
|
||||||
|
this.buttonLoading = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.wrapShow = false;
|
||||||
|
}, 300);
|
||||||
|
this.removeScrollEffect();
|
||||||
|
} else {
|
||||||
|
this.wrapShow = true;
|
||||||
|
this.addScrollEffect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
2
dist/styles/iview.all.css
vendored
2
dist/styles/iview.all.css
vendored
File diff suppressed because one or more lines are too long
2
dist/styles/iview.css
vendored
2
dist/styles/iview.css
vendored
File diff suppressed because one or more lines are too long
4
index.js
4
index.js
|
@ -23,6 +23,7 @@ import Card from './components/card';
|
||||||
import Message from './components/message';
|
import Message from './components/message';
|
||||||
import Notice from './components/notice';
|
import Notice from './components/notice';
|
||||||
import LoadingBar from './components/loading-bar';
|
import LoadingBar from './components/loading-bar';
|
||||||
|
import Modal from './components/modal';
|
||||||
|
|
||||||
const iview = {
|
const iview = {
|
||||||
Button,
|
Button,
|
||||||
|
@ -50,7 +51,8 @@ const iview = {
|
||||||
Card,
|
Card,
|
||||||
Message,
|
Message,
|
||||||
Notice,
|
Notice,
|
||||||
LoadingBar
|
LoadingBar,
|
||||||
|
Modal
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = iview;
|
module.exports = iview;
|
|
@ -2,32 +2,59 @@
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<template>
|
<template>
|
||||||
<div>welcome</div>
|
<Button @click="info">info</Button>
|
||||||
<Checkbox-group :model.sync="fruit">
|
<Button @click="success">success</Button>
|
||||||
<Checkbox value="香蕉"></Checkbox>
|
<Button @click="warning">warning</Button>
|
||||||
<Checkbox value="苹果"></Checkbox>
|
<Button @click="error">error</Button>
|
||||||
<Checkbox value="西瓜"></Checkbox>
|
<Button @click="confirm">confirm</Button>
|
||||||
</Checkbox-group>
|
|
||||||
{{ fruit | json }}
|
|
||||||
<Button @click="update">update fruit</Button>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { Checkbox, Icon, Button } from 'iview';
|
import { Modal, Button, Message } from 'iview';
|
||||||
const CheckboxGroup = Checkbox.Group;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Checkbox, CheckboxGroup, Icon, Button },
|
components: { Modal, Button },
|
||||||
props: {
|
props: {
|
||||||
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
fruit: ['苹果']
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
update () {
|
info () {
|
||||||
this.fruit = ['香蕉', '西瓜']
|
Modal.info({
|
||||||
|
title: '这是对话框标题',
|
||||||
|
content: `<p>这是对话框内容</p><p>这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容这是对话框内容</p>`
|
||||||
|
});
|
||||||
|
},
|
||||||
|
success () {
|
||||||
|
Modal.success();
|
||||||
|
},
|
||||||
|
warning () {
|
||||||
|
Modal.warning();
|
||||||
|
},
|
||||||
|
error () {
|
||||||
|
Modal.error();
|
||||||
|
},
|
||||||
|
confirm () {
|
||||||
|
Modal.confirm({
|
||||||
|
// okText: 'OK',
|
||||||
|
// cancelText: 'Cancel',
|
||||||
|
title: '删除提示',
|
||||||
|
content: '删除后将不可找回,您确定要删除吗?',
|
||||||
|
onCancel () {
|
||||||
|
Message.info('cancel it');
|
||||||
|
},
|
||||||
|
onOk () {
|
||||||
|
setTimeout(() => {
|
||||||
|
Modal.remove();
|
||||||
|
Message.success('OK!');
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,25 @@
|
||||||
<Button @click="warning">warning</Button>
|
<Button @click="warning">warning</Button>
|
||||||
<Button @click="loading">手动消失</Button>
|
<Button @click="loading">手动消失</Button>
|
||||||
<Button @click="destroy">destroy</Button>
|
<Button @click="destroy">destroy</Button>
|
||||||
|
<Alert closable>消息提示文案</Alert>
|
||||||
|
<Alert type="success" show-icon closable>
|
||||||
|
成功提示文案
|
||||||
|
<span slot="desc">成功的提示描述文案成功的提示描述文案成功的提示描述文案成功的提示描述文案成功的提示描述文案</span>
|
||||||
|
</Alert>
|
||||||
|
<Card :bordered="false">
|
||||||
|
<p slot="title">无边框标题</p>
|
||||||
|
<p>无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充无边框内容填充。</p>
|
||||||
|
</Card>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { Message, Button } from 'iview';
|
import { Message, Button, Alert, Card } from 'iview';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Message,
|
Message,
|
||||||
Button
|
Button,
|
||||||
|
Alert,
|
||||||
|
Card
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iview",
|
"name": "iview",
|
||||||
"version": "0.9.1",
|
"version": "0.9.2",
|
||||||
"title": "iView",
|
"title": "iView",
|
||||||
"description": "A high quality UI components Library with Vue.js",
|
"description": "A high quality UI components Library with Vue.js",
|
||||||
"homepage": "http://www.iviewui.com",
|
"homepage": "http://www.iviewui.com",
|
||||||
|
|
36
styles/animation/ease.less
Normal file
36
styles/animation/ease.less
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
.ease-motion(@className, @keyframeName) {
|
||||||
|
.make-motion(@className, @keyframeName);
|
||||||
|
.@{className}-enter, .@{className}-appear {
|
||||||
|
opacity: 0;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-duration: @transition-time;
|
||||||
|
}
|
||||||
|
.@{className}-leave {
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-duration: @transition-time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ease-motion(ease, ivuEase);
|
||||||
|
|
||||||
|
@keyframes ivuEaseIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ivuEaseOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,3 +24,4 @@
|
||||||
|
|
||||||
@import "fade";
|
@import "fade";
|
||||||
@import "move";
|
@import "move";
|
||||||
|
@import "ease";
|
|
@ -62,16 +62,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&-close {
|
&-close {
|
||||||
font-size: 12px;
|
.content-close(-3px);
|
||||||
position: absolute;
|
|
||||||
right: 16px;
|
|
||||||
top: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.@{icon-prefix-cls}-ios-close-empty {
|
|
||||||
.close-base(-3px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-with-desc {
|
&-with-desc {
|
||||||
|
|
|
@ -35,21 +35,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&-head {
|
&-head {
|
||||||
border-bottom: 1px solid @border-color-split;
|
.content-header;
|
||||||
padding: 10px 16px;
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
p {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-extra {
|
&-extra {
|
||||||
|
|
|
@ -19,3 +19,4 @@
|
||||||
@import "timeline";
|
@import "timeline";
|
||||||
@import "page";
|
@import "page";
|
||||||
@import "steps";
|
@import "steps";
|
||||||
|
@import "modal";
|
133
styles/components/modal.less
Normal file
133
styles/components/modal.less
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
@modal-prefix-cls: ~"@{css-prefix}modal";
|
||||||
|
@confirm-prefix-cls: ~"@{css-prefix}modal-confirm";
|
||||||
|
|
||||||
|
.@{modal-prefix-cls} {
|
||||||
|
width: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
outline: none;
|
||||||
|
top: 100px;
|
||||||
|
|
||||||
|
&-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrap {
|
||||||
|
position: fixed;
|
||||||
|
overflow: auto;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: @zindex-modal;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrap * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-mask {
|
||||||
|
.mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 0;
|
||||||
|
border-radius: @border-radius-base;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
.content-header;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
.content-close;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer {
|
||||||
|
border-top: 1px solid @border-color-split;
|
||||||
|
padding: 10px 18px 10px 10px;
|
||||||
|
text-align: right;
|
||||||
|
button + button {
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.@{modal-prefix-cls} {
|
||||||
|
width: auto !important;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.vertical-center-modal {
|
||||||
|
.@{modal-prefix-cls} {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{confirm-prefix-cls} {
|
||||||
|
padding: 10px 25px 20px;
|
||||||
|
&-head {
|
||||||
|
&-icon {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 28px;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 0 1px;
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
|
|
||||||
|
&-info {
|
||||||
|
color: @primary-color;
|
||||||
|
}
|
||||||
|
&-success {
|
||||||
|
color: @success-color;
|
||||||
|
}
|
||||||
|
&-warning {
|
||||||
|
color: @warning-color;
|
||||||
|
}
|
||||||
|
&-error {
|
||||||
|
color: @error-color;
|
||||||
|
}
|
||||||
|
&-confirm {
|
||||||
|
color: @warning-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: @font-size-base;
|
||||||
|
color: @text-color;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body{
|
||||||
|
margin-left: 35px;
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: @text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer{
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
button + button {
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
styles/mixins/content.less
Normal file
32
styles/mixins/content.less
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
@icon-prefix-cls: ~"@{css-prefix}icon";
|
||||||
|
|
||||||
|
.content-header() {
|
||||||
|
border-bottom: 1px solid @border-color-split;
|
||||||
|
padding: 10px 16px;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-close(@top: 0) {
|
||||||
|
font-size: 12px;
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
top: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.@{icon-prefix-cls}-ios-close-empty {
|
||||||
|
.close-base(@top);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,3 +12,5 @@
|
||||||
@import "checkbox";
|
@import "checkbox";
|
||||||
@import "input";
|
@import "input";
|
||||||
@import "breadcrumb";
|
@import "breadcrumb";
|
||||||
|
@import "mask";
|
||||||
|
@import "content"; // card、modal
|
13
styles/mixins/mask.less
Normal file
13
styles/mixins/mask.less
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
.mask() {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(55, 55, 55, 0.6);
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -99,9 +99,10 @@
|
||||||
@tag-font-size : 12px;
|
@tag-font-size : 12px;
|
||||||
|
|
||||||
// Z-index
|
// Z-index
|
||||||
|
@zindex-spin : 8;
|
||||||
@zindex-affix : 10;
|
@zindex-affix : 10;
|
||||||
@zindex-back-top : 10;
|
@zindex-back-top : 10;
|
||||||
@zindex-spin : 8;
|
@zindex-modal : 1000;
|
||||||
@zindex-message : 1010;
|
@zindex-message : 1010;
|
||||||
@zindex-notification : 1010;
|
@zindex-notification : 1010;
|
||||||
@zindex-loading-bar : 2000;
|
@zindex-loading-bar : 2000;
|
||||||
|
|
|
@ -11,3 +11,42 @@ export function oneOf (value, validList) {
|
||||||
export function camelcaseToHyphen (str) {
|
export function camelcaseToHyphen (str) {
|
||||||
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For Modal scrollBar hidden
|
||||||
|
let cached;
|
||||||
|
export function getScrollBarSize (fresh) {
|
||||||
|
if (fresh || cached === undefined) {
|
||||||
|
const inner = document.createElement('div');
|
||||||
|
inner.style.width = '100%';
|
||||||
|
inner.style.height = '200px';
|
||||||
|
|
||||||
|
const outer = document.createElement('div');
|
||||||
|
const outerStyle = outer.style;
|
||||||
|
|
||||||
|
outerStyle.position = 'absolute';
|
||||||
|
outerStyle.top = 0;
|
||||||
|
outerStyle.left = 0;
|
||||||
|
outerStyle.pointerEvents = 'none';
|
||||||
|
outerStyle.visibility = 'hidden';
|
||||||
|
outerStyle.width = '200px';
|
||||||
|
outerStyle.height = '150px';
|
||||||
|
outerStyle.overflow = 'hidden';
|
||||||
|
|
||||||
|
outer.appendChild(inner);
|
||||||
|
|
||||||
|
document.body.appendChild(outer);
|
||||||
|
|
||||||
|
const widthContained = inner.offsetWidth;
|
||||||
|
outer.style.overflow = 'scroll';
|
||||||
|
let widthScroll = inner.offsetWidth;
|
||||||
|
|
||||||
|
if (widthContained === widthScroll) {
|
||||||
|
widthScroll = outer.clientWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(outer);
|
||||||
|
|
||||||
|
cached = widthContained - widthScroll;
|
||||||
|
}
|
||||||
|
return cached;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue