wave-ui 2.26.0 → 2.27.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.
@@ -15,7 +15,7 @@
15
15
  th.w-table__header(
16
16
  v-for="(header, i) in headers"
17
17
  :key="i"
18
- @click="header.sortable !== false && sortTable(header)"
18
+ @click="!colResizing.dragging && header.sortable !== false && sortTable(header)"
19
19
  :class="headerClasses(header)")
20
20
  w-icon.w-table__header-sort(
21
21
  v-if="header.sortable !== false && header.align === 'right'"
@@ -122,6 +122,9 @@
122
122
 
123
123
  import { consoleError } from '../utils/console'
124
124
 
125
+ // When column resizing is on, this is the minimum cell width that we can resize to.
126
+ const minColumnWidth = 15
127
+
125
128
  export default {
126
129
  name: 'w-table',
127
130
  props: {
@@ -404,15 +407,17 @@ export default {
404
407
  columnEl.style.width = colWidth + deltaX + 'px'
405
408
  nextColumnEl.style.width = nextColWidth - deltaX + 'px'
406
409
 
407
- // 2. Check if we went too far (the width applyed is different than the browser-computed one).
408
- const minWidthReached = deltaX < 0 && columnEl.offsetWidth > newColWidth
410
+ // 2. Check if we went too far (the width applied is different than the browser-computed one).
411
+ const minWidthReached = (deltaX < 0 && columnEl.offsetWidth > newColWidth) ||
412
+ columnEl.offsetWidth <= minColumnWidth
409
413
  const maxWidthReached = deltaX > 0 && nextColumnEl.offsetWidth > newNextColWidth
410
414
 
411
415
  // 3. If we went too far, correct the value of both cells widths.
412
416
  // Make sure we don't shrink enough to push other left cells.
413
417
  if (minWidthReached) {
414
- columnEl.style.width = columnEl.offsetWidth + 'px'
415
- nextColumnEl.style.width = maxWidth - columnEl.offsetWidth + 'px'
418
+ const newWidth = Math.max(columnEl.offsetWidth, minColumnWidth)
419
+ columnEl.style.width = newWidth + 'px'
420
+ nextColumnEl.style.width = maxWidth - newWidth + 'px'
416
421
  }
417
422
  // Make sure we don't grow enough to push other right cells.
418
423
  else if (maxWidthReached) {
@@ -421,19 +426,24 @@ export default {
421
426
  }
422
427
  },
423
428
 
424
- onResizerMouseUp (e) {
429
+ onResizerMouseUp () {
425
430
  // Remove listeners.
426
431
  document.removeEventListener('mousemove', this.onResizerMouseMove)
427
432
  document.removeEventListener('mouseup', this.onResizerMouseUp)
428
433
 
429
434
  // Reset all the variables (better for debugging).
430
- this.colResizing.dragging = false
431
- this.colResizing.columnIndex = null
432
- this.colResizing.startCursorX = null
433
- this.colResizing.columnEl = null
434
- this.colResizing.nextColumnEl = null
435
- this.colResizing.colWidth = null
436
- this.colResizing.nextColWidth = null
435
+ // setTimeout 0 to make sure the sorting is not applied when releasing the mouse on a header
436
+ // cell after resizing.
437
+ // (releasing the mouse on table header triggers a click event captured by the sorting feature)
438
+ setTimeout(() => {
439
+ this.colResizing.dragging = false
440
+ this.colResizing.columnIndex = null
441
+ this.colResizing.startCursorX = null
442
+ this.colResizing.columnEl = null
443
+ this.colResizing.nextColumnEl = null
444
+ this.colResizing.colWidth = null
445
+ this.colResizing.nextColWidth = null
446
+ }, 0)
437
447
  }
438
448
  },
439
449
 
@@ -490,6 +500,10 @@ $tr-border-top: 1px;
490
500
  border-collapse: collapse;
491
501
  border: none;
492
502
 
503
+ &--resizable-cols {
504
+ table-layout: fixed; // Allow resizing beyond the cell minimum text width.
505
+ }
506
+
493
507
  &--resizing {
494
508
  &, * {cursor: col-resize;}
495
509
 
@@ -498,8 +512,11 @@ $tr-border-top: 1px;
498
512
 
499
513
  // Table headers.
500
514
  // ------------------------------------------------------
501
- &__header {
502
- padding: $base-increment;
515
+ &__header {padding: $base-increment;}
516
+ &__header--resizable {
517
+ overflow: hidden;
518
+ white-space: nowrap;
519
+ text-overflow: ellipsis;
503
520
  }
504
521
 
505
522
  &--fixed-header th {
@@ -596,7 +613,15 @@ $tr-border-top: 1px;
596
613
  &__header:first-child, &__cell:first-child {padding-left: 2 * $base-increment;}
597
614
  &__header:last-child, &__cell:last-child {padding-right: 2 * $base-increment;}
598
615
 
599
- &--resizable-cols &__cell {position: relative;}
616
+ &--resizable-cols &__cell {
617
+ position: relative;
618
+
619
+ &, & * {
620
+ overflow: hidden;
621
+ // white-space: nowrap; // If you only want the content cell on a single line.
622
+ text-overflow: ellipsis;
623
+ }
624
+ }
600
625
 
601
626
  .no-data &__cell {
602
627
  background-color: rgba(255, 255, 255, 0.2);
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
2
  .w-tooltip-wrap(ref="wrapper" :class="{ 'w-tooltip-wrap--attached': !detachTo }")
3
3
  slot(name="activator" :on="eventHandlers")
4
- transition(:name="transitionName")
4
+ transition(:name="transitionName" appear)
5
5
  //- In Vue 3, a ref in a transition doesn't stay in $refs, it must be set as a function.
6
6
  .w-tooltip(
7
7
  :ref="el => tooltipEl = el"
@@ -26,6 +26,7 @@
26
26
  * and move the tooltip elsewhere in the DOM.
27
27
  */
28
28
 
29
+ import { objectifyClasses } from '../utils/index'
29
30
  import { consoleWarn } from '../utils/console'
30
31
 
31
32
  const marginFromWindowSide = 4 // Amount of px from a window side, instead of overflowing.
@@ -42,8 +43,8 @@ export default {
42
43
  shadow: { type: Boolean },
43
44
  tile: { type: Boolean },
44
45
  round: { type: Boolean },
45
- transition: { type: String, default: '' },
46
- tooltipClass: { type: String },
46
+ transition: { type: String },
47
+ tooltipClass: { type: [String, Object, Array] },
47
48
  // Position.
48
49
  detachTo: {},
49
50
  fixed: { type: Boolean },
@@ -71,6 +72,10 @@ export default {
71
72
  }),
72
73
 
73
74
  computed: {
75
+ tooltipClasses () {
76
+ return objectifyClasses(this.tooltipClass)
77
+ },
78
+
74
79
  transitionName () {
75
80
  const direction = this.position.replace(/top|bottom/, m => ({ top: 'up', bottom: 'down' }[m]))
76
81
  return this.transition || `w-tooltip-slide-fade-${direction}`
@@ -143,7 +148,7 @@ export default {
143
148
  return {
144
149
  [this.color]: !this.bgColor,
145
150
  [`${this.bgColor} ${this.bgColor}--bg`]: this.bgColor,
146
- [this.tooltipClass]: this.tooltipClass,
151
+ ...this.tooltipClasses,
147
152
  [`w-tooltip--${this.position}`]: true,
148
153
  'w-tooltip--tile': this.tile,
149
154
  'w-tooltip--round': this.round,
@@ -280,8 +285,7 @@ export default {
280
285
  },
281
286
 
282
287
  removeTooltip () {
283
- // el.remove() doesn't work on IE11.
284
- if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.parentNode.removeChild(this.tooltipEl)
288
+ if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.remove()
285
289
  }
286
290
  },
287
291
 
@@ -295,8 +299,7 @@ export default {
295
299
  beforeUnmount () {
296
300
  this.removeTooltip()
297
301
 
298
- // el.remove() doesn't work on IE11.
299
- if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.parentNode.removeChild(this.activatorEl)
302
+ if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.remove()
300
303
  },
301
304
 
302
305
  watch: {
@@ -0,0 +1,100 @@
1
+ @mixin default-transition($duration: $transition-duration, $delay: 0s) {
2
+ transition: $duration $delay ease-in-out;
3
+ }
4
+
5
+ @mixin out-back-transition($duration: $transition-duration, $delay: 0s) {
6
+ transition: $duration $delay cubic-bezier(0.18, 0.89, 0.32, 1.28);
7
+ }
8
+
9
+ /**
10
+ * Generates a triangle arrow on the edge of an element.
11
+ *
12
+ * @param $color: the color to apply to the triangle.
13
+ * @param $selector: the element selector that receives the modifiers (--top, --left, etc.).
14
+ * @param $size: the triangle size at the base.
15
+ * @param $thickness: the border thickness, 0 to remove the border.
16
+ */
17
+ @mixin triangle($color: white, $selector: '', $size: 7px, $thickness: 1px) {
18
+ @if ($thickness > 0) {
19
+ // The underneath border triangle.
20
+ &:before {
21
+ content: '';
22
+ position: absolute;
23
+ width: 0;
24
+ height: 0;
25
+ border: $size solid transparent;
26
+ }
27
+
28
+ &#{$selector}--top:before {
29
+ top: 100%;
30
+ left: 50%;
31
+ border-top-color: inherit;
32
+ transform: translateX(-50%);
33
+ margin-top: 0;
34
+ }
35
+ &#{$selector}--bottom:before {
36
+ bottom: 100%;
37
+ left: 50%;
38
+ border-bottom-color: inherit;
39
+ transform: translateX(-50%);
40
+ margin-bottom: 0;
41
+ }
42
+ &#{$selector}--left:before {
43
+ left: 100%;
44
+ top: 50%;
45
+ border-left-color: inherit;
46
+ transform: translateY(-50%);
47
+ margin-left: 0;
48
+ }
49
+ &#{$selector}--right:before {
50
+ right: 100%;
51
+ top: 50%;
52
+ border-right-color: inherit;
53
+ transform: translateY(-50%);
54
+ margin-right: 0;
55
+ }
56
+
57
+ &#{$selector}--align-top:before {transform: none;top: (2 * $base-increment) - 1px;}
58
+ &#{$selector}--align-bottom:before {transform: none;top: auto;bottom: (2 * $base-increment) - 1px;}
59
+ &#{$selector}--align-left:before {transform: none;left: (2 * $base-increment) - 1px;}
60
+ &#{$selector}--align-right:before {transform: none;left: auto;right: (2 * $base-increment) - 1px;}
61
+ }
62
+
63
+ // The colored triangle on top of `:before`.
64
+ &:after {
65
+ content: '';
66
+ position: absolute;
67
+ width: 0;
68
+ height: 0;
69
+ border: ($size - $thickness) solid transparent;
70
+ }
71
+ &#{$selector}--top:after {
72
+ top: 100%;
73
+ left: 50%;
74
+ border-top-color: $color;
75
+ transform: translateX(-50%);
76
+ }
77
+ &#{$selector}--bottom:after {
78
+ bottom: 100%;
79
+ left: 50%;
80
+ border-bottom-color: $color;
81
+ transform: translateX(-50%);
82
+ }
83
+ &#{$selector}--left:after {
84
+ left: 100%;
85
+ top: 50%;
86
+ border-left-color: $color;
87
+ transform: translateY(-50%);
88
+ }
89
+ &#{$selector}--right:after {
90
+ right: 100%;
91
+ top: 50%;
92
+ border-right-color: $color;
93
+ transform: translateY(-50%);
94
+ }
95
+
96
+ &#{$selector}--align-top:after {transform: none;top: 2 * $base-increment;}
97
+ &#{$selector}--align-bottom:after {transform: none;top: auto;bottom: 2 * $base-increment;}
98
+ &#{$selector}--align-left:after {transform: none;left: 2 * $base-increment;}
99
+ &#{$selector}--align-right:after {transform: none;left: auto;right: 2 * $base-increment;}
100
+ }
@@ -28,15 +28,6 @@ $form-field-height: round(2 * $base-font-size) !default;
28
28
  // Always an even number for better vertical alignment. (Used in checkbox, radio, switch)
29
29
  $small-form-el-size: round(divide(1.3 * $base-font-size, 2)) * 2 !default;
30
30
 
31
- // Mixins.
32
- @mixin default-transition($duration: $transition-duration, $delay: 0s) {
33
- transition: $duration $delay ease-in-out;
34
- }
35
-
36
- @mixin out-back-transition($duration: $transition-duration, $delay: 0s) {
37
- transition: $duration $delay cubic-bezier(0.18, 0.89, 0.32, 1.28);
38
- }
39
-
40
31
  // COMPONENTS DEFAULTS.
41
32
  // ========================================================
42
33
  // w-drawer.
@@ -1,4 +1,5 @@
1
1
  @import './variables';
2
+ @import './mixins';
2
3
  @import './base';
3
4
  @import './typography';
4
5
  @import './layout';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Takes CSS classes as a string array or object and turn them into an object.
3
+ *
4
+ * @param {String|Array|Object} classes the CSS classes to merge into an object
5
+ * @return {Object}
6
+ */
7
+ export const objectifyClasses = (classes = {}) => {
8
+ if (typeof classes === 'string') classes = { [classes]: true }
9
+ else if (typeof classes === 'array') classes = { [classes.join(' ')]: true }
10
+ return classes
11
+ }