@v2coding/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +6 -0
  2. package/dist/v2coding-ui.esm.js +10840 -0
  3. package/dist/v2coding-ui.min.js +1 -0
  4. package/dist/v2coding-ui.ssr.js +10747 -0
  5. package/package.json +54 -0
  6. package/src/components/dialog/dialog.vue +179 -0
  7. package/src/components/drawer/drawer.vue +523 -0
  8. package/src/components/exports/index.vue +53 -0
  9. package/src/components/exports/remote-exports-dialog.vue +202 -0
  10. package/src/components/field/field.autocomplete.vue +21 -0
  11. package/src/components/field/field.calendar.vue +117 -0
  12. package/src/components/field/field.cascade.vue +233 -0
  13. package/src/components/field/field.checkbox.vue +134 -0
  14. package/src/components/field/field.color.vue +24 -0
  15. package/src/components/field/field.date.vue +145 -0
  16. package/src/components/field/field.icons.vue +123 -0
  17. package/src/components/field/field.number.vue +43 -0
  18. package/src/components/field/field.radio.vue +100 -0
  19. package/src/components/field/field.rate.vue +37 -0
  20. package/src/components/field/field.rich.vue +165 -0
  21. package/src/components/field/field.select.vue +210 -0
  22. package/src/components/field/field.slider.vue +66 -0
  23. package/src/components/field/field.switch.vue +14 -0
  24. package/src/components/field/field.text.vue +66 -0
  25. package/src/components/field/field.timepicker.vue +70 -0
  26. package/src/components/field/field.timeselect.vue +24 -0
  27. package/src/components/field/field.trigger.dialog.vue +50 -0
  28. package/src/components/field/field.trigger.popover.vue +63 -0
  29. package/src/components/field/field.upload.file.vue +241 -0
  30. package/src/components/field/field.upload.image.vue +125 -0
  31. package/src/components/field/field.upload.portrait.vue +304 -0
  32. package/src/components/fill-view/index.vue +43 -0
  33. package/src/components/form/form.dialog.vue +174 -0
  34. package/src/components/form/form.drawer.vue +246 -0
  35. package/src/components/form/form.fieldset.vue +110 -0
  36. package/src/components/form/form.item.vue +213 -0
  37. package/src/components/form/form.vue +293 -0
  38. package/src/components/head-menu/index.vue +188 -0
  39. package/src/components/head-menu/menu-item.vue +84 -0
  40. package/src/components/history/index.vue +360 -0
  41. package/src/components/icon/icon.vue +63 -0
  42. package/src/components/minimize/index.vue +342 -0
  43. package/src/components/page/page.vue +43 -0
  44. package/src/components/provider/provider.vue +15 -0
  45. package/src/components/scroll-view/scroll-view.vue +384 -0
  46. package/src/components/table/column.vue +262 -0
  47. package/src/components/table/table.pagination.vue +71 -0
  48. package/src/components/table/table.select.vue +165 -0
  49. package/src/components/table/table.vue +805 -0
