wave-ui 2.35.0 → 2.36.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.
@@ -9,9 +9,11 @@ component(
9
9
  :class="classes")
10
10
  //- Left label.
11
11
  template(v-if="labelPosition === 'left'")
12
- label.w-textarea__label.w-textarea__label--left.w-form-el-shakable(v-if="$slots.default" :for="`w-textarea--${_.uid}`")
13
- slot
14
- label.w-textarea__label.w-textarea__label--left.w-form-el-shakable(v-else-if="label" :for="`w-textarea--${_.uid}`" v-html="label")
12
+ label.w-textarea__label.w-textarea__label--left.w-form-el-shakable(
13
+ v-if="$slots.default || label"
14
+ :for="`w-textarea--${_.uid}`"
15
+ :class="labelClasses")
16
+ slot {{ label }}
15
17
 
16
18
  //- Input wrapper.
17
19
  .w-textarea__textarea-wrap(:class="inputWrapClasses")
@@ -39,15 +41,10 @@ component(
39
41
  :tabindex="tabindex || null")
40
42
  template(v-if="labelPosition === 'inside' && showLabelInside")
41
43
  label.w-textarea__label.w-textarea__label--inside.w-form-el-shakable(
42
- v-if="$slots.default"
43
- :for="`w-textarea--${_.uid}`"
44
- :class="isFocused && { [valid === false ? 'error' : this.color]: this.color || valid === false }")
45
- slot
46
- label.w-textarea__label.w-textarea__label--inside.w-form-el-shakable(
47
- v-else-if="label"
44
+ v-if="$slots.default || label"
48
45
  :for="`w-textarea--${_.uid}`"
49
- v-html="label"
50
- :class="isFocused && { [valid === false ? 'error' : color]: color || valid === false }")
46
+ :class="labelClasses")
47
+ slot {{ label }}
51
48
  w-icon.w-textarea__icon.w-textarea__icon--inner-right(
52
49
  v-if="innerIconRight"
53
50
  tag="label"
@@ -56,9 +53,11 @@ component(
56
53
 
57
54
  //- Right label.
58
55
  template(v-if="labelPosition === 'right'")
59
- label.w-textarea__label.w-textarea__label--right.w-form-el-shakable(v-if="$slots.default" :for="`w-textarea--${_.uid}`")
60
- slot
61
- label.w-textarea__label.w-textarea__label--right.w-form-el-shakable(v-else-if="label" :for="`w-textarea--${_.uid}`" v-html="label")
56
+ label.w-textarea__label.w-textarea__label--right.w-form-el-shakable(
57
+ v-if="$slots.default || label"
58
+ :for="`w-textarea--${_.uid}`"
59
+ :class="labelClasses")
60
+ slot {{ label }}
62
61
  </template>
63
62
 
64
63
  <script>
@@ -83,6 +82,7 @@ export default {
83
82
  placeholder: { type: String },
84
83
  color: { type: String, default: 'primary' },
85
84
  bgColor: { type: String },
85
+ labelColor: { type: String, default: 'primary' },
86
86
  dark: { type: Boolean },
87
87
  outline: { type: Boolean },
88
88
  shadow: { type: Boolean },
@@ -142,7 +142,7 @@ export default {
142
142
  },
143
143
  inputWrapClasses () {
144
144
  return {
145
- [this.valid === false ? 'error' : this.color]: this.color || this.valid === false,
145
+ [this.valid === false ? this.validationColor : this.color]: this.color || this.valid === false,
146
146
  [`${this.bgColor}--bg`]: this.bgColor,
147
147
  'w-textarea__textarea-wrap--tile': this.tile,
148
148
  // Box adds a padding on input. If there is a bgColor or shadow, a padding is needed.
@@ -387,8 +387,6 @@ $inactive-color: #777;
387
387
  .w-textarea--filled.w-textarea--floating-label.w-textarea--inner-icon-left & {left: 0;}
388
388
  // Chrome & Safari - Must remain in a separated rule as Firefox discard the whole rule seeing -webkit-.
389
389
  .w-textarea--floating-label.w-textarea--inner-icon-left .w-textarea__textarea:-webkit-autofill & {left: 0;}
390
-
391
- .w-textarea--focused & {color: currentColor;}
392
390
  }
393
391
  }
394
392
  </style>
@@ -1,26 +1,16 @@
1
1
  <template lang="pug">
2
- .w-tooltip-wrap
3
- slot(name="activator" :on="activatorEventHandlers")
4
- transition(:name="transitionName" appear)
5
- .w-tooltip(
6
- v-if="detachableVisible"
7
- ref="detachable"
8
- :key="_.uid"
9
- :class="classes"
10
- :style="styles")
11
- slot
2
+ slot(name="activator" :on="activatorEventHandlers")
3
+ transition(:name="transitionName" appear)
4
+ .w-tooltip(
5
+ v-if="detachableVisible"
6
+ ref="detachable"
7
+ :key="_.uid"
8
+ :class="classes"
9
+ :style="styles")
10
+ slot
12
11
  </template>
13
12
 
14
13
  <script>
15
- /**
16
- * Complexity of this component: Vue 2.x can only mount 1 single root element, but we don't
17
- * want to wrap the activator as it may break the layout.
18
- * Another simpler way would be to append the tooltip inside the activator, but some HTML tags
19
- * can't have children like <input>.
20
- * So a solution is to mount both the activator element and the tooltip in a wrapper then unwrap
21
- * and move the tooltip elsewhere in the DOM.
22
- */
23
-
24
14
  import { objectifyClasses } from '../utils/index'
25
15
  import DetachableMixin from '../mixins/detachable'
26
16
 
@@ -193,8 +183,6 @@ export default {
193
183
  </script>
194
184
 
195
185
  <style lang="scss">
196
- .w-tooltip-wrap {display: none;}
197
-
198
186
  .w-tooltip {
199
187
  // Fix Safari where `width: max-content` does not take padding and border into consideration.
200
188
  display: table;
@@ -9,7 +9,6 @@ import { consoleWarn } from '../utils/console'
9
9
  export default {
10
10
  props: {
11
11
  // Position.
12
- detachTo: { type: [String, Boolean, Object], deprecated: true },
13
12
  appendTo: { type: [String, Boolean, Object] },
14
13
  fixed: { type: Boolean },
15
14
  top: { type: Boolean },
@@ -26,6 +25,10 @@ export default {
26
25
  activator: { type: [String, Object, HTMLElement] } // The activator can be a DOM string selector, a ref or a DOM node.
27
26
  },
28
27
 
28
+ inject: {
29
+ detachableDefaultRoot: { default: null }
30
+ },
31
+
29
32
  data: () => ({
30
33
  // The event listeners handlers have to be removed the exact same way they have been attached.
31
34
  // Since the handler functions have variables that change after hot-reload, keep them exactly
@@ -39,14 +42,15 @@ export default {
39
42
  // DOM element to attach tooltip/menu to.
40
43
  // ! \ This computed uses the DOM - NO SSR (only trigger from beforeMount and later).
41
44
  appendToTarget () {
42
- const defaultTarget = '.w-app'
45
+ let defaultTarget = '.w-app'
43
46
 
44
- // Convert deprecated prop to renamed one.
45
- if (this.detachTo && !this.appendTo) {
46
- consoleWarn(`The ${this.$options.name} prop \`detach-to\` is deprecated. You can replace it with \`append-to\`.`, this)
47
+ // If used inside a w-dialog, w-drawer, or w-menu without an appendTo, default to that open
48
+ // element instead of the w-app.
49
+ if (typeof this.detachableDefaultRoot === 'function') {
50
+ defaultTarget = this.detachableDefaultRoot() || defaultTarget
47
51
  }
48
52
 
49
- let target = this.appendTo || this.detachTo || defaultTarget
53
+ let target = this.appendTo || defaultTarget
50
54
  if (target === true) target = defaultTarget
51
55
  else if (this.appendTo === 'activator') target = this.$el.previousElementSibling
52
56
  else if (target && !['object', 'string'].includes(typeof target)) target = defaultTarget
@@ -84,7 +88,7 @@ export default {
84
88
  if (activator instanceof HTMLElement) return activator
85
89
  return document.querySelector(this.activator)
86
90
  }
87
- return this.$el.firstElementChild
91
+ return this.$el.nextElementSibling
88
92
  },
89
93
  set () {}
90
94
  },
@@ -145,7 +149,7 @@ export default {
145
149
  // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
146
150
  getActivatorCoordinates () {
147
151
  // Get the activator coordinates relative to window.
148
- const { top, left, width, height } = (this.activatorEl).getBoundingClientRect()
152
+ const { top, left, width, height } = this.activatorEl.getBoundingClientRect()
149
153
  let coords = { top, left, width, height }
150
154
 
151
155
  // If absolute position, adjust top & left.
@@ -167,6 +171,11 @@ export default {
167
171
  // Get the activator coordinates.
168
172
  let { top, left, width, height } = this.getActivatorCoordinates()
169
173
 
174
+ // Prevent error in case the detachable component unmounted hook is fired but the activator
175
+ // is still in the DOM until the end of a transition and the user toggles it.
176
+ // Unmounted is called straight away from beforeLeave: https://github.com/vuejs/core/issues/994
177
+ if (!this.detachableEl) return
178
+
170
179
  // 1. First display the menu but hide it (So we can get its dimension).
171
180
  // --------------------------------------------------
172
181
  this.detachableEl.style.visibility = 'hidden'
@@ -273,7 +282,6 @@ export default {
273
282
  this.detachableEl = this.$refs.detachable?.$el || this.$refs.detachable
274
283
 
275
284
  // Move the tooltip/menu elsewhere in the DOM.
276
- // wrapper.parentNode.insertBefore(this.detachableEl, wrapper)
277
285
  if (this.detachableEl) this.appendToTarget.appendChild(this.detachableEl)
278
286
  resolve()
279
287
  })
@@ -315,33 +323,25 @@ export default {
315
323
  },
316
324
 
317
325
  mounted () {
318
- const wrapper = this.$el
319
-
320
- // Unwrap the activator element if the activator is in the activator slot.
321
- if (this.$slots.activator) wrapper.parentNode.insertBefore(this.activatorEl, wrapper)
322
-
323
326
  // If the activator is external.
324
- else if (this.activator) this.bindActivatorEvents()
327
+ if (this.activator) this.bindActivatorEvents()
325
328
 
326
329
  // If the activator seems to be undefined, it is probably a DOM node or Vue ref,
327
330
  // so check it on nextTick.
328
331
  else {
329
332
  this.$nextTick(() => {
330
- this.activator && this.bindActivatorEvents()
333
+ if (this.activator) this.bindActivatorEvents()
331
334
  if (this.modelValue) this.toggle({ type: 'click', target: this.activatorEl })
332
335
  })
333
336
  }
334
337
 
335
338
  // Unwrap the overlay if any.
336
- if (this.overlay) {
337
- this.overlayEl = this.$refs.overlay?.$el
338
- wrapper.parentNode.insertBefore(this.overlayEl, wrapper)
339
- }
339
+ if (this.overlay) this.overlayEl = this.$refs.overlay?.$el
340
340
 
341
341
  if (this.modelValue && this.activator) this.toggle({ type: 'click', target: this.activatorEl })
342
342
  },
343
343
 
344
- beforeUnmount () {
344
+ unmounted () {
345
345
  this.close()
346
346
 
347
347
  this.removeFromDOM()
@@ -353,19 +353,12 @@ export default {
353
353
  document.removeEventListener(eventName, handler)
354
354
  })
355
355
  }
356
-
357
- if (this.overlay && this.overlayEl.parentNode) this.overlayEl.remove()
358
- if (this.activatorEl?.parentNode && this.$slots.activator) this.activatorEl.remove()
359
356
  },
360
357
 
361
358
  watch: {
362
359
  modelValue (bool) {
363
360
  if (!!bool !== this.detachableVisible) this.toggle({ type: 'click', target: this.activatorEl })
364
361
  },
365
- detachTo () {
366
- this.removeFromDOM()
367
- this.insertInDOM()
368
- },
369
362
  appendTo () {
370
363
  this.removeFromDOM()
371
364
  this.insertInDOM()
@@ -29,6 +29,15 @@ export default {
29
29
  },
30
30
  isReadonly () {
31
31
  return this.readonly || this.formProps.readonly
32
+ },
33
+ validationColor () {
34
+ return this.formProps.validationColor
35
+ },
36
+ labelClasses () {
37
+ return {
38
+ [this.labelColor]: this.labelColor && this.valid !== false,
39
+ [this.validationColor]: this.valid === false
40
+ }
32
41
  }
33
42
  },
34
43