sh-view 2.8.0 → 2.8.2

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 (91) hide show
  1. package/.eslintrc.js +25 -20
  2. package/other.js +8 -8
  3. package/package.json +9 -6
  4. package/packages/components/index.js +91 -91
  5. package/packages/components/sh-alert/alert.ts +30 -0
  6. package/packages/components/sh-alert/index.vue +143 -168
  7. package/packages/components/sh-badge/index.vue +242 -242
  8. package/packages/components/sh-calendar/index.vue +650 -650
  9. package/packages/components/sh-card/index.vue +148 -148
  10. package/packages/components/sh-code-editor/index.vue +19 -19
  11. package/packages/components/sh-col/index.vue +92 -92
  12. package/packages/components/sh-corner/index.vue +230 -230
  13. package/packages/components/sh-count-to/index.vue +131 -131
  14. package/packages/components/sh-date/index.vue +301 -301
  15. package/packages/components/sh-drawer/index.vue +579 -579
  16. package/packages/components/sh-drawer/scrollbar.js +78 -78
  17. package/packages/components/sh-empty/index.vue +42 -42
  18. package/packages/components/sh-form/js/props.js +76 -76
  19. package/packages/components/sh-form/js/useForm.js +229 -229
  20. package/packages/components/sh-header/index.vue +261 -260
  21. package/packages/components/sh-icon/css/default/ionicons.svg +869 -869
  22. package/packages/components/sh-icon/css/font/iconfont.json +247 -247
  23. package/packages/components/sh-icon/index.vue +41 -41
  24. package/packages/components/sh-image/index.vue +133 -133
  25. package/packages/components/sh-list/index.vue +146 -146
  26. package/packages/components/sh-loading/index.vue +53 -53
  27. package/packages/components/sh-modal/index.vue +188 -188
  28. package/packages/components/sh-noticebar/index.vue +215 -215
  29. package/packages/components/sh-poptip/index.vue +597 -597
  30. package/packages/components/sh-progress/index.vue +276 -276
  31. package/packages/components/sh-pull-refresh/index.vue +289 -289
  32. package/packages/components/sh-result/index.vue +114 -114
  33. package/packages/components/sh-row/index.vue +66 -66
  34. package/packages/components/sh-split/components/trigger.vue +33 -33
  35. package/packages/components/sh-split/index.vue +342 -342
  36. package/packages/components/sh-table/components/importModal.vue +363 -363
  37. package/packages/components/sh-table/components/sh-column.vue +68 -68
  38. package/packages/components/sh-table/js/excel_to_json.js +313 -313
  39. package/packages/components/sh-table/js/props.js +305 -305
  40. package/packages/components/sh-table/js/tableMethods.js +167 -167
  41. package/packages/components/sh-table/js/useTable.js +636 -636
  42. package/packages/components/sh-table/table.vue +217 -217
  43. package/packages/components/sh-tabs/index.vue +426 -426
  44. package/packages/components/sh-tag/index.vue +168 -168
  45. package/packages/components/sh-toolbar/index.vue +182 -182
  46. package/packages/components/sh-tree/components/table-tree.vue +289 -289
  47. package/packages/components/sh-tree/mixin/treeProps.js +122 -122
  48. package/packages/components/sh-upload/index.vue +535 -535
  49. package/packages/components/sh-water-fall/index.vue +80 -80
  50. package/packages/components/sh-water-mark/index.vue +96 -96
  51. package/packages/css/index.js +4 -4
  52. package/packages/directive/index.js +19 -19
  53. package/packages/directive/module/click-out.js +14 -14
  54. package/packages/directive/module/draggable.js +42 -42
  55. package/packages/directive/module/line-clamp.js +22 -22
  56. package/packages/directive/module/prevent-click.js +18 -18
  57. package/packages/directive/module/resize.js +14 -14
  58. package/packages/directive/module/ripple.js +166 -166
  59. package/packages/index.js +39 -39
  60. package/packages/mixin/index.js +86 -86
  61. package/packages/other/sh-cron-modal/components/cron-content.vue +294 -294
  62. package/packages/other/sh-cron-modal/index.vue +81 -81
  63. package/packages/other/sh-cron-modal/mixin/cron-emits.js +1 -1
  64. package/packages/other/sh-cron-modal/mixin/cron-props.js +9 -9
  65. package/packages/other/sh-cron-modal/tabs/cron-week-box.vue +126 -126
  66. package/packages/other/sh-menu/index.vue +326 -326
  67. package/packages/other/sh-menu/menu-group-content.vue +136 -136
  68. package/packages/other/sh-menu/menu-item-content.vue +71 -71
  69. package/packages/other/sh-menu-card/index.vue +250 -250
  70. package/packages/other/sh-menu-card/menu-box.vue +87 -87
  71. package/packages/other/sh-preview/components/sh-excel.vue +163 -163
  72. package/packages/other/sh-preview/js/data-hook.js +41 -41
  73. package/packages/other/sh-preview/js/data-props.js +15 -15
  74. package/packages/other/sh-system-tip/index.vue +115 -115
  75. package/packages/utils/resize.js +69 -70
  76. package/packages/utils/transfer-queue.js +12 -12
  77. package/packages/vxeTable/index.js +193 -184
  78. package/packages/vxeTable/plugins/export.js +450 -450
  79. package/packages/vxeTable/render/cell/vxe-render-img.vue +27 -27
  80. package/packages/vxeTable/render/cell/vxe-render-table.vue +51 -51
  81. package/packages/vxeTable/render/cell/vxe-render-time.vue +44 -44
  82. package/packages/vxeTable/render/cell/vxe-render-tree.vue +70 -70
  83. package/packages/vxeTable/render/filters/vxe-filter-input.vue +26 -26
  84. package/packages/vxeTable/render/filters/vxe-filter-time.vue +26 -26
  85. package/packages/vxeTable/render/globalRenders.jsx +514 -514
  86. package/packages/vxeTable/render/mixin/cell-hooks.js +198 -198
  87. package/packages/vxeTable/render/mixin/cell-props.js +23 -23
  88. package/packages/vxeTable/render/mixin/filter-hooks.js +46 -46
  89. package/tsconfig.json +25 -0
  90. package/types/component.d.ts +1 -0
  91. package/types/index.ts +0 -0
