Commit af4387600728996f0d7d8f89a563e08295f8d271

Authored by Lawrence Lee
Committed by GitHub
2 parents 1c82a9ab 9c83f0e5

Merge pull request #2 from iview/2.0

Merge
README.md
... ... @@ -4,7 +4,14 @@
4 4 </a>
5 5 </p>
6 6  
7   -# iView [![](https://img.shields.io/travis/iview/iview.svg?style=flat-square)](https://travis-ci.org/iview/iview) [![iView](https://img.shields.io/npm/v/iview.svg?style=flat-square)](https://www.npmjs.org/package/iview) [![NPM downloads](http://img.shields.io/npm/dm/iview.svg?style=flat-square)](https://npmjs.org/package/iview) [![Join the chat at https://gitter.im/iview/iview](https://img.shields.io/badge/chat-on_gitter-30b392.svg?style=flat-square)](https://gitter.im/iview/iview?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
  7 +# iView
  8 +[![](https://img.shields.io/travis/iview/iview.svg?style=flat-square)](https://travis-ci.org/iview/iview)
  9 +[![iView](https://img.shields.io/npm/v/iview.svg?style=flat-square)](https://www.npmjs.org/package/iview)
  10 +[![NPM downloads](http://img.shields.io/npm/dm/iview.svg?style=flat-square)](https://npmjs.org/package/iview)
  11 +[![NPM downloads](https://img.shields.io/npm/dt/iview.svg?style=flat-square)](https://npmjs.org/package/iview)
  12 +![JS gzip size](http://img.badgesize.io/https://unpkg.com/iview/dist/iview.min.js?compression=gzip&label=gzip%20size:%20JS&style=flat-square)
  13 +![CSS gzip size](http://img.badgesize.io/https://unpkg.com/iview/dist/styles/iview.css?compression=gzip&label=gzip%20size:%20CSS&style=flat-square)
  14 +[![Join the chat at https://gitter.im/iview/iview](https://img.shields.io/badge/chat-on_gitter-30b392.svg?style=flat-square)](https://gitter.im/iview/iview?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8 15  
9 16 ### A high quality UI Toolkit built on Vue.js.
10 17  
... ... @@ -82,6 +89,7 @@ Normal browsers and Internet Explorer 9+.
82 89 | [Aresn](https://github.com/icarusion) | ![](https://avatars3.githubusercontent.com/u/5370542?v=3&s=60) |
83 90 | [jingsam](https://github.com/jingsam) | ![](https://avatars3.githubusercontent.com/u/1522494?v=3&s=60) |
84 91 | [rijn](https://github.com/rijn) | ![](https://avatars2.githubusercontent.com/u/6976367?v=3&s=60) |
  92 +| [lcx960324](https://github.com/lcx960324) | ![](https://avatars3.githubusercontent.com/u/9768245?v=3&s=60) |
85 93 | [GITleonine1989](https://github.com/GITleonine1989) | ![](https://avatars1.githubusercontent.com/u/7582490?v=3&s=60) |
86 94 | [huixisheng](https://github.com/huixisheng) | ![](https://avatars1.githubusercontent.com/u/1518967?v=3&s=60) |
87 95  
... ...
examples/routers/badge.vue
... ... @@ -14,37 +14,24 @@
14 14 </style>
15 15 <template>
16 16 <div>
17   - <Badge count="3">
  17 + <Badge dot :count="count">
18 18 <a href="#" class="demo-badge"></a>
19 19 </Badge>
20   - <Badge dot>
21   - <a href="#" class="demo-badge"></a>
22   - </Badge>
23   - <Badge dot>
24   - <Icon type="ios-bell-outline" size="26"></Icon>
25   - </Badge>
26   - <Badge dot>
27   - <a href="#">可以是一个链接</a>
28   - </Badge>
29   - <Badge count="100">
30   - <a href="#" class="demo-badge"></a>
31   - </Badge>
32   - <Badge count="1000" overflow-count="999">
33   - <a href="#" class="demo-badge"></a>
34   - </Badge>
35   - <br>
36   - <Badge count="10"></Badge>
37   - <br><br>
38   - <Badge count="20" class-name="demo-badge-alone"></Badge>
  20 + <Button @click="setCount">set count</Button>
39 21 </div>
40 22 </template>
41 23 <script>
42 24 export default {
43 25 props: {},
44 26 data () {
45   - return {};
  27 + return {
  28 + count: 50
  29 + };
46 30 },
47   - computed: {},
48   - methods: {}
  31 + methods: {
  32 + setCount () {
  33 + this.count = 10;
  34 + }
  35 + }
49 36 };
50 37 </script>
51 38 \ No newline at end of file
... ...
examples/routers/form.vue
... ... @@ -2,12 +2,7 @@
2 2 <div style="width: 300px;">
3 3 <i-form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80">
4 4 <Form-item label="爱好" prop="interest">
5   - <Checkbox-group v-model="formValidate.interest">
6   - <Checkbox label="吃饭"></Checkbox>
7   - <Checkbox label="睡觉"></Checkbox>
8   - <Checkbox label="跑步"></Checkbox>
9   - <Checkbox label="看电影"></Checkbox>
10   - </Checkbox-group>
  5 + <Input v-model="formValidate.interest" number></Input>
11 6 </Form-item>
12 7 <Form-item>
13 8 <i-button type="primary" @click="handleSubmit('formValidate')">提交</i-button>
... ... @@ -21,12 +16,15 @@
21 16 data () {
22 17 return {
23 18 formValidate: {
24   - interest: ['吃饭', '跑步']
  19 + interest: ''
25 20 },
26 21 ruleValidate: {
27 22 interest: [
28   - { required: true, type: 'array', min: 1, message: '至少选择一个爱好', trigger: 'change' },
29   - { type: 'array', max: 2, message: '最多选择两个爱好', trigger: 'change' }
  23 + {
  24 + required: true,
  25 + type: 'number',
  26 + trigger: 'change'
  27 + }
30 28 ]
31 29 }
32 30 }
... ...
examples/routers/menu.vue
1 1 <template>
2 2 <div>
3   - <Menu mode="horizontal" :theme="theme1" @on-select="s">
4   - <Row type="flex" justify="center" align="middle">
5   - <i-col span="12">
6   - <Menu-item name="1">
  3 + <Row>
  4 + <i-col span="8">
  5 + <Menu :theme="theme2">
  6 + <Submenu name="1">
  7 + <template slot="title">
7 8 <Icon type="ios-paper"></Icon>
8 9 内容管理
9   - </Menu-item>
10   - <Menu-item name="2">
  10 + </template>
  11 + <Menu-item name="1-1">文章管理</Menu-item>
  12 + <Menu-item name="1-2">评论管理</Menu-item>
  13 + <Menu-item name="1-3">举报管理</Menu-item>
  14 + </Submenu>
  15 + <Submenu name="2">
  16 + <template slot="title">
11 17 <Icon type="ios-people"></Icon>
12 18 用户管理
13   - </Menu-item>
14   - <Submenu name="3">
15   - <template slot="title">
16   - <Icon type="stats-bars"></Icon>
17   - 统计分析
18   - </template>
19   - <Menu-group title="使用">
20   - <Menu-item name="3-1">新增和启动</Menu-item>
21   - <Menu-item name="3-2">活跃分析</Menu-item>
22   - <Menu-item name="3-3">时段分析</Menu-item>
23   - </Menu-group>
24   - <Menu-group title="留存">
25   - <Menu-item name="3-4">用户留存</Menu-item>
26   - <Menu-item name="3-5">流失用户</Menu-item>
27   - </Menu-group>
28   - </Submenu>
29   - <Menu-item name="4">
30   - <Icon type="settings"></Icon>
31   - 综合设置
32   - </Menu-item>
33   - </i-col>
34   - </Row>
35   - </Menu>
  19 + </template>
  20 + <Menu-item name="2-1">新增用户</Menu-item>
  21 + <Menu-item name="2-2">活跃用户</Menu-item>
  22 + </Submenu>
  23 + <Submenu name="3">
  24 + <template slot="title">
  25 + <Icon type="stats-bars"></Icon>
  26 + 统计分析
  27 + </template>
  28 + <Menu-group title="使用">
  29 + <Menu-item name="3-1">新增和启动</Menu-item>
  30 + <Menu-item name="3-2">活跃分析</Menu-item>
  31 + <Menu-item name="3-3">时段分析</Menu-item>
  32 + </Menu-group>
  33 + <Menu-group title="留存">
  34 + <Menu-item name="3-4">用户留存</Menu-item>
  35 + <Menu-item name="3-5">流失用户</Menu-item>
  36 + </Menu-group>
  37 + </Submenu>
  38 + </Menu>
  39 + </i-col>
  40 + </Row>
36 41 <br>
37 42 <p>切换主题</p>
38   - <Radio-group v-model="theme1">
  43 + <Radio-group v-model="theme2">
39 44 <Radio label="light"></Radio>
40 45 <Radio label="dark"></Radio>
41   - <Radio label="primary"></Radio>
42 46 </Radio-group>
43 47 </div>
44 48 </template>
... ... @@ -46,149 +50,8 @@
46 50 export default {
47 51 data () {
48 52 return {
49   - theme1: 'light'
50   - }
51   - },
52   - methods: {
53   - s (s) {
54   - console.log(s)
  53 + theme2: 'light'
55 54 }
56 55 }
57 56 }
58 57 </script>
59   -
60   -
61   -<!--<template>-->
62   - <!--<div>-->
63   - <!--<Row>-->
64   - <!--<i-col span="8">-->
65   - <!--<Menu :theme="theme2" @on-select="s">-->
66   - <!--<Submenu name="1">-->
67   - <!--<template slot="title">-->
68   - <!--<Icon type="ios-paper"></Icon>-->
69   - <!--内容管理-->
70   - <!--</template>-->
71   - <!--<Menu-item name="1-1">文章管理</Menu-item>-->
72   - <!--<Menu-item name="1-2">评论管理</Menu-item>-->
73   - <!--<Menu-item name="1-3">举报管理</Menu-item>-->
74   - <!--</Submenu>-->
75   - <!--<Submenu name="2">-->
76   - <!--<template slot="title">-->
77   - <!--<Icon type="ios-people"></Icon>-->
78   - <!--用户管理-->
79   - <!--</template>-->
80   - <!--<Menu-item name="2-1">新增用户</Menu-item>-->
81   - <!--<Menu-item name="2-2">活跃用户</Menu-item>-->
82   - <!--</Submenu>-->
83   - <!--<Submenu name="3">-->
84   - <!--<template slot="title">-->
85   - <!--<Icon type="stats-bars"></Icon>-->
86   - <!--统计分析-->
87   - <!--</template>-->
88   - <!--<Menu-group title="使用">-->
89   - <!--<Menu-item name="3-1">新增和启动</Menu-item>-->
90   - <!--<Menu-item name="3-2">活跃分析</Menu-item>-->
91   - <!--<Menu-item name="3-3">时段分析</Menu-item>-->
92   - <!--</Menu-group>-->
93   - <!--<Menu-group title="留存">-->
94   - <!--<Menu-item name="3-4">用户留存</Menu-item>-->
95   - <!--<Menu-item name="3-5">流失用户</Menu-item>-->
96   - <!--</Menu-group>-->
97   - <!--</Submenu>-->
98   - <!--</Menu>-->
99   - <!--</i-col>-->
100   - <!--<i-col span="8">-->
101   - <!--<Menu :theme="theme2" active-name="1-2" :open-names="['1']" @on-select="s">-->
102   - <!--<Submenu name="1">-->
103   - <!--<template slot="title">-->
104   - <!--<Icon type="ios-paper"></Icon>-->
105   - <!--内容管理-->
106   - <!--</template>-->
107   - <!--<Menu-item name="1-1">文章管理</Menu-item>-->
108   - <!--<Menu-item name="1-2">评论管理</Menu-item>-->
109   - <!--<Menu-item name="1-3">举报管理</Menu-item>-->
110   - <!--</Submenu>-->
111   - <!--<Submenu name="2">-->
112   - <!--<template slot="title">-->
113   - <!--<Icon type="ios-people"></Icon>-->
114   - <!--用户管理-->
115   - <!--</template>-->
116   - <!--<Menu-item name="2-1">新增用户</Menu-item>-->
117   - <!--<Menu-item name="2-2">活跃用户</Menu-item>-->
118   - <!--</Submenu>-->
119   - <!--<Submenu name="3">-->
120   - <!--<template slot="title">-->
121   - <!--<Icon type="stats-bars"></Icon>-->
122   - <!--统计分析-->
123   - <!--</template>-->
124   - <!--<Menu-group title="使用">-->
125   - <!--<Menu-item name="3-1">新增和启动</Menu-item>-->
126   - <!--<Menu-item name="3-2">活跃分析</Menu-item>-->
127   - <!--<Menu-item name="3-3">时段分析</Menu-item>-->
128   - <!--</Menu-group>-->
129   - <!--<Menu-group title="留存">-->
130   - <!--<Menu-item name="3-4">用户留存</Menu-item>-->
131   - <!--<Menu-item name="3-5">流失用户</Menu-item>-->
132   - <!--</Menu-group>-->
133   - <!--</Submenu>-->
134   - <!--</Menu>-->
135   - <!--</i-col>-->
136   - <!--<i-col span="8">-->
137   - <!--<Menu :theme="theme2" :open-names="['1']" accordion @on-select="s">-->
138   - <!--<Submenu name="1">-->
139   - <!--<template slot="title">-->
140   - <!--<Icon type="ios-paper"></Icon>-->
141   - <!--内容管理-->
142   - <!--</template>-->
143   - <!--<Menu-item name="1-1">文章管理</Menu-item>-->
144   - <!--<Menu-item name="1-2">评论管理</Menu-item>-->
145   - <!--<Menu-item name="1-3">举报管理</Menu-item>-->
146   - <!--</Submenu>-->
147   - <!--<Submenu name="2">-->
148   - <!--<template slot="title">-->
149   - <!--<Icon type="ios-people"></Icon>-->
150   - <!--用户管理-->
151   - <!--</template>-->
152   - <!--<Menu-item name="2-1">新增用户</Menu-item>-->
153   - <!--<Menu-item name="2-2">活跃用户</Menu-item>-->
154   - <!--</Submenu>-->
155   - <!--<Submenu name="3">-->
156   - <!--<template slot="title">-->
157   - <!--<Icon type="stats-bars"></Icon>-->
158   - <!--统计分析-->
159   - <!--</template>-->
160   - <!--<Menu-group title="使用">-->
161   - <!--<Menu-item name="3-1">新增和启动</Menu-item>-->
162   - <!--<Menu-item name="3-2">活跃分析</Menu-item>-->
163   - <!--<Menu-item name="3-3">时段分析</Menu-item>-->
164   - <!--</Menu-group>-->
165   - <!--<Menu-group title="留存">-->
166   - <!--<Menu-item name="3-4">用户留存</Menu-item>-->
167   - <!--<Menu-item name="3-5">流失用户</Menu-item>-->
168   - <!--</Menu-group>-->
169   - <!--</Submenu>-->
170   - <!--</Menu>-->
171   - <!--</i-col>-->
172   - <!--</Row>-->
173   - <!--<br>-->
174   - <!--<p>切换主题</p>-->
175   - <!--<Radio-group v-model="theme2">-->
176   - <!--<Radio label="light"></Radio>-->
177   - <!--<Radio label="dark"></Radio>-->
178   - <!--</Radio-group>-->
179   - <!--</div>-->
180   -<!--</template>-->
181   -<!--<script>-->
182   - <!--export default {-->
183   - <!--data () {-->
184   - <!--return {-->
185   - <!--theme2: 'light'-->
186   - <!--}-->
187   - <!--},-->
188   - <!--methods: {-->
189   - <!--s (s) {-->
190   - <!--console.log(s);-->
191   - <!--}-->
192   - <!--}-->
193   - <!--}-->
194   -<!--</script>-->
... ...
examples/routers/modal.vue
1 1 <template>
2 2 <div>
  3 + {{ val }}
3 4 <Button @click="confirm">标准</Button>
4 5 <Button @click="custom">自定义按钮文字</Button>
5 6 <Button @click="async">异步关闭</Button>
  7 + <Button type="primary" @click="modal1 = true">显示对话框</Button>
  8 + <Modal
  9 + v-model="modal1"
  10 + title="普通的Modal对话框标题"
  11 + @on-ok="ok"
  12 + @on-cancel="cancel">
  13 + <p>对话框内容</p>
  14 + <p>对话框内容</p>
  15 + <p>对话框内容</p>
  16 + </Modal>
6 17 </div>
7 18 </template>
8 19 <script>
9 20 export default {
  21 + data () {
  22 + return {
  23 + modal1: false,
  24 + val: ''
  25 + }
  26 + },
10 27 methods: {
  28 + ok () {
  29 + this.$Message.info('点击了确定');
  30 + },
  31 + cancel () {
  32 + this.$Message.info('点击了取消');
  33 + },
11 34 confirm () {
12 35 this.$Modal.confirm({
13 36 title: '确认对话框标题',
14 37 content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
  38 + render: (h) => {
  39 + return h('Input', {
  40 + props: {
  41 + value: this.val,
  42 + autofocus: true
  43 + },
  44 + on: {
  45 + input: (val) => {
  46 + this.val = val;
  47 + }
  48 + }
  49 + }, '一个按钮')
  50 + },
15 51 onOk: () => {
16 52 this.$Message.info('点击了确定');
17 53 },
... ...
examples/routers/table.vue
... ... @@ -84,7 +84,8 @@
84 84 {
85 85 name: '张小刚',
86 86 age: 25,
87   - address: '北京市海淀区西二旗'
  87 + address: '北京市海淀区西二旗',
  88 + _disableExpand: true
88 89 },
89 90 {
90 91 name: '李小红',
... ...
examples/routers/tabs.vue
1 1 <template>
2   - <Tabs value="name1" :animated="false">
3   - <Tab-pane label="标签一" name="name1">
  2 + <Tabs value="name1" :animated="true">
  3 + <Tab-pane :label="label1" name="name1">
4 4 <Table :columns="columns1" :data="data1"></Table>
5 5 </Tab-pane>
6 6 <Tab-pane label="标签二" name="name2">
... ... @@ -15,6 +15,12 @@
15 15 export default {
16 16 data () {
17 17 return {
  18 + label1: (h) => {
  19 + return h('div', [
  20 + h('span', '标签一'),
  21 + h('Button', 'button')
  22 + ]);
  23 + },
18 24 columns1: [
19 25 {
20 26 title: '姓名',
... ...
package.json
1 1 {
2 2 "name": "iview",
3   - "version": "2.0.0-rc.15",
  3 + "version": "2.0.0-rc.16",
4 4 "title": "iView",
5 5 "description": "A high quality UI components Library with Vue.js",
6 6 "homepage": "http://www.iviewui.com",
... ...
src/components/badge/badge.vue
... ... @@ -61,17 +61,9 @@
61 61 }
62 62  
63 63 return status;
64   - }
65   - },
66   - data () {
67   - return {
68   - alone: false
69   - };
70   - },
71   - mounted () {
72   - const child_length = this.$refs.badge.children.length;
73   - if (child_length === 1) {
74   - this.alone = true;
  64 + },
  65 + alone () {
  66 + return this.$slots.default === undefined;
75 67 }
76 68 }
77 69 };
... ...
src/components/base/collapse-transition.js 0 → 100644
  1 +// Thanks to https://github.com/ElemeFE/element/blob/dev/src/transitions/collapse-transition.js
  2 +
  3 +import { addClass, removeClass } from '../../utils/assist';
  4 +
  5 +const Transition = {
  6 + beforeEnter(el) {
  7 + addClass(el, 'collapse-transition');
  8 + if (!el.dataset) el.dataset = {};
  9 +
  10 + el.dataset.oldPaddingTop = el.style.paddingTop;
  11 + el.dataset.oldPaddingBottom = el.style.paddingBottom;
  12 +
  13 + el.style.height = '0';
  14 + el.style.paddingTop = 0;
  15 + el.style.paddingBottom = 0;
  16 + },
  17 +
  18 + enter(el) {
  19 + el.dataset.oldOverflow = el.style.overflow;
  20 + if (el.scrollHeight !== 0) {
  21 + el.style.height = el.scrollHeight + 'px';
  22 + el.style.paddingTop = el.dataset.oldPaddingTop;
  23 + el.style.paddingBottom = el.dataset.oldPaddingBottom;
  24 + } else {
  25 + el.style.height = '';
  26 + el.style.paddingTop = el.dataset.oldPaddingTop;
  27 + el.style.paddingBottom = el.dataset.oldPaddingBottom;
  28 + }
  29 +
  30 + el.style.overflow = 'hidden';
  31 + },
  32 +
  33 + afterEnter(el) {
  34 + // for safari: remove class then reset height is necessary
  35 + removeClass(el, 'collapse-transition');
  36 + el.style.height = '';
  37 + el.style.overflow = el.dataset.oldOverflow;
  38 + },
  39 +
  40 + beforeLeave(el) {
  41 + if (!el.dataset) el.dataset = {};
  42 + el.dataset.oldPaddingTop = el.style.paddingTop;
  43 + el.dataset.oldPaddingBottom = el.style.paddingBottom;
  44 + el.dataset.oldOverflow = el.style.overflow;
  45 +
  46 + el.style.height = el.scrollHeight + 'px';
  47 + el.style.overflow = 'hidden';
  48 + },
  49 +
  50 + leave(el) {
  51 + if (el.scrollHeight !== 0) {
  52 + // for safari: add class after set height, or it will jump to zero height suddenly, weired
  53 + addClass(el, 'collapse-transition');
  54 + el.style.height = 0;
  55 + el.style.paddingTop = 0;
  56 + el.style.paddingBottom = 0;
  57 + }
  58 + },
  59 +
  60 + afterLeave(el) {
  61 + removeClass(el, 'collapse-transition');
  62 + el.style.height = '';
  63 + el.style.overflow = el.dataset.oldOverflow;
  64 + el.style.paddingTop = el.dataset.oldPaddingTop;
  65 + el.style.paddingBottom = el.dataset.oldPaddingBottom;
  66 + }
  67 +};
  68 +
  69 +export default {
  70 + name: 'CollapseTransition',
  71 + functional: true,
  72 + render(h, { children }) {
  73 + const data = {
  74 + on: Transition
  75 + };
  76 +
  77 + return h('transition', data, children);
  78 + }
  79 +};
... ...
src/components/base/render.vue 0 → 100644
  1 +<template>
  2 + <div ref="cell"></div>
  3 +</template>
  4 +<script>
  5 + import Vue from 'vue';
  6 + export default {
  7 + name: 'RenderCell',
  8 + props: {
  9 + render: Function
  10 + },
  11 + methods: {
  12 + compile () {
  13 + if (this.render) {
  14 + this.$el.innerHTML = '';
  15 + const component = new Vue({
  16 + functional: true,
  17 + render: (h) => {
  18 + return this.render(h);
  19 + }
  20 + });
  21 + const Cell = component.$mount();
  22 + this.$refs.cell.appendChild(Cell.$el);
  23 + }
  24 + }
  25 + },
  26 + mounted () {
  27 + this.compile();
  28 + }
  29 + };
  30 +</script>
0 31 \ No newline at end of file
... ...
src/components/checkbox/checkbox.vue
... ... @@ -105,7 +105,7 @@
105 105 this.$emit('input', checked);
106 106  
107 107 if (this.group) {
108   - this.$parent.change(this.model);
  108 + this.parent.change(this.model);
109 109 } else {
110 110 this.$emit('on-change', checked);
111 111 this.dispatch('FormItem', 'on-form-change', checked);
... ...
src/components/collapse/panel.vue
... ... @@ -4,18 +4,21 @@
4 4 <Icon type="arrow-right-b"></Icon>
5 5 <slot></slot>
6 6 </div>
7   - <div :class="contentClasses" v-show="isActive">
8   - <div :class="boxClasses"><slot name="content"></slot></div>
9   - </div>
  7 + <collapse-transition>
  8 + <div :class="contentClasses" v-show="isActive">
  9 + <div :class="boxClasses"><slot name="content"></slot></div>
  10 + </div>
  11 + </collapse-transition>
10 12 </div>
11 13 </template>
12 14 <script>
13 15 import Icon from '../icon/icon.vue';
  16 + import CollapseTransition from '../base/collapse-transition';
14 17 const prefixCls = 'ivu-collapse';
15 18  
16 19 export default {
17 20 name: 'Panel',
18   - components: { Icon },
  21 + components: { Icon, CollapseTransition },
19 22 props: {
20 23 name: {
21 24 type: String
... ...
src/components/loading-bar/loading-bar.js
... ... @@ -31,9 +31,7 @@ LoadingBar.newInstance = properties =&gt; {
31 31 },
32 32 component: loading_bar,
33 33 destroy () {
34   - setTimeout(function() {
35   - document.body.removeChild(document.getElementsByClassName('ivu-loading-bar')[0].parentElement);
36   - }, 500);
  34 + document.body.removeChild(document.getElementsByClassName('ivu-loading-bar')[0]);
37 35 }
38 36 };
39 37 };
... ...
src/components/menu/submenu.vue
... ... @@ -4,7 +4,9 @@
4 4 <slot name="title"></slot>
5 5 <Icon type="ios-arrow-down" :class="[prefixCls + '-submenu-title-icon']"></Icon>
6 6 </div>
7   - <ul :class="[prefixCls]" v-if="mode === 'vertical'" v-show="opened"><slot></slot></ul>
  7 + <collapse-transition v-if="mode === 'vertical'">
  8 + <ul :class="[prefixCls]" v-show="opened"><slot></slot></ul>
  9 + </collapse-transition>
8 10 <transition name="slide-up" v-else>
9 11 <Drop
10 12 v-show="opened"
... ... @@ -17,6 +19,7 @@
17 19 <script>
18 20 import Drop from '../select/dropdown.vue';
19 21 import Icon from '../icon/icon.vue';
  22 + import CollapseTransition from '../base/collapse-transition';
20 23 import { getStyle, findComponentUpward } from '../../utils/assist';
21 24 import Emitter from '../../mixins/emitter';
22 25  
... ... @@ -25,7 +28,7 @@
25 28 export default {
26 29 name: 'Submenu',
27 30 mixins: [ Emitter ],
28   - components: { Icon, Drop },
  31 + components: { Icon, Drop, CollapseTransition },
29 32 props: {
30 33 name: {
31 34 type: [String, Number],
... ...
src/components/modal/confirm.js
... ... @@ -8,31 +8,6 @@ const prefixCls = &#39;ivu-modal-confirm&#39;;
8 8 Modal.newInstance = properties => {
9 9 const _props = properties || {};
10 10  
11   - // let props = '';
12   - // Object.keys(_props).forEach(prop => {
13   - // props += ' :' + camelcaseToHyphen(prop) + '=' + prop;
14   - // });
15   - //
16   - // const div = document.createElement('div');
17   - // div.innerHTML = `
18   - // <Modal${props} v-model="visible" :width="width" :scrollable="scrollable">
19   - // <div class="${prefixCls}">
20   - // <div class="${prefixCls}-head">
21   - // <div class="${prefixCls}-head-title" v-html="title"></div>
22   - // </div>
23   - // <div class="${prefixCls}-body">
24   - // <div :class="iconTypeCls"><i :class="iconNameCls"></i></div>
25   - // <div v-html="body"></div>
26   - // </div>
27   - // <div class="${prefixCls}-footer">
28   - // <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>
29   - // <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
30   - // </div>
31   - // </div>
32   - // </Modal>
33   - // `;
34   - // document.body.appendChild(div);
35   -
36 11 const Instance = new Vue({
37 12 mixins: [ Locale ],
38 13 data: Object.assign({}, _props, {
... ... @@ -73,6 +48,35 @@ Modal.newInstance = properties =&gt; {
73 48 }
74 49 }, this.localeOkText));
75 50  
  51 + // render content
  52 + let body_render;
  53 + if (this.render) {
  54 + body_render = h('div', {
  55 + attrs: {
  56 + class: `${prefixCls}-body ${prefixCls}-body-render`
  57 + }
  58 + }, [this.render(h)]);
  59 + } else {
  60 + body_render = h('div', {
  61 + attrs: {
  62 + class: `${prefixCls}-body`
  63 + }
  64 + }, [
  65 + h('div', {
  66 + class: this.iconTypeCls
  67 + }, [
  68 + h('i', {
  69 + class: this.iconNameCls
  70 + })
  71 + ]),
  72 + h('div', {
  73 + domProps: {
  74 + innerHTML: this.body
  75 + }
  76 + })
  77 + ]);
  78 + }
  79 +
76 80 return h(Modal, {
77 81 props: Object.assign({}, _props, {
78 82 width: this.width,
... ... @@ -106,24 +110,7 @@ Modal.newInstance = properties =&gt; {
106 110 }
107 111 })
108 112 ]),
109   - h('div', {
110   - attrs: {
111   - class: `${prefixCls}-body`
112   - }
113   - }, [
114   - h('div', {
115   - class: this.iconTypeCls
116   - }, [
117   - h('i', {
118   - class: this.iconNameCls
119   - })
120   - ]),
121   - h('div', {
122   - domProps: {
123   - innerHTML: this.body
124   - }
125   - })
126   - ]),
  113 + body_render,
127 114 h('div', {
128 115 attrs: {
129 116 class: `${prefixCls}-footer`
... ...
src/components/modal/index.js
... ... @@ -2,18 +2,20 @@ import Modal from &#39;./confirm&#39;;
2 2  
3 3 let modalInstance;
4 4  
5   -function getModalInstance () {
  5 +function getModalInstance (render = undefined) {
6 6 modalInstance = modalInstance || Modal.newInstance({
7 7 closable: false,
8 8 maskClosable: false,
9   - footerHide: true
  9 + footerHide: true,
  10 + render: render
10 11 });
11 12  
12 13 return modalInstance;
13 14 }
14 15  
15 16 function confirm (options) {
16   - let instance = getModalInstance();
  17 + const render = ('render' in options) ? options.render : undefined;
  18 + let instance = getModalInstance(render);
17 19  
18 20 options.onRemove = function () {
19 21 modalInstance = null;
... ...
src/components/modal/modal.vue
1 1 <template>
2   - <div>
  2 + <div v-transfer-dom>
3 3 <transition :name="transitionNames[1]">
4 4 <div :class="maskClasses" v-show="visible" @click="mask"></div>
5 5 </transition>
... ...
src/components/table/cell.vue
... ... @@ -5,7 +5,7 @@
5 5 <Checkbox :value="checked" @on-change="toggleSelect" :disabled="disabled"></Checkbox>
6 6 </template>
7 7 <template v-if="renderType === 'normal'"><span v-html="row[column.key]"></span></template>
8   - <template v-if="renderType === 'expand'">
  8 + <template v-if="renderType === 'expand' && !row._disableExpand">
9 9 <div :class="expandCls" @click="toggleExpand">
10 10 <Icon type="ios-arrow-right"></Icon>
11 11 </div>
... ...
src/components/tabs/pane.vue
... ... @@ -11,7 +11,7 @@
11 11 type: String
12 12 },
13 13 label: {
14   - type: String,
  14 + type: [String, Function],
15 15 default: ''
16 16 },
17 17 icon: {
... ...
src/components/tabs/tabs.vue
... ... @@ -8,7 +8,8 @@
8 8 <div :class="barClasses" :style="barStyle"></div>
9 9 <div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
10 10 <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
11   - {{ item.label }}
  11 + <Render v-if="item.labelType === 'function'" :render="item.label"></Render>
  12 + <template v-else>{{ item.label }}</template>
12 13 <Icon v-if="showClose(item)" type="ios-close-empty" @click.native.stop="handleRemove(index)"></Icon>
13 14 </div>
14 15 </div>
... ... @@ -22,6 +23,7 @@
22 23 </template>
23 24 <script>
24 25 import Icon from '../icon/icon.vue';
  26 + import Render from '../base/render.vue';
25 27 import { oneOf, getStyle } from '../../utils/assist';
26 28 import Emitter from '../../mixins/emitter';
27 29  
... ... @@ -30,7 +32,7 @@
30 32 export default {
31 33 name: 'Tabs',
32 34 mixins: [ Emitter ],
33   - components: { Icon },
  35 + components: { Icon, Render },
34 36 props: {
35 37 value: {
36 38 type: [String, Number]
... ... @@ -128,6 +130,7 @@
128 130 this.navList = [];
129 131 this.getTabs().forEach((pane, index) => {
130 132 this.navList.push({
  133 + labelType: typeof pane.label,
131 134 label: pane.label,
132 135 icon: pane.icon || '',
133 136 name: pane.currentName || index,
... ...
src/components/tree/node.vue
1 1 <template>
2   - <transition name="slide-up">
  2 + <collapse-transition>
3 3 <ul :class="classes" v-show="visible">
4 4 <li>
5 5 <span :class="arrowClasses" @click="handleExpand">
6 6 <Icon type="arrow-right-b"></Icon>
7 7 </span>
8 8 <Checkbox
9   - v-if="showCheckbox"
10   - :value="data.checked"
11   - :indeterminate="indeterminate"
12   - :disabled="data.disabled || data.disableCheckbox"
13   - @click.native.prevent="handleCheck"></Checkbox>
  9 + v-if="showCheckbox"
  10 + :value="data.checked"
  11 + :indeterminate="indeterminate"
  12 + :disabled="data.disabled || data.disableCheckbox"
  13 + @click.native.prevent="handleCheck"></Checkbox>
14 14 <span :class="titleClasses" v-html="data.title" @click="handleSelect"></span>
15 15 <Tree-node
16   - v-for="item in data.children"
17   - :key="item"
18   - :data="item"
19   - :visible="data.expand"
20   - :multiple="multiple"
21   - :show-checkbox="showCheckbox">
  16 + v-for="item in data.children"
  17 + :key="item"
  18 + :data="item"
  19 + :visible="data.expand"
  20 + :multiple="multiple"
  21 + :show-checkbox="showCheckbox">
22 22 </Tree-node>
23 23 </li>
24 24 </ul>
25   - </transition>
  25 + </collapse-transition>
26 26 </template>
27 27 <script>
28 28 import Checkbox from '../checkbox/checkbox.vue';
29 29 import Icon from '../icon/icon.vue';
  30 + import CollapseTransition from '../base/collapse-transition';
30 31 import Emitter from '../../mixins/emitter';
31 32 import { findComponentsDownward } from '../../utils/assist';
32 33  
... ... @@ -35,7 +36,7 @@
35 36 export default {
36 37 name: 'TreeNode',
37 38 mixins: [ Emitter ],
38   - components: { Checkbox, Icon },
  39 + components: { Checkbox, Icon, CollapseTransition },
39 40 props: {
40 41 data: {
41 42 type: Object,
... ...
src/directives/transfer-dom.js
... ... @@ -18,6 +18,7 @@ const directive = {
18 18 inserted (el, { value }, vnode) {
19 19 el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom';
20 20 const parentNode = el.parentNode;
  21 + if (!parentNode) return;
21 22 const home = document.createComment('');
22 23 let hasMovedOut = false;
23 24  
... ... @@ -38,6 +39,7 @@ const directive = {
38 39 componentUpdated (el, { value }) {
39 40 // need to make sure children are done updating (vs. `update`)
40 41 const ref$1 = el.__transferDomData;
  42 + if (!ref$1) return;
41 43 // homes.get(el)
42 44 const parentNode = ref$1.parentNode;
43 45 const home = ref$1.home;
... ... @@ -59,7 +61,9 @@ const directive = {
59 61 }
60 62 },
61 63 unbind: function unbind (el, binding) {
62   - el.className = el.className.replace('v-transfer-dom', '')
  64 + el.className = el.className.replace('v-transfer-dom', '');
  65 + const ref$1 = el.__transferDomData;
  66 + if (!ref$1) return;
63 67 if (el.__transferDomData.hasMovedOut === true) {
64 68 el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el)
65 69 }
... ...
src/locale/lang/fr-FR.js 0 → 100644
  1 +export default {
  2 + i: {
  3 + select: {
  4 + placeholder: 'Sélectionnez',
  5 + noMatch: 'Aucun résultat',
  6 + loading: 'Chargement'
  7 + },
  8 + table: {
  9 + noDataText: 'Aucune donnée',
  10 + noFilteredDataText: 'No filter data',
  11 + confirmFilter: 'Confirmez',
  12 + resetFilter: 'Reset',
  13 + clearFilter: 'Tout'
  14 + },
  15 + datepicker: {
  16 + selectDate: 'Sélectionnez une date',
  17 + selectTime: 'Sélectionnez une heure',
  18 + startTime: 'Heure de début',
  19 + endTime: 'Heure de fin',
  20 + clear: 'Annuler',
  21 + ok: 'OK',
  22 + month: '',
  23 + month1: 'Janvier',
  24 + month2: 'Février',
  25 + month3: 'Mars',
  26 + month4: 'Avril',
  27 + month5: 'Mai',
  28 + month6: 'Juin',
  29 + month7: 'Juillet',
  30 + month8: 'Août',
  31 + month9: 'Septembre',
  32 + month10: 'Octobre',
  33 + month11: 'Novembre',
  34 + month12: 'Decembre',
  35 + year: '',
  36 + weeks: {
  37 + sun: 'Dim',
  38 + mon: 'Lun',
  39 + tue: 'Mar',
  40 + wed: 'Mer',
  41 + thu: 'Jeu',
  42 + fri: 'Ven',
  43 + sat: 'Sam'
  44 + },
  45 + months: {
  46 + m1: 'Jan',
  47 + m2: 'Fev',
  48 + m3: 'Mar',
  49 + m4: 'Avr',
  50 + m5: 'Mai',
  51 + m6: 'Jun',
  52 + m7: 'Jul',
  53 + m8: 'Aoû',
  54 + m9: 'Sep',
  55 + m10: 'Oct',
  56 + m11: 'Nov',
  57 + m12: 'Déc'
  58 + }
  59 + },
  60 + transfer: {
  61 + titles: {
  62 + source: 'Source',
  63 + target: 'Cible'
  64 + },
  65 + filterPlaceholder: 'Recherche',
  66 + notFoundText: 'Pas de résultat'
  67 + },
  68 + modal: {
  69 + okText: 'OK',
  70 + cancelText: 'Annuler'
  71 + },
  72 + poptip: {
  73 + okText: 'OK',
  74 + cancelText: 'Annuler'
  75 + },
  76 + page: {
  77 + prev: 'Page Précédente',
  78 + next: 'Page Suivante',
  79 + total: 'Total',
  80 + item: 'élément',
  81 + items: 'éléments',
  82 + prev5: '5 Pages en Avant',
  83 + next5: '5 Pages en Arrière',
  84 + page: '/page',
  85 + goto: 'Aller à',
  86 + p: ''
  87 + },
  88 + rate: {
  89 + star: 'Étoile',
  90 + stars: 'Étoiles'
  91 + },
  92 + tree: {
  93 + emptyText: 'Aucune donnée'
  94 + }
  95 + }
  96 +};
... ...
src/styles/animation/index.less
... ... @@ -25,4 +25,8 @@
25 25 @import "fade";
26 26 @import "move";
27 27 @import "ease";
28   -@import "slide";
29 28 \ No newline at end of file
  29 +@import "slide";
  30 +
  31 +.collapse-transition {
  32 + transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, @transition-time padding-bottom ease-in-out;
  33 +}
30 34 \ No newline at end of file
... ...
src/styles/components/modal.less
... ... @@ -98,6 +98,11 @@
98 98 color: @text-color;
99 99 position: relative;
100 100  
  101 + &-render{
  102 + margin: 0;
  103 + padding: 0;
  104 + }
  105 +
101 106 &-icon {
102 107 font-size: 36px;
103 108 position: absolute;
... ...
src/utils/assist.js
... ... @@ -232,4 +232,66 @@ function findComponentsDownward (context, componentName, components = []) {
232 232 }
233 233 return components;
234 234 }
235   -export {findComponentsDownward};
236 235 \ No newline at end of file
  236 +export {findComponentsDownward};
  237 +
  238 +/* istanbul ignore next */
  239 +const trim = function(string) {
  240 + return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
  241 +};
  242 +
  243 +/* istanbul ignore next */
  244 +export function hasClass(el, cls) {
  245 + if (!el || !cls) return false;
  246 + if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
  247 + if (el.classList) {
  248 + return el.classList.contains(cls);
  249 + } else {
  250 + return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
  251 + }
  252 +}
  253 +
  254 +/* istanbul ignore next */
  255 +export function addClass(el, cls) {
  256 + if (!el) return;
  257 + let curClass = el.className;
  258 + const classes = (cls || '').split(' ');
  259 +
  260 + for (let i = 0, j = classes.length; i < j; i++) {
  261 + const clsName = classes[i];
  262 + if (!clsName) continue;
  263 +
  264 + if (el.classList) {
  265 + el.classList.add(clsName);
  266 + } else {
  267 + if (!hasClass(el, clsName)) {
  268 + curClass += ' ' + clsName;
  269 + }
  270 + }
  271 + }
  272 + if (!el.classList) {
  273 + el.className = curClass;
  274 + }
  275 +}
  276 +
  277 +/* istanbul ignore next */
  278 +export function removeClass(el, cls) {
  279 + if (!el || !cls) return;
  280 + const classes = cls.split(' ');
  281 + let curClass = ' ' + el.className + ' ';
  282 +
  283 + for (let i = 0, j = classes.length; i < j; i++) {
  284 + const clsName = classes[i];
  285 + if (!clsName) continue;
  286 +
  287 + if (el.classList) {
  288 + el.classList.remove(clsName);
  289 + } else {
  290 + if (hasClass(el, clsName)) {
  291 + curClass = curClass.replace(' ' + clsName + ' ', ' ');
  292 + }
  293 + }
  294 + }
  295 + if (!el.classList) {
  296 + el.className = trim(curClass);
  297 + }
  298 +}
237 299 \ No newline at end of file
... ...