This commit is contained in:
prefert 2020-09-03 15:53:31 +08:00
parent 8f9d3604e6
commit 5bb83ff8e5
258 changed files with 12974 additions and 7838 deletions

View file

@ -44,7 +44,7 @@ export default {
this.anchorCom.$emit('on-select', this.href);
const isRoute = this.$router;
if (isRoute) {
this.$router.push(this.href);
this.$router.push(this.href, () => {});
} else {
window.location.href = this.href;
}

View file

@ -3,12 +3,13 @@
ref="select"
class="ivu-auto-complete"
:label="label"
:disabled="disabled"
:disabled="itemDisabled"
:clearable="clearable"
:placeholder="placeholder"
:size="size"
:placement="placement"
:value="currentValue"
:transfer-class-name="transferClassName"
filterable
remote
auto-complete
@ -24,7 +25,7 @@
v-model="currentValue"
:name="name"
:placeholder="placeholder"
:disabled="disabled"
:disabled="itemDisabled"
:size="size"
:icon="inputIcon"
@on-click="handleClear"
@ -42,10 +43,11 @@
import iInput from '../input/input.vue';
import { oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
export default {
name: 'AutoComplete',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
components: { iSelect, iOption, iInput },
props: {
value: {
@ -90,7 +92,7 @@
validator (value) {
return oneOf(value, ['top', 'bottom', 'top-start', 'bottom-start', 'top-end', 'bottom-end']);
},
default: 'bottom'
default: 'bottom-start'
},
transfer: {
type: Boolean,
@ -103,6 +105,9 @@
},
elementId: {
type: String
},
transferClassName: {
type: String
}
},
data () {
@ -114,8 +119,7 @@
computed: {
inputIcon () {
let icon = '';
//#6161 #7
if (this.clearable && this.currentValue && !this.disabled) {
if (this.clearable && this.currentValue && !this.disabled) {
icon = 'ios-close';
} else if (this.icon) {
icon = this.icon;
@ -152,10 +156,10 @@
remoteMethod (query) {
this.$emit('on-search', query);
},
handleSelect (val) {
handleSelect (option) {
const val = option.value;
if (val === undefined || val === null) return;
this.currentValue = val;
this.$refs.input.blur();
this.$emit('on-select', val);
},
@ -171,7 +175,7 @@
this.$refs.select.reset();
this.$emit('on-clear');
},
handleClickOutside(){
handleClickOutside () {
this.$nextTick(() => {
this.$refs.input.blur();
});

View file

@ -1,5 +1,5 @@
<template>
<span :class="classes">
<span :class="classes" :style="styles">
<img :src="src" v-if="src" @error="handleError">
<Icon :type="icon" :custom="customIcon" v-else-if="icon || customIcon"></Icon>
<span ref="children" :class="[prefixCls + '-string']" :style="childrenStyle" v-else><slot></slot></span>
@ -11,6 +11,8 @@
const prefixCls = 'ivu-avatar';
const sizeList = ['small', 'large', 'default'];
export default {
name: 'Avatar',
components: { Icon },
@ -22,9 +24,7 @@
default: 'circle'
},
size: {
validator (value) {
return oneOf(value, ['small', 'large', 'default']);
},
type: [String, Number],
default () {
return !this.$IVIEW || this.$IVIEW.size === '' ? 'default' : this.$IVIEW.size;
}
@ -53,13 +53,23 @@
return [
`${prefixCls}`,
`${prefixCls}-${this.shape}`,
`${prefixCls}-${this.size}`,
{
[`${prefixCls}-image`]: !!this.src,
[`${prefixCls}-icon`]: !!this.icon || !!this.customIcon
[`${prefixCls}-icon`]: !!this.icon || !!this.customIcon,
[`${prefixCls}-${this.size}`]: oneOf(this.size, sizeList)
}
];
},
styles () {
let style = {};
if (this.size && !oneOf(this.size, sizeList)) {
style.width = `${this.size}px`;
style.height = `${this.size}px`;
style.lineHeight = `${this.size}px`;
style.fontSize = `${this.size/2}px`;
}
return style;
},
childrenStyle () {
let style = {};
if (this.isSlotShow) {

View file

@ -3,17 +3,19 @@
<slot></slot>
<sup :class="dotClasses" :style="styles" v-show="badge"></sup>
</span>
<span v-else-if="status" :class="classes" class="ivu-badge-status" ref="badge">
<span :class="statusClasses"></span>
<span class="ivu-badge-status-text">{{ text }}</span>
<span v-else-if="status || color" :class="classes" class="ivu-badge-status" ref="badge">
<span :class="statusClasses" :style="statusStyles"></span>
<span class="ivu-badge-status-text"><slot name="text">{{ text }}</slot></span>
</span>
<span v-else :class="classes" ref="badge">
<slot></slot>
<sup v-if="hasCount" :style="styles" :class="countClasses" v-show="badge">{{ finalCount }}</sup>
<sup v-if="$slots.count" :style="styles" :class="customCountClasses"><slot name="count"></slot></sup>
<sup v-else-if="hasCount" :style="styles" :class="countClasses" v-show="badge"><slot name="text">{{ finalCount }}</slot></sup>
</span>
</template>
<script>
import { oneOf } from '../../utils/assist';
const initColorList = ['blue', 'green', 'red', 'yellow', 'pink', 'magenta', 'volcano', 'orange', 'gold', 'lime', 'cyan', 'geekblue', 'purple'];
const prefixCls = 'ivu-badge';
export default {
@ -49,6 +51,9 @@
},
offset: {
type: Array
},
color: {
type: String
}
},
computed: {
@ -68,14 +73,27 @@
}
];
},
customCountClasses () {
return [
`${prefixCls}-count`,
`${prefixCls}-count-custom`,
{
[`${this.className}`]: !!this.className,
}
];
},
statusClasses () {
return [
`${prefixCls}-status-dot`,
{
[`${prefixCls}-status-${this.status}`]: !!this.status
[`${prefixCls}-status-${this.status}`]: !!this.status,
[`${prefixCls}-status-${this.color}`]: !!this.color && oneOf(this.color, initColorList)
}
];
},
statusStyles () {
return oneOf(this.color, initColorList) ? {} : { backgroundColor: this.color};
},
styles () {
const style = {};
if (this.offset && this.offset.length === 2) {

View file

@ -13,7 +13,7 @@
</a>
</template>
<template v-if="type === 'message'">
<div :class="[baseClass + '-content']" ref="content">
<div :class="messageContentClasses" ref="content">
<div :class="[baseClass + '-content-text']" v-html="content"></div>
<div :class="[baseClass + '-content-text']">
<render-cell
@ -79,6 +79,13 @@
},
transitionName: {
type: String
},
background: {
type: Boolean,
default: false
},
msgType: {
type: String
}
},
data () {
@ -99,7 +106,8 @@
{
[`${this.className}`]: !!this.className,
[`${this.baseClass}-closable`]: this.closable,
[`${this.baseClass}-with-desc`]: this.withDesc
[`${this.baseClass}-with-desc`]: this.withDesc,
[`${this.baseClass}-with-background`]: this.background
}
];
},
@ -109,6 +117,15 @@
this.render !== undefined ? `${this.baseClass}-content-with-render` : ''
];
},
messageContentClasses () {
return [
`${this.baseClass}-content`,
{
[`${this.baseClass}-content-${this.msgType}`]: this.msgType,
[`${this.baseClass}-content-background`]: this.background
}
];
},
contentWithIcon () {
return [
this.withIcon ? `${this.prefixCls}-content-with-icon` : '',

View file

@ -14,6 +14,8 @@
:closable="notice.closable"
:name="notice.name"
:transition-name="notice.transitionName"
:background="notice.background"
:msg-type="notice.msgType"
:on-close="notice.onClose">
</Notice>
</div>

View file

@ -1,5 +1,5 @@
<template>
<component :is="tagName" :class="classes" :disabled="disabled" @click="handleClickLink" v-bind="tagProps">
<component :is="tagName" :class="classes" :disabled="itemDisabled" @click="handleClickLink" v-bind="tagProps">
<Icon class="ivu-load-loop" type="ios-loading" v-if="loading"></Icon>
<Icon :type="icon" :custom="customIcon" v-if="(icon || customIcon) && !loading"></Icon>
<span v-if="showSlot" ref="slot"><slot></slot></span>
@ -9,12 +9,13 @@
import Icon from '../icon';
import { oneOf } from '../../utils/assist';
import mixinsLink from '../../mixins/link';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-btn';
export default {
name: 'Button',
mixins: [ mixinsLink ],
mixins: [ mixinsLink, mixinsForm ],
components: { Icon },
props: {
type: {
@ -61,12 +62,10 @@
default: false
}
},
data () {
return {
showSlot: true
};
},
computed: {
showSlot () {
return !!this.$slots.default;
},
classes () {
return [
`${prefixCls}`,
@ -109,9 +108,6 @@
this.handleCheckClick(event, openInNewWindow);
}
},
mounted () {
this.showSlot = this.$slots.default !== undefined;
}
};
</script>

View file

@ -1,5 +1,5 @@
<template>
<div :class="classes">
<component :is="tagName" :class="classes" v-bind="tagProps" @click="handleClickLink">
<div :class="headClasses" v-if="showHead"><slot name="title">
<p v-if="title">
<Icon v-if="icon" :type="icon"></Icon>
@ -8,15 +8,17 @@
</slot></div>
<div :class="extraClasses" v-if="showExtra"><slot name="extra"></slot></div>
<div :class="bodyClasses" :style="bodyStyles"><slot></slot></div>
</div>
</component>
</template>
<script>
const prefixCls = 'ivu-card';
const defaultPadding = 16;
import Icon from '../icon/icon.vue';
import mixinsLink from '../../mixins/link';
export default {
name: 'Card',
mixins: [ mixinsLink ],
components: { Icon },
props: {
bordered: {
@ -76,6 +78,31 @@
} else {
return '';
}
},
// Point out if it should render as <a> tag
isHrefPattern () {
const { to } = this;
return !!to;
},
tagName () {
const { isHrefPattern } = this;
return isHrefPattern ? 'a' : 'div';
},
tagProps () {
const { isHrefPattern } = this;
if (isHrefPattern) {
const { linkUrl,target } = this;
return { href: linkUrl, target };
} else {
return {};
}
}
},
methods: {
handleClickLink (event) {
if (!this.isHrefPattern) return;
const openInNewWindow = event.ctrlKey || event.metaKey;
this.handleCheckClick(event, openInNewWindow);
}
},
mounted () {

View file

@ -4,10 +4,10 @@
<Icon type="ios-arrow-back"></Icon>
</button>
<div :class="[prefixCls + '-list']">
<div :class="[prefixCls + '-track', showCopyTrack ? '' : 'higher']" :style="trackStyles" ref="originTrack" @click="handlerClickEvent('currentIndex')">
<div :class="[prefixCls + '-track', showCopyTrack ? '' : 'higher']" :style="trackStyles" ref="originTrack" @click="handleClick('currentIndex')">
<slot></slot>
</div>
<div :class="[prefixCls + '-track', showCopyTrack ? 'higher' : '']" :style="copyTrackStyles" @click="handlerClickEvent('copyTrackIndex')" ref="copyTrack" v-if="loop">
<div :class="[prefixCls + '-track', showCopyTrack ? 'higher' : '']" :style="copyTrackStyles" ref="copyTrack" v-if="loop" @click="handleClick('copyTrackIndex')">
</div>
</div>
<button type="button" :class="arrowClasses" class="right" @click="arrowEvent(1)">
@ -128,7 +128,7 @@
transform: `translate3d(${-this.trackCopyOffset}px, 0px, 0px)`,
transition: `transform 500ms ${this.easing}`,
position: 'absolute',
//top: 0
// top: 0
};
},
arrowClasses () {
@ -145,9 +145,6 @@
}
},
methods: {
handlerClickEvent(type){
this.$emit('on-click',this[type]);
},
// find option component
findChild (cb) {
const find = function (child) {
@ -201,8 +198,8 @@
child.width = this.listWidth;
child.height = typeof this.height === 'number' ? `${this.height}px` : this.height;
});
const slidesLength = this.slides.length || 0;
this.trackWidth = slidesLength * this.listWidth;
this.trackWidth = (this.slides.length || 0) * this.listWidth;
},
// use when slot changed
slotChange () {
@ -296,6 +293,9 @@
this.trackOffset = this.trackIndex * this.listWidth;
this.trackCopyOffset = this.copyTrackIndex * this.listWidth + ofs;
});
},
handleClick (type) {
this.$emit('on-click', this[type]);
}
},
watch: {

View file

@ -7,7 +7,7 @@
:element-id="elementId"
ref="input"
:readonly="!filterable"
:disabled="disabled"
:disabled="itemDisabled"
:value="displayInputRender"
@on-change="handleInput"
:size="size"
@ -23,7 +23,7 @@
<transition name="transition-drop">
<Drop
v-show="visible"
:class="{ [prefixCls + '-transfer']: transfer }"
:class="dropdownCls"
ref="drop"
:data-transfer="transfer"
:transfer="transfer"
@ -34,7 +34,7 @@
ref="caspanel"
:prefix-cls="prefixCls"
:data="data"
:disabled="disabled"
:disabled="itemDisabled"
:change-on-select="changeOnSelect"
:trigger="trigger"></Caspanel>
<div :class="[prefixCls + '-dropdown']" v-show="filterable && query !== '' && querySelections.length">
@ -44,7 +44,6 @@
[selectPrefixCls + '-item-disabled']: item.disabled
}]"
v-for="(item, index) in querySelections"
:key="index"
@click="handleSelectItem(index)" v-html="item.display"></li>
</ul>
</div>
@ -59,18 +58,19 @@
import Drop from '../select/dropdown.vue';
import Icon from '../icon/icon.vue';
import Caspanel from './caspanel.vue';
import {directive as clickOutside} from 'v-click-outside-x';
import clickOutside from '../../directives/clickoutside';
import TransferDom from '../../directives/transfer-dom';
import { oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import Locale from '../../mixins/locale';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-cascader';
const selectPrefixCls = 'ivu-select';
export default {
name: 'Cascader',
mixins: [ Emitter, Locale ],
mixins: [ Emitter, Locale, mixinsForm ],
components: { iInput, Drop, Icon, Caspanel },
directives: { clickOutside, TransferDom },
props: {
@ -142,6 +142,16 @@
},
elementId: {
type: String
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? true : this.$IVIEW.capture;
}
},
transferClassName: {
type: String
}
},
data () {
@ -166,13 +176,13 @@
[`${prefixCls}-show-clear`]: this.showCloseIcon,
[`${prefixCls}-size-${this.size}`]: !!this.size,
[`${prefixCls}-visible`]: this.visible,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-not-found`]: this.filterable && this.query !== '' && !this.querySelections.length
}
];
},
showCloseIcon () {
return this.currentValue && this.currentValue.length && this.clearable && !this.disabled;
return this.currentValue && this.currentValue.length && this.clearable && !this.itemDisabled;
},
displayRender () {
let label = [];
@ -208,7 +218,7 @@
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
item.__label = label ? label + ' / ' + item.label : item.label;
item.__value = value ? [...value, item.value] : [item.value];
item.__value = value ? value + ',' + item.value : item.value;
if (item.children && item.children.length) {
getSelections(item.children, item.__label, item.__value);
@ -268,23 +278,29 @@
}
}
return size;
},
dropdownCls () {
return {
[prefixCls + '-transfer']: this.transfer,
[this.transferClassName]: this.transferClassName
};
}
},
methods: {
clearSelect () {
if (this.disabled) return false;
if (this.itemDisabled) return false;
const oldVal = JSON.stringify(this.currentValue);
this.currentValue = this.selected = this.tmpSelected = [];
this.handleClose();
this.emitValue(this.currentValue, oldVal);
// this.$broadcast('on-clear');
// this.$broadcast('on-clear');
this.broadcast('Caspanel', 'on-clear');
},
handleClose () {
this.visible = false;
},
toggleOpen () {
if (this.disabled) return false;
if (this.itemDisabled) return false;
if (this.visible) {
if (!this.filterable) this.handleClose();
} else {
@ -329,7 +345,7 @@
this.query = '';
this.$refs.input.currentValue = '';
const oldVal = JSON.stringify(this.currentValue);
this.currentValue = item.value;
this.currentValue = item.value.split(',');
// use setTimeout for #4786, can not use nextTick, because @on-find-selected use nextTick
setTimeout(() => {
this.emitValue(this.currentValue, oldVal);
@ -352,7 +368,7 @@
if ('__label' in new_item) {
delete new_item.__label;
}
if (Array.isArray(new_item.children) && new_item.children.length) {
if ('children' in new_item && new_item.children.length) {
new_item.children = new_item.children.map(i => deleteData(i));
}
return new_item;

View file

@ -7,18 +7,9 @@
:prefix-cls="prefixCls"
:data="item"
:tmp-item="tmpItem"
@click.native.stop="handleClickItem(item, $event)"
@mouseenter.native.stop="handleHoverItem(item)"
></Casitem>
</ul>
<Caspanel
v-if="sublist && sublist.length"
:prefix-cls="prefixCls"
:data="sublist"
:disabled="disabled"
:trigger="trigger"
:change-on-select="changeOnSelect">
</Caspanel>
@click.native.stop="handleClickItem(item)"
@mouseenter.native.stop="handleHoverItem(item)"></Casitem>
</ul><Caspanel v-if="sublist && sublist.length" :prefix-cls="prefixCls" :data="sublist" :disabled="disabled" :trigger="trigger" :change-on-select="changeOnSelect"></Caspanel>
</span>
</template>
<script>
@ -57,25 +48,15 @@
}
},
methods: {
isIcon(node){
let nodeName = (node.nodeName || '').toLocaleUpperCase();
let isIvu = node.classList.contains('ivu-icon');
if(nodeName == 'I' && isIvu){
return true;
}
return false;
},
handleClickItem (item, ev) {
let isIcon = this.isIcon(ev.target);
handleClickItem (item) {
if (this.trigger !== 'click' && item.children && item.children.length) return; // #1922
this.handleTriggerItem(item, false, true,isIcon);
this.handleTriggerItem(item, false, true);
},
handleHoverItem (item) {
if (this.trigger !== 'hover' || !item.children || !item.children.length) return; // #1922
this.handleTriggerItem(item, false, true,false);
this.handleTriggerItem(item, false, true);
},
//#6158 -- default fromInit = false to fromInit = true;
handleTriggerItem (item, fromInit = true, fromUser = false,isIcon=false) {
handleTriggerItem (item, fromInit = false, fromUser = false) {
if (item.disabled) return;
const cascader = findComponentUpward(this, 'Cascader');
@ -108,7 +89,7 @@
if (item.children && item.children.length){
this.sublist = item.children;
!isIcon && this.dispatch('Cascader', 'on-result-change', {
this.dispatch('Cascader', 'on-result-change', {
lastValue: false,
changeOnSelect: this.changeOnSelect,
fromInit: fromInit
@ -123,7 +104,7 @@
}
} else {
this.sublist = [];
!isIcon && this.dispatch('Cascader', 'on-result-change', {
this.dispatch('Cascader', 'on-result-change', {
lastValue: true,
changeOnSelect: this.changeOnSelect,
fromInit: fromInit

View file

@ -49,7 +49,7 @@
},
methods: {
updateModel (update) {
this.childrens = findComponentsDownward(this, 'Checkbox', 'CheckboxGroup');
this.childrens = findComponentsDownward(this, 'Checkbox');
if (this.childrens) {
const { value } = this;
this.childrens.forEach(child => {

View file

@ -6,7 +6,7 @@
v-if="group"
type="checkbox"
:class="inputClasses"
:disabled="disabled"
:disabled="itemDisabled"
:value="label"
v-model="model"
:name="name"
@ -17,7 +17,7 @@
v-else
type="checkbox"
:class="inputClasses"
:disabled="disabled"
:disabled="itemDisabled"
:checked="currentValue"
:name="name"
@change="change"
@ -30,12 +30,13 @@
<script>
import { findComponentUpward, oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-checkbox';
export default {
name: 'Checkbox',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
disabled: {
type: Boolean,
@ -70,6 +71,11 @@
},
name: {
type: String
},
// 4.0.0
border: {
type: Boolean,
default: false
}
},
data () {
@ -89,8 +95,9 @@
{
[`${prefixCls}-group-item`]: this.group,
[`${prefixCls}-wrapper-checked`]: this.currentValue,
[`${prefixCls}-wrapper-disabled`]: this.disabled,
[`${prefixCls}-${this.size}`]: !!this.size
[`${prefixCls}-wrapper-disabled`]: this.itemDisabled,
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-border`]: this.border
}
];
},
@ -99,7 +106,7 @@
`${prefixCls}`,
{
[`${prefixCls}-checked`]: this.currentValue,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-indeterminate`]: this.indeterminate
}
];
@ -131,7 +138,7 @@
},
methods: {
change (event) {
if (this.disabled) {
if (this.itemDisabled) {
return false;
}

View file

@ -1,8 +1,14 @@
<template>
<div :style="circleSize" :class="wrapClasses">
<svg viewBox="0 0 100 100">
<path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0" :style="trailStyle" />
<path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeColor" :stroke-width="computedStrokeWidth" fill-opacity="0" :style="pathStyle" />
<defs v-if="showDefs">
<linearGradient :id="id" x1="100%" y1="0%" x2="0%" y2="0%">
<stop offset="0%" :stop-color="strokeColor[0]"></stop>
<stop offset="100%" :stop-color="strokeColor[1]"></stop>
</linearGradient>
</defs>
<path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0" :style="trailStyle" :stroke-linecap="strokeLinecap" />
<path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeValue" :stroke-width="computedStrokeWidth" fill-opacity="0" :style="pathStyle" />
</svg>
<div :class="innerClasses">
<slot></slot>
@ -11,6 +17,7 @@
</template>
<script>
import { oneOf } from '../../utils/assist';
import random from '../../utils/random_str';
const prefixCls = 'ivu-chart-circle';
@ -30,7 +37,7 @@
default: 6
},
strokeColor: {
type: String,
type: [String, Array],
default: '#2d8cf0'
},
strokeLinecap: {
@ -52,6 +59,11 @@
default: false
}
},
data () {
return {
id: `ivu-chart-circle-${random(3)}`
};
},
computed: {
circleSize () {
return {
@ -112,6 +124,16 @@
},
innerClasses () {
return `${prefixCls}-inner`;
},
strokeValue () {
let color = this.strokeColor;
if (typeof this.strokeColor !== 'string') {
color = `url(#${this.id})`;
}
return color;
},
showDefs () {
return typeof this.strokeColor !== 'string';
}
}
};