@@ -1,597 +1,597 @@
1
- <template>
2
- <div v-clickout="handleClose" class="sh-poptip" :class="classes" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave">
3
- <div ref="referenceRef" class="sh-poptip-rel" @click="handleClick" @mousedown="handleFocus(false)" @mouseup="handleBlur(false)"><slot></slot></div>
4
- <teleport to="body" :disabled="!transfer">
5
- <transition name="fade">
6
- <div v-show="visible" ref="popperRef" :class="popperClasses" :style="styles" @click="handleTransferClick" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave">
7
- <div class="sh-poptip-content">
8
- <div class="sh-poptip-arrow"></div>
9
- <div v-if="confirm" class="sh-poptip-inner">
10
- <div class="sh-poptip-body">
11
- <sh-icon type="ios-help-circle"></sh-icon>
12
- <div class="sh-poptip-body-message">
13
- <slot name="title">{{ title }}</slot>
14
- </div>
15
- </div>
16
- <div class="sh-poptip-footer">
17
- <vxe-button type="text" size="small" @click="cancel">{{ cancelText }}</vxe-button>
18
- <vxe-button status="primary" size="small" @click="ok">{{ comfirmText }}</vxe-button>
19
- </div>
20
- </div>
21
- <div v-else class="sh-poptip-inner">
22
- <div v-if="showTitle" ref="title" class="sh-poptip-title" :style="titleStyle">
23
- <slot name="title">
24
- <div class="sh-poptip-title-inner">{{ title }}</div>
25
- </slot>
26
- </div>
27
- <div class="sh-poptip-body" :style="contentStyle">
28
- <div :class="contentClasses">
29
- <slot name="content">
30
- <div class="sh-poptip-body-content-inner">{{ content }}</div>
31
- </slot>
32
- </div>
33
- </div>
34
- </div>
35
- </div>
36
- </div>
37
- </transition>
38
- </teleport>
39
- </div>
40
- </template>
41
-
42
- <script>
43
- import { defineComponent, computed, onMounted, onUpdated, onBeforeUnmount, getCurrentInstance, ref, watch, nextTick } from 'vue'
44
- import { transferIndex, transferIncrease } from '../../utils/transfer-queue'
45
- import Popper from 'popper.js'
46
- const handleGetIndex = () => {
47
- transferIncrease()
48
- return transferIndex
49
- }
50
- export default defineComponent({
51
- name: 'ShPoptip',
52
- props: {
53
- modelValue: {
54
- type: Boolean,
55
- default: false
56
- },
57
- trigger: {
58
- type: String,
59
- default: 'click' // 'click', 'focus', 'hover'
60
- },
61
- placement: {
62
- type: String,
63
- default: 'top' // 'top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'
64
- },
65
- title: {
66
- type: [String, Number]
67
- },
68
- content: {
69
- type: [String, Number],
70
- default: ''
71
- },
72
- width: {
73
- type: [String, Number]
74
- },
75
- height: {
76
- type: [String, Number]
77
- },
78
- confirm: {
79
- type: Boolean,
80
- default: false
81
- },
82
- comfirmText: {
83
- type: String,
84
- default: '确认'
85
- },
86
- cancelText: {
87
- type: String,
88
- default: '取消'
89
- },
90
- transfer: {
91
- type: Boolean,
92
- default: false
93
- },
94
- popperClass: {
95
- type: String
96
- },
97
- wordWrap: {
98
- type: Boolean,
99
- default: false
100
- },
101
- padding: {
102
- type: String
103
- },
104
- disabled: {
105
- type: Boolean,
106
- default: false
107
- },
108
- capture: {
109
- type: Boolean
110
- },
111
- transferClassName: {
112
- type: String
113
- },
114
- eventsEnabled: {
115
- type: Boolean,
116
- default: false
117
- },
118
- boundariesPadding: {
119
- type: Number,
120
- default: 5
121
- },
122
- reference: Object,
123
- popper: Object,
124
- offset: {
125
- type: Number,
126
- default: 0
127
- },
128
- transition: String,
129
- options: {
130
- type: Object,
131
- default() {
132
- return {
133
- modifiers: {
134
- computeStyle: {
135
- gpuAcceleration: false
136
- },
137
- preventOverflow: {
138
- boundariesElement: 'window'
139
- }
140
- }
141
- }
142
- }
143
- }
144
- },
145
- emits: ['update:modelValue', 'popper-show', 'popper-hide', 'created', 'confirm', 'cancel'],
146
- setup(props, context) {
147
- const { emit, slots } = context
148
- const popperRef = ref()
149
- const referenceRef = ref()
150
- const visible = ref(props.modelValue)
151
- const showTitle = ref(true)
152
- const isInput = ref(false)
153
- const disableCloseUnderTransfer = ref(false)
154
- const tIndex = ref(handleGetIndex())
155
- let enterTimer = null
156
- let popperJS = null
157
-
158
- const classes = computed(() => {
159
- return {
160
- 'sh-poptip-confirm': props.confirm
161
- }
162
- })
163
- const popperClasses = computed(() => {
164
- return {
165
- 'sh-poptip-popper': true,
166
- 'sh-poptip-confirm': props.transfer && props.confirm,
167
- 'sh-poptip-transfer': props.transfer,
168
- [`${props.popperClass}`]: props.popperClass,
169
- [`${props.transferClassName}`]: props.transferClassName
170
- }
171
- })
172
- const styles = computed(() => {
173
- let style = {
174
- width: `${props.width}px`
175
- }
176
- if (props.transfer) style['z-index'] = 1060 + tIndex.value
177
- return style
178
- })
179
- const contentClasses = computed(() => {
180
- return {
181
- 'sh-poptip-body-content': true,
182
- 'sh-poptip-body-content-word-wrap': props.wordWrap
183
- }
184
- })
185
- const titleStyle = computed(() => {
186
- return {
187
- padding: props.padding
188
- }
189
- })
190
- const contentStyle = computed(() => {
191
- return {
192
- height: `${props.height}px`,
193
- padding: props.padding
194
- }
195
- })
196
-
197
- const handleClick = () => {
198
- if (props.disabled) return
199
- if (props.confirm) {
200
- visible.value = !visible.value
201
- return true
202
- }
203
- if (props.trigger !== 'click') {
204
- return false
205
- }
206
- visible.value = !visible.value
207
- }
208
- const handleTransferClick = () => {
209
- if (props.transfer) disableCloseUnderTransfer.value = true
210
- }
211
- const handleClose = () => {
212
- if (disableCloseUnderTransfer.value) {
213
- disableCloseUnderTransfer.value = false
214
- return false
215
- }
216
- if (props.confirm) {
217
- visible.value = false
218
- return true
219
- }
220
- if (props.trigger !== 'click') {
221
- return false
222
- }
223
- visible.value = false
224
- }
225
- const handleFocus = (fromInput = true) => {
226
- if (props.disabled) return
227
- if (props.trigger !== 'focus' || props.confirm || (isInput.value && !fromInput)) {
228
- return false
229
- }
230
- visible.value = true
231
- }
232
- const handleBlur = (fromInput = true) => {
233
- if (props.trigger !== 'focus' || props.confirm || (isInput.value && !fromInput)) {
234
- return false
235
- }
236
- visible.value = false
237
- }
238
- const handleMouseenter = () => {
239
- if (props.disabled) return
240
- if (props.trigger !== 'hover' || props.confirm) {
241
- return false
242
- }
243
- if (enterTimer) clearTimeout(enterTimer)
244
- enterTimer = setTimeout(() => {
245
- visible.value = true
246
- }, 100)
247
- }
248
- const handleMouseleave = () => {
249
- if (props.trigger !== 'hover' || props.confirm) {
250
- return false
251
- }
252
- if (enterTimer) {
253
- clearTimeout(enterTimer)
254
- enterTimer = setTimeout(() => {
255
- visible.value = false
256
- }, 100)
257
- }
258
- }
259
- const cancel = () => {
260
- visible.value = false
261
- emit('cancel')
262
- }
263
- const ok = () => {
264
- visible.value = false
265
- emit('confirm')
266
- }
267
- const getInputChildren = () => {
268
- const $input = referenceRef.value.querySelectorAll('input')
269
- const $textarea = referenceRef.value.querySelectorAll('textarea')
270
- let $children = null
271
- if ($input.length) {
272
- $children = $input[0]
273
- } else if ($textarea.length) {
274
- $children = $textarea[0]
275
- }
276
- return $children
277
- }
278
- const handleIndexIncrease = () => {
279
- tIndex.value = handleGetIndex()
280
- }
281
- const createPopper = () => {
282
- if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(props.placement)) {
283
- return
284
- }
285
- const options = props.options
286
- const popper = props.popper || popperRef.value
287
- const reference = referenceRef.value
288
- if (!popper || !reference) return
289
- if (popperJS && popperJS.hasOwnProperty('destroy')) {
290
- popperJS.destroy()
291
- }
292
- options.eventsEnabled = props.eventsEnabled
293
- options.placement = props.placement
294
- if (!options.modifiers.offset) {
295
- options.modifiers.offset = {}
296
- }
297
- options.modifiers.offset.offset = props.offset
298
- options.onCreate = () => {
299
- nextTick(updatePopper)
300
- emit('created')
301
- }
302
- popperJS = new Popper(reference, popper, options)
303
- }
304
- const updatePopper = () => {
305
- popperJS ? popperJS.update() : createPopper()
306
- }
307
- watch(
308
- () => props.modelValue,
309
- val => {
310
- visible.value = val
311
- emit('update:modelValue', val)
312
- }
313
- )
314
- watch(
315
- () => visible.value,
316
- val => {
317
- if (val) {
318
- if (handleIndexIncrease) handleIndexIncrease() // just use for Poptip
319
- updatePopper()
320
- emit('popper-show')
321
- } else {
322
- emit('popper-hide')
323
- }
324
- emit('update:modelValue', val)
325
- }
326
- )
327
- onMounted(() => {
328
- if (!props.confirm) {
329
- showTitle.value = slots.title !== undefined || props.title
330
- }
331
- if (props.trigger === 'focus') {
332
- nextTick(() => {
333
- const $children = getInputChildren()
334
- if ($children) {
335
- isInput.value = true
336
- $children.addEventListener('focus', handleFocus, false)
337
- $children.addEventListener('blur', handleBlur, false)
338
- }
339
- })
340
- }
341
- })
342
- onUpdated(() => {
343
- nextTick(() => updatePopper())
344
- })
345
- onBeforeUnmount(() => {
346
- if (popperJS) {
347
- popperJS.destroy()
348
- }
349
- const $children = getInputChildren()
350
- if ($children) {
351
- $children.removeEventListener('focus', handleFocus, false)
352
- $children.removeEventListener('blur', handleBlur, false)
353
- }
354
- })
355
-
356
- return {
357
- referenceRef,
358
- popperRef,
359
- classes,
360
- visible,
361
- popperClasses,
362
- styles,
363
- titleStyle,
364
- contentStyle,
365
- contentClasses,
366
- showTitle,
367
- handleClose,
368
- handleMouseenter,
369
- handleMouseleave,
370
- handleClick,
371
- handleFocus,
372
- handleBlur,
373
- handleTransferClick,
374
- cancel,
375
- ok
376
- }
377
- }
378
- })
379
- </script>
380
-
381
- <style scoped lang="scss">
382
- $poptip-arrow: sh-poptip-arrow;
383
- $poptip-arrow-width: 7px;
384
- $poptip-arrow-outer-width: ($poptip-arrow-width + 1);
385
- $poptip-distance: $poptip-arrow-width - 1 + 4;
386
- $poptip-arrow-color: hsla(0, 0%, 85%, 0.5);
387
- @mixin popper($arrow, $arrow-width, $arrow-distance, $bg) {
388
- display: block;
389
- visibility: visible;
390
- position: absolute;
391
- z-index: 2000;
392
- &[x-placement^='top'] {
393
- padding: $arrow-width 0 $arrow-distance 0;
394
- }
395
- &[x-placement^='right'] {
396
- padding: 0 $arrow-width 0 $arrow-distance;
397
- }
398
- &[x-placement^='bottom'] {
399
- padding: $arrow-distance 0 $arrow-width 0;
400
- }
401
- &[x-placement^='left'] {
402
- padding: 0 $arrow-distance 0 $arrow-width;
403
- }
404
- &[x-placement^='top'] .#{$arrow} {
405
- bottom: $arrow-distance - $arrow-width;
406
- border-width: $arrow-width $arrow-width 0;
407
- border-top-color: $bg;
408
- }
409
- &[x-placement='top'] .#{$arrow} {
410
- left: 50%;
411
- margin-left: -$arrow-width;
412
- }
413
- &[x-placement='top-start'] .#{$arrow} {
414
- left: 16px;
415
- }
416
- &[x-placement='top-end'] .#{$arrow} {
417
- right: 16px;
418
- }
419
- &[x-placement^='right'] .#{$arrow} {
420
- left: $arrow-distance - $arrow-width;
421
- border-width: $arrow-width $arrow-width $arrow-width 0;
422
- border-right-color: $bg;
423
- }
424
- &[x-placement='right'] .#{$arrow} {
425
- top: 50%;
426
- margin-top: -$arrow-width;
427
- }
428
- &[x-placement='right-start'] .#{$arrow} {
429
- top: 8px;
430
- }
431
- &[x-placement='right-end'] .#{$arrow} {
432
- bottom: 8px;
433
- }
434
- &[x-placement^='left'] .#{$arrow} {
435
- right: $arrow-distance - $arrow-width;
436
- border-width: $arrow-width 0 $arrow-width $arrow-width;
437
- border-left-color: $bg;
438
- }
439
- &[x-placement='left'] .#{$arrow} {
440
- top: 50%;
441
- margin-top: -$arrow-width;
442
- }
443
- &[x-placement='left-start'] .#{$arrow} {
444
- top: 8px;
445
- }
446
- &[x-placement='left-end'] .#{$arrow} {
447
- bottom: 8px;
448
- }
449
- &[x-placement^='bottom'] .#{$arrow} {
450
- top: $arrow-distance - $arrow-width;
451
- border-width: 0 $arrow-width $arrow-width;
452
- border-bottom-color: $bg;
453
- }
454
- &[x-placement='bottom'] .#{$arrow} {
455
- left: 50%;
456
- margin-left: -$arrow-width;
457
- }
458
- &[x-placement='bottom-start'] .#{$arrow} {
459
- left: 16px;
460
- }
461
- &[x-placement='bottom-end'] .#{$arrow} {
462
- right: 16px;
463
- }
464
- }
465
- .sh-poptip {
466
- display: inline-block;
467
- &-rel {
468
- display: inline-block;
469
- position: relative;
470
- width: 100%;
471
- }
472
- &-title {
473
- margin: 0;
474
- padding: 8px 16px;
475
- position: relative;
476
- &:after {
477
- content: '';
478
- display: block;
479
- height: 1px;
480
- position: absolute;
481
- left: 8px;
482
- right: 8px;
483
- bottom: 0;
484
- background-color: var(--vxe-table-border-color);
485
- }
486
- &-inner {
487
- color: var(--vxe-font-color);
488
- font-size: var(--vxe-font-size);
489
- font-weight: 500;
490
- }
491
- }
492
- &-body {
493
- padding: 8px 16px;
494
- overflow: auto;
495
- &-content {
496
- &-word-wrap {
497
- white-space: pre-wrap;
498
- text-align: justify;
499
- }
500
- &-inner {
501
- color: var(--vxe-font-color);
502
- }
503
- }
504
- }
505
- &-inner {
506
- width: 100%;
507
- background-color: var(--vxe-table-body-background-color);
508
- background-clip: padding-box;
509
- border-radius: var(--vxe-border-radius);
510
- box-shadow: var(--box-shadow);
511
- white-space: nowrap;
512
- }
513
- &-popper {
514
- min-width: 150px;
515
- font-size: var(--vxe-font-size);
516
- z-index: 100;
517
- @include popper($poptip-arrow, $poptip-arrow-width, $poptip-distance, $poptip-arrow-color);
518
- &[x-placement^='top'] .sh-poptip-arrow:after {
519
- content: ' ';
520
- bottom: 1px;
521
- margin-left: -$poptip-arrow-width;
522
- border-bottom-width: 0;
523
- border-top-width: $poptip-arrow-width;
524
- border-top-color: #fff;
525
- }
526
- &[x-placement^='right'] .sh-poptip-arrow:after {
527
- content: ' ';
528
- left: 1px;
529
- bottom: -$poptip-arrow-width;
530
- border-left-width: 0;
531
- border-right-width: $poptip-arrow-width;
532
- border-right-color: #fff;
533
- }
534
- &[x-placement^='bottom'] .sh-poptip-arrow:after {
535
- content: ' ';
536
- top: 1px;
537
- margin-left: -$poptip-arrow-width;
538
- border-top-width: 0;
539
- border-bottom-width: $poptip-arrow-width;
540
- border-bottom-color: #fff;
541
- }
542
- &[x-placement^='left'] .sh-poptip-arrow:after {
543
- content: ' ';
544
- right: 1px;
545
- border-right-width: 0;
546
- border-left-width: $poptip-arrow-width;
547
- border-left-color: #fff;
548
- bottom: -$poptip-arrow-width;
549
- }
550
- }
551
- &-arrow {
552
- display: block;
553
- width: 0;
554
- height: 0;
555
- position: absolute;
556
- border-color: transparent;
557
- border-style: solid;
558
- border-width: 8px;
559
- &:after {
560
- display: block;
561
- width: 0;
562
- height: 0;
563
- position: absolute;
564
- border-color: transparent;
565
- border-style: solid;
566
- content: '';
567
- border-width: 7px;
568
- }
569
- }
570
- &-confirm &-popper {
571
- max-width: 300px;
572
- }
573
- &-confirm &-inner {
574
- white-space: normal;
575
- }
576
- &-confirm &-body {
577
- padding: 12px 12px 8px;
578
- .sh-icon {
579
- font-size: 16px;
580
- color: var(--vxe-warning-color);
581
- line-height: 20px;
582
- position: absolute;
583
- }
584
-
585
- &-message {
586
- padding-left: 20px;
587
- }
588
- }
589
- &-confirm &-footer {
590
- text-align: right;
591
- padding: 8px 12px 12px;
592
- button {
593
- margin-left: 4px;
594
- }
595
- }
596
- }
597
- </style>
1
+ <template>
2
+ <div v-clickout="handleClose" class="sh-poptip" :class="classes" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave">
3
+ <div ref="referenceRef" class="sh-poptip-rel" @click="handleClick" @mousedown="handleFocus(false)" @mouseup="handleBlur(false)"><slot></slot></div>
4
+ <teleport to="body" :disabled="!transfer">
5
+ <transition name="fade">
6
+ <div v-show="visible" ref="popperRef" :class="popperClasses" :style="styles" @click="handleTransferClick" @mouseenter="handleMouseenter" @mouseleave="handleMouseleave">
7
+ <div class="sh-poptip-content">
8
+ <div class="sh-poptip-arrow"></div>
9
+ <div v-if="confirm" class="sh-poptip-inner">
10
+ <div class="sh-poptip-body">
11
+ <sh-icon type="ios-help-circle"></sh-icon>
12
+ <div class="sh-poptip-body-message">
13
+ <slot name="title">{{ title }}</slot>
14
+ </div>
15
+ </div>
16
+ <div class="sh-poptip-footer">
17
+ <vxe-button type="text" size="small" @click="cancel">{{ cancelText }}</vxe-button>
18
+ <vxe-button status="primary" size="small" @click="ok">{{ comfirmText }}</vxe-button>
19
+ </div>
20
+ </div>
21
+ <div v-else class="sh-poptip-inner">
22
+ <div v-if="showTitle" ref="title" class="sh-poptip-title" :style="titleStyle">
23
+ <slot name="title">
24
+ <div class="sh-poptip-title-inner">{{ title }}</div>
25
+ </slot>
26
+ </div>
27
+ <div class="sh-poptip-body" :style="contentStyle">
28
+ <div :class="contentClasses">
29
+ <slot name="content">
30
+ <div class="sh-poptip-body-content-inner">{{ content }}</div>
31
+ </slot>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </transition>
38
+ </teleport>
39
+ </div>
40
+ </template>
41
+
42
+ <script>
43
+ import { defineComponent, computed, onMounted, onUpdated, onBeforeUnmount, getCurrentInstance, ref, watch, nextTick } from 'vue'
44
+ import { transferIndex, transferIncrease } from '../../utils/transfer-queue'
45
+ import Popper from 'popper.js'
46
+ const handleGetIndex = () => {
47
+ transferIncrease()
48
+ return transferIndex
49
+ }
50
+ export default defineComponent({
51
+ name: 'ShPoptip',
52
+ props: {
53
+ modelValue: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ trigger: {
58
+ type: String,
59
+ default: 'click' // 'click', 'focus', 'hover'
60
+ },
61
+ placement: {
62
+ type: String,
63
+ default: 'top' // 'top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'
64
+ },
65
+ title: {
66
+ type: [String, Number]
67
+ },
68
+ content: {
69
+ type: [String, Number],
70
+ default: ''
71
+ },
72
+ width: {
73
+ type: [String, Number]
74
+ },
75
+ height: {
76
+ type: [String, Number]
77
+ },
78
+ confirm: {
79
+ type: Boolean,
80
+ default: false
81
+ },
82
+ comfirmText: {
83
+ type: String,
84
+ default: '确认'
85
+ },
86
+ cancelText: {
87
+ type: String,
88
+ default: '取消'
89
+ },
90
+ transfer: {
91
+ type: Boolean,
92
+ default: false
93
+ },
94
+ popperClass: {
95
+ type: String
96
+ },
97
+ wordWrap: {
98
+ type: Boolean,
99
+ default: false
100
+ },
101
+ padding: {
102
+ type: String
103
+ },
104
+ disabled: {
105
+ type: Boolean,
106
+ default: false
107
+ },
108
+ capture: {
109
+ type: Boolean
110
+ },
111
+ transferClassName: {
112
+ type: String
113
+ },
114
+ eventsEnabled: {
115
+ type: Boolean,
116
+ default: false
117
+ },
118
+ boundariesPadding: {
119
+ type: Number,
120
+ default: 5
121
+ },
122
+ reference: Object,
123
+ popper: Object,
124
+ offset: {
125
+ type: Number,
126
+ default: 0
127
+ },
128
+ transition: String,
129
+ options: {
130
+ type: Object,
131
+ default() {
132
+ return {
133
+ modifiers: {
134
+ computeStyle: {
135
+ gpuAcceleration: false
136
+ },
137
+ preventOverflow: {
138
+ boundariesElement: 'window'
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ },
145
+ emits: ['update:modelValue', 'popper-show', 'popper-hide', 'created', 'confirm', 'cancel'],
146
+ setup(props, context) {
147
+ const { emit, slots } = context
148
+ const popperRef = ref()
149
+ const referenceRef = ref()
150
+ const visible = ref(props.modelValue)
151
+ const showTitle = ref(true)
152
+ const isInput = ref(false)
153
+ const disableCloseUnderTransfer = ref(false)
154
+ const tIndex = ref(handleGetIndex())
155
+ let enterTimer = null
156
+ let popperJS = null
157
+
158
+ const classes = computed(() => {
159
+ return {
160
+ 'sh-poptip-confirm': props.confirm
161
+ }
162
+ })
163
+ const popperClasses = computed(() => {
164
+ return {
165
+ 'sh-poptip-popper': true,
166
+ 'sh-poptip-confirm': props.transfer && props.confirm,
167
+ 'sh-poptip-transfer': props.transfer,
168
+ [`${props.popperClass}`]: props.popperClass,
169
+ [`${props.transferClassName}`]: props.transferClassName
170
+ }
171
+ })
172
+ const styles = computed(() => {
173
+ let style = {
174
+ width: `${props.width}px`
175
+ }
176
+ if (props.transfer) style['z-index'] = 1060 + tIndex.value
177
+ return style
178
+ })
179
+ const contentClasses = computed(() => {
180
+ return {
181
+ 'sh-poptip-body-content': true,
182
+ 'sh-poptip-body-content-word-wrap': props.wordWrap
183
+ }
184
+ })
185
+ const titleStyle = computed(() => {
186
+ return {
187
+ padding: props.padding
188
+ }
189
+ })
190
+ const contentStyle = computed(() => {
191
+ return {
192
+ height: `${props.height}px`,
193
+ padding: props.padding
194
+ }
195
+ })
196
+
197
+ const handleClick = () => {
198
+ if (props.disabled) return
199
+ if (props.confirm) {
200
+ visible.value = !visible.value
201
+ return true
202
+ }
203
+ if (props.trigger !== 'click') {
204
+ return false
205
+ }
206
+ visible.value = !visible.value
207
+ }
208
+ const handleTransferClick = () => {
209
+ if (props.transfer) disableCloseUnderTransfer.value = true
210
+ }
211
+ const handleClose = () => {
212
+ if (disableCloseUnderTransfer.value) {
213
+ disableCloseUnderTransfer.value = false
214
+ return false
215
+ }
216
+ if (props.confirm) {
217
+ visible.value = false
218
+ return true
219
+ }
220
+ if (props.trigger !== 'click') {
221
+ return false
222
+ }
223
+ visible.value = false
224
+ }
225
+ const handleFocus = (fromInput = true) => {
226
+ if (props.disabled) return
227
+ if (props.trigger !== 'focus' || props.confirm || (isInput.value && !fromInput)) {
228
+ return false
229
+ }
230
+ visible.value = true
231
+ }
232
+ const handleBlur = (fromInput = true) => {
233
+ if (props.trigger !== 'focus' || props.confirm || (isInput.value && !fromInput)) {
234
+ return false
235
+ }
236
+ visible.value = false
237
+ }
238
+ const handleMouseenter = () => {
239
+ if (props.disabled) return
240
+ if (props.trigger !== 'hover' || props.confirm) {
241
+ return false
242
+ }
243
+ if (enterTimer) clearTimeout(enterTimer)
244
+ enterTimer = setTimeout(() => {
245
+ visible.value = true
246
+ }, 100)
247
+ }
248
+ const handleMouseleave = () => {
249
+ if (props.trigger !== 'hover' || props.confirm) {
250
+ return false
251
+ }
252
+ if (enterTimer) {
253
+ clearTimeout(enterTimer)
254
+ enterTimer = setTimeout(() => {
255
+ visible.value = false
256
+ }, 100)
257
+ }
258
+ }
259
+ const cancel = () => {
260
+ visible.value = false
261
+ emit('cancel')
262
+ }
263
+ const ok = () => {
264
+ visible.value = false
265
+ emit('confirm')
266
+ }
267
+ const getInputChildren = () => {
268
+ const $input = referenceRef.value.querySelectorAll('input')
269
+ const $textarea = referenceRef.value.querySelectorAll('textarea')
270
+ let $children = null
271
+ if ($input.length) {
272
+ $children = $input[0]
273
+ } else if ($textarea.length) {
274
+ $children = $textarea[0]
275
+ }
276
+ return $children
277
+ }
278
+ const handleIndexIncrease = () => {
279
+ tIndex.value = handleGetIndex()
280
+ }
281
+ const createPopper = () => {
282
+ if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(props.placement)) {
283
+ return
284
+ }
285
+ const options = props.options
286
+ const popper = props.popper || popperRef.value
287
+ const reference = referenceRef.value
288
+ if (!popper || !reference) return
289
+ if (popperJS && popperJS.hasOwnProperty('destroy')) {
290
+ popperJS.destroy()
291
+ }
292
+ options.eventsEnabled = props.eventsEnabled
293
+ options.placement = props.placement
294
+ if (!options.modifiers.offset) {
295
+ options.modifiers.offset = {}
296
+ }
297
+ options.modifiers.offset.offset = props.offset
298
+ options.onCreate = () => {
299
+ nextTick(updatePopper)
300
+ emit('created')
301
+ }
302
+ popperJS = new Popper(reference, popper, options)
303
+ }
304
+ const updatePopper = () => {
305
+ popperJS ? popperJS.update() : createPopper()
306
+ }
307
+ watch(
308
+ () => props.modelValue,
309
+ val => {
310
+ visible.value = val
311
+ emit('update:modelValue', val)
312
+ }
313
+ )
314
+ watch(
315
+ () => visible.value,
316
+ val => {
317
+ if (val) {
318
+ if (handleIndexIncrease) handleIndexIncrease() // just use for Poptip
319
+ updatePopper()
320
+ emit('popper-show')
321
+ } else {
322
+ emit('popper-hide')
323
+ }
324
+ emit('update:modelValue', val)
325
+ }
326
+ )
327
+ onMounted(() => {
328
+ if (!props.confirm) {
329
+ showTitle.value = slots.title !== undefined || props.title
330
+ }
331
+ if (props.trigger === 'focus') {
332
+ nextTick(() => {
333
+ const $children = getInputChildren()
334
+ if ($children) {
335
+ isInput.value = true
336
+ $children.addEventListener('focus', handleFocus, false)
337
+ $children.addEventListener('blur', handleBlur, false)
338
+ }
339
+ })
340
+ }
341
+ })
342
+ onUpdated(() => {
343
+ nextTick(() => updatePopper())
344
+ })
345
+ onBeforeUnmount(() => {
346
+ if (popperJS) {
347
+ popperJS.destroy()
348
+ }
349
+ const $children = getInputChildren()
350
+ if ($children) {
351
+ $children.removeEventListener('focus', handleFocus, false)
352
+ $children.removeEventListener('blur', handleBlur, false)
353
+ }
354
+ })
355
+
356
+ return {
357
+ referenceRef,
358
+ popperRef,
359
+ classes,
360
+ visible,
361
+ popperClasses,
362
+ styles,
363
+ titleStyle,
364
+ contentStyle,
365
+ contentClasses,
366
+ showTitle,
367
+ handleClose,
368
+ handleMouseenter,
369
+ handleMouseleave,
370
+ handleClick,
371
+ handleFocus,
372
+ handleBlur,
373
+ handleTransferClick,
374
+ cancel,
375
+ ok
376
+ }
377
+ }
378
+ })
379
+ </script>
380
+
381
+ <style scoped lang="scss">
382
+ $poptip-arrow: sh-poptip-arrow;
383
+ $poptip-arrow-width: 7px;
384
+ $poptip-arrow-outer-width: ($poptip-arrow-width + 1);
385
+ $poptip-distance: $poptip-arrow-width - 1 + 4;
386
+ $poptip-arrow-color: hsla(0, 0%, 85%, 0.5);
387
+ @mixin popper($arrow, $arrow-width, $arrow-distance, $bg) {
388
+ display: block;
389
+ visibility: visible;
390
+ position: absolute;
391
+ z-index: 2000;
392
+ &[x-placement^='top'] {
393
+ padding: $arrow-width 0 $arrow-distance 0;
394
+ }
395
+ &[x-placement^='right'] {
396
+ padding: 0 $arrow-width 0 $arrow-distance;
397
+ }
398
+ &[x-placement^='bottom'] {
399
+ padding: $arrow-distance 0 $arrow-width 0;
400
+ }
401
+ &[x-placement^='left'] {
402
+ padding: 0 $arrow-distance 0 $arrow-width;
403
+ }
404
+ &[x-placement^='top'] .#{$arrow} {
405
+ bottom: $arrow-distance - $arrow-width;
406
+ border-width: $arrow-width $arrow-width 0;
407
+ border-top-color: $bg;
408
+ }
409
+ &[x-placement='top'] .#{$arrow} {
410
+ left: 50%;
411
+ margin-left: -$arrow-width;
412
+ }
413
+ &[x-placement='top-start'] .#{$arrow} {
414
+ left: 16px;
415
+ }
416
+ &[x-placement='top-end'] .#{$arrow} {
417
+ right: 16px;
418
+ }
419
+ &[x-placement^='right'] .#{$arrow} {
420
+ left: $arrow-distance - $arrow-width;
421
+ border-width: $arrow-width $arrow-width $arrow-width 0;
422
+ border-right-color: $bg;
423
+ }
424
+ &[x-placement='right'] .#{$arrow} {
425
+ top: 50%;
426
+ margin-top: -$arrow-width;
427
+ }
428
+ &[x-placement='right-start'] .#{$arrow} {
429
+ top: 8px;
430
+ }
431
+ &[x-placement='right-end'] .#{$arrow} {
432
+ bottom: 8px;
433
+ }
434
+ &[x-placement^='left'] .#{$arrow} {
435
+ right: $arrow-distance - $arrow-width;
436
+ border-width: $arrow-width 0 $arrow-width $arrow-width;
437
+ border-left-color: $bg;
438
+ }
439
+ &[x-placement='left'] .#{$arrow} {
440
+ top: 50%;
441
+ margin-top: -$arrow-width;
442
+ }
443
+ &[x-placement='left-start'] .#{$arrow} {
444
+ top: 8px;
445
+ }
446
+ &[x-placement='left-end'] .#{$arrow} {
447
+ bottom: 8px;
448
+ }
449
+ &[x-placement^='bottom'] .#{$arrow} {
450
+ top: $arrow-distance - $arrow-width;
451
+ border-width: 0 $arrow-width $arrow-width;
452
+ border-bottom-color: $bg;
453
+ }
454
+ &[x-placement='bottom'] .#{$arrow} {
455
+ left: 50%;
456
+ margin-left: -$arrow-width;
457
+ }
458
+ &[x-placement='bottom-start'] .#{$arrow} {
459
+ left: 16px;
460
+ }
461
+ &[x-placement='bottom-end'] .#{$arrow} {
462
+ right: 16px;
463
+ }
464
+ }
465
+ .sh-poptip {
466
+ display: inline-block;
467
+ &-rel {
468
+ display: inline-block;
469
+ position: relative;
470
+ width: 100%;
471
+ }
472
+ &-title {
473
+ margin: 0;
474
+ padding: 8px 16px;
475
+ position: relative;
476
+ &:after {
477
+ content: '';
478
+ display: block;
479
+ height: 1px;
480
+ position: absolute;
481
+ left: 8px;
482
+ right: 8px;
483
+ bottom: 0;
484
+ background-color: var(--vxe-table-border-color);
485
+ }
486
+ &-inner {
487
+ color: var(--vxe-font-color);
488
+ font-size: var(--vxe-font-size);
489
+ font-weight: 500;
490
+ }
491
+ }
492
+ &-body {
493
+ padding: 8px 16px;
494
+ overflow: auto;
495
+ &-content {
496
+ &-word-wrap {
497
+ white-space: pre-wrap;
498
+ text-align: justify;
499
+ }
500
+ &-inner {
501
+ color: var(--vxe-font-color);
502
+ }
503
+ }
504
+ }
505
+ &-inner {
506
+ width: 100%;
507
+ background-color: var(--vxe-table-body-background-color);
508
+ background-clip: padding-box;
509
+ border-radius: var(--vxe-border-radius);
510
+ box-shadow: var(--box-shadow);
511
+ white-space: nowrap;
512
+ }
513
+ &-popper {
514
+ min-width: 150px;
515
+ font-size: var(--vxe-font-size);
516
+ z-index: 100;
517
+ @include popper($poptip-arrow, $poptip-arrow-width, $poptip-distance, $poptip-arrow-color);
518
+ &[x-placement^='top'] .sh-poptip-arrow:after {
519
+ content: ' ';
520
+ bottom: 1px;
521
+ margin-left: -$poptip-arrow-width;
522
+ border-bottom-width: 0;
523
+ border-top-width: $poptip-arrow-width;
524
+ border-top-color: #fff;
525
+ }
526
+ &[x-placement^='right'] .sh-poptip-arrow:after {
527
+ content: ' ';
528
+ left: 1px;
529
+ bottom: -$poptip-arrow-width;
530
+ border-left-width: 0;
531
+ border-right-width: $poptip-arrow-width;
532
+ border-right-color: #fff;
533
+ }
534
+ &[x-placement^='bottom'] .sh-poptip-arrow:after {
535
+ content: ' ';
536
+ top: 1px;
537
+ margin-left: -$poptip-arrow-width;
538
+ border-top-width: 0;
539
+ border-bottom-width: $poptip-arrow-width;
540
+ border-bottom-color: #fff;
541
+ }
542
+ &[x-placement^='left'] .sh-poptip-arrow:after {
543
+ content: ' ';
544
+ right: 1px;
545
+ border-right-width: 0;
546
+ border-left-width: $poptip-arrow-width;
547
+ border-left-color: #fff;
548
+ bottom: -$poptip-arrow-width;
549
+ }
550
+ }
551
+ &-arrow {
552
+ display: block;
553
+ width: 0;
554
+ height: 0;
555
+ position: absolute;
556
+ border-color: transparent;
557
+ border-style: solid;
558
+ border-width: 8px;
559
+ &:after {
560
+ display: block;
561
+ width: 0;
562
+ height: 0;
563
+ position: absolute;
564
+ border-color: transparent;
565
+ border-style: solid;
566
+ content: '';
567
+ border-width: 7px;
568
+ }
569
+ }
570
+ &-confirm &-popper {
571
+ max-width: 300px;
572
+ }
573
+ &-confirm &-inner {
574
+ white-space: normal;
575
+ }
576
+ &-confirm &-body {
577
+ padding: 12px 12px 8px;
578
+ .sh-icon {
579
+ font-size: 16px;
580
+ color: var(--vxe-warning-color);
581
+ line-height: 20px;
582
+ position: absolute;
583
+ }
584
+
585
+ &-message {
586
+ padding-left: 20px;
587
+ }
588
+ }
589
+ &-confirm &-footer {
590
+ text-align: right;
591
+ padding: 8px 12px 12px;
592
+ button {
593
+ margin-left: 4px;
594
+ }
595
+ }
596
+ }
597
+ </style>