wave-ui 2.26.0 → 2.29.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.
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
- .w-tooltip-wrap(ref="wrapper" :class="{ 'w-tooltip-wrap--attached': !detachTo }")
2
+ .w-tooltip-wrap(: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"
@@ -9,11 +9,7 @@
9
9
  v-show="showTooltip"
10
10
  :class="classes"
11
11
  :style="styles")
12
- //- When there is a bg color, another div wrapper is needed for the triangle
13
- //- to inherit the current color.
14
- div(v-if="bgColor" :class="color")
15
- slot
16
- slot(v-else)
12
+ slot
17
13
  </template>
18
14
 
19
15
  <script>
@@ -26,6 +22,7 @@
26
22
  * and move the tooltip elsewhere in the DOM.
27
23
  */
28
24
 
25
+ import { objectifyClasses } from '../utils/index'
29
26
  import { consoleWarn } from '../utils/console'
30
27
 
31
28
  const marginFromWindowSide = 4 // Amount of px from a window side, instead of overflowing.
@@ -42,8 +39,8 @@ export default {
42
39
  shadow: { type: Boolean },
43
40
  tile: { type: Boolean },
44
41
  round: { type: Boolean },
45
- transition: { type: String, default: '' },
46
- tooltipClass: { type: String },
42
+ transition: { type: String },
43
+ tooltipClass: { type: [String, Object, Array] },
47
44
  // Position.
48
45
  detachTo: {},
49
46
  fixed: { type: Boolean },
@@ -71,32 +68,41 @@ export default {
71
68
  }),
72
69
 
