wave-ui 1.45.13 → 1.47.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-ui",
3
- "version": "1.45.13",
3
+ "version": "1.47.0",
4
4
  "description": "An emerging UI framework for Vue.js & Vue 3 with only the bright side. :sunny:",
5
5
  "author": "Antoni Andre <antoniandre.web@gmail.com>",
6
6
  "main": "./dist/wave-ui.umd.js",
@@ -229,7 +229,6 @@ export default {
229
229
  &--icon-outside &__icon {
230
230
  position: absolute;
231
231
  opacity: 1;
232
- // top: 2 * $base-increment - 1px; // Needed for IE 11, but dropping support.
233
232
  left: 1px;
234
233
  z-index: 1;
235
234
  transform: translateX(-50%);
@@ -2,23 +2,23 @@
2
2
  .w-confirm
3
3
  w-menu(v-model="showPopup" v-bind="wMenuProps")
4
4
  template(#activator="{ on }")
5
- w-button.w-confirm__button(v-on="on" v-bind="buttonProps")
5
+ w-button.w-confirm__button(v-on="{ ...$listeners, ...on }" v-bind="buttonProps")
6
6
  slot
7
7
  w-flex(:column="!inline" align-center)
8
8
  div
9
- slot(name="question") Are you sure?
9
+ slot(name="question") {{ question }}
10
10
  .w-flex.justify-end(:class="inline ? 'ml2' : 'mt2'")
11
11
  w-button.mr2(
12
- v-if="!noCancel"
13
- v-bind="cancelButton"
12
+ v-if="cancel !== false"
13
+ v-bind="cancelButtonProps"
14
14
  :bg-color="(cancelButton || {}).bgColor || 'error'"
15
15
  @click="onCancel")
16
- slot(name="cancel") Cancel
16
+ slot(name="cancel") {{ cancelButton.label }}
17
17
  w-button(
18
- v-bind="confirmButton"
18
+ v-bind="confirmButtonProps"
19
19
  :bg-color="(confirmButton || {}).bgColor || 'success'"
20
20
  @click="onConfirm")
21
- slot(name="confirm") Confirm
21
+ slot(name="confirm") {{ confirmButton.label }}
22
22
  </template>
23
23
 
24
24
  <script>
@@ -30,11 +30,16 @@ export default {
30
30
  color: { type: String },
31
31
  icon: { type: String },
32
32
  mainButton: { type: Object }, // Allow passing down an object of props to the w-button component.
33
+ question: { type: String, default: 'Are you sure?' },
33
34
 
34
35
  // Cancel & confirm buttons props.
35
- noCancel: { type: Boolean }, // Removes the cancel button.
36
- cancelButton: { type: [Boolean, Object] }, // Allow passing down an object of props to the w-button component.
37
- confirmButton: { type: Object }, // Allow passing down an object of props to the w-button component.
36
+ // Allow passing down an object of props to the w-button component.
37
+ // If a string is given, that will be the label of the button.
38
+ // If false, no cancel button.
39
+ cancel: { type: [Boolean, Object, String], default: undefined },
40
+ // Allow passing down an object of props to the w-button component.
41
+ // If a string is given, that will be the label of the button.
42
+ confirm: { type: [Object, String] },
38
43
 
39
44
  // global menu props.
40
45
  inline: { type: Boolean }, // The layout inside the menu.
@@ -63,6 +68,26 @@ export default {
63
68
  }),
64
69
 
65
70
  computed: {
71
+ cancelButton () {
72
+ let button = { label: typeof this.cancel === 'string' ? this.cancel : 'Cancel' }
73
+ if (typeof this.cancel === 'object') button = Object.assign({}, button, this.cancel)
74
+ return button
75
+ },
76
+ // Props to pass down to the w-button component.
77
+ cancelButtonProps () {
78
+ const { label, ...props } = this.cancelButton // Everything except label.
79
+ return props
80
+ },
81
+ confirmButton () {
82
+ let button = { label: typeof this.confirm === 'string' ? this.confirm : 'Confirm' }
83
+ if (typeof this.confirm === 'object') button = Object.assign({}, button, this.confirm)
84
+ return button
85
+ },
86
+ // Props to pass down to the w-button component.
87
+ confirmButtonProps () {
88
+ const { label, ...props } = this.confirmButton // Everything except label.
89
+ return props
90
+ },
66
91
  wMenuProps () {
67
92
  return {
68
93
  top: this.top,
@@ -261,6 +261,8 @@ export default {
261
261
  return file
262
262
  }))
263
263
  this.$emit('update:modelValue', this.inputFiles)
264
+ this.$emit('input', this.inputFiles)
265
+ this.$emit('change', this.inputFiles)
264
266
  },
265
267
 
266
268
  // For file input.
@@ -289,7 +291,7 @@ export default {
289
291
  // On page load, check if the field is autofilled by the browser.
290
292
  // 20211229. Only a problem on Chrome. Firefox ok, Safari always prompts before filling up.
291
293
  setTimeout(() => {
292
- if (this.$refs.input.matches(':-webkit-autofill')) this.isAutofilled = true
294
+ if (this.$refs.input && this.$refs.input.matches(':-webkit-autofill')) this.isAutofilled = true
293
295
  }, 400) // Can't be less than 350: time for the browser to autofill.
294
296
  },
295
297
 
@@ -3,20 +3,20 @@
3
3
  slot(name="activator" :on="activatorEventHandlers")
4
4
  transition(:name="transitionName" appear)
5
5
  .w-menu(
6
- v-if="custom && menuVisible"
7
- ref="menu"
8
- @click="hideOnMenuClick && closeMenu(true)"
6
+ v-if="custom && detachableVisible"
7
+ ref="detachable"
8
+ @click="hideOnMenuClick && close(true)"
9
9
  @mouseenter="showOnHover && (hoveringMenu = true)"
10
- @mouseleave="showOnHover && ((hoveringMenu = false), closeMenu())"
10
+ @mouseleave="showOnHover && ((hoveringMenu = false), close())"
11
11
  :class="classes"
12
12
  :style="styles")
13
13
  slot
14
14
  w-card.w-menu(
15
- v-else-if="menuVisible"
16
- ref="menu"
17
- @click.native="hideOnMenuClick && closeMenu(true)"
15
+ v-else-if="detachableVisible"
16
+ ref="detachable"
17
+ @click.native="hideOnMenuClick && close(true)"
18
18
  @mouseenter.native="showOnHover && (hoveringMenu = true)"
19
- @mouseleave.native="showOnHover && ((hoveringMenu = false), closeMenu())"
19
+ @mouseleave.native="showOnHover && ((hoveringMenu = false), close())"
20
20
  :tile="tile"
21
21
  :title-class="titleClasses"
22
22
  :content-class="contentClasses"
@@ -32,12 +32,12 @@
32
32
  w-overlay(
33
33
  v-if="overlay"
34
34
  ref="overlay"
35
- :value="menuVisible"
35
+ :value="detachableVisible"
36
36
  :persistent="persistent"
37
37
  :class="overlayClasses"
38
38
  v-bind="overlayProps"
39
39
  :z-index="(zIndex || 200) - 1"
40
- @input="menuVisible = false")
40
+ @input="detachableVisible = false")
41
41
  </template>
42
42
 
43
43
  <script>
@@ -51,12 +51,13 @@
51
51
  */
52
52
 
53
53
  import { objectifyClasses } from '../utils/index'
54
- import { consoleWarn } from '../utils/console'
54
+ import DetachableMixin from '../mixins/detachable'
55
55
 
56
56
  // const marginFromWindowSide = 4 // Amount of px from a window side, instead of overflowing.
57
57
 
58
58
  export default {
59
59
  name: 'w-menu',
60
+ mixins: [DetachableMixin],
60
61
 
61
62
  props: {
62
63
  value: {}, // Show or hide.
@@ -75,7 +76,8 @@ export default {
75
76
  contentClass: { type: [String, Object, Array] },
76
77
  // Position.
77
78
  arrow: { type: Boolean }, // The small triangle pointing toward the activator.
78
- detachTo: { type: [String, Boolean, Object] },
79
+ detachTo: { type: [String, Boolean, Object], deprecated: true },
80
+ appendTo: { type: [String, Boolean, Object] },
79
81
  fixed: { type: Boolean },
80
82
  top: { type: Boolean },
81
83
  bottom: { type: Boolean },
@@ -97,49 +99,31 @@ export default {
97
99
  emits: ['input', 'update:modelValue', 'open', 'close'],
98
100
 
99
101
  data: () => ({
100
- menuVisible: false,
102
+ detachableVisible: false,
101
103
  hoveringActivator: false,
102
104
  hoveringMenu: false,
103
105
  // The menu computed top & left coordinates.
104
- menuCoordinates: {
106
+ detachableCoords: {
105
107
  top: 0,
106
108
  left: 0
107
109
  },
108
110
  activatorEl: null,
109
111
  activatorWidth: 0,
110
- menuEl: null,
112
+ detachableEl: null,
111
113
  timeoutId: null
112
114
  }),
113
115
 
114
116
  computed: {
117
+ /**
118
+ * Other computed in the detachable mixin:
119
+ * - `appendToTarget`
120
+ * - `detachableParentEl`
121
+ **/
122
+
115
123
  transitionName () {
116
124
  return this.transition || 'scale-fade'
117
125
  },
118
126
 
119
- // DOM element to attach menu to.
120
- detachToTarget () {
121
- let target = this.detachTo || '.w-app'
122
- if (target === true) target = '.w-app'
123
- else if (target && !['object', 'string'].includes(typeof target)) target = '.w-app'
124
- else if (typeof target === 'object' && !target.nodeType) {
125
- target = '.w-app'
126
- consoleWarn('Invalid node provided in w-menu `detach-to`. Falling back to .w-app.', this)
127
- }
128
- if (typeof target === 'string') target = document.querySelector(target)
129
-
130
- if (!target) {
131
- consoleWarn(`Unable to locate ${this.detachTo ? `target ${this.detachTo}` : '.w-app'}`, this)
132
- target = document.querySelector('.w-app')
133
- }
134
-
135
- return target
136
- },
137
-
138
- // DOM element that will receive the menu.
139
- menuParentEl () {
140
- return this.detachToTarget
141
- },
142
-
143
127
  position () {
144
128
  return (
145
129
  (this.top && 'top') ||
@@ -150,21 +134,21 @@ export default {
150
134
  )
151
135
  },
152
136
 
153
- menuMinWidth () {
154
- if (this.minWidth === 'activator') return this.activatorWidth ? `${this.activatorWidth}px` : 0
155
- else return isNaN(this.minWidth) ? this.minWidth : (this.minWidth ? `${this.minWidth}px` : 0)
156
- },
157
-
158
137
  alignment () {
159
138
  return (
160
- ((this.top || this.bottom) && this.alignLeft && 'left') ||
161
- ((this.top || this.bottom) && this.alignRight && 'right') ||
162
- ((this.left || this.right) && this.alignTop && 'top') ||
163
- ((this.left || this.right) && this.alignBottom && 'bottom') ||
139
+ (['top', 'bottom'].includes(this.position) && this.alignLeft && 'left') ||
140
+ (['top', 'bottom'].includes(this.position) && this.alignRight && 'right') ||
141
+ (['left', 'right'].includes(this.position) && this.alignTop && 'top') ||
142
+ (['left', 'right'].includes(this.position) && this.alignBottom && 'bottom') ||
164
143
  ''
165
144
  )
166
145
  },
167
146
 
147
+ menuMinWidth () {
148
+ if (this.minWidth === 'activator') return this.activatorWidth ? `${this.activatorWidth}px` : 0
149
+ else return isNaN(this.minWidth) ? this.minWidth : (this.minWidth ? `${this.minWidth}px` : 0)
150
+ },
151
+
168
152
  menuClasses () {
169
153
  return objectifyClasses(this.menuClass)
170
154
  },
@@ -201,8 +185,8 @@ export default {
201
185
  styles () {
202
186
  return {
203
187
  zIndex: this.zIndex || this.zIndex === 0 || (this.overlay && !this.zIndex && 200) || null,
204
- top: (this.menuCoordinates.top && `${~~this.menuCoordinates.top}px`) || null,
205
- left: (this.menuCoordinates.left && `${~~this.menuCoordinates.left}px`) || null,
188
+ top: (this.detachableCoords.top && `${~~this.detachableCoords.top}px`) || null,
189
+ left: (this.detachableCoords.left && `${~~this.detachableCoords.left}px`) || null,
206
190
  minWidth: (this.minWidth && this.menuMinWidth) || null,
207
191
  '--w-menu-bg-color': this.arrow && this.$waveui.colors[this.bgColor || 'white']
208
192
  }
@@ -217,18 +201,20 @@ export default {
217
201
  blur: this.toggleMenu,
218
202
  mouseenter: e => {
219
203
  this.hoveringActivator = true
220
- this.openMenu(e)
204
+ this.open(e)
221
205
  },
222
206
  mouseleave: e => {
223
207
  this.hoveringActivator = false
224
208
  // Wait 10ms, the time to get the hoveringMenu updated on mouseenter on the menu.
225
209
  setTimeout(() => {
226
- if (!this.hoveringMenu) this.closeMenu()
210
+ if (!this.hoveringMenu) this.close()
227
211
  }, 10)
228
212
  }
229
213
  }
230
-
231
- if ('ontouchstart' in window) handlers.click = this.toggleMenu
214
+ // Check the window exists: SSR-proof.
215
+ if (typeof window !== 'undefined' && 'ontouchstart' in window) {
216
+ handlers.click = this.toggleMenu
217
+ }
232
218
  }
233
219
  else handlers = { click: this.toggleMenu }
234
220
  return handlers
@@ -236,8 +222,19 @@ export default {
236
222
  },
237
223
 
238
224
  methods: {
225
+ /**
226
+ * Other methods in the `detachable` mixin:
227
+ * - `getActivatorCoordinates`
228
+ * - `computeDetachableCoords`
229
+ * - `onResize`
230
+ * - `onOutsideMousedown`
231
+ * - `insertInDOM`
232
+ * - `removeFromDOM`
233
+ **/
234
+
235
+ // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
239
236
  toggleMenu (e) {
240
- let shouldShowMenu = this.menuVisible
237
+ let shouldShowMenu = this.detachableVisible
241
238
  if ('ontouchstart' in window && this.showOnHover && e.type === 'click') {
242
239
  shouldShowMenu = !shouldShowMenu
243
240
  }
@@ -254,24 +251,25 @@ export default {
254
251
  this.timeoutId = clearTimeout(this.timeoutId)
255
252
 
256
253
  if (shouldShowMenu) {
257
- this.$emit('update:modelValue', (this.menuVisible = true))
254
+ this.$emit('update:modelValue', (this.detachableVisible = true))
258
255
  this.$emit('input', true)
259
256
  this.$emit('open')
260
257
 
261
- this.openMenu(e)
258
+ this.open(e)
262
259
  }
263
- else this.closeMenu()
260
+ else this.close()
264
261
  },
265
262
 
266
- async openMenu (e) {
267
- this.menuVisible = true
268
- await this.insertMenu()
263
+ // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
264
+ async open (e) {
265
+ this.detachableVisible = true
266
+ await this.insertInDOM()
269
267
 
270
268
  if (this.minWidth === 'activator') this.activatorWidth = this.activatorEl.offsetWidth
271
269
 
272
- if (!this.noPosition) this.computeMenuPosition(e)
270
+ if (!this.noPosition) this.computeDetachableCoords(e)
273
271
 
274
- // In `getCoordinates` accessing the menu computed styles takes a few ms (less than 10ms),
272
+ // In `getActivatorCoordinates` accessing the menu computed styles takes a few ms (less than 10ms),
275
273
  // if we don't postpone the Menu apparition it will start transition from a visible menu and
276
274
  // thus will not transition.
277
275
  this.timeoutId = setTimeout(() => {
@@ -289,172 +287,35 @@ export default {
289
287
  * - click of activator
290
288
  * - hover outside if showOnHover
291
289
  * - click inside menu if hideOnMenuClick.
290
+ * / ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
292
291
  *
293
292
  * @param {Boolean} force when showOnHover is set to true, hovering menu should keep it open.
294
293
  * But if hideOnMenuClick is also set to true, this should force close
295
294
  * even while hovering the menu.
296
295
  */
297
- async closeMenu (force = false) {
296
+ async close (force = false) {
298
297
  // Might be already closed.
299
298
  // E.g. showOnHover & hideOnMenuClick: on click, force hide then mouseleave is also firing.
300
- if (!this.menuVisible) return
299
+ if (!this.detachableVisible) return
301
300
 
302
301
  if (this.showOnHover && !force) {
303
302
  await new Promise(resolve => setTimeout(resolve, 10))
304
303
  if (this.showOnHover && (this.hoveringMenu || this.hoveringActivator)) return
305
304
  }
306
305
 
307
- this.$emit('update:modelValue', (this.menuVisible = false))
306
+ this.$emit('update:modelValue', (this.detachableVisible = false))
308
307
  this.$emit('input', false)
309
308
  this.$emit('close')
310
309
  // Remove the mousedown listener if the menu got closed without a mousedown outside of the menu.
311
310
  document.removeEventListener('mousedown', this.onOutsideMousedown)
312
311
  window.removeEventListener('resize', this.onResize)
313
- },
314
-
315
- onOutsideMousedown (e) {
316
- if (!this.menuEl.contains(e.target) && !this.activatorEl.contains(e.target)) {
317
- this.$emit('update:modelValue', (this.menuVisible = false))
318
- this.$emit('input', false)
319
- this.$emit('close')
320
- document.removeEventListener('mousedown', this.onOutsideMousedown)
321
- window.removeEventListener('resize', this.onResize)
322
- }
323
- },
324
-
325
- onResize () {
326
- if (this.minWidth === 'activator') this.activatorWidth = this.activatorEl.offsetWidth
327
- this.computeMenuPosition()
328
- },
329
-
330
- getCoordinates (e) {
331
- // Get the activator coordinates relative to window.
332
- const { top, left, width, height } = (e ? e.target : this.activatorEl).getBoundingClientRect()
333
- let coords = { top, left, width, height }
334
-
335
- // If absolute position, adjust top & left.
336
- if (!this.fixed) {
337
- const { top: targetTop, left: targetLeft } = this.menuParentEl.getBoundingClientRect()
338
- const computedStyles = window.getComputedStyle(this.menuParentEl, null)
339
- coords = {
340
- ...coords,
341
- top: top - targetTop + this.menuParentEl.scrollTop - parseInt(computedStyles.getPropertyValue('border-top-width')),
342
- left: left - targetLeft + this.menuParentEl.scrollLeft - parseInt(computedStyles.getPropertyValue('border-left-width'))
343
- }
344
- }
345
-
346
- return coords
347
- },
348
-
349
- computeMenuPosition (e) {
350
- // Get the activator coordinates.
351
- let { top, left, width, height } = this.getCoordinates(e)
352
-
353
- // 1. First display the menu but hide it (So we can get its dimension).
354
- // --------------------------------------------------
355
- this.menuEl.style.visibility = 'hidden'
356
- this.menuEl.style.display = 'flex'
357
- const computedStyles = window.getComputedStyle(this.menuEl, null)
358
-
359
- // 2. Position the menu top, left, right, bottom and apply chosen alignment.
360
- // --------------------------------------------------
361
- // Subtract half or full activator width or height and menu width or height according to the
362
- // menu alignment.
363
- // Note: the menu position relies on transform translate, the custom animation may override the
364
- // css transform property so do without it i.e. no translateX(-50%), and recalculate top & left
365
- // manually.
366
- switch (this.position) {
367
- case 'top': {
368
- top -= this.menuEl.offsetHeight
369
- if (this.alignRight) {
370
- // left: 100% of activator.
371
- left += width - this.menuEl.offsetWidth +
372
- parseInt(computedStyles.getPropertyValue('border-right-width'))
373
- }
374
- else if (!this.alignLeft) left += (width - this.menuEl.offsetWidth) / 2 // left: 50% of activator - half menu width.
375
- break
376
- }
377
- case 'bottom': {
378
- top += height
379
- if (this.alignRight) {
380
- // left: 100% of activator.
381
- left += width - this.menuEl.offsetWidth +
382
- parseInt(computedStyles.getPropertyValue('border-right-width'))
383
- }
384
- else if (!this.alignLeft) left += (width - this.menuEl.offsetWidth) / 2 // left: 50% of activator - half menu width.
385
- break
386
- }
387
- case 'left': {
388
- left -= this.menuEl.offsetWidth
389
- if (this.alignBottom) top += height - this.menuEl.offsetHeight
390
- else if (!this.alignTop) top += (height - this.menuEl.offsetHeight) / 2 // top: 50% of activator - half menu height.
391
- break
392
- }
393
- case 'right': {
394
- left += width
395
- if (this.alignBottom) {
396
- top += height - this.menuEl.offsetHeight +
397
- parseInt(computedStyles.getPropertyValue('margin-top'))
398
- }
399
- else if (!this.alignTop) {
400
- top += (height - this.menuEl.offsetHeight) / 2 + // top: 50% of activator - half menu height.
401
- parseInt(computedStyles.getPropertyValue('margin-top'))
402
- }
403
- break
404
- }
405
- }
406
-
407
- // 3. Keep fully in viewport.
408
- // @todo: do this.
409
- // --------------------------------------------------
410
- // if (this.position === 'top' && ((top - this.menuEl.offsetHeight) < 0)) {
411
- // const margin = - parseInt(computedStyles.getPropertyValue('margin-top'))
412
- // top -= top - this.menuEl.offsetHeight - margin - marginFromWindowSide
413
- // }
414
- // else if (this.position === 'left' && left - this.menuEl.offsetWidth < 0) {
415
- // const margin = - parseInt(computedStyles.getPropertyValue('margin-left'))
416
- // left -= left - this.menuEl.offsetWidth - margin - marginFromWindowSide
417
- // }
418
- // else if (this.position === 'right' && left + width + this.menuEl.offsetWidth > window.innerWidth) {
419
- // const margin = parseInt(computedStyles.getPropertyValue('margin-left'))
420
- // left -= left + width + this.menuEl.offsetWidth - window.innerWidth + margin + marginFromWindowSide
421
- // }
422
- // else if (this.position === 'bottom' && top + height + this.menuEl.offsetHeight > window.innerHeight) {
423
- // const margin = parseInt(computedStyles.getPropertyValue('margin-top'))
424
- // top -= top + height + this.menuEl.offsetHeight - window.innerHeight + margin + marginFromWindowSide
425
- // }
426
-
427
- // 4. Hide the menu again so the transition happens correctly.
428
- // --------------------------------------------------
429
- this.menuEl.style.visibility = null
430
-
431
- // The menu coordinates are also recalculated while resizing window with open menu: keep the menu visible.
432
- if (!this.menuVisible) this.menuEl.style.display = 'none'
433
-
434
- this.menuCoordinates = { top, left }
435
- },
436
-
437
- insertMenu () {
438
- return new Promise(resolve => {
439
- this.$nextTick(() => {
440
- this.menuEl = this.$refs.menu?.$el || this.$refs.menu
441
-
442
- // Move the menu elsewhere in the DOM.
443
- // wrapper.parentNode.insertBefore(this.menuEl, wrapper)
444
- this.detachToTarget.appendChild(this.menuEl)
445
- resolve()
446
- })
447
- })
448
- },
449
-
450
- removeMenu () {
451
- if (this.menuEl && this.menuEl.parentNode) this.menuEl.remove()
452
312
  }
453
313
  },
454
314
 
455
315
  mounted () {
456
316
  const wrapper = this.$el
457
317
  this.activatorEl = wrapper.firstElementChild
318
+
458
319
  // Unwrap the activator element.
459
320
  wrapper.parentNode.insertBefore(this.activatorEl, wrapper)
460
321
 
@@ -468,18 +329,22 @@ export default {
468
329
  },
469
330
 
470
331
  beforeDestroy () {
471
- this.removeMenu()
332
+ this.removeFromDOM()
472
333
  if (this.overlay && this.overlayEl.parentNode) this.overlayEl.remove()
473
334
  if (this.activatorEl && this.activatorEl.parentNode) this.activatorEl.remove()
474
335
  },
475
336
 
476
337
  watch: {
477
338
  value (bool) {
478
- if (!!bool !== this.menuVisible) this.toggleMenu({ type: 'click', target: this.activatorEl })
339
+ if (!!bool !== this.detachableVisible) this.toggleMenu({ type: 'click', target: this.activatorEl })
479
340
  },
480
341
  detachTo () {
481
- this.removeMenu()
482
- this.insertMenu()
342
+ this.removeFromDOM()
343
+ this.insertInDOM()
344
+ },
345
+ appendTo () {
346
+ this.removeFromDOM()
347
+ this.insertInDOM()
483
348
  }
484
349
  }
485
350
  }
@@ -21,7 +21,7 @@ component(
21
21
  v-model="showMenu"
22
22
  :menu-class="`w-select__menu ${menuClass || ''}`"
23
23
  transition="slide-fade-down"
24
- :detach-to="(menuProps || {}).detachTo !== undefined ? (menuProps || {}).detachTo : '.w-app'"
24
+ :append-to="(menuProps || {}).appendTo !== undefined ? (menuProps || {}).appendTo : '.w-app'"
25
25
  align-left
26
26
  custom
27
27
  min-width="activator"
@@ -89,7 +89,6 @@ export default {
89
89
  background-color: rgba(255, 255, 255, 0.85);
90
90
  padding-left: 2 * $base-increment;
91
91
  padding-right: 2 * $base-increment;
92
- font-size: round(0.85 * $base-font-size);
93
92
  cursor: default;
94
93
  user-select: none;
95
94
 
@@ -100,23 +99,35 @@ export default {
100
99
  &--tile {border-radius: initial;}
101
100
  &--shadow {box-shadow: $box-shadow;}
102
101
 
103
- &.size--xs {font-size: round(0.7 * $base-font-size);}
102
+ &.size--xs {
103
+ $font-size: round(0.7 * $base-font-size);
104
+ font-size: $font-size;
105
+ line-height: $font-size + 2px;
106
+ }
104
107
  &.size--sm {
105
- font-size: round(0.82 * $base-font-size);
108
+ $font-size: round(0.82 * $base-font-size);
109
+ font-size: $font-size;
110
+ line-height: $font-size + 2px;
106
111
  padding: round(0.25 * $base-increment) $base-increment;
107
112
  }
108
113
  &.size--md {
109
- font-size: round(0.95 * $base-font-size);
114
+ $font-size: round(0.85 * $base-font-size);
115
+ font-size: $font-size;
116
+ line-height: $font-size + 4px;
110
117
  padding-top: round(0.25 * $base-increment);
111
118
  padding-bottom: round(0.25 * $base-increment);
112
119
  }
113
120
  &.size--lg {
114
- font-size: round(1.1 * $base-font-size);
121
+ $font-size: round(1.1 * $base-font-size);
122
+ font-size: $font-size;
123
+ line-height: $font-size + 4px;
115
124
  padding-top: round(0.5 * $base-increment);
116
125
  padding-bottom: round(0.5 * $base-increment);
117
126
  }
118
127
  &.size--xl {
119
- font-size: round(1.3 * $base-font-size);
128
+ $font-size: round(1.3 * $base-font-size);
129
+ font-size: $font-size;
130
+ line-height: $font-size + 4px;
120
131
  padding-top: round(1 * $base-increment);
121
132
  padding-bottom: round(1 * $base-increment);
122
133
  }