wave-ui 3.7.1 → 3.8.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/dist/wave-ui.cjs.js +1 -1
- package/dist/wave-ui.css +1 -1
- package/dist/wave-ui.es.js +892 -688
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +14 -15
- package/src/wave-ui/components/index.js +1 -0
- package/src/wave-ui/components/w-autocomplete.vue +309 -0
- package/src/wave-ui/components/w-card.vue +2 -0
- package/src/wave-ui/components/w-input.vue +13 -11
- package/src/wave-ui/components/w-list.vue +2 -2
- package/src/wave-ui/components/w-select.vue +60 -47
- package/src/wave-ui/components/w-textarea.vue +0 -1
|
@@ -10,7 +10,7 @@ component(
|
|
|
10
10
|
template(v-if="labelPosition === 'left'")
|
|
11
11
|
label.w-select__label.w-select__label--left.w-form-el-shakable(
|
|
12
12
|
v-if="$slots.default || label"
|
|
13
|
-
|
|
13
|
+
@click="$refs['selection-input'].click()"
|
|
14
14
|
:class="labelClasses")
|
|
15
15
|
slot {{ label }}
|
|
16
16
|
|
|
@@ -24,10 +24,9 @@ component(
|
|
|
24
24
|
custom
|
|
25
25
|
min-width="activator"
|
|
26
26
|
v-bind="menuProps || {}")
|
|
27
|
-
template(#activator
|
|
27
|
+
template(#activator)
|
|
28
28
|
//- Input wrapper.
|
|
29
29
|
.w-select__selection-wrap(
|
|
30
|
-
v-on="on"
|
|
31
30
|
@click="!isDisabled && !isReadonly && onInputFieldClick()"
|
|
32
31
|
role="button"
|
|
33
32
|
aria-haspopup="listbox"
|
|
@@ -44,17 +43,11 @@ component(
|
|
|
44
43
|
slot(name="selection" :item="multiple ? inputValue : inputValue[0]")
|
|
45
44
|
.w-select__selection(
|
|
46
45
|
ref="selection-input"
|
|
47
|
-
:contenteditable="isDisabled || isReadonly ? 'false' : 'true'"
|
|
48
46
|
@focus="!isDisabled && !isReadonly && onFocus($event)"
|
|
49
47
|
@blur="onBlur"
|
|
50
48
|
@keydown="!isDisabled && !isReadonly && onKeydown($event)"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
:disabled="isDisabled || null"
|
|
54
|
-
readonly
|
|
55
|
-
aria-readonly="true"
|
|
56
|
-
:tabindex="tabindex || null"
|
|
57
|
-
v-html="$slots.selection ? '' : selectionString || placeholder")
|
|
49
|
+
v-bind="selectionAttributes"
|
|
50
|
+
v-html="selectionHtml")
|
|
58
51
|
//- For standard HTML form submission.
|
|
59
52
|
input(
|
|
60
53
|
v-for="(val, i) in (inputValue.length ? inputValue : [{}])"
|
|
@@ -65,7 +58,6 @@ component(
|
|
|
65
58
|
template(v-if="labelPosition === 'inside' && showLabelInside")
|
|
66
59
|
label.w-select__label.w-select__label--inside.w-form-el-shakable(
|
|
67
60
|
v-if="$slots.default || label"
|
|
68
|
-
:for="`w-select--${_.uid}`"
|
|
69
61
|
:class="labelClasses")
|
|
70
62
|
slot {{ label }}
|
|
71
63
|
w-icon.w-select__icon.w-select__icon--inner-right(
|
|
@@ -79,7 +71,7 @@ component(
|
|
|
79
71
|
@item-click="$emit('item-click', $event)"
|
|
80
72
|
@item-select="onListItemSelect"
|
|
81
73
|
@keydown:enter="noUnselect && !multiple && closeMenu()"
|
|
82
|
-
@keydown:escape="showMenu && (
|
|
74
|
+
@keydown:escape="showMenu && (showMenu = false) /* Will call closeMenu() from w-menu(@close). */"
|
|
83
75
|
:items="selectItems"
|
|
84
76
|
:multiple="multiple"
|
|
85
77
|
arrows-navigation
|
|
@@ -90,7 +82,7 @@ component(
|
|
|
90
82
|
:item-color-key="itemColorKey"
|
|
91
83
|
role="listbox"
|
|
92
84
|
tabindex="-1")
|
|
93
|
-
template(v-for="i in items.length"
|
|
85
|
+
template(v-for="i in items.length" #[`item.${i}`]="{ item, selected, index }")
|
|
94
86
|
slot(
|
|
95
87
|
v-if="$slots[`item.${i}`] && $slots[`item.${i}`](item, selected, index)"
|
|
96
88
|
:name="`item.${i}`"
|
|
@@ -103,7 +95,7 @@ component(
|
|
|
103
95
|
template(v-if="labelPosition === 'right'")
|
|
104
96
|
label.w-select__label.w-select__label--right.w-form-el-shakable(
|
|
105
97
|
v-if="$slots.default || label"
|
|
106
|
-
|
|
98
|
+
@click="$refs['selection-input'].click()"
|
|
107
99
|
:class="labelClasses")
|
|
108
100
|
slot {{ label }}
|
|
109
101
|
</template>
|
|
@@ -181,20 +173,32 @@ export default {
|
|
|
181
173
|
return obj
|
|
182
174
|
})
|
|
183
175
|
},
|
|
184
|
-
hasValue () {
|
|
185
|
-
return Array.isArray(this.inputValue) ? this.inputValue.length : (this.inputValue !== null)
|
|
186
|
-
},
|
|
187
176
|
hasLabel () {
|
|
188
177
|
return this.label || this.$slots.default
|
|
189
178
|
},
|
|
190
179
|
showLabelInside () {
|
|
191
|
-
return !this.staticLabel || (!this.
|
|
180
|
+
return !this.staticLabel || (!this.inputValue.length && !this.placeholder)
|
|
181
|
+
},
|
|
182
|
+
selectionAttributes () {
|
|
183
|
+
return {
|
|
184
|
+
class: { 'w-select__selection--placeholder': !this.$slots.selection && !this.selectionString && this.placeholder },
|
|
185
|
+
disabled: this.isDisabled || null,
|
|
186
|
+
readonly: true,
|
|
187
|
+
ariareadonly: 'true',
|
|
188
|
+
tabindex: this.tabindex ?? null,
|
|
189
|
+
contenteditable: this.isDisabled || this.isReadonly ? 'false' : 'true'
|
|
190
|
+
}
|
|
192
191
|
},
|
|
193
192
|
selectionString () {
|
|
194
|
-
return this.inputValue
|
|
193
|
+
return this.inputValue.map(
|
|
195
194
|
item => item[this.itemValueKey] !== undefined ? item[this.itemLabelKey] : (item[this.itemLabelKey] ?? item)
|
|
196
195
|
).join(', ')
|
|
197
196
|
},
|
|
197
|
+
selectionHtml () {
|
|
198
|
+
if (!this.inputValue.length) return this.placeholder || ''
|
|
199
|
+
if (this.$slots.selection) return ''
|
|
200
|
+
return this.selectionString
|
|
201
|
+
},
|
|
198
202
|
classes () {
|
|
199
203
|
return {
|
|
200
204
|
'w-select': true,
|
|
@@ -203,7 +207,7 @@ export default {
|
|
|
203
207
|
'w-select--disabled': this.isDisabled,
|
|
204
208
|
'w-select--fit-to-content': this.fitToContent,
|
|
205
209
|
'w-select--readonly': this.isReadonly,
|
|
206
|
-
[`w-select--${this.
|
|
210
|
+
[`w-select--${this.inputValue.length ? 'filled' : 'empty'}`]: true,
|
|
207
211
|
'w-select--focused': (this.isFocused || this.showMenu) && !this.isReadonly,
|
|
208
212
|
'w-select--floating-label': this.hasLabel && this.labelPosition === 'inside' && !this.staticLabel,
|
|
209
213
|
'w-select--no-padding': !this.outline && !this.bgColor && !this.shadow && !this.round,
|
|
@@ -274,7 +278,25 @@ export default {
|
|
|
274
278
|
index = (index + items.length + direction) % items.length
|
|
275
279
|
}
|
|
276
280
|
|
|
277
|
-
|
|
281
|
+
// If the current item is disabled, find the next one enabled (forward or backward).
|
|
282
|
+
let allItemsAreDisabled = false
|
|
283
|
+
if (items[index].disabled) {
|
|
284
|
+
const direction = e.keyCode === 38 ? -1 : 1 // Prev or next.
|
|
285
|
+
|
|
286
|
+
// Modulo to prevent out of range; + items.length to also work with negative values.
|
|
287
|
+
let newIndex = (index + direction + items.length) % items.length
|
|
288
|
+
const itemsCount = items.length
|
|
289
|
+
let loop = 0 // While-safety: will always end at least after 1 full array cycle.
|
|
290
|
+
while (loop < itemsCount && items[newIndex].disabled) {
|
|
291
|
+
// Circle through the array of items forward or backward, and reloop when out of range.
|
|
292
|
+
newIndex = (newIndex + items.length + direction) % items.length
|
|
293
|
+
loop++
|
|
294
|
+
}
|
|
295
|
+
if (loop >= itemsCount) allItemsAreDisabled = true
|
|
296
|
+
index = newIndex
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (!allItemsAreDisabled) this.onInput(items[index])
|
|
278
300
|
}
|
|
279
301
|
}
|
|
280
302
|
},
|
|
@@ -283,7 +305,7 @@ export default {
|
|
|
283
305
|
onInput (items) {
|
|
284
306
|
this.inputValue = items === null ? [] : (this.multiple ? items : [items])
|
|
285
307
|
// Return the original items when returnObject is true (no `value` if there wasn't),
|
|
286
|
-
// or the
|
|
308
|
+
// or the item value otherwise.
|
|
287
309
|
items = this.inputValue.map(item => this.returnObject ? this.items[item.index] : item.value)
|
|
288
310
|
|
|
289
311
|
// Emit the selection to the v-model.
|
|
@@ -292,6 +314,7 @@ export default {
|
|
|
292
314
|
this.$emit('update:modelValue', selection)
|
|
293
315
|
this.$emit('input', selection)
|
|
294
316
|
},
|
|
317
|
+
|
|
295
318
|
onInputFieldClick () {
|
|
296
319
|
if (this.showMenu) this.showMenu = false // Will call `closeMenu()` from w-menu(@close).
|
|
297
320
|
else this.openMenu()
|
|
@@ -324,7 +347,7 @@ export default {
|
|
|
324
347
|
return items.map(item => {
|
|
325
348
|
let value = item
|
|
326
349
|
if (item && typeof item === 'object') { // `null` is also an object!
|
|
327
|
-
value = item[this.itemValueKey]
|
|
350
|
+
value = item[this.itemValueKey] ?? item[this.itemLabelKey] ?? item
|
|
328
351
|
}
|
|
329
352
|
|
|
330
353
|
return this.selectItems[allValues.indexOf(value)]
|
|
@@ -459,6 +482,9 @@ export default {
|
|
|
459
482
|
align-items: center;
|
|
460
483
|
cursor: pointer;
|
|
461
484
|
caret-color: transparent;
|
|
485
|
+
border-radius: inherit;
|
|
486
|
+
|
|
487
|
+
&--placeholder {color: #888;}
|
|
462
488
|
|
|
463
489
|
.w-select__selection-slot + & {
|
|
464
490
|
position: absolute;
|
|
@@ -485,8 +511,6 @@ export default {
|
|
|
485
511
|
}
|
|
486
512
|
|
|
487
513
|
.w-select--readonly & {cursor: auto;}
|
|
488
|
-
|
|
489
|
-
&--placeholder {color: #888;}
|
|
490
514
|
}
|
|
491
515
|
|
|
492
516
|
&__selection-slot {
|
|
@@ -512,8 +536,8 @@ export default {
|
|
|
512
536
|
-webkit-tap-highlight-color: transparent;
|
|
513
537
|
}
|
|
514
538
|
|
|
515
|
-
&--inner-left {left:
|
|
516
|
-
&--inner-right {right:
|
|
539
|
+
&--inner-left {left: $base-increment;}
|
|
540
|
+
&--inner-right {right: $base-increment;}
|
|
517
541
|
.w-select--no-padding &--inner-left {left: 1px;}
|
|
518
542
|
.w-select--no-padding &--inner-right {right: 1px;}
|
|
519
543
|
|
|
@@ -548,17 +572,15 @@ export default {
|
|
|
548
572
|
|
|
549
573
|
&__label--inside {
|
|
550
574
|
position: absolute;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
right: 0;
|
|
575
|
+
inset: 0 0 auto;
|
|
576
|
+
min-height: inherit;
|
|
554
577
|
white-space: nowrap;
|
|
555
578
|
// Use margin instead of padding as the scale transformation below decreases the real padding
|
|
556
579
|
// size and misaligns the label.
|
|
557
580
|
margin-left: 2 * $base-increment;
|
|
558
|
-
transform: translateY(-50%);
|
|
559
581
|
pointer-events: none;
|
|
560
582
|
|
|
561
|
-
.w-select--inner-icon-right & {padding-right:
|
|
583
|
+
.w-select--inner-icon-right & {padding-right: 26px;}
|
|
562
584
|
|
|
563
585
|
.w-select--no-padding & {
|
|
564
586
|
left: 0;
|
|
@@ -575,28 +597,19 @@ export default {
|
|
|
575
597
|
transition: $transition-duration ease;
|
|
576
598
|
}
|
|
577
599
|
|
|
578
|
-
//
|
|
579
|
-
.w-select--focused.w-select--floating-label &,
|
|
600
|
+
// Move label with underline style.
|
|
580
601
|
.w-select--open.w-select--floating-label &,
|
|
581
602
|
.w-select--filled.w-select--floating-label &,
|
|
582
603
|
.w-select--has-placeholder.w-select--floating-label & {
|
|
583
|
-
transform: translateY(-
|
|
604
|
+
transform: translateY(-80%) scale(0.85);
|
|
584
605
|
}
|
|
585
|
-
// Chrome & Safari - Must
|
|
606
|
+
// Chrome & Safari - Must stay a separated rule or Firefox discards the whole rule seeing -webkit-.
|
|
586
607
|
.w-select--floating-label .w-select__select:-webkit-autofill & {
|
|
587
|
-
transform: translateY(-
|
|
588
|
-
}
|
|
589
|
-
// Move label with outline style or with shadow.
|
|
590
|
-
.w-select--focused.w-select--floating-label .w-select__selection-wrap--box &,
|
|
591
|
-
.w-select--open.w-select--floating-label .w-select__selection-wrap--box &,
|
|
592
|
-
.w-select--filled.w-select--floating-label .w-select__selection-wrap--box &,
|
|
593
|
-
.w-select--has-placeholder.w-select--floating-label .w-select__selection-wrap--box & {
|
|
594
|
-
transform: translateY(-180%) scale(0.85);
|
|
608
|
+
transform: translateY(-80%) scale(0.85);
|
|
595
609
|
}
|
|
596
|
-
.w-select--focused.w-select--floating-label.w-select--inner-icon-left &,
|
|
597
610
|
.w-select--open.w-select--floating-label.w-select--inner-icon-left &,
|
|
598
611
|
.w-select--filled.w-select--floating-label.w-select--inner-icon-left & {left: 0;}
|
|
599
|
-
// Chrome & Safari - Must
|
|
612
|
+
// Chrome & Safari - Must stay a separated rule or Firefox discards the whole rule seeing -webkit-.
|
|
600
613
|
.w-select--floating-label.w-select--inner-icon-left .w-select__select:-webkit-autofill & {left: 0;}
|
|
601
614
|
}
|
|
602
615
|
|
|
@@ -42,7 +42,6 @@ component(
|
|
|
42
42
|
template(v-if="labelPosition === 'inside' && showLabelInside")
|
|
43
43
|
label.w-textarea__label.w-textarea__label--inside.w-form-el-shakable(
|
|
44
44
|
v-if="$slots.default || label"
|
|
45
|
-
:for="`w-textarea--${_.uid}`"
|
|
46
45
|
:class="labelClasses")
|
|
47
46
|
slot {{ label }}
|
|
48
47
|
w-icon.w-textarea__icon.w-textarea__icon--inner-right(
|