@@ -0,0 +1,523 @@
1
+ <template>
2
+ <div v-transfer-dom :data-transfer="transfer">
3
+ <transition name="fade">
4
+ <div :class="maskClasses" :style="maskStyle" v-show="visible" v-if="mask" @click="handleMask"></div>
5
+ </transition>
6
+ <div :class="wrapClasses" @click="handleWrapClick">
7
+ <transition :name="'move-' + placement">
8
+ <div :class="classes" :style="mainStyles" v-show="visible">
9
+ <div :class="contentClasses" ref="content">
10
+ <a class="ui-drawer-close" v-if="closable" @click="close">
11
+ <slot name="close">
12
+ <i class="el-icon-close"></i>
13
+ </slot>
14
+ </a>
15
+ <div :class="[prefixCls + '-header']" v-if="showHead"><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div>
16
+ <div :class="[prefixCls + '-body']" :style="styles"><slot></slot></div>
17
+ </div>
18
+ <div class="ui-drawer-drag" :class="{ 'ui-drawer-drag-left': placement === 'left' }" v-if="draggable" @mousedown="handleTriggerMousedown">
19
+ <slot name="trigger">
20
+ <div class="ui-drawer-drag-move-trigger">
21
+ <div class="ui-drawer-drag-move-trigger-point">
22
+ <i></i><i></i><i></i><i></i><i></i>
23
+ </div>
24
+ </div>
25
+ </slot>
26
+ </div>
27
+ </div>
28
+ </transition>
29
+ </div>
30
+ </div>
31
+ </template>
32
+ <script>
33
+ import { oneOf} from './assist';
34
+ import TransferDom from './transfer-dom';
35
+ import { on, off } from './dom';
36
+
37
+ const prefixCls = 'ui-drawer';
38
+
39
+ export default {
40
+ name: 'UiDrawer',
41
+ directives: { TransferDom },
42
+ props: {
43
+ value: {
44
+ type: Boolean,
45
+ default: false
46
+ },
47
+ title: {
48
+ type: String
49
+ },
50
+ width: {
51
+ type: [Number, String],
52
+ default: 256
53
+ },
54
+ closable: {
55
+ type: Boolean,
56
+ default: true
57
+ },
58
+ maskClosable: {
59
+ type: Boolean,
60
+ default: true
61
+ },
62
+ mask: {
63
+ type: Boolean,
64
+ default: true
65
+ },
66
+ maskStyle: {
67
+ type: Object
68
+ },
69
+ styles: {
70
+ type: Object
71
+ },
72
+ scrollable: {
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+ placement: {
77
+ validator (value) {
78
+ return oneOf(value, ['left', 'right']);
79
+ },
80
+ default: 'right'
81
+ },
82
+ zIndex: {
83
+ type: Number,
84
+ default: 1000
85
+ },
86
+ transfer: {
87
+ type: Boolean,
88
+ default: true,
89
+ },
90
+ className: {
91
+ type: String
92
+ },
93
+ inner: {
94
+ type: Boolean,
95
+ default: false
96
+ },
97
+ // Whether drag and drop is allowed to adjust width
98
+ draggable: {
99
+ type: Boolean,
100
+ default: false
101
+ },
102
+ beforeClose: Function,
103
+ },
104
+ data () {
105
+ return {
106
+ prefixCls: prefixCls,
107
+ visible: this.value,
108
+ wrapShow: false,
109
+ showHead: true,
110
+ canMove: false,
111
+ dragWidth: this.width,
112
+ wrapperWidth: this.width,
113
+ wrapperLeft: 0,
114
+ minWidth: 256
115
+ };
116
+ },
117
+ computed: {
118
+ wrapClasses () {
119
+ return [
120
+ `${prefixCls}-wrap`,
121
+ {
122
+ [`${prefixCls}-hidden`]: !this.wrapShow,
123
+ [`${this.className}`]: !!this.className,
124
+ [`${prefixCls}-no-mask`]: !this.mask,
125
+ [`${prefixCls}-wrap-inner`]: this.inner,
126
+ [`${prefixCls}-wrap-dragging`]: this.canMove
127
+ }
128
+ ];
129
+ },
130
+ mainStyles () {
131
+ let style = {};
132
+ const width = parseInt(this.dragWidth);
133
+ const styleWidth = {
134
+ width: width <= 100 ? `${width}%` : `${width}px`
135
+ };
136
+ Object.assign(style, styleWidth);
137
+ return style;
138
+ },
139
+ contentClasses () {
140
+ return [
141
+ `${prefixCls}-content`,
142
+ {
143
+ [`${prefixCls}-content-no-mask`]: !this.mask
144
+ }
145
+ ];
146
+ },
147
+ classes () {
148
+ return [
149
+ `${prefixCls}`,
150
+ `${prefixCls}-${this.placement}`,
151
+ {
152
+ [`${prefixCls}-no-header`]: !this.showHead,
153
+ [`${prefixCls}-inner`]: this.inner
154
+ }
155
+ ];
156
+ },
157
+ maskClasses () {
158
+ return [
159
+ `${prefixCls}-mask`,
160
+ {
161
+ [`${prefixCls}-mask-inner`]: this.inner
162
+ }
163
+ ];
164
+ }
165
+ },
166
+ methods: {
167
+ close () {
168
+ if (!this.beforeClose) {
169
+ return this.handleClose();
170
+ }
171
+ const before = this.beforeClose();
172
+ if (before && before.then) {
173
+ before.then(() => {
174
+ this.handleClose();
175
+ });
176
+ } else {
177
+ this.handleClose();
178
+ }
179
+ },
180
+ handleClose () {
181
+ this.visible = false;
182
+ this.$emit('input', false);
183
+ this.$emit('on-close');
184
+ },
185
+ handleMask () {
186
+ if (this.maskClosable && this.mask) {
187
+ this.close();
188
+ }
189
+ },
190
+ handleWrapClick (event) {
191
+ // use indexOf,do not use === ,because ivu-modal-wrap can have other custom className
192
+ const className = event.target.getAttribute('class');
193
+ if (className && className.indexOf(`${prefixCls}-wrap`) > -1) this.handleMask();
194
+ },
195
+ handleMousemove (event) {
196
+ if (!this.canMove || !this.draggable) return;
197
+ // 更新容器宽度和距离左侧页面距离,如果是window则距左侧距离为0
198
+ this.handleSetWrapperWidth();
199
+ const left = event.pageX - this.wrapperLeft;
200
+ // 如果抽屉方向为右边,宽度计算需用容器宽度减去left
201
+ let width = this.placement === 'right' ? this.wrapperWidth - left : left;
202
+ // 限定最小宽度
203
+ width = Math.max(width, parseFloat(this.minWidth));
204
+ event.atMin = width === parseFloat(this.minWidth);
205
+ // 如果当前width不大于100,视为百分比
206
+ if (width <= 100) width = (width / this.wrapperWidth) * 100;
207
+ this.dragWidth = width;
208
+ this.$emit('on-resize-width', parseInt(this.dragWidth));
209
+ },
210
+ handleSetWrapperWidth () {
211
+ const {
212
+ width,
213
+ left
214
+ } = this.$el.getBoundingClientRect();
215
+ this.wrapperWidth = width;
216
+ this.wrapperLeft = left;
217
+ },
218
+ handleMouseup () {
219
+ if (!this.draggable) return;
220
+ this.canMove = false;
221
+ },
222
+ handleTriggerMousedown () {
223
+ this.canMove = true;
224
+ // 防止鼠标选中抽屉中文字,造成拖动trigger触发浏览器原生拖动行为
225
+ window.getSelection().removeAllRanges();
226
+ },
227
+ },
228
+ mounted () {
229
+ if (this.visible) {
230
+ this.wrapShow = true;
231
+ }
232
+ let showHead = true;
233
+ if (this.$slots.header === undefined && !this.title) {
234
+ showHead = false;
235
+ }
236
+ this.showHead = showHead;
237
+ on(document, 'mousemove', this.handleMousemove);
238
+ on(document, 'mouseup', this.handleMouseup);
239
+ this.handleSetWrapperWidth();
240
+ },
241
+ beforeDestroy () {
242
+ off(document, 'mousemove', this.handleMousemove);
243
+ off(document, 'mouseup', this.handleMouseup);
244
+ },
245
+ watch: {
246
+ value (val) {
247
+ this.visible = val;
248
+ },
249
+ visible (val) {
250
+ if (val === false) {
251
+ this.timer = setTimeout(() => {
252
+ this.wrapShow = false;
253
+ }, 300);
254
+ } else {
255
+ if (this.timer) clearTimeout(this.timer);
256
+ this.wrapShow = true;
257
+ }
258
+ this.$emit('on-visible-change', val);
259
+ },
260
+ title (val) {
261
+ if (this.$slots.header === undefined) {
262
+ this.showHead = !!val;
263
+ }
264
+ },
265
+ width (val) {
266
+ this.dragWidth = val;
267
+ }
268
+ }
269
+ };
270
+ </script>
271
+
272
+ <style lang="less">
273
+ @drawer-prefix-cls: ~"ui-drawer";
274
+
275
+ .content-header() {
276
+ border-bottom: 1px solid #e8eaec;
277
+ padding: 14px 16px;
278
+ line-height: 1;
279
+
280
+ p,
281
+ &-inner
282
+ {
283
+ display: inline-block;
284
+ width: 100%;
285
+ height: 20px;
286
+ line-height: 20px;
287
+ font-size: 16px;
288
+ color: #17233d;
289
+ font-weight: 500;
290
+ overflow: hidden;
291
+ text-overflow: ellipsis;
292
+ white-space: nowrap;
293
+ }
294
+ p i, p span{
295
+ //vertical-align: middle;
296
+ }
297
+ }
298
+
299
+ .content-close(@top: 0, @icon-font-size: 22px) {
300
+ font-size: 12px;
301
+ position: absolute;
302
+ right: 15px;
303
+ top: 15px;
304
+ overflow: hidden;
305
+ cursor: pointer;
306
+
307
+ .el-icon-close {
308
+ font-size: @icon-font-size;
309
+ color: #999;
310
+ transition: color .2s ease;
311
+ position: relative;
312
+ top: @top;
313
+ &:hover {
314
+ color: #444;
315
+ }
316
+ }
317
+ }
318
+
319
+ .mask() {
320
+ position: fixed;
321
+ top: 0;
322
+ bottom: 0;
323
+ left: 0;
324
+ right: 0;
325
+ background-color: rgba(55, 55, 55, 0.6);
326
+ height: 100%;
327
+ z-index: 1000;
328
+
329
+ &-hidden {
330
+ display: none;
331
+ }
332
+ }
333
+
334
+ .@{drawer-prefix-cls} {
335
+ width: auto;
336
+ height: 100%;
337
+ position: fixed;
338
+ top: 0;
339
+
340
+ &-inner{
341
+ position: absolute;
342
+ }
343
+
344
+ &-left{
345
+ left: 0;
346
+ }
347
+ &-right{
348
+ right: 0;
349
+ }
350
+
351
+ &-hidden {
352
+ display: none !important;
353
+ }
354
+
355
+ &-wrap {
356
+ position: fixed;
357
+ overflow: auto;
358
+ top: 0;
359
+ right: 0;
360
+ bottom: 0;
361
+ left: 0;
362
+ z-index: 1000;
363
+ -webkit-overflow-scrolling: touch;
364
+ outline: 0;
365
+
366
+ &-inner{
367
+ position: absolute;
368
+ overflow: hidden;
369
+ }
370
+
371
+ &-dragging{
372
+ user-select: none;
373
+ }
374
+ }
375
+
376
+ &-wrap * {
377
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
378
+ }
379
+
380
+ &-mask {
381
+ .mask;
382
+ &-inner{
383
+ position: absolute;
384
+ }
385
+ }
386
+
387
+ &-content {
388
+ width: 100%;
389
+ height: 100%;
390
+ position: absolute;
391
+ top: 0;
392
+ bottom: 0;
393
+ background-color: #fff;
394
+ border: 0;
395
+ background-clip: padding-box;
396
+ box-shadow: 0 4px 12px rgba(0,0,0,.15);
397
+
398
+ &-no-mask{
399
+ pointer-events: auto;
400
+ }
401
+ }
402
+
403
+ &-header {
404
+ .content-header;
405
+ }
406
+
407
+ &-close {
408
+ z-index: 1;
409
+ .content-close(1px, 20px);
410
+ }
411
+
412
+ &-body {
413
+ width: 100%;
414
+ height: calc(~'100% - 51px');
415
+ padding: 16px;
416
+ font-size: 14px;
417
+ line-height: 1.5;
418
+ word-wrap: break-word;
419
+ position: absolute;
420
+ overflow: auto;
421
+ box-sizing: border-box;
422
+ }
423
+
424
+ &-no-header &-body{
425
+ height: 100%;
426
+ }
427
+
428
+ &-no-mask{
429
+ pointer-events: none;
430
+
431
+ .@{drawer-prefix-cls}-drag{
432
+ pointer-events: auto;
433
+ }
434
+ }
435
+
436
+ &-drag{
437
+ top: 0;
438
+ height: 100%;
439
+ width: 0;
440
+ position: absolute;
441
+ &-left{
442
+ right: 0;
443
+ }
444
+ &-move-trigger{
445
+ width: 8px;
446
+ height: 100px;
447
+ line-height: 100px;
448
+ position: absolute;
449
+ top: 50%;
450
+ background: rgb(243, 243, 243);
451
+ transform: translate(-50%, -50%);
452
+ border-radius: ~"4px / 6px";
453
+ box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
454
+ cursor: col-resize;
455
+ &-point{
456
+ display: inline-block;
457
+ width: 50%;
458
+ transform: translateX(50%);
459
+ i{
460
+ display: block;
461
+ border-bottom: 1px solid rgb(192, 192, 192);
462
+ padding-bottom: 2px;
463
+ }
464
+ }
465
+ }
466
+ }
467
+ }
468
+
469
+ .motion-common(@time) {
470
+ animation-duration: @time;
471
+ animation-fill-mode: both;
472
+ }
473
+
474
+ .make-motion(@className, @keyframeName, @time: .3s) {
475
+ .@{className}-enter-active, .@{className}-appear {
476
+ .motion-common(@time);
477
+ animation-play-state: paused;
478
+ }
479
+ .@{className}-leave-active {
480
+ .motion-common(@time);
481
+ animation-play-state: paused;
482
+ }
483
+ .@{className}-enter-active, .@{className}-appear {
484
+ animation-name: ~"@{keyframeName}In";
485
+ animation-play-state: running;
486
+ }
487
+ .@{className}-leave-active {
488
+ animation-name: ~"@{keyframeName}Out";
489
+ animation-play-state: running;
490
+ }
491
+ }
492
+
493
+ .fade-motion(@className, @keyframeName) {
494
+ .make-motion(@className, @keyframeName, .15s);
495
+ .@{className}-enter-active, .@{className}-appear {
496
+ opacity: 0;
497
+ animation-timing-function: linear;
498
+ }
499
+ .@{className}-leave-active {
500
+ animation-timing-function: linear;
501
+ }
502
+ }
503
+
504
+ .fade-motion(fade, uiFadeIn);
505
+
506
+ @keyframes uiFadeIn {
507
+ 0% {
508
+ opacity: 0;
509
+ }
510
+ 100% {
511
+ opacity: 1;
512
+ }
513
+ }
514
+
515
+ @keyframes ivuFadeOut {
516
+ 0% {
517
+ opacity: 1;
518
+ }
519
+ 100% {
520
+ opacity: 0;
521
+ }
522
+ }
523
+ </style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <div class="export-wrapper" @click="handleExport">
3
+ <slot>导出</slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import exports from './exports';
9
+
10
+ const Export = {
11
+ name: 'ui-export',
12
+ props: {},
13
+ methods: {
14
+ handleExport() {
15
+ const data = [
16
+ {id: 1, name: 'i那是大', age: 10, sex: 1},
17
+ {id: 2, name: 'asdasd 123安师大', age: 12, sex: 0},
18
+ {id: 3, name: '安达充再擦', age: 11, sex: 1},
19
+ {id: 4, name: '1发撒说', age: 14, sex: 2},
20
+ ];
21
+ const columns = [
22
+ {key: 'id', title: 'ID'},
23
+ {key: 'name', title: '名称'},
24
+ {key: 'age', title: '年龄'},
25
+ {
26
+ title: '性别',
27
+ transform: ({sex}) => {
28
+ if (sex === 1) {
29
+ return '男';
30
+ }
31
+ if (sex === 2) {
32
+ return '女';
33
+ }
34
+ return '保密';
35
+ },
36
+ },
37
+ ];
38
+ const filename = 'file.xlsx';
39
+ exports(data, filename, columns);
40
+ },
41
+ },
42
+ };
43
+
44
+ export default {
45
+ install: (Vue) => {
46
+ Vue.component(Export.name, Export);
47
+ },
48
+ };
49
+ </script>
50
+
51
+ <style scoped>
52
+
53
+ </style>