73
70
  computed: {
71
+ tooltipClasses () {
72
+ return objectifyClasses(this.tooltipClass)
73
+ },
74
+
74
75
  transitionName () {
75
76
  const direction = this.position.replace(/top|bottom/, m => ({ top: 'up', bottom: 'down' }[m]))
76
77
  return this.transition || `w-tooltip-slide-fade-${direction}`
77
78
  },
78
79
 
80
+ // DOM element to attach tooltip to.
81
+ // ! \ This computed uses the DOM - NO SSR (only trigger from beforeMount and later).
79
82
  detachToTarget () {
80
- let target = this.detachTo || '.w-app'
81
- if (target === true) target = '.w-app'
82
- else if (target && !['object', 'string'].includes(typeof target)) target = '.w-app'
83
+ const defaultTarget = '.w-app'
84
+
85
+ let target = this.detachTo || defaultTarget
86
+ if (target === true) target = defaultTarget
87
+ else if (target && !['object', 'string'].includes(typeof target)) target = defaultTarget
83
88
  else if (typeof target === 'object' && !target.nodeType) {
84
- target = '.w-app'
89
+ target = defaultTarget
85
90
  consoleWarn('Invalid node provided in w-tooltip `attach-to`. Falling back to .w-app.', this)
86
91
  }
87
92
  if (typeof target === 'string') target = document.querySelector(target)
88
93
 
89
94
  if (!target) {
90
- consoleWarn(`Unable to locate ${this.detachTo ? `target ${this.detachTo}` : '.w-app'}`, this)
91
- target = document.querySelector('.w-app')
95
+ consoleWarn(`Unable to locate ${this.detachTo ? `target ${this.detachTo}` : defaultTarget}`, this)
96
+ target = document.querySelector(defaultTarget)
92
97
  }
93
98
 
94
99
  return target
95
100
  },
96
101
 
97
102
  // DOM element that will receive the tooltip.
103
+ // ! \ This computed uses the DOM - NO SSR (only trigger from beforeMount and later).
98
104
  tooltipParentEl () {
99
- return this.detachTo ? this.detachToTarget : this.$refs.wrapper
105
+ return this.detachTo ? this.detachToTarget : this.$el
100
106
  },
101
107
 
102
108
  position () {
@@ -141,9 +147,9 @@ export default {
141
147
 
142
148
  classes () {
143
149
  return {
144
- [this.color]: !this.bgColor,
145
- [`${this.bgColor} ${this.bgColor}--bg`]: this.bgColor,
146
- [this.tooltipClass]: this.tooltipClass,
150
+ [this.color]: this.color,
151
+ [`${this.bgColor}--bg`]: this.bgColor,
152
+ ...this.tooltipClasses,
147
153
  [`w-tooltip--${this.position}`]: true,
148
154
  'w-tooltip--tile': this.tile,
149
155
  'w-tooltip--round': this.round,
@@ -155,11 +161,13 @@ export default {
155
161
  }
156
162
  },
157
163
 
164
+ // The tooltip styles.
158
165
  styles () {
159
166
  return {
160
167
  zIndex: this.zIndex || this.zIndex === 0 || null,
161
- top: `${~~this.tooltipCoordinates.top}px`,
162
- left: `${~~this.tooltipCoordinates.left}px`
168
+ top: (this.tooltipCoordinates.top && `${~~this.tooltipCoordinates.top}px`) || null,
169
+ left: (this.tooltipCoordinates.left && `${~~this.tooltipCoordinates.left}px`) || null,
170
+ '--w-tooltip-bg-color': this.$waveui.colors[this.bgColor || 'white']
163
171
  }
164
172
  },
165
173
 
@@ -174,16 +182,18 @@ export default {
174
182
  mouseleave: this.toggle
175
183
  }
176
184
 
177
- if ('ontouchstart' in window) handlers.click = this.toggle
185
+ // Check the window exists: SSR-proof.
186
+ if (typeof window !== 'undefined' && 'ontouchstart' in window) handlers.click = this.toggle
178
187
  }
179
188
  return handlers
180
189
  }
181
190
  },
182
191
 
183
192
  methods: {
193
+ // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
184
194
  toggle (e) {
185
195
  let shouldShowTooltip = this.showTooltip
186
- if ('ontouchstart' in window) {
196
+ if (typeof window !== 'undefined' && 'ontouchstart' in window) {
187
197
  if (e.type === 'click') shouldShowTooltip = !shouldShowTooltip
188
198
  }
189
199
  else if (e.type === 'click' && this.showOnClick) shouldShowTooltip = !shouldShowTooltip
@@ -211,6 +221,7 @@ export default {
211
221
  }
212
222
  },
213
223
 
224
+ // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
214
225
  getCoordinates () {
215
226
  const { top, left, width, height } = this.activatorEl.getBoundingClientRect()
216
227
  let coords = { top, left, width, height }
@@ -268,7 +279,7 @@ export default {
268
279
  },
269
280
 
270
281
  insertTooltip () {
271
- const wrapper = this.$refs.wrapper
282
+ const wrapper = this.$el
272
283
 
273
284
  // Unwrap the activator element.
274
285
  wrapper.parentNode.insertBefore(this.activatorEl, wrapper)
@@ -280,13 +291,12 @@ export default {
280
291
  },
281
292
 
282
293
  removeTooltip () {
283
- // el.remove() doesn't work on IE11.
284
- if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.parentNode.removeChild(this.tooltipEl)
294
+ if (this.tooltipEl && this.tooltipEl.parentNode) this.tooltipEl.remove()
285
295
  }
286
296
  },
287
297
 
288
298
  mounted () {
289
- this.activatorEl = this.$refs.wrapper.firstElementChild
299
+ this.activatorEl = this.$el.firstElementChild
290
300
  if (this.detachTo) this.insertTooltip()
291
301
 
292
302
  if (this.modelValue) this.toggle({ type: 'click', target: this.activatorEl })
@@ -295,8 +305,7 @@ export default {
295
305
  beforeUnmount () {
296
306
  this.removeTooltip()
297
307
 
298
- // el.remove() doesn't work on IE11.
299
- if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.parentNode.removeChild(this.activatorEl)
308
+ if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.remove()
300
309
  },
301
310
 
302
311
  watch: {
@@ -363,94 +372,17 @@ export default {
363
372
 
364
373
  &--custom-transition {transform: none;}
365
374
 
366
- &:after {
367
- content: '';
368
- position: absolute;
369
- width: 0;
370
- height: 0;
371
- border: 6px solid transparent;
372
- }
373
- &--top:after {
374
- top: 100%;
375
- left: 50%;
376
- border-top-color: $tooltip-bg-color;
377
- transform: translateX(-50%);
378
- margin-top: 1px;
379
- }
380
- &--bottom:after {
381
- bottom: 100%;
382
- left: 50%;
383
- border-bottom-color: $tooltip-bg-color;
384
- transform: translateX(-50%);
385
- margin-bottom: 1px;
386
- }
387
- &--left:after {
388
- left: 100%;
389
- top: 50%;
390
- border-left-color: $tooltip-bg-color;
391
- transform: translateY(-50%);
392
- margin-left: 1px;
393
- }
394
- &--right:after {
395
- right: 100%;
396
- top: 50%;
397
- border-right-color: $tooltip-bg-color;
398
- transform: translateY(-50%);
399
- margin-right: 1px;
400
- }
401
-
402
375
  // Tooltip without border.
403
376
  // --------------------------------------------------------
404
- &--no-border.w-tooltip--top:after {margin-top: -1px;border-top-color: inherit;}
405
- &--no-border.w-tooltip--bottom:after {margin-bottom: -1px;border-bottom-color: inherit;}
406
- &--no-border.w-tooltip--left:after {margin-left: -1px;border-left-color: inherit;}
407
- &--no-border.w-tooltip--right:after {margin-right: -1px;border-right-color: inherit;}
377
+ &--no-border {
378
+ @include triangle(var(--w-tooltip-bg-color), '.w-tooltip', 7px, 0);
379
+ }
408
380
 
409
381
  // Tooltip with border.
410
382
  // --------------------------------------------------------
411
- &:not(&--no-border).w-tooltip--top:after {margin-top: -1px;}
412
- &:not(&--no-border).w-tooltip--bottom:after {margin-bottom: -1px;}
413
- &:not(&--no-border).w-tooltip--left:after {margin-left: -1px;}
414
- &:not(&--no-border).w-tooltip--right:after {margin-right: -1px;}
415
-
416
383
  &:not(&--no-border) {
417
- &:before {
418
- content: '';
419
- position: absolute;
420
- width: 0;
421
- height: 0;
422
- border: 7px solid transparent;
423
- }
424
- &.w-tooltip--top:before {
425
- top: 100%;
426
- left: 50%;
427
- border-top-color: inherit;
428
- transform: translateX(-50%);
429
- margin-top: 0;
430
- }
431
- &.w-tooltip--bottom:before {
432
- bottom: 100%;
433
- left: 50%;
434
- border-bottom-color: inherit;
435
- transform: translateX(-50%);
436
- margin-bottom: 0;
437
- }
438
- &.w-tooltip--left:before {
439
- left: 100%;
440
- top: 50%;
441
- border-left-color: inherit;
442
- transform: translateY(-50%);
443
- margin-left: 0;
444
- }
445
- &.w-tooltip--right:before {
446
- right: 100%;
447
- top: 50%;
448
- border-right-color: inherit;
449
- transform: translateY(-50%);
450
- margin-right: 0;
451
- }
384
+ @include triangle(var(--w-tooltip-bg-color), '.w-tooltip', 7px);
452
385
  }
453
- // --------------------------------------------------------
454
386
  }
455
387
 
456
388
  // Transitions.
@@ -10,24 +10,3 @@ a {text-decoration: none;}
10
10
  padding-left: 3 * $base-increment;
11
11
  padding-right: 3 * $base-increment;
12
12
  }
13
-
14
- .nav-menu ~ .main-content {padding-left: 4em;}
15
-
16
- footer {
17
- margin-top: 5em;
18
-
19
- .nav-drawer ~ & {padding-left: 12px;}
20
-
21
- .heart:hover {animation: heartbeat 1s infinite;}
22
- small {font-size: 10px;}
23
- .caption {padding-top: 1px;}
24
- }
25
-
26
- @keyframes heartbeat {
27
- 0%, 30%, 60%, 100% {transform: scale(1);}
28
- 15%, 45% {transform: scale(1.2);}
29
- }
30
-
31
- @media screen and (max-width: 560px) {
32
- button.go-top {display: none;}
33
- }
@@ -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.
@@ -66,3 +57,7 @@ $textarea-line-height: 1.2;
66
57
  $tooltip-bg-color: #fff;
67
58
  $tooltip-color: rgba(0, 0, 0, 0.7);
68
59
  // --------------------------------------------------------
60
+
61
+ // Mixins.
62
+ // --------------------------------------------------------
63
+ @import './mixins';
@@ -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 (Array.isArray(classes)) classes = { [classes.join(' ')]: true }
10
+ return classes
11
+ }