View file

@ -42,13 +42,12 @@
methods: {
setActive () {
const activeKey = this.getActiveKey();
this.$nextTick(() => {
this.$children.forEach((child, index) => {
const name = child.name || index.toString();
child.isActive = activeKey.indexOf(name) > -1;
child.index = index;
});
this.$children.forEach((child, index) => {
const name = child.name || index.toString();
child.isActive = activeKey.indexOf(name) > -1;
child.index = index;
});
},
getActiveKey () {

View file

@ -64,6 +64,7 @@
},
mounted () {
this.mounted = true;
this.$parent.setActive();
}
};
</script>

View file

@ -1,6 +1,6 @@
<template>
<div
v-click-outside="handleClose"
v-click-outside:[capture]="handleClose"
:class="classes">
<div
ref="reference"
@ -13,7 +13,7 @@
<Icon :type="arrowType" :custom="customArrowType" :size="arrowSize" :class="arrowClasses"></Icon>
<div
ref="input"
:tabindex="disabled ? undefined : 0"
:tabindex="itemDisabled ? undefined : 0"
:class="inputClasses"
@keydown.tab="onTab"
@keydown.esc="onEscape"
@ -116,7 +116,7 @@
<script>
import tinycolor from 'tinycolor2';
import {directive as clickOutside} from 'v-click-outside-x';
import {directive as clickOutside} from '../../directives/v-click-outside-x';
import TransferDom from '../../directives/transfer-dom';
import Drop from '../../components/select/dropdown.vue';
import RecommendColors from './recommend-colors.vue';
@ -129,6 +129,7 @@ import Icon from '../icon/icon.vue';
import Locale from '../../mixins/locale';
import {oneOf} from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
import Prefixes from './prefixMixin';
import {changeColor, toRGBAString} from './utils';
@ -139,7 +140,7 @@ export default {
directives: {clickOutside, TransferDom},
mixins: [Emitter, Locale, Prefixes],
mixins: [Emitter, Locale, Prefixes, mixinsForm],
props: {
value: {
@ -221,6 +222,16 @@ export default {
type: Boolean,
default: true
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? true : this.$IVIEW.capture;
}
},
transferClassName: {
type: String
}
},
data() {
@ -292,7 +303,7 @@ export default {
`${this.inputPrefixCls}-wrapper`,
`${this.inputPrefixCls}-wrapper-${this.size}`,
{
[`${this.prefixCls}-disabled`]: this.disabled,
[`${this.prefixCls}-disabled`]: this.itemDisabled,
},
];
},
@ -303,7 +314,7 @@ export default {
`${this.inputPrefixCls}-${this.size}`,
{
[`${this.prefixCls}-focused`]: this.visible,
[`${this.prefixCls}-disabled`]: this.disabled,
[`${this.prefixCls}-disabled`]: this.itemDisabled,
},
];
},
@ -313,6 +324,7 @@ export default {
{
[`${this.prefixCls}-transfer`]: this.transfer,
[`${this.prefixCls}-hide-drop`]: this.hideDropDown,
[this.transferClassName]: this.transferClassName
},
];
},
@ -430,7 +442,7 @@ export default {
this.visible = false;
},
toggleVisible() {
if (this.disabled) {
if (this.itemDisabled) {
return;
}

View file

@ -75,10 +75,9 @@
return this.calendar(tableYear, tableMonth, (cell) => {
// normalize date offset from the dates provided by jsCalendar
// Comment out this code to fix daylight saving time bug
// Comment out this code to fix daylight saving time bug
// https://www.cnblogs.com/hamsterPP/p/5415472.html
if (cell.date instanceof Date) cell.date.setTime(cell.date.getTime() + cell.date.getTimezoneOffset() * 60000 + 480 * 60 * 1000);
//if (cell.date instanceof Date) cell.date.setTime(clearHours(cell.date));
const time = cell.date && clearHours(cell.date);
const dateIsInCurrentMonth = cell.date && tableMonth === cell.date.getMonth();

View file

@ -296,18 +296,7 @@
},
changePanelDate(panel, type, increment, updateOtherPanel = true){
const current = new Date(this[`${panel}PanelDate`]);
if (this.splitPanels) {
// fix #6404
current[`set${type}`](current[`get${type}`]() + increment);
} else {
if (panel === 'left') {
current[`set${type}`](current[`get${type}`]() + increment);
} else {
current[`set${type}`](current[`get${type}`]() + increment);
}
}
current[`set${type}`](current[`get${type}`]() + increment);
this[`${panel}PanelDate`] = current;
if (!updateOtherPanel) return;

View file

@ -101,7 +101,8 @@
];
},
showSeconds () {
return !(this.format || '').match(/mm$/);
//fix Hour & Minute Picker bug,show seconds when has "ss"
return !!(this.format || '').match(/ss/);
},
leftDatePanelLabel () {
return this.panelLabelConfig(this.date);

View file

@ -81,7 +81,8 @@
},
computed: {
showSeconds () {
return !(this.format || '').match(/mm$/);
//fix Hour & Minute Picker bug,show seconds when has "ss"
return !!(this.format || '').match(/ss/);
},
visibleDate () { // TODO
const date = this.date;

View file

@ -1,9 +1,9 @@
<template>
<div
:class="wrapperClasses"
v-click-outside:mousedown.capture="handleClose"
v-click-outside:touchstart.capture="handleClose"
v-click-outside.capture="handleClose"
v-click-outside:[capture].mousedown="handleClose"
v-click-outside:[capture].touchstart="handleClose"
v-click-outside:[capture]="handleClose"
>
<div ref="reference" :class="[prefixCls + '-rel']">
<slot>
@ -12,7 +12,7 @@
:element-id="elementId"
:class="[prefixCls + '-editor']"
:readonly="!editable || readonly"
:disabled="disabled"
:disabled="itemDisabled"
:size="size"
:placeholder="placeholder"
:value="visualValue"
@ -35,7 +35,7 @@
<Drop
@click.native="handleTransferClick"
v-show="opened"
:class="{ [prefixCls + '-transfer']: transfer }"
:class="dropdownCls"
:placement="placement"
ref="drop"
:data-transfer="transfer"
@ -75,17 +75,16 @@
</div>
</template>
<script>
import iInput from '../../components/input/input.vue';
import Drop from '../../components/select/dropdown.vue';
import Icon from '../../components/icon/icon.vue';
import {directive as clickOutside} from 'v-click-outside-x';
import {directive as clickOutside} from '../../directives/v-click-outside-x';
import TransferDom from '../../directives/transfer-dom';
import { oneOf } from '../../utils/assist';
import { DEFAULT_FORMATS, TYPE_VALUE_RESOLVER_MAP, getDayCountOfMonth } from './util';
import {findComponentsDownward} from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-date-picker';
const pickerPrefixCls = 'ivu-picker';
@ -120,7 +119,7 @@
export default {
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
components: { iInput, Drop, Icon },
directives: { clickOutside, TransferDom },
props: {
@ -214,6 +213,16 @@
separator: {
type: String,
default: ' - '
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? true : this.$IVIEW.capture;
}
},
transferClassName: {
type: String
}
},
data(){
@ -351,6 +360,12 @@
}
return size;
},
dropdownCls () {
return {
[prefixCls + '-transfer']: this.transfer,
[this.transferClassName]: this.transferClassName
};
}
},
methods: {
@ -393,7 +408,7 @@
if (this.readonly) return;
this.isFocused = true;
if (e && e.type === 'focus') return; // just focus, don't open yet
if(!this.disabled){
if(!this.itemDisabled){
this.visible = true;
}
},
@ -526,8 +541,9 @@
const pickerPossibleValues = timePickers[pickerIndex][`${timeParts[col]}List`];
const nextIndex = pickerPossibleValues.findIndex(({text}) => this.focusedTime.time[pickerIndex][col] === text) + increment;
const nextValue = pickerPossibleValues[nextIndex % pickerPossibleValues.length].text;
const currentIndex = pickerPossibleValues.findIndex(({text}) => this.focusedTime.time[pickerIndex][col] === text);
const nextIndex = (currentIndex + increment + pickerPossibleValues.length) % pickerPossibleValues.length;
const nextValue = pickerPossibleValues[nextIndex].text;
const times = this.focusedTime.time.map((time, i) => {
if (i !== pickerIndex) return time;
time[col] = nextValue;
@ -635,7 +651,7 @@
}
},
handleInputMouseenter () {
if (this.readonly || this.disabled) return;
if (this.readonly || this.itemDisabled) return;
if (this.visualValue && this.clearable) {
this.showClose = true;
}
@ -647,7 +663,7 @@
if (this.showClose) {
if (e) e.stopPropagation();
this.handleClear();
} else if (!this.disabled) {
} else if (!this.itemDisabled) {
this.handleFocus();
}
},

View file

@ -1,11 +1,11 @@
<template>
<div v-transfer-dom :data-transfer="transfer">
<transition name="fade">
<div :class="maskClasses" :style="maskStyle" v-if="mask && visible" @click="handleMask"></div>
<div :class="maskClasses" :style="maskStyle" v-show="visible" v-if="mask" @click="handleMask"></div>
</transition>
<div :class="wrapClasses" @click="handleWrapClick">
<transition :name="'move-' + placement">
<div :class="classes" :style="mainStyles" v-if="visible">
<div :class="classes" :style="mainStyles" v-show="visible">
<div :class="contentClasses" ref="content">
<a class="ivu-drawer-close" v-if="closable" @click="close">
<slot name="close">

View file

@ -40,6 +40,7 @@
if (this.disabled) return;
const $parent = findComponentUpward(this, 'Dropdown');
const hasChildren = this.$parent && this.$parent.$options.name === 'Dropdown';
if (hasChildren) {
this.$parent.$emit('on-haschild-click');
} else {

View file

@ -21,7 +21,7 @@
</template>
<script>
import Drop from '../select/dropdown.vue';
import {directive as clickOutside} from 'v-click-outside-x';
import clickOutside from '../../directives/clickoutside';
import TransferDom from '../../directives/transfer-dom';
import { oneOf, findComponentUpward } from '../../utils/assist';
@ -61,6 +61,13 @@
type: Boolean,
default: false
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? true : this.$IVIEW.capture;
}
}
},
computed: {
transition () {

View file

@ -1,10 +1,10 @@
<template>
<div :class="classes">
<label :class="[prefixCls + '-label']" :for="labelFor" :style="labelStyles" v-if="label || $slots.label"><slot name="label">{{ label }}</slot></label>
<label :class="[prefixCls + '-label']" :for="labelFor" :style="labelStyles" v-if="label || $slots.label"><slot name="label">{{ label }}{{ FormInstance.colon }}</slot></label>
<div :class="[prefixCls + '-content']" :style="contentStyles">
<slot></slot>
<transition name="fade">
<div :class="[prefixCls + '-error-tip']" v-if="validateState === 'error' && showMessage && form.showMessage">{{ validateMessage }}</div>
<div :class="[prefixCls + '-error-tip']" v-if="validateState === 'error' && showMessage && FormInstance.showMessage">{{ validateMessage }}</div>
</transition>
</div>
</div>
@ -96,9 +96,15 @@
},
rules (){
this.setRules();
}
},
required (n, o) {
this.isRequired = n;
if (o && !n) {
this.resetField();
}
},
},
inject: ['form'],
inject: ['FormInstance'],
computed: {
classes () {
return [
@ -118,7 +124,7 @@
// return parent;
// },
fieldValue () {
const model = this.form.model;
const model = this.FormInstance.model;
if (!model || !this.prop) { return; }
let path = this.prop;
@ -130,7 +136,7 @@
},
labelStyles () {
let style = {};
const labelWidth = this.labelWidth === 0 || this.labelWidth ? this.labelWidth : this.form.labelWidth;
const labelWidth = this.labelWidth === 0 || this.labelWidth ? this.labelWidth : this.FormInstance.labelWidth;
if (labelWidth || labelWidth === 0) {
style.width = `${labelWidth}px`;
@ -139,7 +145,7 @@
},
contentStyles () {
let style = {};
const labelWidth = this.labelWidth === 0 || this.labelWidth ? this.labelWidth : this.form.labelWidth;
const labelWidth = this.labelWidth === 0 || this.labelWidth ? this.labelWidth : this.FormInstance.labelWidth;
if (labelWidth || labelWidth === 0) {
style.marginLeft = `${labelWidth}px`;
@ -165,7 +171,7 @@
this.$on('on-form-change', this.onFieldChange);
},
getRules () {
let formRules = this.form.rules;
let formRules = this.FormInstance.rules;
const selfRules = this.rules;
formRules = formRules ? formRules[this.prop] : [];
@ -178,42 +184,41 @@
return rules.filter(rule => !rule.trigger || rule.trigger.indexOf(trigger) !== -1);
},
validate(trigger, callback = function () {}) {
this.$nextTick(() => {
let rules = this.getFilteredRule(trigger);
if (!rules || rules.length === 0) {
if (!this.required) {
this.validateState = '';
callback();
return true;
}else {
rules = [{required: true}];
}
let rules = this.getFilteredRule(trigger);
if (!rules || rules.length === 0) {
if (!this.required) {
callback();
return true;
}else {
rules = [{required: true}];
}
}
this.validateState = 'validating';
this.validateState = 'validating';
let descriptor = {};
descriptor[this.prop] = rules;
let descriptor = {};
descriptor[this.prop] = rules;
const validator = new AsyncValidator(descriptor);
let model = {};
const validator = new AsyncValidator(descriptor);
let model = {};
model[this.prop] = this.fieldValue;
model[this.prop] = this.fieldValue;
validator.validate(model, { firstFields: true }, errors => {
this.validateState = !errors ? 'success' : 'error';
this.validateMessage = errors ? errors[0].message : '';
validator.validate(model, { firstFields: true }, errors => {
this.validateState = !errors ? 'success' : 'error';
this.validateMessage = errors ? errors[0].message : '';
callback(this.validateMessage);
});
this.validateDisabled = false;
callback(this.validateMessage);
this.FormInstance && this.FormInstance.$emit('on-validate', this.prop, !errors, this.validateMessage || null);
});
this.validateDisabled = false;
},
resetField () {
this.validateState = '';
this.validateMessage = '';
let model = this.form.model;
let model = this.FormInstance.model;
let value = this.fieldValue;
let path = this.prop;
if (path.indexOf(':') !== -1) {

View file

@ -37,10 +37,25 @@
return oneOf(value, ['on', 'off']);
},
default: 'off'
},
// 4.0.0
hideRequiredMark: {
type: Boolean,
default: false
},
// 4.0.0
labelColon: {
type: [Boolean, String],
default: false
},
// 4.0.0
disabled: {
type: Boolean,
default: false
}
},
provide() {
return { form : this };
provide () {
return { FormInstance : this };
},
data () {
return {
@ -53,9 +68,17 @@
`${prefixCls}`,
`${prefixCls}-label-${this.labelPosition}`,
{
[`${prefixCls}-inline`]: this.inline
[`${prefixCls}-inline`]: this.inline,
[`${prefixCls}-hide-required-mark`]: this.hideRequiredMark
}
];
},
colon () {
let colon = '';
if (this.labelColon) {
colon = (typeof this.labelColon === 'boolean') ? ':' : this.labelColon;
}
return colon;
}
},
methods: {
@ -68,6 +91,13 @@
return new Promise(resolve => {
let valid = true;
let count = 0;
// fields promise
if (this.fields.length === 0) {
resolve(valid);
if (typeof callback === 'function') {
callback(valid);
}
}
this.fields.forEach(field => {
field.validate('', errors => {
if (errors) {

View file

@ -16,7 +16,7 @@
<input
:id="elementId"
:class="inputClasses"
:disabled="disabled"
:disabled="itemDisabled"
autocomplete="off"
spellcheck="false"
:autofocus="autofocus"
@ -24,7 +24,6 @@
@blur="blur"
@keydown.stop="keyDown"
@input="change"
ref="precisionCursor"
@mouseup="preventDefault"
@change="change"
:readonly="readonly || !editable"
@ -37,6 +36,7 @@
<script>
import { oneOf, findComponentUpward } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-input-number';
const iconPrefixCls = 'ivu-icon';
@ -67,7 +67,7 @@
export default {
name: 'InputNumber',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
max: {
type: Number,
@ -87,7 +87,7 @@
},
value: {
type: Number,
default: null,
default: 1
},
size: {
validator (value) {
@ -147,7 +147,7 @@
`${prefixCls}`,
{
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-focused`]: this.focused
}
];
@ -222,9 +222,10 @@
this.changeStep('down', e);
},
changeStep (type, e) {
if (this.disabled || this.readonly) {
if (this.itemDisabled || this.readonly) {
return false;
}
const targetVal = Number(e.target.value);
let val = Number(this.currentValue);
const step = Number(this.step);
@ -261,8 +262,7 @@
if (val && !isNaN(this.precision)) val = Number(Number(val).toFixed(this.precision));
const {min, max} = this;
// #6245
if ( val!==null && !this.activeChange ) {
if (val!==null) {
if (val > max) {
val = max;
} else if (val < min) {
@ -311,24 +311,15 @@
this.setValue(null);
return;
}
if (event.type == 'input' && val.match(/^\-?\.?$|\.$/g)) return; // prevent fire early if decimal. If no more input the change event will fire later
//#fixed when setting the precision val, input point cannot show problem
const precision = this.precision;
let cacheVal = this.currentValue;
if( precision ){
const valMatchPointArr = (val+'').match(/\./g);
if( valMatchPointArr && valMatchPointArr.length >= 2 ){
cacheVal = this.currentValue + '.';
}
}
if (event.type == 'input' && val.match(/^\-?\.?$|\.$/)) return; // prevent fire early if decimal. If no more input the change event will fire later
val = Number(val);
if (!isNaN(val) ) {
if (!isNaN(val)) {
this.currentValue = val;
this.setValue(val);
} else {
event.target.value = cacheVal;
event.target.value = this.currentValue;
}
},
changeVal (val) {
@ -353,14 +344,6 @@
},
currentValue (val) {
this.changeVal(val);
//optimization - Solve the problem of cursor positioning inaccuracy
this.$nextTick(()=>{
if( this.precision ){
const currentValueLength = ( this.currentValue || 0 ).toString().length;
const precisionCursor = this.$refs.precisionCursor;
precisionCursor.selectionStart = precisionCursor.selectionEnd = currentValueLength;
}
});
},
min () {
this.changeVal(this.currentValue);

View file

@ -2,41 +2,44 @@
<div :class="wrapClasses">
<template v-if="type !== 'textarea'">
<div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-show="slotReady"><slot name="prepend"></slot></div>
<div :class="[prefixCls + '-inner-container']">
<i class="ivu-icon" :class="['ivu-icon-ios-close-circle', prefixCls + '-icon', prefixCls + '-icon-clear' , prefixCls + '-icon-normal']" v-if="clearable && currentValue && !disabled" @click="handleClear"></i>
<i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon', prefixCls + '-icon-normal']" v-else-if="icon" @click="handleIconClick"></i>
<i class="ivu-icon ivu-icon-ios-search" :class="[prefixCls + '-icon', prefixCls + '-icon-normal', prefixCls + '-search-icon']" v-else-if="search && enterButton === false" @click="handleSearch"></i>
<span class="ivu-input-suffix" v-else-if="showSuffix"><slot name="suffix"><i class="ivu-icon" :class="['ivu-icon-' + suffix]" v-if="suffix"></i></slot></span>
<transition name="fade">
<i class="ivu-icon ivu-icon-ios-loading ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" v-if="!icon"></i>
</transition>
<input
:id="elementId"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
ref="input"
:type="type"
:class="inputClasses"
:placeholder="placeholder"
:disabled="disabled"
:maxlength="maxlength"
:readonly="readonly"
:name="name"
:value="currentValue"
:number="number"
:autofocus="autofocus"
@keyup.enter="handleEnter"
@keyup="handleKeyup"
@keypress="handleKeypress"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
@input="handleInput"
@change="handleChange">
</div>
<i class="ivu-icon" :class="['ivu-icon-ios-close-circle', prefixCls + '-icon', prefixCls + '-icon-clear' , prefixCls + '-icon-normal']" v-if="clearable && currentValue && !itemDisabled" @click="handleClear"></i>
<i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon', prefixCls + '-icon-normal']" v-else-if="icon" @click="handleIconClick"></i>
<i class="ivu-icon ivu-icon-ios-search" :class="[prefixCls + '-icon', prefixCls + '-icon-normal', prefixCls + '-search-icon']" v-else-if="search && enterButton === false" @click="handleSearch"></i>
<span class="ivu-input-suffix" v-else-if="showSuffix"><slot name="suffix"><i class="ivu-icon" :class="['ivu-icon-' + suffix]" v-if="suffix"></i></slot></span>
<span class="ivu-input-word-count" v-else-if="showWordLimit">{{ textLength }}/{{ upperLimit }}</span>
<span class="ivu-input-suffix" v-else-if="password" @click="handleToggleShowPassword">
<i class="ivu-icon ivu-icon-ios-eye-off-outline" v-if="showPassword"></i>
<i class="ivu-icon ivu-icon-ios-eye-outline" v-else></i>
</span>
<transition name="fade">
<i class="ivu-icon ivu-icon-ios-loading ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" v-if="!icon"></i>
</transition>
<input
:id="elementId"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
ref="input"
:type="currentType"
:class="inputClasses"
:placeholder="placeholder"
:disabled="itemDisabled"
:maxlength="maxlength"
:readonly="readonly"
:name="name"
:value="currentValue"
:number="number"
:autofocus="autofocus"
@keyup.enter="handleEnter"
@keyup="handleKeyup"
@keypress="handleKeypress"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
@input="handleInput"
@change="handleChange">
<div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady"><slot name="append"></slot></div>
<div :class="[prefixCls + '-group-append', prefixCls + '-search']" v-else-if="search && enterButton" @click="handleSearch">
<i class="ivu-icon ivu-icon-ios-search" v-if="enterButton === true"></i>
@ -44,46 +47,49 @@
</div>
<span class="ivu-input-prefix" v-else-if="showPrefix"><slot name="prefix"><i class="ivu-icon" :class="['ivu-icon-' + prefix]" v-if="prefix"></i></slot></span>
</template>
<textarea
v-else
:id="elementId"
:wrap="wrap"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
ref="textarea"
:class="textareaClasses"
:style="textareaStyles"
:placeholder="placeholder"
:disabled="disabled"
:rows="rows"
:maxlength="maxlength"
:readonly="readonly"
:name="name"
:value="currentValue"
:autofocus="autofocus"
@keyup.enter="handleEnter"
@keyup="handleKeyup"
@keypress="handleKeypress"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
@input="handleInput">
</textarea>
<template v-else>
<textarea
:id="elementId"
:wrap="wrap"
:autocomplete="autocomplete"
:spellcheck="spellcheck"
ref="textarea"
:class="textareaClasses"
:style="textareaStyles"
:placeholder="placeholder"
:disabled="itemDisabled"
:rows="rows"
:maxlength="maxlength"
:readonly="readonly"
:name="name"
:value="currentValue"
:autofocus="autofocus"
@keyup.enter="handleEnter"
@keyup="handleKeyup"
@keypress="handleKeypress"
@keydown="handleKeydown"
@focus="handleFocus"
@blur="handleBlur"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
@input="handleInput">
</textarea>
<span class="ivu-input-word-count" v-if="showWordLimit">{{ textLength }}/{{ upperLimit }}</span>
</template>
</div>
</template>
<script>
import { oneOf, findComponentUpward } from '../../utils/assist';
import calcTextareaHeight from '../../utils/calcTextareaHeight';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-input';
export default {
name: 'Input',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
type: {
validator (value) {
@ -108,7 +114,7 @@
default: ''
},
maxlength: {
type: Number
type: [String, Number]
},
disabled: {
type: Boolean,
@ -174,28 +180,60 @@
enterButton: {
type: [Boolean, String],
default: false
},
// 4.0.0
showWordLimit: {
type: Boolean,
default: false
},
// 4.0.0
password: {
type: Boolean,
default: false
}
},
data () {
return {
currentValue: this.value,
prefixCls: prefixCls,
prepend: true,
append: true,
slotReady: false,
textareaStyles: {},
showPrefix: false,
showSuffix: false,
isOnComposition: false
isOnComposition: false,
showPassword: false
};
},
computed: {
currentType () {
let type = this.type;
if (type === 'password' && this.password && this.showPassword) type = 'text';
return type;
},
prepend () {
let state = false;
if (this.type !== 'textarea') state = this.$slots.prepend !== undefined;
return state;
},
append () {
let state = false;
if (this.type !== 'textarea') state = this.$slots.append !== undefined;
return state;
},
showPrefix () {
let state = false;
if (this.type !== 'textarea') state = this.prefix !== '' || this.$slots.prefix !== undefined;
return state;
},
showSuffix () {
let state = false;
if (this.type !== 'textarea') state = this.suffix !== '' || this.$slots.suffix !== undefined;
return state;
},
wrapClasses () {
return [
`${prefixCls}-wrapper`,
{
[`${prefixCls}-wrapper-${this.size}`]: !!this.size,
[`${prefixCls}-type`]: this.type,
[`${prefixCls}-type-${this.type}`]: this.type,
[`${prefixCls}-group`]: this.prepend || this.append || (this.search && this.enterButton),
[`${prefixCls}-group-${this.size}`]: (this.prepend || this.append || (this.search && this.enterButton)) && !!this.size,
[`${prefixCls}-group-with-prepend`]: this.prepend,
@ -210,7 +248,7 @@
`${prefixCls}`,
{
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-with-prefix`]: this.showPrefix,
[`${prefixCls}-with-suffix`]: this.showSuffix || (this.search && this.enterButton === false)
}
@ -220,9 +258,19 @@
return [
`${prefixCls}`,
{
[`${prefixCls}-disabled`]: this.disabled
[`${prefixCls}-disabled`]: this.itemDisabled
}
];
},
upperLimit () {
return this.maxlength;
},
textLength () {
if (typeof this.value === 'number') {
return String(this.value).length;
}
return (this.value || '').length;
}
},
methods: {
@ -315,9 +363,18 @@
this.$emit('on-clear');
},
handleSearch () {
if (this.disabled) return false;
if (this.itemDisabled) return false;
this.$refs.input.focus();
this.$emit('on-search', this.currentValue);
},
handleToggleShowPassword () {
if (this.itemDisabled) return false;
this.showPassword = !this.showPassword;
this.focus();
const len = this.currentValue.length;
setTimeout(() => {
this.$refs.input.setSelectionRange(len, len);
}, 0);
}
},
watch: {
@ -326,15 +383,6 @@
}
},
mounted () {
if (this.type !== 'textarea') {
this.prepend = this.$slots.prepend !== undefined;
this.append = this.$slots.append !== undefined;
this.showPrefix = this.prefix !== '' || this.$slots.prefix !== undefined;
this.showSuffix = this.suffix !== '' || this.$slots.suffix !== undefined;
} else {
this.prepend = false;
this.append = false;
}
this.slotReady = true;
this.resizeTextarea();
}

View file

@ -31,7 +31,7 @@ function getMessageInstance () {
return messageInstance;
}
function notice (content = '', duration = defaults.duration, type, onClose = function () {}, closable = false, render = function () {}) {
function notice (content = '', duration = defaults.duration, type, onClose = function () {}, closable = false, render = function () {}, background = false) {
const iconType = iconTypes[type];
// if loading
@ -53,7 +53,9 @@ function notice (content = '', duration = defaults.duration, type, onClose = fun
render: render,
onClose: onClose,
closable: closable,
type: 'message'
type: 'message',
msgType: type,
background: background
});
// 用于手动消除
@ -90,7 +92,7 @@ export default {
content: options
};
}
return notice(options.content, options.duration, type, options.onClose, options.closable, options.render);
return notice(options.content, options.duration, type, options.onClose, options.closable, options.render, options.background);
},
config (options) {
if (options.top || options.top === 0) {

View file

@ -24,7 +24,6 @@ Modal.newInstance = properties => {
buttonLoading: false,
scrollable: false,
closable: false,
autoClose: true,
closing: false // 关闭有动画,期间使用此属性避免重复点击
}),
render (h) {
@ -32,8 +31,7 @@ Modal.newInstance = properties => {
if (this.showCancel) {
footerVNodes.push(h(Button, {
props: {
type: 'text',
size: 'large'
type: 'text'
},
on: {
click: this.cancel
@ -43,7 +41,6 @@ Modal.newInstance = properties => {
footerVNodes.push(h(Button, {
props: {
type: 'primary',
size: 'large',
loading: this.buttonLoading
},
on: {
@ -103,8 +100,7 @@ Modal.newInstance = properties => {
props: Object.assign({}, _props, {
width: this.width,
scrollable: this.scrollable,
closable: this.closable,
autoClose: this.autoClose
closable: this.closable
}),
domProps: {
value: this.visible
@ -172,11 +168,8 @@ Modal.newInstance = properties => {
if (this.loading) {
this.buttonLoading = true;
} else {
if (this.autoClose) {
this.$children[0].visible = false;
this.remove();
}
this.$children[0].visible = false;
this.remove();
}
this.onOk();
},
@ -189,9 +182,7 @@ Modal.newInstance = properties => {
},
destroy () {
this.$destroy();
if( this.$el ){
document.body.removeChild(this.$el);
}
if (this.$el) document.body.removeChild(this.$el);
this.onRemove();
},
onOk () {},
@ -255,10 +246,6 @@ Modal.newInstance = properties => {
modal.$parent.onCancel = props.onCancel;
}
if ('autoClose' in props) {
modal.$parent.autoClose = props.autoClose;
}
if ('onOk' in props) {
modal.$parent.onOk = props.onOk;
}

View file

@ -19,8 +19,8 @@
<div :class="[prefixCls + '-body']"><slot></slot></div>
<div :class="[prefixCls + '-footer']" v-if="!footerHide">
<slot name="footer">
<i-button type="text" size="large" @click.native="cancel">{{ localeCancelText }}</i-button>
<i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
<i-button type="text" @click.native="cancel">{{ localeCancelText }}</i-button>
<i-button type="primary" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
</slot>
</div>
</div>
@ -83,7 +83,7 @@
},
styles: {
type: Object,
default() {
default () {
return {};
}
},
@ -127,10 +127,6 @@
type: Number,
default: 1000
},
autoClose: {
type: Boolean,
default: true
}
},
data () {
return {
@ -209,10 +205,12 @@
let style = {};
if (this.draggable) {
let customTop = this.styles.top ? parseFloat(this.styles.top) : 0;
let customLeft = this.styles.left ? parseFloat(this.styles.left) : 0;
const customTop = this.styles.top ? parseFloat(this.styles.top) : 0;
const customLeft = this.styles.left ? parseFloat(this.styles.left) : 0;
if (this.dragData.x !== null) style.left = `${this.dragData.x - customLeft}px`;
if (this.dragData.y !== null) style.top = `${this.dragData.y}px`;
if (this.dragData.y !== null) style.top = `${this.dragData.y - customTop}px`;
const width = parseInt(this.width);
const styleWidth = {
width: width <= 100 ? `${width}%` : `${width}px`
@ -271,11 +269,8 @@
if (this.loading) {
this.buttonLoading = true;
} else {
if (this.autoClose) {
this.visible = false;
this.$emit('input', false);
}
this.visible = false;
this.$emit('input', false);
}
this.$emit('on-ok');
},

View file

@ -1,7 +1,7 @@
<template>
<div v-if="showSizer || showElevator" :class="optsClasses">
<div v-if="showSizer" :class="sizerClasses">
<i-select v-model="currentPageSize" :size="size" :placement="placement" :transfer="transfer" @on-change="changeSize">
<i-select v-model="currentPageSize" :size="size" :placement="placement" :transfer="transfer" :disabled="disabled" @on-change="changeSize">
<i-option v-for="item in pageSizeOpts" :key="item" :value="item" style="text-align:center;">{{ item }} {{ t('i.page.page') }}</i-option>
</i-select>
</div>
@ -12,6 +12,7 @@
:value="_current"
autocomplete="off"
spellcheck="false"
:disabled="disabled"
@keyup.enter="changePage"
>
{{ t('i.page.p') }}
@ -43,7 +44,8 @@
allPages: Number,
isSmall: Boolean,
placement: String,
transfer: Boolean
transfer: Boolean,
disabled: Boolean
},
data () {
return {

View file

@ -3,7 +3,7 @@
<li
:title="t('i.page.prev')"
:class="prevClasses"
@click.stop="prev">
@click="prev">
<a><i class="ivu-icon ivu-icon-ios-arrow-back"></i></a>
</li>
<div :class="simplePagerClasses" :title="currentPage + '/' + allPages">
@ -12,6 +12,7 @@
:value="currentPage"
autocomplete="off"
spellcheck="false"
:disabled="disabled"
@keydown="keyDown"
@keyup="keyUp"
@change="keyUp">
@ -21,7 +22,7 @@
<li
:title="t('i.page.next')"
:class="nextClasses"
@click.stop="next">
@click="next">
<a><i class="ivu-icon ivu-icon-ios-arrow-forward"></i></a>
</li>
</ul>
@ -32,24 +33,24 @@
<li
:title="t('i.page.prev')"
:class="prevClasses"
@click.stop="prev">
@click="prev">
<a><template v-if="prevText !== ''">{{ prevText }}</template><i v-else class="ivu-icon ivu-icon-ios-arrow-back"></i></a>
</li>
<li title="1" :class="firstPageClasses" @click.stop="changePage(1)"><a>1</a></li>
<li :title="t('i.page.prev5')" v-if="currentPage > 5" :class="[prefixCls + '-item-jump-prev']" @click.stop="fastPrev"><a><i class="ivu-icon ivu-icon-ios-arrow-back"></i></a></li>
<li :title="currentPage - 3" v-if="currentPage === 5" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage - 3)"><a>{{ currentPage - 3 }}</a></li>
<li :title="currentPage - 2" v-if="currentPage - 2 > 1" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage - 2)"><a>{{ currentPage - 2 }}</a></li>
<li :title="currentPage - 1" v-if="currentPage - 1 > 1" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage - 1)"><a>{{ currentPage - 1 }}</a></li>
<li title="1" :class="firstPageClasses" @click="changePage(1)"><a>1</a></li>
<li :title="t('i.page.prev5')" v-if="currentPage > 5" :class="[prefixCls + '-item-jump-prev']" @click="fastPrev"><a><i class="ivu-icon ivu-icon-ios-arrow-back"></i></a></li>
<li :title="currentPage - 3" v-if="currentPage === 5" :class="[prefixCls + '-item']" @click="changePage(currentPage - 3)"><a>{{ currentPage - 3 }}</a></li>
<li :title="currentPage - 2" v-if="currentPage - 2 > 1" :class="[prefixCls + '-item']" @click="changePage(currentPage - 2)"><a>{{ currentPage - 2 }}</a></li>
<li :title="currentPage - 1" v-if="currentPage - 1 > 1" :class="[prefixCls + '-item']" @click="changePage(currentPage - 1)"><a>{{ currentPage - 1 }}</a></li>
<li :title="currentPage" v-if="currentPage != 1 && currentPage != allPages" :class="[prefixCls + '-item',prefixCls + '-item-active']"><a>{{ currentPage }}</a></li>
<li :title="currentPage + 1" v-if="currentPage + 1 < allPages" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage + 1)"><a>{{ currentPage + 1 }}</a></li>
<li :title="currentPage + 2" v-if="currentPage + 2 < allPages" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage + 2)"><a>{{ currentPage + 2 }}</a></li>
<li :title="currentPage + 3" v-if="allPages - currentPage === 4" :class="[prefixCls + '-item']" @click.stop="changePage(currentPage + 3)"><a>{{ currentPage + 3 }}</a></li>
<li :title="t('i.page.next5')" v-if="allPages - currentPage >= 5" :class="[prefixCls + '-item-jump-next']" @click.stop="fastNext"><a><i class="ivu-icon ivu-icon-ios-arrow-forward"></i></a></li>
<li :title="allPages" v-if="allPages > 1" :class="lastPageClasses" @click.stop="changePage(allPages)"><a>{{ allPages }}</a></li>
<li :title="currentPage + 1" v-if="currentPage + 1 < allPages" :class="[prefixCls + '-item']" @click="changePage(currentPage + 1)"><a>{{ currentPage + 1 }}</a></li>
<li :title="currentPage + 2" v-if="currentPage + 2 < allPages" :class="[prefixCls + '-item']" @click="changePage(currentPage + 2)"><a>{{ currentPage + 2 }}</a></li>
<li :title="currentPage + 3" v-if="allPages - currentPage === 4" :class="[prefixCls + '-item']" @click="changePage(currentPage + 3)"><a>{{ currentPage + 3 }}</a></li>
<li :title="t('i.page.next5')" v-if="allPages - currentPage >= 5" :class="[prefixCls + '-item-jump-next']" @click="fastNext"><a><i class="ivu-icon ivu-icon-ios-arrow-forward"></i></a></li>
<li :title="allPages" v-if="allPages > 1" :class="lastPageClasses" @click="changePage(allPages)"><a>{{ allPages }}</a></li>
<li
:title="t('i.page.next')"
:class="nextClasses"
@click.stop="next">
@click="next">
<a><template v-if="nextText !== ''">{{ nextText }}</template><i v-else class="ivu-icon ivu-icon-ios-arrow-forward"></i></a>
</li>
<Options
@ -61,6 +62,7 @@
:show-elevator="showElevator"
:_current.once="currentPage"
:current="currentPage"
:disabled="disabled"
:all-pages="allPages"
:is-small="isSmall"
@on-size="onSize"
@ -145,11 +147,7 @@
type: String,
default: ''
},
cacheKey: {
type: String,
default: ''
},
cachePageSize: {
disabled: {
type: Boolean,
default: false
}
@ -200,6 +198,7 @@
`${prefixCls}`,
{
[`${this.className}`]: !!this.className,
[`${prefixCls}-with-disabled`]: this.disabled,
'mini': !!this.size
}
];
@ -208,7 +207,7 @@
return [
`${prefixCls}-prev`,
{
[`${prefixCls}-disabled`]: this.currentPage === 1,
[`${prefixCls}-disabled`]: this.currentPage === 1 || this.disabled,
[`${prefixCls}-custom-text`]: this.prevText !== ''
}
];
@ -217,7 +216,7 @@
return [
`${prefixCls}-next`,
{
[`${prefixCls}-disabled`]: this.currentPage === this.allPages,
[`${prefixCls}-disabled`]: this.currentPage === this.allPages || this.disabled,
[`${prefixCls}-custom-text`]: this.nextText !== ''
}
];
@ -237,17 +236,11 @@
[`${prefixCls}-item-active`]: this.currentPage === this.allPages
}
];
},
pageSizeKey() {
if (this.cachePageSize && this.cacheKey !== null) {
return `pageSize_${this.cacheKey}`;
} else {
return null;
}
}
},
methods: {
changePage (page) {
if (this.disabled) return;
if (this.currentPage != page) {
this.currentPage = page;
this.$emit('update:current', page);
@ -255,6 +248,7 @@
}
},
prev () {
if (this.disabled) return;
const current = this.currentPage;
if (current <= 1) {
return false;
@ -262,6 +256,7 @@
this.changePage(current - 1);
},
next () {
if (this.disabled) return;
const current = this.currentPage;
if (current >= this.allPages) {
return false;
@ -269,6 +264,7 @@
this.changePage(current + 1);
},
fastPrev () {
if (this.disabled) return;
const page = this.currentPage - 5;
if (page > 0) {
this.changePage(page);
@ -277,6 +273,7 @@
}
},
fastNext () {
if (this.disabled) return;
const page = this.currentPage + 5;
if (page > this.allPages) {
this.changePage(this.allPages);
@ -285,14 +282,13 @@
}
},
onSize (pageSize) {
if (this.disabled) return;
this.currentPageSize = pageSize;
this.$emit('on-page-size-change', pageSize);
this.changePage(1);
if (this.cachePageSize && this.cacheKey !== null) {
window.localStorage.setItem(this.pageSizeKey, pageSize);
}
},
onPage (page) {
if (this.disabled) return;
this.changePage(page);
},
keyDown (e) {

View file

@ -49,7 +49,7 @@
<script>
import Popper from '../base/popper';
import iButton from '../button/button.vue';
import {directive as clickOutside} from 'v-click-outside-x';
import clickOutside from '../../directives/clickoutside';
import TransferDom from '../../directives/transfer-dom';
import { oneOf } from '../../utils/assist';
import { transferIndex, transferIncrease } from '../../utils/transfer-queue';
@ -112,15 +112,20 @@
padding: {
type: String
},
//
modal: {
type: Boolean,
default: false,
},
// 3.4.0
disabled: {
type: Boolean,
default: false
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? false : this.$IVIEW.capture;
}
},
transferClassName: {
type: String
}
},
data () {
@ -146,7 +151,9 @@
`${prefixCls}-popper`,
{
[`${prefixCls}-confirm`]: this.transfer && this.confirm,
[`${this.popperClass}`]: !!this.popperClass
[`${this.popperClass}`]: !!this.popperClass,
[prefixCls + '-transfer']: this.transfer,
[this.transferClassName]: this.transferClassName
}
];
},
@ -206,20 +213,18 @@
if (this.transfer) this.disableCloseUnderTransfer = true;
},
handleClose () {
if (!this.modal) {
if (this.disableCloseUnderTransfer) {
this.disableCloseUnderTransfer = false;
return false;
}
if (this.confirm) {
this.visible = false;
return true;
}
if (this.trigger !== 'click') {
return false;
}
this.visible = false;
if (this.disableCloseUnderTransfer) {
this.disableCloseUnderTransfer = false;
return false;
}
if (this.confirm) {
this.visible = false;
return true;
}
if (this.trigger !== 'click') {
return false;
}
this.visible = false;
},
handleFocus (fromInput = true) {
if (this.disabled) return;

View file

@ -5,7 +5,7 @@
<input
type="radio"
:class="inputClasses"
:disabled="disabled"
:disabled="itemDisabled"
:checked="currentValue"
:name="groupName"
@change="change"
@ -17,12 +17,13 @@
<script>
import { findComponentUpward, oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-radio';
export default {
name: 'Radio',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
value: {
type: [String, Number, Boolean, Object],
@ -53,6 +54,11 @@
},
name: {
type: String
},
// 4.0.0
border: {
type: Boolean,
default: false
}
},
data () {
@ -72,9 +78,10 @@
{
[`${prefixCls}-group-item`]: this.group,
[`${prefixCls}-wrapper-checked`]: this.currentValue,
[`${prefixCls}-wrapper-disabled`]: this.disabled,
[`${prefixCls}-wrapper-disabled`]: this.itemDisabled,
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-focus`]: this.focusWrapper
[`${prefixCls}-focus`]: this.focusWrapper,
[`${prefixCls}-border`]: this.border
}
];
},
@ -83,7 +90,7 @@
`${prefixCls}`,
{
[`${prefixCls}-checked`]: this.currentValue,
[`${prefixCls}-disabled`]: this.disabled
[`${prefixCls}-disabled`]: this.itemDisabled
}
];
},
@ -121,7 +128,7 @@
},
methods: {
change (event) {
if (this.disabled) {
if (this.itemDisabled) {
return false;
}

View file

@ -29,6 +29,7 @@
<script>
import Locale from '../../mixins/locale';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
import Icon from '../icon/icon.vue';
@ -36,7 +37,7 @@
export default {
name: 'Rate',
mixins: [ Locale, Emitter ],
mixins: [ Locale, Emitter, mixinsForm ],
components: { Icon },
props: {
count: {
@ -93,7 +94,7 @@
return [
`${prefixCls}`,
{
[`${prefixCls}-disabled`]: this.disabled
[`${prefixCls}-disabled`]: this.itemDisabled
}
];
},
@ -145,7 +146,7 @@
];
},
handleMousemove(value, event) {
if (this.disabled) return;
if (this.itemDisabled) return;
this.isHover = true;
if (this.allowHalf) {
@ -157,7 +158,7 @@
this.hoverIndex = value;
},
handleMouseleave () {
if (this.disabled) return;
if (this.itemDisabled) return;
this.isHover = false;
this.setHalf(this.currentValue);
@ -167,7 +168,7 @@
this.isHalf = this.allowHalf && val.toString().indexOf('.') >= 0;
},
handleClick (value) {
if (this.disabled) return;
if (this.itemDisabled) return;
//value++;
if (this.isHalf) value -= 0.5;

View file

@ -7,6 +7,7 @@
</template>
<script>
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
import { findComponentUpward } from '../../utils/assist';
const prefixCls = 'ivu-select-item';
@ -14,7 +15,7 @@
export default {
name: 'iOption',
componentName: 'select-item',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
value: {
type: [String, Number],
@ -34,6 +35,10 @@
isFocused: {
type: Boolean,
default: false
},
// 4.0.0
tag: {
type: [String, Number]
}
},
data () {
@ -47,7 +52,7 @@
return [
`${prefixCls}`,
{
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-selected`]: this.selected && !this.autoComplete,
[`${prefixCls}-focus`]: this.isFocused
}
@ -62,15 +67,17 @@
},
methods: {
select () {
if (this.disabled) return false;
if (this.itemDisabled) return false;
this.dispatch('iSelect', 'on-select-selected', {
value: this.value,
label: this.optionLabel,
tag: this.tag
});
this.$emit('on-select-selected', {
value: this.value,
label: this.optionLabel,
tag: this.tag
});
},
},

View file

@ -9,8 +9,8 @@
class="ivu-tag ivu-tag-checked"
v-for="(item, index) in selectedMultiple"
v-if="maxTagCount === undefined || index < maxTagCount">
<span class="ivu-tag-text">{{ item.label }}</span>
<Icon type="ios-close" @click.native.stop="removeTag(item)"></Icon>
<span class="ivu-tag-text" :class="{ 'ivu-select-multiple-tag-hidden': item.disabled }">{{ item.tag !== undefined ? item.tag : item.label }}</span>
<Icon type="ios-close" v-if="!item.disabled" @click.native.stop="removeTag(item)"></Icon>
</div><div class="ivu-tag ivu-tag-checked" v-if="maxTagCount !== undefined && selectedMultiple.length > maxTagCount">
<span class="ivu-tag-text ivu-select-max-tag">
<template v-if="maxTagPlaceholder">{{ maxTagPlaceholder(selectedMultiple.length - maxTagCount) }}</template>
@ -34,6 +34,7 @@
spellcheck="false"
@keydown="resetInputState"
@keydown.delete="handleInputDelete"
@keydown.enter="handleInputEnter"
@focus="onInputFocus"
@blur="onInputBlur"
@ -101,6 +102,14 @@
// 3.4.0
maxTagPlaceholder: {
type: Function
},
// 4.0.0
allowCreate: {
type: Boolean
},
// 4.0.0
showCreateItem: {
type: Boolean
}
},
data () {
@ -216,6 +225,7 @@
this.$emit('on-input-focus');
},
onInputBlur () {
if (this.showCreateItem) return;
if (!this.values.length) this.query = ''; // #5155
this.$emit('on-input-blur');
},
@ -229,10 +239,13 @@
},
handleInputDelete (e) {
const targetValue = e.target.value;
if (this.multiple && this.selectedMultiple.length && this.query === '' && targetValue === '' ) {
if (this.multiple && this.selectedMultiple.length && this.query === '' && targetValue === '') {
this.removeTag(this.selectedMultiple[this.selectedMultiple.length - 1]);
}
},
handleInputEnter () {
this.$emit('on-enter');
},
onHeaderClick(e){
if (this.filterable && e.target === this.$el){
this.$refs.input.focus();

View file

@ -1,9 +1,9 @@
<template>
<div
:class="classes"
v-click-outside.capture="onClickOutside"
v-click-outside:mousedown.capture="onClickOutside"
v-click-outside:touchstart.capture="onClickOutside"
v-click-outside:[capture]="onClickOutside"
v-click-outside:[capture].mousedown="onClickOutside"
v-click-outside:[capture].touchstart="onClickOutside"
>
<div
ref="reference"
@ -35,7 +35,7 @@
:values="values"
:clearable="canBeCleared"
:prefix="prefix"
:disabled="disabled"
:disabled="itemDisabled"
:remote="remote"
:input-element-id="elementId"
:initial-label="initialLabel"
@ -43,11 +43,14 @@
:query-prop="query"
:max-tag-count="maxTagCount"
:max-tag-placeholder="maxTagPlaceholder"
:allow-create="allowCreate"
:show-create-item="showCreateItem"
@on-query-change="onQueryChange"
@on-input-focus="isFocused = true"
@on-input-blur="isFocused = false"
@on-clear="clearSingleSelect"
@on-enter="handleCreateItem"
>
<slot name="prefix" slot="prefix"></slot>
</select-head>
@ -63,10 +66,12 @@
:transfer="transfer"
v-transfer-dom
>
<ul v-show="showNotFoundLabel && !$slots.empty" :class="[prefixCls + '-not-found']"><li>{{ localeNotFoundText }}</li></ul>
<!--feature #5327-->
<ul v-if="showNotFoundLabel && $slots.empty" :class="[prefixCls + '-not-found']" @mousedown.prevent><li><slot name="empty"></slot></li></ul>
<ul v-show="showNotFoundLabel && !allowCreate" :class="[prefixCls + '-not-found']"><li>{{ localeNotFoundText }}</li></ul>
<ul :class="prefixCls + '-dropdown-list'">
<li :class="prefixCls + '-item'" v-if="showCreateItem" @click="handleCreateItem">
{{ query }}
<Icon type="md-return-left" :class="prefixCls + '-item-enter'" />
</li>
<functional-options
v-if="(!remote) || (remote && !loading)"
:options="selectOptions"
@ -81,10 +86,12 @@
</template>
<script>
import Drop from './dropdown.vue';
import {directive as clickOutside} from 'v-click-outside-x';
import Icon from '../icon';
import {directive as clickOutside} from '../../directives/v-click-outside-x';
import TransferDom from '../../directives/transfer-dom';
import { oneOf } from '../../utils/assist';
import { oneOf, findComponentsDownward } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
import Locale from '../../mixins/locale';
import SelectHead from './select-head.vue';
import FunctionalOptions from './functional-options.vue';
@ -157,8 +164,8 @@
export default {
name: 'iSelect',
mixins: [ Emitter, Locale ],
components: { FunctionalOptions, Drop, SelectHead },
mixins: [ Emitter, Locale, mixinsForm ],
components: { FunctionalOptions, Drop, SelectHead, Icon },
directives: { clickOutside, TransferDom },
props: {
value: {
@ -254,13 +261,31 @@
// 3.4.0
maxTagPlaceholder: {
type: Function
},
// 4.0.0
allowCreate: {
type: Boolean,
default: false
},
// 4.0.0
capture: {
type: Boolean,
default () {
return !this.$IVIEW ? true : this.$IVIEW.capture;
}
},
// 4.2.0
// label
filterByLabel: {
type: Boolean,
default: false
}
},
mounted(){
this.$on('on-select-selected', this.onOptionClick);
// set the initial values if there are any
if ( this.selectOptions.length > 0){
if (!this.remote && this.selectOptions.length > 0){
this.values = this.getInitialValue().map(value => {
if (typeof value !== 'number' && !value) return null;
return this.getOptionData(value);
@ -288,8 +313,6 @@
hasExpectedValue: false,
preventRemoteCall: false,
filterQueryChange: false, // #4273
// #6349
hideMenuTimer: null
};
},
computed: {
@ -298,7 +321,7 @@
`${prefixCls}`,
{
[`${prefixCls}-visible`]: this.visible,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-multiple`]: this.multiple,
[`${prefixCls}-single`]: !this.multiple,
[`${prefixCls}-show-clear`]: this.showCloseIcon,
@ -334,6 +357,17 @@
return this.loadingText;
}
},
showCreateItem () {
let state = false;
if (this.allowCreate && this.query !== '') {
state = true;
const $options = findComponentsDownward(this, 'iOption');
if ($options && $options.length) {
if ($options.find(item => item.optionLabel === this.query)) state = false;
}
}
return state;
},
transitionName () {
return this.placement === 'bottom' ? 'slide-up' : 'slide-down';
},
@ -359,7 +393,7 @@
},
canBeCleared(){
const uiStateMatch = this.hasMouseHoverHead || this.active;
const qualifiesForClear = !this.multiple && !this.disabled && this.clearable;
const qualifiesForClear = !this.multiple && !this.itemDisabled && this.clearable;
return uiStateMatch && qualifiesForClear && this.reset; // we return a function
},
selectOptions() {
@ -414,8 +448,9 @@
const optionPassesFilter = this.filterable ? this.validateOption(cOptions) : option;
if (!optionPassesFilter) continue;
}
optionCounter = optionCounter + 1;
selectOptions.push(this.processOption(option, selectedValues, currentIndex === optionCounter));
selectOptions.push(this.processOption(option, selectedValues, optionCounter === currentIndex));
}
}
@ -425,7 +460,7 @@
return extractOptions(this.selectOptions);
},
selectTabindex(){
return this.disabled || this.filterable ? -1 : 0;
return this.itemDisabled || this.filterable ? -1 : 0;
},
remote(){
return typeof this.remoteMethod === 'function';
@ -445,17 +480,22 @@
}
},
clearSingleSelect(){ // PUBLIC API
// fix #446
if (!this.multiple) this.$emit('input', '');
this.$emit('on-clear');
this.hideMenu();
if (this.clearable) this.reset();
this.$emit('on-clear'); // #6331
},
getOptionData(value){
const option = this.flatOptions.find(({componentOptions}) => componentOptions.propsData.value === value);
if (!option) return null;
const label = getOptionLabel(option);
// disabled bug
const disabled = option.componentOptions.propsData.disabled;
return {
value: value,
label: label,
disabled: disabled
};
},
getInitialValue(){
@ -475,6 +515,7 @@
const optionValue = option.componentOptions.propsData.value;
const disabled = option.componentOptions.propsData.disabled;
const isSelected = values.includes(optionValue);
const propsData = {
...option.componentOptions.propsData,
selected: isSelected,
@ -492,22 +533,19 @@
},
validateOption({children, elm, propsData}){
const value = propsData.value;
const label = propsData.label || '';
const textContent = (elm && elm.textContent) || (children || []).reduce((str, node) => {
const nodeText = node.elm ? node.elm.textContent : node.text;
return `${str} ${nodeText}`;
}, '') || '';
const stringValues = [label, textContent];
const stringValues = this.filterByLabel ? [label].toString() : [value, label, textContent].toString();
const query = this.query.toLowerCase().trim();
const findValuesIndex = stringValues.findIndex(item=>{
let itemToLowerCase = item.toLowerCase();
return itemToLowerCase.includes(query);
});
return findValuesIndex === -1 ? false : true;
return stringValues.toLowerCase().includes(query);
},
toggleMenu (e, force) {
if (this.disabled) {
if (this.itemDisabled) {
return false;
}
@ -517,22 +555,9 @@
this.broadcast('Drop', 'on-update-popper');
}
},
updateFocusIndex(){
this.focusIndex = this.flatOptions.findIndex((opt) => {
if (!opt || !opt.componentOptions) return false;
return opt.componentOptions.propsData.value === this.publicValue;
});
},
hideMenu () {
this.toggleMenu(null, false);
setTimeout(() =>{
this.unchangedQuery = true;
// resolve if we use filterable, dropItem not selected #6349
this.hideMenuTimer = setTimeout(()=>{
this.updateFocusIndex();
this.hideMenuTimer = null;
});
}, ANIMATION_TIMEOUT);
setTimeout(() => this.unchangedQuery = true, ANIMATION_TIMEOUT);
},
onClickOutside(event){
if (this.visible) {
@ -577,31 +602,32 @@
},
handleKeydown (e) {
const key = e.key || e.code;
if ( key === 'Backspace'){
const keyCode = e.keyCode || e.which;
if (key === 'Backspace' || keyCode===8){
return; // so we don't call preventDefault
}
if (this.visible) {
e.preventDefault();
if ( key === 'Tab'){
if (key === 'Tab'){
e.stopPropagation();
}
// Esc slide-up
if ( key === 'Escape') {
if (key === 'Escape') {
e.stopPropagation();
this.hideMenu();
}
// next
if ( key === 'ArrowUp') {
if (key === 'ArrowUp') {
this.navigateOptions(-1);
}
// prev
if ( key === 'ArrowDown') {
if (key === 'ArrowDown') {
this.navigateOptions(1);
}
// enter
if ( key === 'Enter') {
if (key === 'Enter') {
if (this.focusIndex === -1) return this.hideMenu();
const optionComponent = this.flatOptions[this.focusIndex];
@ -650,6 +676,7 @@
},
onOptionClick(option) {
if (this.multiple){
// keep the query for remote select
if (this.remote) this.lastRemoteQuery = this.lastRemoteQuery || this.query;
else this.lastRemoteQuery = '';
@ -660,6 +687,7 @@
} else {
this.values = this.values.concat(option);
}
this.isFocused = true; // so we put back focus after clicking with mouse on option elements
} else {
this.query = String(option.label).trim();
@ -702,12 +730,9 @@
this.query = query;
this.unchangedQuery = this.visible;
this.filterQueryChange = true;
if(this.filterable){
this.updateFocusIndex();
}
},
toggleHeaderFocus({type}){
if (this.disabled) {
if (this.itemDisabled) {
return;
}
this.isFocused = type === 'focus';
@ -720,15 +745,35 @@
this.hasExpectedValue = true;
}
},
// 4.0.0 create new item
handleCreateItem () {
if (this.allowCreate && this.query !== '' && this.showCreateItem) {
const query = this.query;
this.$emit('on-create', query);
this.query = '';
const option = {
value: query,
label: query,
tag: undefined
};
if (this.multiple) {
this.onOptionClick(option);
} else {
// nextTick
this.$nextTick(() => this.onOptionClick(option));
}
}
}
},
watch: {
value(value){
const {getInitialValue, getOptionData, publicValue, values} = this;
this.checkUpdateStatus();
const vModelValue = (publicValue && this.labelInValue) ?
(this.multiple ? publicValue.map(({value}) => value) : publicValue.value) : publicValue;
if (value === '') this.values = [];
else if (checkValuesNotEqual(value,vModelValue,values)) {
else if (checkValuesNotEqual(value,publicValue,values)) {
this.$nextTick(() => this.values = getInitialValue().map(getOptionData).filter(Boolean));
if (!this.multiple) this.dispatch('FormItem', 'on-form-change', this.publicValue);
}
@ -792,15 +837,14 @@
const optionInstance = findChild(this, ({$options}) => {
return $options.componentName === 'select-item' && $options.propsData.value === optionValue;
});
if(optionInstance && optionInstance.$el ){
let bottomOverflowDistance = optionInstance.$el.getBoundingClientRect().bottom - this.$refs.dropdown.$el.getBoundingClientRect().bottom;
let topOverflowDistance = optionInstance.$el.getBoundingClientRect().top - this.$refs.dropdown.$el.getBoundingClientRect().top;
if (bottomOverflowDistance > 0) {
this.$refs.dropdown.$el.scrollTop += bottomOverflowDistance;
}
if (topOverflowDistance < 0) {
this.$refs.dropdown.$el.scrollTop += topOverflowDistance;
}
let bottomOverflowDistance = optionInstance.$el.getBoundingClientRect().bottom - this.$refs.dropdown.$el.getBoundingClientRect().bottom;
let topOverflowDistance = optionInstance.$el.getBoundingClientRect().top - this.$refs.dropdown.$el.getBoundingClientRect().top;
if (bottomOverflowDistance > 0) {
this.$refs.dropdown.$el.scrollTop += bottomOverflowDistance;
}
if (topOverflowDistance < 0) {
this.$refs.dropdown.$el.scrollTop += topOverflowDistance;
}
},
dropVisible(open){

View file

@ -13,4 +13,4 @@ export default {
style: this.mark.style || {}
}, label);
}
};
};

View file

@ -22,8 +22,7 @@
<template v-if="showStops">
<div
:class="[prefixCls + '-stop']"
v-for="(item,index) in stops"
:key="index"
v-for="item in stops"
:style="{ 'left': item + '%' }"
@click.self="sliderClick"
></div>
@ -176,7 +175,7 @@
type: Boolean,
default: true
},
// 3.5.4
// 4.0.0
marks: {
type: Object
}
@ -397,10 +396,10 @@
this.currentValue = [...value];
if (!this.dragging) {
// if (this.currentValue[index] !== this.oldValue[index]) {
this.emitChange();
// this.oldValue[index] = this.currentValue[index];
// }
if (this.currentValue[index] !== this.oldValue[index]) {
this.emitChange();
this.oldValue[index] = this.currentValue[index];
}
}
},
handleDecimal(pos,step){
@ -475,4 +474,4 @@
this.observer.removeListener(this.$refs.slider, this.handleSetSliderWidth);
}
};
</script>
</script>

View file

@ -157,13 +157,9 @@
this.$nextTick(() => {
this.computedMin = this.getComputedThresholdValue('min');
this.computedMax = this.getComputedThresholdValue('max');
let value = this.valueIsPx ? this.px2percent(this.value, this.$refs.outerWrapper[this.offsetSize]) : this.value;
let anotherValue = this.getAnotherOffset(value);
if (parseFloat(value) <= parseFloat(this.computedMin)) value = this.getMax(value, this.computedMin);
if (parseFloat(anotherValue) <= parseFloat(this.computedMax)) value = this.getAnotherOffset(this.getMax(anotherValue, this.computedMax));
this.offset = value * 10000 / 100;
this.currentValue = value;
this.$emit('input', value);
// https://github.com/view-design/ViewUI/commit/d827b6405c365b9b7c130448f509724564cad8c1
// todo px
this.offset = (this.valueIsPx ? this.px2percent(this.value, this.$refs.outerWrapper[this.offsetSize]) : this.value) * 10000 / 100;
});
}
},
@ -179,6 +175,7 @@
this.$nextTick(() => {
this.computeOffset();
});
on(window, 'resize', this.computeOffset);
},
beforeDestroy () {

View file

@ -1,19 +1,18 @@
<template>
<div :class="wrapClasses" :style="styles">
<div :class="wrapClasses">
<div :class="[prefixCls + '-tail']"><i></i></div>
<div :class="[prefixCls + '-head']">
<div :class="[prefixCls + '-head-inner']">
<slot name="status">
<span v-if="!icon && currentStatus != 'finish' && currentStatus != 'error'">{{ stepNumber }}</span>
<span v-else :class="iconClasses"></span>
</slot>
<span v-if="!icon && !$slots.icon && currentStatus !== 'finish' && currentStatus !== 'error'">{{ stepNumber }}</span>
<span v-else-if="$slots.icon" class="ivu-steps-icon"><slot name="icon"></slot></span>
<span v-else :class="iconClasses"></span>
</div>
</div>
<div :class="[prefixCls + '-main']">
<div :class="[prefixCls + '-title']">{{ title }}</div>
<slot>
<div v-if="content" :class="[prefixCls + '-content']">{{ content }}</div>
</slot>
<div :class="[prefixCls + '-title']"><slot name="title">{{ title }}</slot></div>
<div :class="[prefixCls + '-content']" v-if="content || $slots.content">
<slot name="content">{{ content }}</slot>
</div>
</div>
</div>
</template>
@ -59,7 +58,7 @@
`${prefixCls}-item`,
`${prefixCls}-status-${this.currentStatus}`,
{
[`${prefixCls}-custom`]: !!this.icon,
[`${prefixCls}-custom`]: !!this.icon || !!this.$slots.icon,
[`${prefixCls}-next-error`]: this.nextError
}
];
@ -70,9 +69,9 @@
if (this.icon) {
icon = this.icon;
} else {
if (this.currentStatus == 'finish') {
if (this.currentStatus === 'finish') {
icon = 'ios-checkmark';
} else if (this.currentStatus == 'error') {
} else if (this.currentStatus === 'error') {
icon = 'ios-close';
}
}
@ -81,20 +80,15 @@
`${prefixCls}-icon`,
`${iconPrefixCls}`,
{
[`${iconPrefixCls}-${icon}`]: icon != ''
[`${iconPrefixCls}-${icon}`]: icon !== ''
}
];
},
styles () {
return {
width: `${1/this.total*100}%`
};
}
},
watch: {
status (val) {
this.currentStatus = val;
if (this.currentStatus == 'error') {
if (this.currentStatus === 'error') {
this.$parent.setNextError();
}
}

View file

@ -72,8 +72,8 @@
// status,,
// todo error,current
if (!(isInit && child.currentStatus)) {
if (index == this.current) {
if (this.status != 'error') {
if (index === this.current) {
if (this.status !== 'error') {
child.currentStatus = 'process';
}
} else if (index < this.current) {
@ -83,14 +83,14 @@
}
}
if (child.currentStatus != 'error' && index != 0) {
if (child.currentStatus !== 'error' && index !== 0) {
this.$children[index - 1].nextError = false;
}
});
},
setNextError () {
this.$children.forEach((child, index) => {
if (child.currentStatus == 'error' && index != 0) {
if (child.currentStatus === 'error' && index !== 0) {
this.$children[index - 1].nextError = true;
}
});

View file

@ -16,10 +16,13 @@
<script>
import { oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-switch';
export default {
name: 'iSwitch',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
props: {
value: {
type: [String, Number, Boolean],
@ -71,7 +74,7 @@
`${prefixCls}`,
{
[`${prefixCls}-checked`]: this.currentValue === this.trueValue,
[`${prefixCls}-disabled`]: this.disabled,
[`${prefixCls}-disabled`]: this.itemDisabled,
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-loading`]: this.loading,
}
@ -79,6 +82,7 @@
},
wrapStyles () {
let style = {};
if (this.trueColor && this.currentValue === this.trueValue) {
style['border-color'] = this.trueColor;
style['background-color'] = this.trueColor;
@ -86,6 +90,7 @@
style['border-color'] = this.falseColor;
style['background-color'] = this.falseColor;
}
return style;
},
innerClasses () {
@ -95,6 +100,7 @@
methods: {
handleToggle () {
const checked = this.currentValue === this.trueValue ? this.falseValue : this.trueValue;
this.currentValue = checked;
this.$emit('input', checked);
this.$emit('on-change', checked);
@ -102,13 +108,16 @@
},
toggle (event) {
event.preventDefault();
if (this.disabled || this.loading) {
if (this.itemDisabled || this.loading) {
return false;
}
if (!this.beforeChange) {
return this.handleToggle();
}
const before = this.beforeChange();
if (before && before.then) {
before.then(() => {
this.handleToggle();

View file

@ -1,13 +1,20 @@
<template>
<div :class="classes" ref="cell">
<div :class="classes" ref="cell" @click="handleCellClick">
<template v-if="renderType === 'index'"><span>{{ column.indexMethod ? column.indexMethod(row) : (naturalIndex + 1) }}</span></template>
<template v-if="renderType === 'selection'">
<Checkbox :value="checked" @click.native.stop="handleClick" @on-change="toggleSelect" :disabled="disabled"></Checkbox>
</template>
<div class="ivu-table-cell-tree-level" v-if="showLevel" :style="treeLevelStyle"></div>
<div class="ivu-table-cell-tree" :class="{ 'ivu-table-cell-tree-loading': childrenLoading }" v-if="showChildren" @click.prevent.stop="handleToggleTree">
<Icon type="ios-loading" v-if="childrenLoading" class="ivu-load-loop" />
<Icon type="ios-add" v-else-if="!childrenExpand" />
<Icon type="ios-remove" v-else />
</div>
<div class="ivu-table-cell-tree ivu-table-cell-tree-empty" v-else-if="showTreeNode"></div>
<template v-if="renderType === 'html'"><span v-html="row[column.key]"></span></template>
<template v-if="renderType === 'normal'">
<template v-if="column.tooltip">
<Tooltip transfer :content="row[column.key]" :theme="tableRoot.tooltipTheme" :disabled="!showTooltip" :max-width="300" class="ivu-table-cell-tooltip">
<Tooltip transfer :content="row[column.key]" :theme="tableRoot.tooltipTheme" :disabled="!showTooltip && !tooltipShow" :max-width="300" class="ivu-table-cell-tooltip" @on-popper-show="handleTooltipShow" @on-popper-hide="handleTooltipHide">
<span ref="content" @mouseenter="handleTooltipIn" @mouseleave="handleTooltipOut" class="ivu-table-cell-tooltip-content">{{ row[column.key] }}</span>
</Tooltip>
</template>
@ -28,6 +35,7 @@
v-if="renderType === 'slot'"
:row="row"
:column="column"
:display="column.display || 'block'"
:index="index"></table-slot>
</div>
</template>
@ -54,6 +62,12 @@
fixed: {
type: [Boolean, String],
default: false
},
// tree
treeNode: Boolean,
treeLevel: {
type: Number,
default: 0
}
},
data () {
@ -62,6 +76,7 @@
uid: -1,
context: this.$parent.$parent.$parent.currentContext,
showTooltip: false, // overflow
tooltipShow: false
};
},
computed: {
@ -83,11 +98,52 @@
[`${this.prefixCls}-cell-expand-expanded`]: this.expanded
}
];
},
showChildren () {
let status = false;
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
const data = this.row;
if ((data.children && data.children.length) || ('_loading' in data)) {
if (this.column.tree) status = true;
}
}
return status;
},
showTreeNode () {
let status = false;
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
if (this.column.tree && this.treeNode) status = true;
}
return status;
},
showLevel () {
let status = false;
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
if (this.column.tree && this.treeNode) status = true;
}
return status;
},
treeLevelStyle () {
return {
'padding-left': this.treeLevel * this.tableRoot.indentSize + 'px'
};
},
childrenExpand () {
const data = this.tableRoot.getDataByRowKey(this.row._rowKey);
return data._isShowChildren;
},
childrenLoading () {
const data = this.tableRoot.getDataByRowKey(this.row._rowKey);
return '_loading' in data && data._loading;
}
},
methods: {
toggleSelect () {
this.$parent.$parent.$parent.toggleSelect(this.index);
if (this.treeNode) {
this.$parent.$parent.$parent.toggleSelect(this.index, this.row._rowKey);
} else {
this.$parent.$parent.$parent.toggleSelect(this.index);
}
},
toggleExpand () {
this.$parent.$parent.$parent.toggleExpand(this.index);
@ -101,6 +157,18 @@
},
handleTooltipOut () {
this.showTooltip = false;
},
handleTooltipShow () {
this.tooltipShow = true;
},
handleTooltipHide () {
this.tooltipShow = false;
},
handleToggleTree () {
this.$parent.$parent.$parent.toggleTree(this.row._rowKey);
},
handleCellClick (event) {
this.$parent.$parent.$parent.$emit('on-cell-click', this.row, this.column, this.row[this.column.key], event);
}
},
created () {

View file

@ -6,6 +6,7 @@ export default {
cellClassName = row.cellClassName[column.key];
}
return [
`${this.prefixCls}-column-${column.__id}`,
{
[`${cellClassName}`]: cellClassName, // cell className
[`${column.className}`]: column.className, // column className

View file

@ -8,13 +8,23 @@ export default {
column: {
type: Object,
default: null
},
display: {
type: String,
default: 'block'
}
},
render: (h, ctx) => {
return h('div', ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot]({
return h('div', {
'class': {
'ivu-table-cell-slot': true,
'ivu-table-cell-slot-inline': ctx.props.display === 'inline',
'ivu-table-cell-slot-inline-block': ctx.props.display === 'inline-block'
}
}, ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot]({
row: ctx.props.row,
column: ctx.props.column,
index: ctx.props.index
}));
}
};
};

View file

@ -0,0 +1,46 @@
<template>
<div style="overflow:hidden;">
<table class="ivu-table-summary" cellspacing="0" cellpadding="0" border="0" :style="styleObject">
<colgroup>
<col v-for="(column, index) in columns" :width="setCellWidth(column)">
</colgroup>
<tbody :class="[prefixCls + '-tbody']">
<tr class="ivu-table-row">
<td v-for="(column, index) in columns" :class="alignCls(column)">
<div class="ivu-table-cell" :class="cellCls(column)">
<span>{{ data[column.key].value }}</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import Mixin from './mixin';
export default {
name: 'TableSummary',
mixins: [ Mixin ],
props: {
prefixCls: String,
styleObject: Object,
columns: Array,
data: Object, // rebuildData
columnsWidth: Object,
fixed: {
type: [Boolean, String],
default: false
},
},
methods: {
cellCls (column) {
return [
{
['ivu-table-hidden']: (this.fixed === 'left' && column.fixed !== 'left') || (this.fixed === 'right' && column.fixed !== 'right') || (!this.fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right'))
}
];
}
}
};
</script>

View file

@ -1,3 +1,4 @@
<!--
<template>
<table cellspacing="0" cellpadding="0" border="0" :style="styleObject">
<colgroup>
@ -14,7 +15,7 @@
@mouseleave.native.stop="handleMouseOut(row._index)"
@click.native="clickCurrentRow(row._index)"
@dblclick.native.stop="dblclickCurrentRow(row._index)">
<td v-for="column in columns" :class="alignCls(column, row)">
<td v-for="(column, colIndex) in columns" :class="alignCls(column, row)" v-bind="getSpan(row, column, index, colIndex)" v-if="showWithSpan(row, column, index, colIndex)">
<table-cell
:fixed="fixed"
:prefix-cls="prefixCls"
@ -38,6 +39,7 @@
</tbody>
</table>
</template>
-->
<script>
// todo :key="row"
import TableTr from './table-tr.vue';
@ -65,7 +67,7 @@
default: false
},
rowKey: {
type: Boolean,
type: [Boolean, String],
default: false
}
},
@ -87,24 +89,319 @@
rowChecked (_index) {
return this.objData[_index] && this.objData[_index]._isChecked;
},
rowDisabled(_index){
rowDisabled (_index) {
return this.objData[_index] && this.objData[_index]._isDisabled;
},
rowExpanded(_index){
rowExpanded (_index) {
return this.objData[_index] && this.objData[_index]._isExpanded;
},
handleMouseIn (_index) {
this.$parent.handleMouseIn(_index);
rowStatusByRowKey (type, rowKey) {
const data = this.$parent.getDataByRowKey(rowKey);
return data[type];
},
handleMouseOut (_index) {
this.$parent.handleMouseOut(_index);
handleMouseIn (_index, event, rowKey) {
event.stopPropagation();
this.$parent.handleMouseIn(_index, rowKey);
},
clickCurrentRow (_index) {
this.$parent.clickCurrentRow(_index);
handleMouseOut (_index, event, rowKey) {
event.stopPropagation();
this.$parent.handleMouseOut(_index, rowKey);
},
dblclickCurrentRow (_index) {
this.$parent.dblclickCurrentRow(_index);
clickCurrentRow (_index, event, rowKey) {
this.$parent.clickCurrentRow(_index, rowKey);
},
dblclickCurrentRow (_index, event, rowKey) {
event.stopPropagation();
this.$parent.dblclickCurrentRow(_index, rowKey);
},
contextmenuCurrentRow (_index, event, rowKey) {
event.stopPropagation();
if (this.$parent.contextMenu) event.preventDefault();
this.$parent.contextmenuCurrentRow(_index, rowKey, event);
},
selectStartCurrentRow (_index, event) {
if (this.$parent.contextMenu) {
// event.stopPropagation();
// event.preventDefault();
}
},
getSpan (row, column, rowIndex, columnIndex) {
const fn = this.$parent.spanMethod;
if (typeof fn === 'function') {
const result = fn({
row,
column,
rowIndex,
columnIndex
});
let rowspan = 1;
let colspan = 1;
if (Array.isArray(result)) {
rowspan = result[0];
colspan = result[1];
} else if (typeof result === 'object') {
rowspan = result.rowspan;
colspan = result.colspan;
}
return {
rowspan,
colspan
};
} else {
return {};
}
},
showWithSpan (row, column, rowIndex, columnIndex) {
const result = this.getSpan(row, column, rowIndex, columnIndex);
return !(('rowspan' in result && result.rowspan === 0) || ('colspan' in result && result.colspan === 0));
},
isTrShow (rowKey) {
let status = true;
let child;
for (let i in this.objData) {
const row = this.objData[i];
const showChildren = row._isShowChildren;
if (row._rowKey === rowKey) {
status = status && showChildren;
break;
} else if (row.children && row.children.length) {
child = this.getTrStatus(rowKey, row, status && showChildren);
if (child[0] && child[0]._rowKey === rowKey) {
return child[1];
}
}
}
return status;
},
getTrStatus (rowKey, data, parentStatus) {
let status = parentStatus;
let childData;
if (data.children && data.children.length) {
for (let i = 0; i < data.children.length; i++) {
const row = data.children[i];
const showChildren = row._isShowChildren;
if (row._rowKey === rowKey) {
childData = row;
status = status && showChildren;
break;
} else if (row.children && row.children.length) {
const child = this.getTrStatus(rowKey, row, status && showChildren);
if (child[0] && child[0]._rowKey === rowKey) {
return child;
}
}
}
}
return [childData, status];
},
getLevel (rowKey) {
let level;
let child;
for (let i = 0; i < this.data.length; i++) {
const row = this.data[i];
if (row[this.rowKey] === rowKey) {
level = 0;
break;
} else if (row.children && row.children.length) {
child = this.getChildLevel(row, rowKey, 1);
if (child[0] && child[0][this.rowKey] === rowKey) {
return child[1];
}
}
}
return level;
},
getChildLevel (data, rowKey, level) {
let newLevel;
let childData;
if (data.children && data.children.length) {
for (let i = 0; i < data.children.length; i++) {
const row = data.children[i];
if (row[this.rowKey] === rowKey) {
childData = row;
newLevel = level;
break;
} else if (row.children && row.children.length) {
const child = this.getChildLevel(row, rowKey, level + 1);
if (child[0] && child[0][this.rowKey] === rowKey) {
return child;
}
}
}
}
return [childData, newLevel];
},
getChildNode (h, data, nodes) {
if (data.children && data.children.length) {
data.children.forEach((row, index) => {
let $tds = [];
this.columns.forEach((column, colIndex) => {
if (this.showWithSpan(row, column, index, colIndex)) {
const $tableCell = h(TableCell, {
props: {
fixed: this.fixed,
'prefix-cls': this.prefixCls,
row: row,
column: column,
'natural-index': index,
index: row._index,
checked: this.rowStatusByRowKey('_isChecked', row._rowKey),
disabled: this.rowStatusByRowKey('_isDisabled', row._rowKey),
expanded: this.rowStatusByRowKey('_isExpanded', row._rowKey),
treeNode: true,
treeLevel: this.getLevel(row._rowKey)
},
key: column._columnKey,
});
const $td = h('td', {
class: this.alignCls(column, row),
attrs: this.getSpan(row, column, index, colIndex)
}, [$tableCell]);
$tds.push($td);
}
});
//
const trStyle = {};
if (!this.isTrShow(data._rowKey)) trStyle.display = 'none';
const $tableTr = h(TableTr, {
props: {
draggable: false,
row: row,
'prefix-cls': this.prefixCls,
isChildren: true
},
style: trStyle,
key: this.rowKey ? row._rowKey : index,
nativeOn: {
mouseenter: (e) => this.handleMouseIn(row._index, e, row._rowKey),
mouseleave: (e) => this.handleMouseOut(row._index, e, row._rowKey),
click: (e) => this.clickCurrentRow(row._index, e, row._rowKey),
dblclick: (e) => this.dblclickCurrentRow(row._index, e, row._rowKey),
contextmenu: (e) => this.contextmenuCurrentRow(row._index, e, row._rowKey),
selectstart: (e) => this.selectStartCurrentRow(row._index, e, row._rowKey)
}
}, $tds);
nodes.push($tableTr);
if (row.children && row.children.length) {
this.getChildNode(h, row, nodes);
}
});
return nodes;
} else {
return nodes;
}
}
},
render (h) {
let $cols = [];
this.columns.forEach(column => {
const $col = h('col', {
attrs: {
width: this.setCellWidth(column)
}
});
$cols.push($col);
});
const $colgroup = h('colgroup', {}, $cols);
let $tableTrs = [];
this.data.forEach((row, index) => {
let $tds = [];
this.columns.forEach((column, colIndex) => {
if (this.showWithSpan(row, column, index, colIndex)) {
const $tableCell = h(TableCell, {
props: {
fixed: this.fixed,
'prefix-cls': this.prefixCls,
row: row,
column: column,
'natural-index': index,
index: row._index,
checked: this.rowChecked(row._index),
disabled: this.rowDisabled(row._index),
expanded: this.rowExpanded(row._index)
},
key: column._columnKey,
});
const $td = h('td', {
class: this.alignCls(column, row),
attrs: this.getSpan(row, column, index, colIndex)
}, [$tableCell]);
$tds.push($td);
}
});
const $tableTr = h(TableTr, {
props: {
draggable: this.draggable,
row: row,
'prefix-cls': this.prefixCls
},
key: this.rowKey ? row._rowKey : index,
nativeOn: {
mouseenter: (e) => this.handleMouseIn(row._index, e),
mouseleave: (e) => this.handleMouseOut(row._index, e),
click: (e) => this.clickCurrentRow(row._index, e),
dblclick: (e) => this.dblclickCurrentRow(row._index, e),
contextmenu: (e) => this.contextmenuCurrentRow(row._index, e),
selectstart: (e) => this.selectStartCurrentRow(row._index, e)
}
}, $tds);
$tableTrs.push($tableTr);
//
if (this.rowExpanded(row._index)) {
const $Expand = h(Expand, {
props: {
row: row,
render: this.expandRender,
index: row._index
},
key: this.rowKey ? row._rowKey : index
});
const $td = h('td', {
attrs: {
colspan: this.columns.length
},
class: this.prefixCls + '-expanded-cell'
}, [$Expand]);
const $tr = h('tr', {
class: {
[this.prefixCls + '-expanded-hidden']: this.fixed
}
}, [$td]);
$tableTrs.push($tr);
}
//
if (row.children && row.children.length) {
const $childNodes = this.getChildNode(h, row, []);
$childNodes.forEach(item => {
$tableTrs.push(item);
});
}
});
const $tbody = h('tbody', {
class: this.prefixCls + '-tbody'
}, [$tableTrs]);
return h('table', {
attrs: {
cellspacing: '0',
cellpadding: '0',
border: '0'
},
style: this.styleObject
}, [$colgroup, $tbody]);
}
};
</script>

View file

@ -30,6 +30,7 @@
placement="bottom"
popper-class="ivu-table-popper"
transfer
:capture="false"
@on-popper-hide="handleFilterHide(getColumn(rowIndex, index)._index)">
<span :class="[prefixCls + '-filter']">
<i class="ivu-icon ivu-icon-ios-funnel" :class="{on: getColumn(rowIndex, index)._isFiltered}"></i>
@ -60,6 +61,13 @@
</Poptip>
</template>
</div>
<div
v-if="column.resizable"
class="ivu-table-header-resizable"
@mousedown="handleMouseDown(column, $event)"
@mousemove="handleMouseMove(column, $event)"
@mouseout="handleMouseOut"
></div>
</th>
<th v-if="$parent.showVerticalScrollBar && rowIndex===0" :class='scrollBarCellClass()' :rowspan="headRows.length"></th>
@ -94,6 +102,13 @@
columnRows: Array,
fixedColumnRows: Array
},
data () {
return {
draggingColumn: null,
dragging: false,
dragState: {}
};
},
computed: {
styles () {
const style = Object.assign({}, this.styleObject);
@ -104,13 +119,25 @@
isSelectAll () {
let isSelectAll = true;
if (!this.data.length) isSelectAll = false;
if (!this.data.find(item => !item._disabled)) isSelectAll = false; // #1751
for (let i = 0; i < this.data.length; i++) {
if (!this.objData[this.data[i]._index]._isChecked && !this.objData[this.data[i]._index]._isDisabled) {
// disabledfalse#1751
let isAllDisabledAndUnSelected = true;
for (let i in this.objData) {
const objData = this.objData[i];
if (!objData._isChecked && !objData._isDisabled) {
isSelectAll = false;
break;
} else if (objData.children && objData.children.length) {
isSelectAll = this.isChildrenSelected(objData, isSelectAll);
}
if (!(objData._isDisabled && !objData._isChecked)) {
isAllDisabledAndUnSelected = false;
} else if (objData.children && objData.children.length) {
isAllDisabledAndUnSelected = this.isChildrenAllDisabledAndUnSelected(objData, isAllDisabledAndUnSelected);
}
}
if (isAllDisabledAndUnSelected) isSelectAll = false;
return isSelectAll;
},
@ -123,9 +150,17 @@
}
},
isSelectDisabled () {
let isSelectDisabled = false;
if (!this.data.length) isSelectDisabled = true;
if (!this.data.find(item => !item._disabled)) isSelectDisabled = true;
let isSelectDisabled = true;
if (this.data.length) {
for (let i in this.objData) {
const objData = this.objData[i];
if (!objData._isDisabled) {
isSelectDisabled = false;
} else if (objData.children && objData.children.length) {
isSelectDisabled = this.isChildrenDisabled(objData, isSelectDisabled);
}
}
}
return isSelectDisabled;
}
},
@ -222,6 +257,139 @@
} else {
return this.headRows[rowIndex][index];
}
},
handleMouseDown (column, event) {
if (this.$isServer) return;
if (this.draggingColumn) {
this.dragging = true;
const table = this.$parent;
const tableEl = table.$el;
const tableLeft = tableEl.getBoundingClientRect().left;
const columnEl = this.$el.querySelector(`th.ivu-table-column-${column.__id}`);
const columnRect = columnEl.getBoundingClientRect();
const minLeft = columnRect.left - tableLeft + 30;
table.showResizeLine = true;
this.dragState = {
startMouseLeft: event.clientX,
startLeft: columnRect.right - tableLeft,
startColumnLeft: columnRect.left - tableLeft,
tableLeft
};
const resizeProxy = table.$refs.resizeLine;
resizeProxy.style.left = this.dragState.startLeft + 'px';
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
const handleMouseMove = (event) => {
const deltaLeft = event.clientX - this.dragState.startMouseLeft;
const proxyLeft = this.dragState.startLeft + deltaLeft;
resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px';
};
const handleMouseUp = () => {
if (this.dragging) {
const {
startColumnLeft,
startLeft
} = this.dragState;
const finalLeft = parseInt(resizeProxy.style.left, 10);
const columnWidth = finalLeft - startColumnLeft;
const _column = table.columns.find(item => item.__id === column.__id);
if (_column) _column.width = columnWidth;
table.$emit('on-column-width-resize', _column.width, startLeft - startColumnLeft, column, event);
document.body.style.cursor = '';
this.dragging = false;
this.draggingColumn = null;
this.dragState = {};
table.showResizeLine = false;
}
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
document.onselectstart = null;
document.ondragstart = null;
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}
},
handleMouseMove (column, event) {
let target = event.target;
while (target && target.tagName !== 'TH') {
target = target.parentNode;
}
if (!column || !column.resizable) return;
if (!this.dragging) {
let rect = target.getBoundingClientRect();
const bodyStyle = document.body.style;
if (rect.width > 12 && rect.right - event.pageX < 8) {
bodyStyle.cursor = 'col-resize';
this.draggingColumn = column;
} else if (!this.dragging) {
bodyStyle.cursor = '';
this.draggingColumn = null;
}
}
},
handleMouseOut () {
if (this.$isServer) return;
document.body.style.cursor = '';
},
isChildrenSelected (objData, isSelectAll) {
let status = isSelectAll;
if (objData.children && objData.children.length) {
objData.children.forEach(row => {
if (!row._isChecked && !row._isDisabled) {
status = false;
} else if (row.children && row.children.length) {
status = this.isChildrenSelected(row, status);
}
});
}
return status;
},
isChildrenAllDisabledAndUnSelected (objData, isAllDisabledAndUnSelected) {
let status = isAllDisabledAndUnSelected;
if (objData.children && objData.children.length) {
objData.children.forEach(row => {
if (!(row._isDisabled && !row._isChecked)) {
status = false;
} else if (row.children && row.children.length) {
status = this.isChildrenAllDisabledAndUnSelected(row, status);
}
});
}
return status;
},
isChildrenDisabled (objData, isSelectDisabled) {
let status = isSelectDisabled;
if (objData.children && objData.children.length) {
objData.children.forEach(row => {
if (!row._isDisabled) {
status = false;
} else if (row.children && row.children.length) {
status = this.isChildrenDisabled(row, status);
}
});
}
return status;
}
}
};

View file

@ -1,13 +1,14 @@
<template>
<tr :class="rowClasses(row._index)" :draggable="draggable" @dragstart="onDrag($event,row._index)" @drop="onDrop($event,row._index)" @dragover="allowDrop($event)" v-if="draggable"><slot></slot></tr>
<tr :class="rowClasses(row._index)" v-else><slot></slot></tr>
<tr :class="rowClasses(row._index)" :draggable="false" v-else><slot></slot></tr>
</template>
<script>
export default {
props: {
row: Object,
prefixCls: String,
draggable: Boolean
draggable: Boolean,
isChildren: Boolean // rowKey
},
computed: {
objData () {
@ -27,12 +28,13 @@
e.preventDefault();
},
rowClasses (_index) {
const objData = this.isChildren ? this.$parent.$parent.getDataByRowKey(this.row._rowKey) : this.objData[_index];
return [
`${this.prefixCls}-row`,
this.rowClsName(_index),
{
[`${this.prefixCls}-row-highlight`]: this.objData[_index] && this.objData[_index]._isHighlight,
[`${this.prefixCls}-row-hover`]: this.objData[_index] && this.objData[_index]._isHover
[`${this.prefixCls}-row-highlight`]: objData && objData._isHighlight,
[`${this.prefixCls}-row-hover`]: objData && objData._isHover
}
];
},

View file

@ -1,5 +1,5 @@
<template>
<div :class="wrapClasses" :style="styles">
<div :class="wrapClasses" :style="styles" ref="tableWrap">
<div :class="classes">
<div :class="[prefixCls + '-title']" v-if="showSlotHeader" ref="title"><slot name="header"></slot></div>
<div :class="[prefixCls + '-header']" v-if="showHeader" ref="header" @mousewheel="handleMouseWheel">
@ -25,6 +25,15 @@
:columns-width="columnsWidth"
:obj-data="objData"></table-body>
</div>
<table-summary
v-if="showSummary && (data && data.length)"
ref="summary"
:prefix-cls="prefixCls"
:styleObject="tableStyle"
:columns="cloneColumns"
:data="summaryData"
:columns-width="columnsWidth"
/>
<div
:class="[prefixCls + '-tip']" :style="bodyStyle" @scroll="handleBodyScroll"
v-show="((!!localeNoDataText && (!data || data.length === 0)) || (!!localeNoFilteredDataText && (!rebuildData || rebuildData.length === 0)))">
@ -64,6 +73,16 @@
:columns-width="columnsWidth"
:obj-data="objData"></table-body>
</div>
<table-summary
v-if="showSummary && (data && data.length)"
fixed="left"
:prefix-cls="prefixCls"
:styleObject="fixedTableStyle"
:columns="leftFixedColumns"
:data="summaryData"
:columns-width="columnsWidth"
:style="{ 'margin-top': showHorizontalScrollBar ? scrollBarWidth + 'px' : 0 }"
/>
</div>
<div :class="[prefixCls + '-fixed-right']" :style="fixedRightTableStyle" v-if="isRightFixed">
<div :class="fixedHeaderClasses" v-if="showHeader">
@ -90,10 +109,28 @@
:columns-width="columnsWidth"
:obj-data="objData"></table-body>
</div>
<table-summary
v-if="showSummary && (data && data.length)"
fixed="right"
:prefix-cls="prefixCls"
:styleObject="fixedRightTableStyle"
:columns="rightFixedColumns"
:data="summaryData"
:columns-width="columnsWidth"
:style="{ 'margin-top': showHorizontalScrollBar ? scrollBarWidth + 'px' : 0 }"
/>
</div>
<div :class="[prefixCls + '-fixed-right-header']" :style="fixedRightHeaderStyle" v-if="isRightFixed"></div>
<div :class="[prefixCls + '-footer']" v-if="showSlotFooter" ref="footer"><slot name="footer"></slot></div>
</div>
<div class="ivu-table-resize-line" v-show="showResizeLine" ref="resizeLine"></div>
<div class="ivu-table-context-menu" :style="contextMenuStyles" v-if="showContextMenu">
<Dropdown trigger="custom" :visible="contextMenuVisible" transfer @on-clickoutside="handleClickContextMenuOutside">
<DropdownMenu slot="list">
<slot name="contextMenu"></slot>
</DropdownMenu>
</Dropdown>
</div>
<Spin fix size="large" v-if="loading">
<slot name="loading"></slot>
</Spin>
@ -102,6 +139,7 @@
<script>
import tableHead from './table-head.vue';
import tableBody from './table-body.vue';
import tableSummary from './summary.vue';
import Spin from '../spin/spin.vue';
import { oneOf, getStyle, deepCopy, getScrollBarSize } from '../../utils/assist';
import { on, off } from '../../utils/dom';
@ -119,7 +157,7 @@
export default {
name: 'Table',
mixins: [ Locale ],
components: { tableHead, tableBody, Spin },
components: { tableHead, tableBody, tableSummary, Spin },
provide () {
return {
tableRoot: this
@ -205,7 +243,44 @@
default: 'dark'
},
// #5380 :key 使 index
// 4.1 String
rowKey: {
type: [Boolean, String],
default: false
},
// 4.0.0
spanMethod: {
type: Function
},
// 4.0.0
showSummary: {
type: Boolean,
default: false
},
// 4.0.0
summaryMethod: {
type: Function
},
// 4.0.0
sumText: {
type: String
},
// 4.1.0
indentSize: {
type: Number,
default: 16
},
// 4.1.0
loadData: {
type: Function
},
// 4.1.0
contextMenu: {
type: Boolean,
default: false
},
// 4.2.0
showContextMenu: {
type: Boolean,
default: false
}
@ -235,6 +310,12 @@
showHorizontalScrollBar:false,
headerWidth:0,
headerHeight:0,
showResizeLine: false,
contextMenuVisible: false,
contextMenuStyles: {
top: 0,
left: 0
}
};
},
computed: {
@ -252,13 +333,22 @@
return this.noFilteredDataText;
}
},
localeSumText () {
if (this.sumText === undefined) {
return this.t('i.table.sumText');
} else {
return this.sumText;
}
},
wrapClasses () {
return [
`${prefixCls}-wrapper`,
{
[`${prefixCls}-hide`]: !this.ready,
[`${prefixCls}-with-header`]: this.showSlotHeader,
[`${prefixCls}-with-footer`]: this.showSlotFooter
[`${prefixCls}-with-footer`]: this.showSlotFooter,
[`${prefixCls}-with-summary`]: this.showSummary,
[`${prefixCls}-wrapper-with-border`]: this.border
}
];
},
@ -283,12 +373,18 @@
},
styles () {
let style = {};
let summaryHeight = 0;
if (this.showSummary) {
if (this.size === 'small') summaryHeight = 40;
else if (this.size === 'large') summaryHeight = 60;
else summaryHeight = 48;
}
if (this.height) {
const height = parseInt(this.height);
let height = parseInt(this.height) + summaryHeight;
style.height = `${height}px`;
}
if (this.maxHeight) {
const maxHeight = parseInt(this.maxHeight);
const maxHeight = parseInt(this.maxHeight) + summaryHeight;
style.maxHeight = `${maxHeight}px`;
}
if (this.width) style.width = `${this.width}px`;
@ -379,6 +475,58 @@
},
isRightFixed () {
return this.columns.some(col => col.fixed && col.fixed === 'right');
},
// for summary data
summaryData () {
if (!this.showSummary) return {};
let sums = {};
if (this.summaryMethod) {
sums = this.summaryMethod({ columns: this.cloneColumns, data: this.rebuildData });
} else {
this.cloneColumns.forEach((column, index) => {
const key = column.key;
if (index === 0) {
sums[key] = {
key: column.key,
value: this.localeSumText
};
return;
}
const values = this.rebuildData.map(item => Number(item[column.key]));
const precisions = [];
let notNumber = true;
values.forEach(value => {
if (!isNaN(value)) {
notNumber = false;
let decimal = ('' + value).split('.')[1];
precisions.push(decimal ? decimal.length : 0);
}
});
const precision = Math.max.apply(null, precisions);
if (!notNumber) {
const currentValue = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return parseFloat((prev + curr).toFixed(Math.min(precision, 20)));
} else {
return prev;
}
}, 0);
sums[key] = {
key: column.key,
value: currentValue
};
} else {
sums[key] = {
key: column.key,
value: ''
};
}
});
}
return sums;
}
},
methods: {
@ -422,7 +570,7 @@
columnWidth = parseInt(usableWidth / usableLength);
}
for (let i = 0; i < this.cloneColumns.length; i++) {
const column = this.cloneColumns[i];
let width = columnWidth + (column.minWidth?column.minWidth:0);
@ -440,7 +588,7 @@
else if (column.maxWidth < width){
width = column.maxWidth;
}
if (usableWidth>0) {
usableWidth -= width - (column.minWidth?column.minWidth:0);
usableLength--;
@ -487,72 +635,178 @@
}
}
this.tableWidth = this.cloneColumns.map(cell => cell._width).reduce((a, b) => a + b, 0) + (this.showVerticalScrollBar?this.scrollBarWidth:0) + 1;
this.columnsWidth = columnsWidth;
this.fixedHeader();
},
handleMouseIn (_index) {
handleMouseIn (_index, rowKey) {
if (this.disabledHover) return;
if (this.objData[_index]._isHover) return;
this.objData[_index]._isHover = true;
const objData = rowKey ? this.getDataByRowKey(rowKey) : this.objData[_index];
if (objData._isHover) return;
objData._isHover = true;
},
handleMouseOut (_index) {
handleMouseOut (_index, rowKey) {
if (this.disabledHover) return;
this.objData[_index]._isHover = false;
const objData = rowKey ? this.getDataByRowKey(rowKey) : this.objData[_index];
objData._isHover = false;
},
// highlightCurrentRow clearCurrentRow
handleCurrentRow (type, _index) {
handleCurrentRow (type, _index, rowKey) {
const objData = rowKey ? this.getDataByRowKey(rowKey) : this.objData[_index];
let oldData = null;
let oldIndex = -1;
for (let i in this.objData) {
if (this.objData[i]._isHighlight) {
oldIndex = parseInt(i);
this.objData[i]._isHighlight = false;
break;
} else if (this.objData[i].children && this.objData[i].children.length) {
const resetData = this.handleResetChildrenRow(this.objData[i]);
if (resetData) oldData = JSON.parse(JSON.stringify(resetData));
}
}
if (type === 'highlight') this.objData[_index]._isHighlight = true;
const oldData = oldIndex < 0 ? null : JSON.parse(JSON.stringify(this.cloneData[oldIndex]));
const newData = type === 'highlight' ? JSON.parse(JSON.stringify(this.cloneData[_index])) : null;
if (type === 'highlight') objData._isHighlight = true;
if (oldIndex >= 0) {
oldData = JSON.parse(JSON.stringify(this.cloneData[oldIndex]));
}
const newData = type === 'highlight' ? rowKey ? JSON.parse(JSON.stringify(this.getBaseDataByRowKey(rowKey))) : JSON.parse(JSON.stringify(this.cloneData[_index])) : null;
this.$emit('on-current-change', newData, oldData);
},
highlightCurrentRow (_index) {
if (!this.highlightRow || this.objData[_index]._isHighlight) return;
this.handleCurrentRow('highlight', _index);
handleResetChildrenRow (objData) {
let data = null;
if (objData.children && objData.children.length) {
for (let i = 0; i < objData.children.length; i++) {
const item = objData.children[i];
if (item._isHighlight) {
item._isHighlight = false;
data = item;
break;
} else if (item.children && item.children.length) {
data = this.handleResetChildrenRow(item);
}
}
}
return data;
},
highlightCurrentRow (_index, rowKey) {
const objData = rowKey ? this.getDataByRowKey(rowKey) : this.objData[_index];
if (!this.highlightRow || objData._isHighlight) return;
this.handleCurrentRow('highlight', _index, rowKey);
},
clearCurrentRow () {
if (!this.highlightRow) return;
this.handleCurrentRow('clear');
},
clickCurrentRow (_index) {
this.highlightCurrentRow (_index);
this.$emit('on-row-click', JSON.parse(JSON.stringify(this.cloneData[_index])), _index);
clickCurrentRow (_index, rowKey) {
this.highlightCurrentRow (_index, rowKey);
if (rowKey) {
this.$emit('on-row-click', JSON.parse(JSON.stringify(this.getBaseDataByRowKey(rowKey))));
} else {
this.$emit('on-row-click', JSON.parse(JSON.stringify(this.cloneData[_index])), _index);
}
},
dblclickCurrentRow (_index) {
this.highlightCurrentRow (_index);
this.$emit('on-row-dblclick', JSON.parse(JSON.stringify(this.cloneData[_index])), _index);
dblclickCurrentRow (_index, rowKey) {
this.highlightCurrentRow (_index, rowKey);
if (rowKey) {
this.$emit('on-row-dblclick', JSON.parse(JSON.stringify(this.getBaseDataByRowKey(rowKey))));
} else {
this.$emit('on-row-dblclick', JSON.parse(JSON.stringify(this.cloneData[_index])), _index);
}
},
contextmenuCurrentRow (_index, rowKey, event) {
if (this.contextMenuVisible) this.handleClickContextMenuOutside();
this.$nextTick(() => {
const $TableWrap = this.$refs.tableWrap;
const TableBounding = $TableWrap.getBoundingClientRect();
const position = {
left: `${event.clientX - TableBounding.left}px`,
top: `${event.clientY - TableBounding.top}px`
};
this.contextMenuStyles = position;
this.contextMenuVisible = true;
if (rowKey) {
this.$emit('on-contextmenu', JSON.parse(JSON.stringify(this.getBaseDataByRowKey(rowKey))), event, position);
} else {
this.$emit('on-contextmenu', JSON.parse(JSON.stringify(this.cloneData[_index])), event, position);
}
});
},
getSelection () {
//
let selectionIndexes = [];
let selectionRowKeys = [];
for (let i in this.objData) {
if (this.objData[i]._isChecked) selectionIndexes.push(parseInt(i));
const objData = this.objData[i];
if (objData._isChecked) selectionIndexes.push(parseInt(i));
if (objData.children && objData.children.length) {
selectionRowKeys = selectionRowKeys.concat(this.getSelectionChildrenRowKeys(objData, selectionRowKeys));
}
}
return JSON.parse(JSON.stringify(this.data.filter((data, index) => selectionIndexes.indexOf(index) > -1)));
// RowKeys
selectionRowKeys = [...new Set(selectionRowKeys)];
let selection = [];
this.data.forEach((item, index) => {
if (selectionIndexes.indexOf(index) > -1) {
selection = selection.concat(item);
}
if (item.children && item.children.length && selectionRowKeys.length) {
selection = selection.concat(this.getSelectionChildren(item, selection, selectionRowKeys));
}
});
selection = [...new Set(selection)];
return JSON.parse(JSON.stringify(selection));
},
toggleSelect (_index) {
getSelectionChildrenRowKeys (objData, selectionRowKeys) {
if (objData.children && objData.children.length) {
objData.children.forEach(item => {
if (item._isChecked) selectionRowKeys.push(item._rowKey);
if (item.children && item.children.length) {
selectionRowKeys = selectionRowKeys.concat(this.getSelectionChildrenRowKeys(item, selectionRowKeys));
}
});
}
return selectionRowKeys;
},
getSelectionChildren (data, selection, selectionRowKeys) {
if (data.children && data.children.length) {
data.children.forEach(item => {
if (selectionRowKeys.indexOf(item[this.rowKey]) > -1) {
selection = selection.concat(item);
}
if (item.children && item.children.length) {
selection = selection.concat(this.getSelectionChildren(item, selection, selectionRowKeys));
}
});
}
return selection;
},
toggleSelect (_index, rowKey) {
let data = {};
for (let i in this.objData) {
if (parseInt(i) === _index) {
data = this.objData[i];
break;
if (rowKey) {
data = this.getDataByRowKey(rowKey);
} else {
for (let i in this.objData) {
if (parseInt(i) === _index) {
data = this.objData[i];
break;
}
}
}
const status = !data._isChecked;
this.objData[_index]._isChecked = status;
data._isChecked = status;
const selection = this.getSelection();
this.$emit(status ? 'on-select' : 'on-select-cancel', selection, JSON.parse(JSON.stringify(this.data[_index])));
const selectedData = rowKey ? this.getBaseDataByRowKey(rowKey, this.data) : this.data[_index];
this.$emit(status ? 'on-select' : 'on-select-cancel', selection, JSON.parse(JSON.stringify(selectedData)));
this.$emit('on-selection-change', selection);
},
toggleExpand (_index) {
@ -567,11 +821,116 @@
const status = !data._isExpanded;
this.objData[_index]._isExpanded = status;
this.$emit('on-expand', JSON.parse(JSON.stringify(this.cloneData[_index])), status);
if(this.height || this.maxHeight){
this.$nextTick(()=>this.fixedBody());
}
},
toggleTree (rowKey) {
const data = this.getDataByRowKey(rowKey);
// async loading
if ('_loading' in data && data._loading) return;
if ('_loading' in data && !data._loading && data.children.length === 0) {
const sourceData = this.getBaseDataByRowKey(rowKey, this.data);
this.$set(sourceData, '_loading', true);
this.loadData(sourceData, children => {
this.$set(sourceData, '_loading', false);
if (children.length) {
this.$set(sourceData, 'children', children);
this.$nextTick(() => {
const newData = this.getDataByRowKey(rowKey);
newData._isShowChildren = !newData._isShowChildren;
// updateDataStatus _showChildren @on-expand-tree
// _showChildren
this.updateDataStatus(rowKey, '_showChildren', newData._isShowChildren);
});
}
});
return;
}
data._isShowChildren = !data._isShowChildren;
// updateDataStatus _showChildren @on-expand-tree
// this.updateDataStatus(rowKey, '_showChildren', data._isShowChildren);
this.$emit('on-expand-tree', rowKey, data._isShowChildren);
},
/**
* @description 当修改某内置属性 _isShowChildren 因当将原 data 对应 _showChildren 也修改否则修改 data 状态会重置
* @param rowKey rowKey
* @param key 原数据对应的字段
* @param value 修改的值
* */
// todo
updateDataStatus (rowKey, key, value) {
const data = this.getBaseDataByRowKey(rowKey, this.data);
this.$set(data, key, value);
},
getDataByRowKey (rowKey, objData = this.objData) {
let data = null;
for (let i in objData) {
const thisData = objData[i];
if (thisData._rowKey === rowKey) {
data = thisData;
break;
} else if (thisData.children && thisData.children.length) {
data = this.getChildrenByRowKey(rowKey, thisData);
if (data) {
break;
}
}
}
return data;
},
getChildrenByRowKey (rowKey, objData) {
let data = null;
if (objData.children && objData.children.length) {
for (let i = 0; i < objData.children.length; i++) {
const item = objData.children[i];
if (item._rowKey === rowKey) {
data = item;
break;
} else if (item.children && item.children.length) {
data = this.getChildrenByRowKey(rowKey, item);
if (data) {
break;
}
}
}
}
return data;
},
getBaseDataByRowKey (rowKey, sourceData = this.cloneData) {
let data = null;
for (let i = 0; i < sourceData.length; i++) {
const thisData = sourceData[i];
if (thisData[this.rowKey] === rowKey) {
data = thisData;
break;
} else if (thisData.children && thisData.children.length) {
data = this.getChildrenDataByRowKey(rowKey, thisData);
if (data && data[this.rowKey] === rowKey) return data;
}
}
return data;
},
getChildrenDataByRowKey (rowKey, cloneData) {
let data = null;
if (cloneData.children && cloneData.children.length) {
for (let i = 0; i < cloneData.children.length; i++) {
const item = cloneData.children[i];
if (item[this.rowKey] === rowKey) {
data = item;
break;
} else if (item.children && item.children.length) {
data = this.getChildrenDataByRowKey(rowKey, item);
if (data) {
break;
}
}
}
}
return data;
},
selectAll (status) {
// this.rebuildData.forEach((data) => {
// if(this.objData[data._index]._isDisabled){
@ -581,11 +940,13 @@
// }
// });
for(const data of this.rebuildData){
if(this.objData[data._index]._isDisabled){
continue;
}else{
this.objData[data._index]._isChecked = status;
for (const data of this.rebuildData) {
const objData = this.objData[data._index];
if (!objData._isDisabled) {
objData._isChecked = status;
}
if (data.children && data.children.length) {
this.selectAllChildren(objData, status);
}
}
const selection = this.getSelection();
@ -596,7 +957,18 @@
}
this.$emit('on-selection-change', selection);
},
selectAllChildren (data, status) {
if (data.children && data.children.length) {
data.children.map(item => {
if (!item._isDisabled) {
item._isChecked = status;
}
if (item.children && item.children.length) {
this.selectAllChildren(item, status);
}
});
}
},
fixedHeader () {
if (this.height || this.maxHeight) {
this.$nextTick(() => {
@ -633,7 +1005,7 @@
this.showHorizontalScrollBar = bodyEl.offsetWidth < bodyContentEl.offsetWidth + (this.showVerticalScrollBar?this.scrollBarWidth:0);
this.showVerticalScrollBar = this.bodyHeight? bodyHeight - (this.showHorizontalScrollBar?this.scrollBarWidth:0) < bodyContentHeight : false;
if(this.showVerticalScrollBar){
bodyEl.classList.add(this.prefixCls +'-overflowY');
}else{
@ -644,7 +1016,7 @@
}else{
bodyEl.classList.remove(this.prefixCls +'-overflowX');
}
}
}
},
hideColumnFilter () {
@ -654,6 +1026,7 @@
if (this.showHeader) this.$refs.header.scrollLeft = event.target.scrollLeft;
if (this.isLeftFixed) this.$refs.fixedBody.scrollTop = event.target.scrollTop;
if (this.isRightFixed) this.$refs.fixedRightBody.scrollTop = event.target.scrollTop;
if (this.showSummary && this.$refs.summary) this.$refs.summary.$el.scrollLeft = event.target.scrollLeft;
this.hideColumnFilter();
},
handleFixedMousewheel(event) {
@ -714,6 +1087,11 @@
}
}
});
for (let i = 0; i < data.length; i++) {
if (data[i].children && data[i].children.length) {
data[i].children = this.sortData(data[i].children, type, index);
}
}
return data;
},
handleSort (_index, type) {
@ -807,10 +1185,28 @@
let data = deepCopy(this.data);
data.forEach((row, index) => {
row._index = index;
row._rowKey = rowKey++;
row._rowKey = (typeof this.rowKey) === 'string' ? row[this.rowKey] : rowKey++;
if (row.children && row.children.length) {
row.children = this.makeChildrenData(row);
}
});
return data;
},
makeChildrenData (data) {
if (data.children && data.children.length) {
return data.children.map((row, index) => {
const newRow = deepCopy(row);
newRow._index = index;
newRow._rowKey = (typeof this.rowKey) === 'string' ? newRow[this.rowKey] : rowKey++;
if (newRow.children && newRow.children.length) {
newRow.children = this.makeChildrenData(newRow);
}
return newRow;
});
} else {
return data;
}
},
makeDataWithSort () {
let data = this.makeData();
let sortType = 'normal';
@ -838,35 +1234,71 @@
this.cloneColumns.forEach(col => data = this.filterData(data, col));
return data;
},
makeObjBaseData (row) {
const newRow = deepCopy(row);
if ((typeof this.rowKey) === 'string') {
newRow._rowKey = newRow[this.rowKey];
}
newRow._isHover = false;
if (newRow._disabled) {
newRow._isDisabled = newRow._disabled;
} else {
newRow._isDisabled = false;
}
if (newRow._checked) {
newRow._isChecked = newRow._checked;
} else {
newRow._isChecked = false;
}
if (newRow._expanded) {
newRow._isExpanded = newRow._expanded;
} else {
newRow._isExpanded = false;
}
if (newRow._highlight) {
newRow._isHighlight = newRow._highlight;
} else {
newRow._isHighlight = false;
}
return newRow;
},
makeObjData () {
let data = {};
this.data.forEach((row, index) => {
const newRow = deepCopy(row);// todo
newRow._isHover = false;
if (newRow._disabled) {
newRow._isDisabled = newRow._disabled;
} else {
newRow._isDisabled = false;
}
if (newRow._checked) {
newRow._isChecked = newRow._checked;
} else {
newRow._isChecked = false;
}
if (newRow._expanded) {
newRow._isExpanded = newRow._expanded;
} else {
newRow._isExpanded = false;
}
if (newRow._highlight) {
newRow._isHighlight = newRow._highlight;
} else {
newRow._isHighlight = false;
const newRow = this.makeObjBaseData(row);
if (newRow.children && newRow.children.length) {
if (newRow._showChildren) {
newRow._isShowChildren = newRow._showChildren;
} else {
newRow._isShowChildren = false;
}
newRow.children = this.makeChildrenObjData(newRow);
}
// else if ('_loading' in newRow && newRow.children && newRow.children.length === 0) {
// newRow._isShowChildren = false;
// }
data[index] = newRow;
});
return data;
},
makeChildrenObjData (data) {
if (data.children && data.children.length) {
return data.children.map(row => {
const newRow = this.makeObjBaseData(row);
if (newRow._showChildren) {
newRow._isShowChildren = newRow._showChildren;
} else {
newRow._isShowChildren = false;
}
if (newRow.children && newRow.children.length) {
newRow.children = this.makeChildrenObjData(newRow);
}
return newRow;
});
} else {
return data;
}
},
// id便
makeColumnsId (columns) {
return columns.map(item => {
@ -949,6 +1381,9 @@
},
dragAndDrop(a,b) {
this.$emit('on-drag-drop', a,b);
},
handleClickContextMenuOutside () {
this.contextMenuVisible = false;
}
},
created () {
@ -967,15 +1402,18 @@
this.$on('on-visible-change', (val) => {
if (val) {
this.$nextTick(()=>{
this.$nextTick(() => {
this.handleResize();
});
}
});
},
beforeDestroy () {
this.$off('on-visible-change');
off(window, 'resize', this.handleResize);
this.observer.removeListener(this.$el, this.handleResize);
this.observer.removeAllListeners(this.$el);
this.observer.uninstall(this.$el);
this.observer = null;
},
watch: {
data: {

View file

@ -34,6 +34,11 @@
// 0
index: {
type: Number
},
// 4.3.0
contextMenu: {
type: Boolean,
default: false
}
},
data () {

View file

@ -1,5 +1,5 @@
<template>
<div :class="classes">
<div :class="classes" ref="tabsWrap">
<div :class="[prefixCls + '-bar']">
<div :class="[prefixCls + '-nav-right']" v-if="showSlot"><slot name="extra"></slot></div>
<div
@ -12,10 +12,21 @@
<div ref="navWrap" :class="[prefixCls + '-nav-wrap', scrollable ? prefixCls + '-nav-scrollable' : '']">
<span :class="[prefixCls + '-nav-prev', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollPrev"><Icon type="ios-arrow-back"></Icon></span>
<span :class="[prefixCls + '-nav-next', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollNext"><Icon type="ios-arrow-forward"></Icon></span>
<div ref="navScroll" :class="[prefixCls + '-nav-scroll']">
<div ref="navScroll" :class="[prefixCls + '-nav-scroll']" @DOMMouseScroll="handleScroll" @mousewheel="handleScroll">
<div ref="nav" :class="[prefixCls + '-nav']" :style="navStyle">
<div :class="barClasses" :style="barStyle"></div>
<div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
<div
:class="tabCls(item)"
v-for="(item, index) in navList"
@click="handleChange(index)"
@dblclick="handleDblclick(index)"
@contextmenu.stop="handleContextmenu(index, $event)"
@selectstart.stop="handlePreventSelect(index, $event)"
:draggable="draggable"
@dragstart="handleDrag(index, $event)"
@drop="handleDrop(index, $event)"
@dragover.prevent
>
<Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
<Render v-if="item.labelType === 'function'" :render="item.label"></Render>
<template v-else>{{ item.label }}</template>
@ -27,6 +38,13 @@
</div>
</div>
<div :class="contentClasses" :style="contentStyle" ref="panes"><slot></slot></div>
<div class="ivu-tabs-context-menu" :style="contextMenuStyles">
<Dropdown trigger="custom" :visible="contextMenuVisible" transfer @on-clickoutside="handleClickContextMenuOutside">
<DropdownMenu slot="list">
<slot name="contextMenu"></slot>
</DropdownMenu>
</Dropdown>
</div>
</div>
</template>
<script>
@ -100,12 +118,10 @@
name: {
type: String
},
custContentClass: {
type: String,
default: ''
},
custContentStyle: {
type: Object,
// 4.3.0
draggable: {
type: Boolean,
default: false
}
},
data () {
@ -122,6 +138,11 @@
},
scrollable: false,
transitioning: false,
contextMenuVisible: false,
contextMenuStyles: {
top: 0,
left: 0
}
};
},
computed: {
@ -140,8 +161,7 @@
`${prefixCls}-content`,
{
[`${prefixCls}-content-animated`]: this.animated
},
this.custContentClass
}
];
},
barClasses () {
@ -162,12 +182,6 @@
transform: `translateX(${p}) translateZ(0px)`
};
}
const { custContentStyle } = this;
if (custContentStyle) {
for (const key in custContentStyle){
style[key] = custContentStyle[key];
}
}
return style;
},
barStyle () {
@ -231,7 +245,7 @@
if (item.tab === this.name) {
TabPanes.push(item);
}
}else if (this.$children.includes(item)) { // #6279 #6299
} else {
TabPanes.push(item);
}
});
@ -253,7 +267,8 @@
icon: pane.icon || '',
name: pane.currentName || index,
disabled: pane.disabled,
closable: pane.closable
closable: pane.closable,
contextMenu: pane.contextMenu
});
if (!pane.currentName) pane.currentName = index;
if (index === 0) {
@ -306,11 +321,44 @@
setTimeout(() => this.transitioning = false, transitionTime);
const nav = this.navList[index];
if (nav.disabled) return;
if (!nav || nav.disabled) return;
this.activeKey = nav.name;
this.$emit('input', nav.name);
this.$emit('on-click', nav.name);
},
handleDblclick (index) {
const nav = this.navList[index];
if (!nav || nav.disabled) return;
this.$emit('on-dblclick', nav.name);
},
handleContextmenu (index, event) {
if (this.contextMenuVisible) this.handleClickContextMenuOutside();
this.$nextTick(() => {
const nav = this.navList[index];
if (!nav || nav.disabled || !nav.contextMenu) return;
event.preventDefault();
const $TabsWrap = this.$refs.tabsWrap;
const TabsBounding = $TabsWrap.getBoundingClientRect();
const position = {
left: `${event.clientX - TabsBounding.left}px`,
top: `${event.clientY - TabsBounding.top}px`
};
this.contextMenuStyles = position;
this.contextMenuVisible = true;
this.$emit('on-contextmenu', nav, event, position);
});
},
handleClickContextMenuOutside () {
this.contextMenuVisible = false;
},
//
handlePreventSelect (index, event) {
const nav = this.navList[index];
if (!nav || nav.disabled || !nav.contextMenu) return;
event.preventDefault();
},
handleTabKeyNavigation(e){
if (e.keyCode !== 37 && e.keyCode !== 39) return;
const direction = e.keyCode === 39 ? 1 : -1;
@ -455,6 +503,20 @@
}
}
},
handleScroll (e) {
e.preventDefault();
e.stopPropagation();
const type = e.type;
let delta = 0;
if (type === 'DOMMouseScroll' || type === 'mousewheel') {
delta = (e.wheelDelta) ? e.wheelDelta : -(e.detail || 0) * 40;
}
if (delta > 0) {
this.scrollPrev();
} else {
this.scrollNext();
}
},
handleResize(){
this.updateNavScroll();
},
@ -479,6 +541,26 @@
}, transitionTime);
}
});
},
//
handleDrag (index, event) {
const nav = this.navList[index];
if (nav) {
event.dataTransfer.setData('tab-name', nav.name);
}
},
handleDrop (index, event) {
const nav = this.navList[index];
if (nav) {
const dragName = event.dataTransfer.getData('tab-name');
event.preventDefault();
let navNames = this.navList.map(item => item.name);
const a = parseInt(navNames.findIndex(item => item === dragName));
const b = parseInt(navNames.findIndex(item => item === nav.name));
navNames.splice(b, 1, ...navNames.splice(a, 1 , navNames[b]));
this.$emit('on-drag-drop', dragName, nav.name, a, b, navNames);
}
}
},
watch: {

View file

@ -50,6 +50,13 @@
fade: {
type: Boolean,
default: true
},
// 4.0.0
size: {
validator (value) {
return oneOf(value, ['default', 'medium', 'large']);
},
default: 'default'
}
},
data () {
@ -61,6 +68,7 @@
classes () {
return [
`${prefixCls}`,
`${prefixCls}-size-${this.size}`,
{
[`${prefixCls}-${this.color}`]: !!this.color && oneOf(this.color, initColorList),
[`${prefixCls}-${this.type}`]: !!this.type,
@ -144,4 +152,4 @@
}
}
};
</script>
</script>

View file

@ -49,6 +49,12 @@
];
}
},
watch: {
time () {
// https://segmentfault.com/q/1010000021110866
if (!isServer) this.setTime();
}
},
methods: {
handleClick () {
if (this.hash !== '') window.location.hash = this.hash;
@ -96,4 +102,4 @@
if (this.timer) clearInterval(this.timer);
}
};
</script>
</script>

View file

@ -5,7 +5,7 @@
</div>
<transition name="fade">
<div
:class="[prefixCls + '-popper', prefixCls + '-' + theme]"
:class="dropdownCls"
:style="dropStyles"
ref="popper"
v-show="!disabled && (visible || always)"
@ -74,6 +74,9 @@
},
maxWidth: {
type: [String, Number]
},
transferClassName: {
type: String
}
},
data () {
@ -101,6 +104,16 @@
if (this.transfer) styles['z-index'] = 1060 + this.tIndex;
return styles;
},
dropdownCls () {
return [
`${prefixCls}-popper`,
`${prefixCls}-${this.theme}`,
{
[prefixCls + '-transfer']: this.transfer,
[this.transferClassName]: this.transferClassName
}
];
}
},
watch: {

View file

@ -1,11 +1,21 @@
<template>
<div :class="prefixCls + '-operation'">
<i-button type="primary" size="small" :disabled="!rightActive" @click.native="moveToLeft">
<Icon type="ios-arrow-back"></Icon> <span>{{ operations[0] }}</span>
</i-button>
<i-button type="primary" size="small" :disabled="!leftActive" @click.native="moveToRight">
<span>{{ operations[1] }}</span> <Icon type="ios-arrow-forward"></Icon>
</i-button>
<template v-if="reverseOperation">
<i-button type="primary" size="small" :disabled="!leftActive" @click.native="moveToRight">
<span>{{ operations[1] }}</span> <Icon type="ios-arrow-forward"></Icon>
</i-button>
<i-button type="primary" size="small" :disabled="!rightActive" @click.native="moveToLeft">
<Icon type="ios-arrow-back"></Icon> <span>{{ operations[0] }}</span>
</i-button>
</template>
<template v-else>
<i-button type="primary" size="small" :disabled="!rightActive" @click.native="moveToLeft">
<Icon type="ios-arrow-back"></Icon> <span>{{ operations[0] }}</span>
</i-button>
<i-button type="primary" size="small" :disabled="!leftActive" @click.native="moveToRight">
<span>{{ operations[1] }}</span> <Icon type="ios-arrow-forward"></Icon>
</i-button>
</template>
</div>
</template>
<script>
@ -19,7 +29,8 @@
prefixCls: String,
operations: Array,
leftActive: Boolean,
rightActive: Boolean
rightActive: Boolean,
reverseOperation: Boolean
},
methods: {
moveToLeft () {

View file

@ -57,7 +57,8 @@
prefixCls: this.prefixCls,
operations: this.operations,
leftActive: this.leftValidKeysCount > 0,
rightActive: this.rightValidKeysCount > 0
rightActive: this.rightValidKeysCount > 0,
reverseOperation: this.reverseOperation
}
}),
@ -138,6 +139,12 @@
},
notFoundText: {
type: String
},
// 4.2.0
//
reverseOperation: {
type: Boolean,
default: false
}
},
data () {
@ -235,11 +242,9 @@
},
handleLeftCheckedKeysChange (keys) {
this.leftCheckedKeys = keys;
this.handleCheckedKeys();
},
handleRightCheckedKeysChange (keys) {
this.rightCheckedKeys = keys;
this.handleCheckedKeys();
},
handleCheckedKeys () {
const sourceSelectedKeys = this.getValidKeys('left');

View file

@ -1,7 +1,7 @@
<template>
<collapse-transition :appear="appear">
<ul :class="classes">
<li>
<li @contextmenu.stop="handleContextmenu(data, $event)" @selectstart.stop="handlePreventSelect(data, $event)">
<span :class="arrowClasses" @click="handleExpand">
<Icon v-if="showArrow" :type="arrowType" :custom="customArrowType" :size="arrowSize" />
<Icon v-if="showLoading" type="ios-loading" class="ivu-load-loop" />
@ -12,9 +12,11 @@
:indeterminate="data.indeterminate"
:disabled="data.disabled || data.disableCheckbox"
@click.native.prevent="handleCheck"></Checkbox>
<Render v-if="data.render" :render="data.render" :data="data" :node="node"></Render>
<Render v-else-if="isParentRender" :render="parentRender" :data="data" :node="node"></Render>
<span v-else :class="titleClasses" @click="handleSelect">{{ data.title }}</span>
<span :class="titleClasses" @click="handleSelect">
<Render v-if="data.render" :render="data.render" :data="data" :node="node"></Render>
<Render v-else-if="isParentRender" :render="parentRender" :data="data" :node="node"></Render>
<template v-else>{{ data.title }}</template>
</span>
<Tree-node
v-if="data.expand"
:appear="appearByClickArrow"
@ -71,9 +73,7 @@
data () {
return {
prefixCls: prefixCls,
appearByClickArrow: false,
// #6139
loadingChildrenState : true
appearByClickArrow: false
};
},
computed: {
@ -107,7 +107,7 @@
];
},
showArrow () {
return (this.data[this.childrenKey] && this.data[this.childrenKey].length) || ('loading' in this.data && !this.data.loading && this.loadingChildrenState);
return (this.data[this.childrenKey] && this.data[this.childrenKey].length) || ('loading' in this.data && !this.data.loading);
},
showLoading () {
return 'loading' in this.data && this.data.loading;
@ -175,7 +175,7 @@
methods: {
handleExpand () {
const item = this.data;
if (item.disabled) return;
// if (item.disabled) return;
// Vue.js 2.6.9 transition appear iView appear appear false
this.appearByClickArrow = true;
@ -190,8 +190,6 @@
if (children.length) {
this.$set(this.data, this.childrenKey, children);
this.$nextTick(() => this.handleExpand());
}else{
this.loadingChildrenState = false;
}
});
return;
@ -218,6 +216,17 @@
nodeKey: this.data.nodeKey
};
this.dispatch('Tree', 'on-check', changes);
},
handleContextmenu (data, event) {
if (data.contextmenu) {
event.preventDefault();
this.dispatch('Tree', 'contextmenu', { data, event });
}
},
handlePreventSelect (data, event) {
if (data.contextmenu) {
event.preventDefault();
}
}
}
};

View file

@ -1,5 +1,5 @@
<template>
<div :class="prefixCls">
<div :class="prefixCls" ref="treeWrap">
<Tree-node
v-for="(item, i) in stateTree"
:key="i"
@ -10,6 +10,13 @@
:children-key="childrenKey">
</Tree-node>
<div :class="[prefixCls + '-empty']" v-if="!stateTree.length">{{ localeEmptyText }}</div>
<div class="ivu-tree-context-menu" :style="contextMenuStyles">
<Dropdown trigger="custom" :visible="contextMenuVisible" transfer @on-clickoutside="handleClickContextMenuOutside">
<DropdownMenu slot="list">
<slot name="contextMenu"></slot>
</DropdownMenu>
</Dropdown>
</div>
</div>
</template>
<script>
@ -70,6 +77,11 @@
prefixCls: prefixCls,
stateTree: this.data,
flatState: [],
contextMenuVisible: false,
contextMenuStyles: {
top: 0,
left: 0
}
};
},
watch: {
@ -121,9 +133,9 @@
const node = this.flatState[nodeKey].node;
const parent = this.flatState[parentKey].node;
if (node.checked == parent.checked && node.indeterminate == parent.indeterminate) return; // no need to update upwards
if (node.checked == true) {
// #6121
this.$set(parent, 'checked', parent[this.childrenKey].every(node => node.checked || node.disabled !== undefined ));
this.$set(parent, 'checked', parent[this.childrenKey].every(node => node.checked));
this.$set(parent, 'indeterminate', !parent.checked);
} else {
this.$set(parent, 'checked', false);
@ -160,16 +172,10 @@
},
updateTreeDown(node, changes = {}) {
if (this.checkStrictly) return;
for (let key in changes) {
// after #6121
if( key === 'checked' && node.disabled ){
this.$set(node, key, node.checked);
}else{
this.$set(node, key, changes[key]);
}
// before -- this.$set(node, key, changes[key]);
}
for (let key in changes) {
this.$set(node, key, changes[key]);
}
if (node[this.childrenKey]) {
node[this.childrenKey].forEach(child => {
this.updateTreeDown(child, changes);
@ -177,6 +183,7 @@
}
},
handleSelect (nodeKey) {
if (!this.flatState[nodeKey]) return;
const node = this.flatState[nodeKey].node;
if (!this.multiple){ // reset previously selected node
const currentSelectedKey = this.flatState.findIndex(obj => obj.node.selected);
@ -187,6 +194,7 @@
this.$emit('on-select-change', this.getSelectedNodes(), node);
},
handleCheck({ checked, nodeKey }) {
if (!this.flatState[nodeKey]) return;
const node = this.flatState[nodeKey].node;
this.$set(node, 'checked', checked);
this.$set(node, 'indeterminate', false);
@ -195,6 +203,23 @@
this.updateTreeDown(node, {checked, indeterminate: false}); // reset `indeterminate` when going down
this.$emit('on-check-change', this.getCheckedNodes(), node);
},
handleContextmenu ({ data, event }) {
if (this.contextMenuVisible) this.handleClickContextMenuOutside();
this.$nextTick(() => {
const $TreeWrap = this.$refs.treeWrap;
const TreeBounding = $TreeWrap.getBoundingClientRect();
const position = {
left: `${event.clientX - TreeBounding.left}px`,
top: `${event.clientY - TreeBounding.top}px`
};
this.contextMenuStyles = position;
this.contextMenuVisible = true;
this.$emit('on-contextmenu', data, event, position);
});
},
handleClickContextMenuOutside () {
this.contextMenuVisible = false;
}
},
created(){
@ -205,6 +230,7 @@
this.$on('on-check', this.handleCheck);
this.$on('on-selected', this.handleSelect);
this.$on('toggle-expand', node => this.$emit('on-toggle-expand', node));
this.$on('contextmenu', this.handleContextmenu);
}
};
</script>

View file

@ -13,6 +13,7 @@
:class="[prefixCls + '-input']"
@change="handleChange"
:multiple="multiple"
:webkitdirectory="webkitdirectory"
:accept="accept">
<slot></slot>
</div>
@ -29,12 +30,13 @@
import ajax from './ajax';
import { oneOf } from '../../utils/assist';
import Emitter from '../../mixins/emitter';
import mixinsForm from '../../mixins/form';
const prefixCls = 'ivu-upload';
export default {
name: 'Upload',
mixins: [ Emitter ],
mixins: [ Emitter, mixinsForm ],
components: { UploadList },
props: {
action: {
@ -141,6 +143,10 @@
disabled: {
type: Boolean,
default: false
},
webkitdirectory: {
type: Boolean,
default: false
}
},
data () {
@ -166,7 +172,7 @@
},
methods: {
handleClick () {
if (this.disabled) return;
if (this.itemDisabled) return;
this.$refs.input.click();
},
handleChange (e) {
@ -180,11 +186,11 @@
},
onDrop (e) {
this.dragOver = false;
if (this.disabled) return;
if (this.itemDisabled) return;
this.uploadFiles(e.dataTransfer.files);
},
handlePaste (e) {
if (this.disabled) return;
if (this.itemDisabled) return;
if (this.paste) {
this.uploadFiles(e.clipboardData.files);
}

View file

@ -0,0 +1,219 @@
const CLICK = 'click';
const captureInstances = Object.create(null);
const nonCaptureInstances = Object.create(null);
const instancesList = [captureInstances, nonCaptureInstances];
/**
* The common event handler for bot capture and non-capture events.
*
* @param {!Object} context - The event context.
* @param {!Object} instances - The capture or non-capture registered instances.
* @param {Event} event - The event object.
* @returns {undefined} Default.
*/
const commonHandler = function _onCommonEvent(context, instances, event) {
const {target} = event;
const itemIteratee = function _itemIteratee(item) {
const {el} = item;
if (el !== target && !el.contains(target)) {
const {binding} = item;
if (binding.modifiers.stop) {
event.stopPropagation();
}
if (binding.modifiers.prevent) {
event.preventDefault();
}
binding.value.call(context, event);
}
};
const keysIteratee = function _keysIteratee(eventName) {
return instances[eventName].forEach(itemIteratee);
};
Object.keys(instances).forEach(keysIteratee);
};
/**
* Event handler for capture events.
*
* @param {Event} event - The event object.
*/
const captureEventHandler = function onCaptureEvent(event) {
/* eslint-disable-next-line babel/no-invalid-this */
commonHandler(this, captureInstances, event);
};
/**
* Event handler for non-capture events.
*
* @param {Event} event - The event object.
*/
const nonCaptureEventHandler = function onNonCaptureEvent(event) {
/* eslint-disable-next-line babel/no-invalid-this */
commonHandler(this, nonCaptureInstances, event);
};
/**
* Get the correct event handler: Capture or non-capture.
*
* @param {boolean} useCapture - Indicate which handler to use; 'true' to use
* capture handler or 'false' for non-capture.
* @returns {Function} - The event handler.
*/
const getEventHandler = function _getEventHandler(useCapture) {
return useCapture ? captureEventHandler : nonCaptureEventHandler;
};
/**
* The directive definition.
* {@link https://vuejs.org/v2/guide/custom-directive.html|Custom directive}
*
* @namespace
* @property {!Object} $_captureInstances - Registered capture instances.
* @property {!Object} $_nonCaptureInstances - Registered non-capture instances.
* @property {Function} $_onCaptureEvent - Event handler for capture events.
* @property {Function} $_onNonCaptureEvent - Event handler for non-capture events.
* @property {Function} bind - Called only once, when the directive is first
* bound to the element.
* @property {Function} unbind - Called only once, when the directive is unbound
* from the element.
* @property {string} version - The version number of this release.
*/
export const directive = Object.defineProperties(
{},
{
$_captureInstances: {
value: captureInstances,
},
$_nonCaptureInstances: {
value: nonCaptureInstances,
},
$_onCaptureEvent: {
value: captureEventHandler,
},
$_onNonCaptureEvent: {
value: nonCaptureEventHandler,
},
/**
* 注意这里的 arg 修改为 capture这样可以动态设置原先的事件作为 modifiers
* */
bind: {
value: function bind(el, binding) {
if (typeof binding.value !== 'function') {
throw new TypeError('Binding value must be a function.');
}
let eventType;
const modifiers = binding.modifiers;
if (modifiers.click) eventType = 'click';
else if (modifiers.mousedown) eventType = 'mousedown';
else if (modifiers.touchstart) eventType = 'touchstart';
else eventType = CLICK;
const useCapture = binding.arg;
const normalisedBinding = {
...binding,
...{
modifiers: {
...{
capture: false,
prevent: false,
stop: false,
},
...binding.modifiers,
},
},
};
const instances = useCapture ? captureInstances : nonCaptureInstances;
if (!Array.isArray(instances[eventType])) {
instances[eventType] = [];
}
if (instances[eventType].push({el, binding: normalisedBinding}) === 1) {
if (typeof document === 'object' && document) {
document.addEventListener(
eventType,
getEventHandler(useCapture),
useCapture,
);
}
}
},
},
unbind: {
value: function unbind(el) {
const compareElements = function _compareElements(item) {
return item.el !== el;
};
const instancesIteratee = function _instancesIteratee(instances) {
const instanceKeys = Object.keys(instances);
if (instanceKeys.length) {
const useCapture = instances === captureInstances;
const keysIteratee = function _keysIteratee(eventName) {
const newInstance = instances[eventName].filter(compareElements);
if (newInstance.length) {
instances[eventName] = newInstance;
} else {
if (typeof document === 'object' && document) {
document.removeEventListener(
eventName,
getEventHandler(useCapture),
useCapture,
);
}
delete instances[eventName];
}
};
instanceKeys.forEach(keysIteratee);
}
};
instancesList.forEach(instancesIteratee);
},
},
/* Note: This needs to be manually updated to match package.json. */
version: {
enumerable: true,
value: '3.7.1',
},
},
);
/**
* @typedef {Function} Vue - The constructor.
* @property {Function} directive - You can register a global custom directive
* with the Vue.directive() method, passing in a directiveID followed by a
* definition object.
*/
/**
* A Vue.js plugin should expose an install method. The method will be called
* with the Vue constructor as the first argument, along with possible options.
* {@link https://vuejs.org/v2/guide/plugins.html#Writing-a-Plugin|Writing a plugin}.
*
* @param {Vue} Vue - The Vue function.
*/
export function install(Vue) {
Vue.directive('click-outside', directive);
}

View file

@ -173,6 +173,7 @@ const install = function(Vue, opts = {}) {
Vue.prototype.$IVIEW = {
size: opts.size || '',
transfer: 'transfer' in opts ? opts.transfer : '',
capture: 'capture' in opts ? opts.capture : true,
select: {
arrow: opts.select ? opts.select.arrow ? opts.select.arrow : '' : '',
customArrow: opts.select ? opts.select.customArrow ? opts.select.customArrow : '' : '',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'لا توجد بيانات',
confirmFilter: 'تأكيد',
resetFilter: 'إعادة تعيين',
clearFilter: 'الكل'
clearFilter: 'الكل',
sumText: 'المجموع'
},
datepicker: {
selectDate: 'إختر التاريخ',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'لا توجد بيانات',
confirmFilter: 'تأكيد',
resetFilter: 'إعادة تعيين',
clearFilter: 'الكل'
clearFilter: 'الكل',
sumText: 'المجموع'
},
datepicker: {
selectDate: 'إختر التاريخ',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Nenalezeny žádné položky',
confirmFilter: 'Potvrdit',
resetFilter: 'Reset',
clearFilter: 'Vše'
clearFilter: 'Vše',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Vybrat datum',
@ -108,4 +109,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'No filter data',
confirmFilter: 'Bekræft',
resetFilter: 'Nulstil',
clearFilter: 'Alle'
clearFilter: 'Alle',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Vælg dato',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Keine gefilterten Daten',
confirmFilter: 'Bestätigen',
resetFilter: 'Zurücksetzen',
clearFilter: 'Alle'
clearFilter: 'Alle',
sumText: 'Summe'
},
datepicker: {
selectDate: 'Datum auswählen',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Χωρίς φίλτρο',
confirmFilter: 'Επιβεβαίωση',
resetFilter: 'Επαναφορά',
clearFilter: 'Όλα'
clearFilter: 'Όλα',
sumText: 'Σύνολο'
},
datepicker: {
selectDate: 'Επιλέξτε ημέρα',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'No filter data',
confirmFilter: 'Confirm',
resetFilter: 'Reset',
clearFilter: 'All'
clearFilter: 'All',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Select date',
@ -111,4 +112,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Sin Datos para el filtro',
confirmFilter: 'Aceptar',
resetFilter: 'Quitar filtro',
clearFilter: 'Todos'
clearFilter: 'Todos',
sumText: 'Suma'
},
datepicker: {
selectDate: 'Seleccionar fecha',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'بدون اطلاعات فیلترشده',
confirmFilter: 'تایید',
resetFilter: 'بازنشانی',
clearFilter: 'همه'
clearFilter: 'همه',
sumText: 'جمع'
},
datepicker: {
selectDate: 'انتخاب تاریخ',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Ei suodatettua dataa',
confirmFilter: 'Hyväksy',
resetFilter: 'Nollaa',
clearFilter: 'Kaikki'
clearFilter: 'Kaikki',
sumText: 'Summa'
},
datepicker: {
selectDate: 'Valitse päivämäärä',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'No filter data',
confirmFilter: 'Confirmez',
resetFilter: 'Reset',
clearFilter: 'Tout'
clearFilter: 'Tout',
sumText: 'Somme'
},
datepicker: {
selectDate: 'Sélectionnez une date',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'कोई आकड़ा उपलब्ध नहीं है',
confirmFilter: 'पुष्टि करें',
resetFilter: 'पुनः तैयार करना',
clearFilter: 'सब कुछ'
clearFilter: 'सब कुछ',
sumText: 'Sum'
},
datepicker: {
selectDate: 'दिनांक चुनें',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Tidak ada data filter',
confirmFilter: 'Konfirmasi',
resetFilter: 'Tata ulang',
clearFilter: 'Semua'
clearFilter: 'Semua',
sumText: 'Jml'
},
datepicker: {
selectDate: 'Pilih tanggal',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Filtro senza risultati',
confirmFilter: 'Conferma',
resetFilter: 'Reset',
clearFilter: 'Tutto'
clearFilter: 'Tutto',
sumText: 'Somma'
},
datepicker: {
selectDate: 'Seleziona data',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'スクリーニングしたデータなし',
confirmFilter: 'スクリーニング',
resetFilter: 'リセット',
clearFilter: '全部'
clearFilter: '全部',
sumText: '合計'
},
datepicker: {
selectDate: '日時を選んでください',
@ -111,4 +112,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: '필터된 데이터 없음',
confirmFilter: '확인',
resetFilter: '초기화',
clearFilter: '전부'
clearFilter: '전부',
sumText: '합'
},
datepicker: {
selectDate: '날짜 선택',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'No filter data',
confirmFilter: 'Батлах',
resetFilter: 'Шинээр тохируулах',
clearFilter: 'Бүгд'
clearFilter: 'Бүгд',
sumText: 'Нийт'
},
datepicker: {
selectDate: 'Огноо сонгох',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'ᠨᠦᠬᠦᠴᠡᠯ ᠳᠦ ᠨᠡᠶᠢᠴᠡᠭᠰᠡᠨ ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ ᠣᠯᠳᠠᠭᠰᠠᠨ ᠦᠭᠡᠢ',
confirmFilter: 'ᠰᠢᠯᠢᠬᠦ',
resetFilter: 'ᠪᠣᠴᠠᠭᠠᠬᠤ',
clearFilter: 'ᠪᠦᠬᠦ'
clearFilter: 'ᠪᠦᠬᠦ',
sumText: 'Sum'
},
datepicker: {
selectDate: 'ᠡᠳᠦᠷ ᠰᠠᠷ᠎ᠠ ᠰᠣᠩᠭᠣᠬᠤ',

115
src/locale/lang/nb-NO.js Normal file
View file

@ -0,0 +1,115 @@
import setLang from '../lang';
const lang = {
i: {
locale: 'nb-NO',
select: {
placeholder: 'Velg',
noMatch: 'Ingen treff',
loading: 'Laster'
},
table: {
noDataText: 'Ingen data',
noFilteredDataText: 'Filtreringen gir ingen treff',
confirmFilter: 'Bekreft',
resetFilter: 'Nullstill',
clearFilter: 'Alle',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Velg dato',
selectTime: 'Velg klokkeslett',
startTime: 'Start klokken',
endTime: 'Slutt klokken',
clear: 'Nullstill',
ok: 'OK',
datePanelLabel: '[mmmm] [yyyy]',
month: 'Måned',
month1: 'Januar',
month2: 'Februar',
month3: 'Mars',
month4: 'April',
month5: 'Mai',
month6: 'Juni',
month7: 'Juli',
month8: 'August',
month9: 'September',
month10: 'Oktober',
month11: 'November',
month12: 'Desember',
year: 'År',
weekStartDay: '1',
weeks: {
sun: 'Søn',
mon: 'Man',
tue: 'Tir',
wed: 'Ons',
thu: 'Tor',
fri: 'Fre',
sat: 'Lør'
},
months: {
m1: 'Jan',
m2: 'Feb',
m3: 'Mar',
m4: 'Apr',
m5: 'Mai',
m6: 'Jun',
m7: 'Jul',
m8: 'Aug',
m9: 'Sep',
m10: 'Okt',
m11: 'Nov',
m12: 'Des'
}
},
transfer: {
titles: {
source: 'Kilde',
target: 'Mål'
},
filterPlaceholder: 'Søkeord her',
notFoundText: 'Ikke funnet'
},
modal: {
okText: 'OK',
cancelText: 'Avbryt'
},
poptip: {
okText: 'OK',
cancelText: 'Avbryt'
},
page: {
prev: 'Forrige side',
next: 'Neste side',
total: 'Total',
item: 'element',
items: 'elementer',
prev5: 'Forrige 5 sider',
next5: 'Neste 5 sider',
page: '/side',
goto: 'Gå til',
p: ''
},
rate: {
star: 'Stjerne',
stars: 'Stjerner'
},
time: {
before: ' siden',
after: ' etter',
just: 'akkurat nå',
seconds: ' sekunder',
minutes: ' minutter',
hours: ' timer',
days: ' dager'
},
tree: {
emptyText: 'Ingen data'
}
}
};
setLang(lang);
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Geen gefilterde data',
confirmFilter: 'Bevestig',
resetFilter: 'Herstel',
clearFilter: 'Alles'
clearFilter: 'Alles',
sumText: 'Som'
},
datepicker: {
selectDate: 'Selecteer datum',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Brak danych',
confirmFilter: 'Potwierdź',
resetFilter: 'Resetuj',
clearFilter: 'Wszystkie'
clearFilter: 'Wszystkie',
sumText: 'Razem'
},
datepicker: {
selectDate: 'Wybierz datę',
@ -111,4 +112,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Sem dados filtrados',
confirmFilter: 'Confirmar',
resetFilter: 'Limpar',
clearFilter: 'Todos'
clearFilter: 'Todos',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Selecione a data',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Sem dados filtrados',
confirmFilter: 'Confirmar',
resetFilter: 'Limpar',
clearFilter: 'Todos'
clearFilter: 'Todos',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Selecione a data',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Filtru fără rezultate',
confirmFilter: 'Confirmă',
resetFilter: 'Resetează',
clearFilter: 'Tot'
clearFilter: 'Tot',
sumText: 'Suma'
},
datepicker: {
selectDate: 'Selectează data',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Нет данных по фильтру',
confirmFilter: 'Подтвердить',
resetFilter: 'Сброс',
clearFilter: 'Все'
clearFilter: 'Все',
sumText: 'Сумма'
},
datepicker: {
selectDate: 'Выбрать дату',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Ingen filter data',
confirmFilter: 'Bekräfta',
resetFilter: 'Återställ filter',
clearFilter: 'Rensa filter'
clearFilter: 'Rensa filter',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Välj datum',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'ไม่พบตัวกรองข้อมูล',
confirmFilter: 'ยืนยัน',
resetFilter: 'รีเซ็ต',
clearFilter: 'ทั้งหมด'
clearFilter: 'ทั้งหมด',
sumText: 'Sum'
},
datepicker: {
selectDate: 'เลือกวัน',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Süzülen veri yok',
confirmFilter: 'Onayla',
resetFilter: 'Sıfırla',
clearFilter: 'Hepsi'
clearFilter: 'Hepsi',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Tarih seç',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Немає даних по фільтру',
confirmFilter: 'Підтвердити',
resetFilter: 'Скинути',
clearFilter: 'Усе'
clearFilter: 'Усе',
sumText: 'Sum'
},
datepicker: {
selectDate: 'Обрати дату',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: 'Không có dữ liệu lọc',
confirmFilter: 'Xác nhận',
resetFilter: 'Làm lại',
clearFilter: 'Xóa hết'
clearFilter: 'Xóa hết',
sumText: 'Tổng'
},
datepicker: {
selectDate: 'Chọn ngày',
@ -102,4 +103,4 @@ const lang = {
setLang(lang);
export default lang;
export default lang;

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: '暂无筛选结果',
confirmFilter: '筛选',
resetFilter: '重置',
clearFilter: '全部'
clearFilter: '全部',
sumText: '合计'
},
datepicker: {
selectDate: '选择日期',

View file

@ -13,7 +13,8 @@ const lang = {
noFilteredDataText: '暫無篩選結果',
confirmFilter: '篩選',
resetFilter: '重置',
clearFilter: '全部'
clearFilter: '全部',
sumText: '合計'
},
datepicker: {
selectDate: '選擇日期',

115
src/locale/lang/zh-UG.js Normal file
View file

@ -0,0 +1,115 @@
import setLang from '../lang';
const lang = {
i: {
locale: 'zh-UG',
select: {
placeholder: 'تاللاش',
noMatch: 'ئۇچۇر يوق',
loading: 'سەل ساقلاش'
},
table: {
noDataText: 'ئۇچۇر يوق',
noFilteredDataText: 'بۇنداق نەتىجە يوق',
confirmFilter: 'تاسقاش',
resetFilter: 'تازلاش',
clearFilter: 'بارلىق',
sumText: 'جەمئىي'
},
datepicker: {
selectDate: 'چىسلا تاللاش',
selectTime: 'ۋاقىت تاللاش',
startTime: 'باشلىنىش',
endTime: 'ئاخىرلىشىش',
clear: 'بىكارلاش',
ok: 'جەزىملەش',
datePanelLabel: '[yyyyيىل] [mئاي]',
month: 'ئاي',
month1: '1-ئاي',
month2: '2-ئاي',
month3: '3-ئاي',
month4: '4-ئاي',
month5: '5-ئاي',
month6: '6-ئاي',
month7: '7-ئاي',
month8: '8-ئاي',
month9: '9-ئاي',
month10: '10-ئاي',
month11: '11-ئاي',
month12: '12-ئاي',
year: 'يىل',
weekStartDay: '0',
weeks: {
sun: 'يەك',
mon: 'دۈ',
tue: 'سەي',
wed: 'چار',
thu: 'پەي',
fri: 'جۈ',
sat: 'شەن'
},
months: {
m1: '1-ئاي',
m2: '2-ئاي',
m3: '3-ئاي',
m4: '4-ئاي',
m5: '5-ئاي',
m6: '6-ئاي',
m7: '7-ئاي',
m8: '8-ئاي',
m9: '9-ئاي',
m10: '10-ئاي',
m11: '11-ئاي',
m12: '12-ئاي'
}
},
transfer: {
titles: {
source: 'ئەسلى تىزىملىك',
target: 'نىشان تىزىملىك'
},
filterPlaceholder: 'ئىزدەيدىغان مەزمۇننى كىرگۈزۈڭ',
notFoundText: 'ئۇچۇر يوق'
},
modal: {
okText: 'جەزىملەش',
cancelText: 'بىكار قىلىش'
},
poptip: {
okText: 'جەزىملەش',
cancelText: 'بىكار قىلىش'
},
page: {
prev: 'ئالدىنقى بەت',
next: 'كىيىنكى بەت',
total: 'جەمئىي',
item: 'تال',
items: 'تال',
prev5: 'ئالدىغا 5 بەت',
next5: 'ئارقىغا 5 بەت',
page: 'تال/ھەر بىر بەت',
goto: 'ئاتلاش',
p: 'بەت'
},
rate: {
star: 'يۇلتۇز',
stars: 'يۇلتۇز'
},
time: {
before: ' بۇرۇن',
after: ' كىيىن',
just: 'بايىلا',
seconds: ' سىكونت',
minutes: ' مىنۇت',
hours: ' سائەت',
days: ' كۈن'
},
tree: {
emptyText: 'ئۇچۇر يوق'
}
}
};
setLang(lang);
export default lang;

View file

@ -11,4 +11,4 @@ export default {
return state;
}
}
};
};

Some files were not shown because too many files have changed in this diff Show more