wave-ui 1.66.0 → 1.67.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 +398 -87
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +7 -5
- package/src/wave-ui/components/index.js +1 -1
- package/src/wave-ui/components/w-button/button.vue +14 -10
- package/src/wave-ui/components/w-card.vue +12 -4
- package/src/wave-ui/components/w-confirm.vue +7 -1
- package/src/wave-ui/components/w-progress.vue +1 -1
- package/src/wave-ui/components/w-rating.vue +2 -1
- package/src/wave-ui/components/w-scrollable.vue +243 -0
- package/src/wave-ui/components/w-select.vue +20 -10
- package/src/wave-ui/components/w-table.vue +214 -64
- package/src/wave-ui/components/w-tabs/index.vue +39 -34
- package/src/wave-ui/components/w-tag.vue +1 -0
- package/src/wave-ui/components/w-tree.vue +104 -29
- package/src/wave-ui/core.js +1 -1
|
@@ -6,11 +6,11 @@ ul.w-tree(:class="classes")
|
|
|
6
6
|
:class="itemClasses(item)")
|
|
7
7
|
//- The keys `route` & `disabled` are always present in any currentDepthItems.
|
|
8
8
|
component.w-tree__item-label(
|
|
9
|
-
:is="
|
|
9
|
+
:is="getTreeItemComponent(item)"
|
|
10
10
|
v-bind="item.route && { [!$router || hasExternalLink(item) ? 'href' : 'to']: item.route }"
|
|
11
11
|
@click="!disabled && !item.disabled && onLabelClick(item, $event)"
|
|
12
12
|
@keydown="!disabled && !item.disabled && onLabelKeydown(item, $event)"
|
|
13
|
-
:tabindex="
|
|
13
|
+
:tabindex="getTreeItemTabindex(item)")
|
|
14
14
|
//- @click.stop to not follow link if item is a link.
|
|
15
15
|
w-button.w-tree__item-expand(
|
|
16
16
|
v-if="(item.children || item.branch) && ((expandOpenIcon && item.open) || expandIcon) && !(unexpandableEmpty && !item.children)"
|
|
@@ -22,21 +22,31 @@ ul.w-tree(:class="classes")
|
|
|
22
22
|
:disabled="disabled || item.disabled"
|
|
23
23
|
text
|
|
24
24
|
sm)
|
|
25
|
-
slot(
|
|
26
|
-
|
|
25
|
+
slot(
|
|
26
|
+
name="item"
|
|
27
|
+
:item="item.originalItem"
|
|
28
|
+
:depth="depth"
|
|
29
|
+
:path="item.path"
|
|
30
|
+
:open="item.open")
|
|
31
|
+
w-icon(
|
|
32
|
+
v-if="itemIcon(item)"
|
|
33
|
+
class="w-tree__item-icon"
|
|
34
|
+
:color="item.originalItem[itemIconColorKey] || iconColor").
|
|
35
|
+
{{ itemIcon(item) }}
|
|
27
36
|
span(v-html="item.label")
|
|
28
37
|
span.ml1(v-if="counts && (item.children || item.branch)").
|
|
29
38
|
({{ item.originalItem.children ? item.originalItem.children.length : 0 }})
|
|
30
39
|
component(
|
|
31
40
|
:is="noTransition ? 'div' : 'w-transition-expand'"
|
|
32
41
|
:y="!noTransition || null"
|
|
33
|
-
@after-enter="$emit('open',
|
|
34
|
-
@after-leave="$emit('close',
|
|
42
|
+
@after-enter="$emit('open', emitPayload(item))"
|
|
43
|
+
@after-leave="$emit('close', emitPayload(item))")
|
|
35
44
|
w-tree(
|
|
36
45
|
v-if="item.children && item.open"
|
|
37
46
|
v-bind="$props"
|
|
38
47
|
:depth="depth + 1"
|
|
39
48
|
:data="item.originalItem.children"
|
|
49
|
+
:parent="item"
|
|
40
50
|
@before-open="$emit('before-open', $event)"
|
|
41
51
|
@open="$emit('open', $event)"
|
|
42
52
|
@before-close="$emit('before-close', $event)"
|
|
@@ -44,8 +54,8 @@ ul.w-tree(:class="classes")
|
|
|
44
54
|
@click="$emit('click', $event)"
|
|
45
55
|
@select="$emit('select', $event)"
|
|
46
56
|
@input="$emit('input', $event)")
|
|
47
|
-
template(#item="{ item, depth, open }")
|
|
48
|
-
slot(name="item" :item="item" :depth="depth" :open="open")
|
|
57
|
+
template(#item="{ item, depth, path, open }")
|
|
58
|
+
slot(name="item" :item="item" :depth="depth" :path="path" :open="open")
|
|
49
59
|
</template>
|
|
50
60
|
|
|
51
61
|
<script>
|
|
@@ -60,7 +70,8 @@ export default {
|
|
|
60
70
|
props: {
|
|
61
71
|
value: { type: [Object, Array] },
|
|
62
72
|
data: { type: [Object, Array], required: true },
|
|
63
|
-
depth: { type: Number, default: 0 },
|
|
73
|
+
depth: { type: Number, default: 0 }, // To get the context from nested items.
|
|
74
|
+
parent: { type: Object, default: null }, // To get the context from nested items.
|
|
64
75
|
branchClass: { type: String },
|
|
65
76
|
leafClass: { type: String },
|
|
66
77
|
branchIcon: { type: String },
|
|
@@ -97,6 +108,7 @@ export default {
|
|
|
97
108
|
return {
|
|
98
109
|
[`w-tree--depth${this.depth}`]: true,
|
|
99
110
|
'w-tree--expand-icon': this.expandIcon && !this.depth,
|
|
111
|
+
'w-tree--selectable': this.selectable,
|
|
100
112
|
'w-tree--disabled': this.disabled && !this.depth,
|
|
101
113
|
'w-tree--no-expand-button': !this.expandIcon
|
|
102
114
|
}
|
|
@@ -115,7 +127,7 @@ export default {
|
|
|
115
127
|
if (!Array.isArray(items)) items = [items]
|
|
116
128
|
|
|
117
129
|
items.forEach((item, i) => {
|
|
118
|
-
|
|
130
|
+
const itemWrapper = {
|
|
119
131
|
originalItem: item, // Store the original item to return it on event emits.
|
|
120
132
|
_uid: this.depth.toString() + (i + 1),
|
|
121
133
|
label: item[this.itemLabelKey],
|
|
@@ -123,12 +135,50 @@ export default {
|
|
|
123
135
|
branch: item.branch,
|
|
124
136
|
route: item[this.itemRouteKey],
|
|
125
137
|
disabled: item[this.itemDisabledKey],
|
|
138
|
+
selected: oldItems[i]?.selected || false,
|
|
126
139
|
depth: this.depth,
|
|
127
|
-
open: !!(oldItems[i]?.open || this.expandAll || item[this.itemOpenKey])
|
|
128
|
-
|
|
140
|
+
open: !!(oldItems[i]?.open || this.expandAll || item[this.itemOpenKey]),
|
|
141
|
+
parent: this.parent || null,
|
|
142
|
+
path: [] // Ancestors path from root to leaf including self.
|
|
143
|
+
}
|
|
144
|
+
itemWrapper.path = this.getTreeItemPath(itemWrapper)
|
|
145
|
+
this.currentDepthItems.push(itemWrapper)
|
|
129
146
|
})
|
|
130
147
|
},
|
|
131
148
|
|
|
149
|
+
getTreeItemComponent (item) {
|
|
150
|
+
return !this.disabled && !item.disabled && item.route ? (!this.$router || this.hasExternalLink(item) ? 'a' : 'router-link') : 'div'
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
getTreeItemTabindex (item) {
|
|
154
|
+
return !this.disabled && !item.disabled && (item.children || item.branch || this.selectable) && !(this.unexpandableEmpty && !item.children) ? 0 : null
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the tree path of the given item.
|
|
159
|
+
* The full ancestors items are stored in the array and not only their `originalItem`s in case
|
|
160
|
+
* it is mutated before we return it to the user through slots and emitted events.
|
|
161
|
+
* Before it is returned to the user, this array is mapped to only give the `originalItem`s.
|
|
162
|
+
*
|
|
163
|
+
* @param {Object} item the tree item to get the ancestors path for.
|
|
164
|
+
* @return an array of item objects from the root to the leaf (including the item itself).
|
|
165
|
+
*/
|
|
166
|
+
getTreeItemPath (item) {
|
|
167
|
+
const ancestorsPath = [item]
|
|
168
|
+
|
|
169
|
+
let ancestor = item.parent
|
|
170
|
+
while (ancestor) {
|
|
171
|
+
ancestorsPath.push(ancestor)
|
|
172
|
+
ancestor = ancestor.parent
|
|
173
|
+
}
|
|
174
|
+
ancestorsPath.reverse()
|
|
175
|
+
return ancestorsPath
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
getTreeItemPathForOutput (item) {
|
|
179
|
+
return item.path.map(item => item.originalItem)
|
|
180
|
+
},
|
|
181
|
+
|
|
132
182
|
/**
|
|
133
183
|
* Expand/collapse the given tree item when possible (not disabled, has children).
|
|
134
184
|
*
|
|
@@ -139,12 +189,12 @@ export default {
|
|
|
139
189
|
if (typeof open === 'boolean') item.open = open
|
|
140
190
|
else item.open = !item.open
|
|
141
191
|
|
|
142
|
-
const
|
|
192
|
+
const emitPayload = this.emitPayload(item)
|
|
143
193
|
|
|
144
|
-
this.$emit(item.open ? 'before-open' : 'before-close',
|
|
194
|
+
this.$emit(item.open ? 'before-open' : 'before-close', emitPayload)
|
|
145
195
|
|
|
146
196
|
if (!this.unexpandableEmpty && !item.children) {
|
|
147
|
-
this.$emit(item.open ? 'open' : 'close',
|
|
197
|
+
this.$emit(item.open ? 'open' : 'close', emitPayload)
|
|
148
198
|
}
|
|
149
199
|
|
|
150
200
|
return true // Just to chain instructions.
|
|
@@ -154,19 +204,12 @@ export default {
|
|
|
154
204
|
const route = item[this.itemRouteKey]
|
|
155
205
|
if (route && this.$router && !this.hasExternalLink(item)) e.preventDefault()
|
|
156
206
|
|
|
157
|
-
this.$emit('click', { item: item.originalItem, depth: this.depth, e })
|
|
158
207
|
if (item.children || (item.branch && !this.unexpandableEmpty)) this.expandDepth(item)
|
|
208
|
+
if (this.selectable) item.selected = !item.selected
|
|
159
209
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
emitItemSelection (item, e) {
|
|
164
|
-
const emitParams = { item: item.originalItem, depth: this.depth, e }
|
|
165
|
-
if (item.children || (item.branch && !this.unexpandableEmpty)) {
|
|
166
|
-
emitParams.open = item.open
|
|
167
|
-
}
|
|
168
|
-
this.$emit('input', emitParams)
|
|
169
|
-
this.$emit('select', emitParams)
|
|
210
|
+
const emitPayload = this.emitPayload(item, e)
|
|
211
|
+
this.$emit('click', emitPayload)
|
|
212
|
+
this.emitItemSelection(item, e) // Always emitting on click, but different event for selection.
|
|
170
213
|
},
|
|
171
214
|
|
|
172
215
|
onLabelKeydown (item, e) {
|
|
@@ -195,7 +238,32 @@ export default {
|
|
|
195
238
|
}
|
|
196
239
|
}
|
|
197
240
|
|
|
198
|
-
if (
|
|
241
|
+
if (e.which === 13) {
|
|
242
|
+
if (this.selectable) item.selected = !item.selected
|
|
243
|
+
// Always emitting on enter keydown, but different event for selection.
|
|
244
|
+
this.emitItemSelection(item, e)
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
emitItemSelection (item, e) {
|
|
249
|
+
const emitPayload = this.emitPayload(item, e)
|
|
250
|
+
|
|
251
|
+
this.$emit('update:model-value', emitPayload)
|
|
252
|
+
if (this.selectable) this.$emit('select', emitPayload)
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
emitPayload (item, e) {
|
|
256
|
+
const emitPayload = {
|
|
257
|
+
item: item.originalItem,
|
|
258
|
+
depth: this.depth,
|
|
259
|
+
path: this.getTreeItemPathForOutput(item)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (e) emitPayload.e = e
|
|
263
|
+
if (item.children || (item.branch && !this.unexpandableEmpty)) emitPayload.open = item.open
|
|
264
|
+
if (this.selectable) emitPayload.selected = item.selected
|
|
265
|
+
|
|
266
|
+
return emitPayload
|
|
199
267
|
},
|
|
200
268
|
|
|
201
269
|
/**
|
|
@@ -246,6 +314,7 @@ export default {
|
|
|
246
314
|
return {
|
|
247
315
|
[item.children || item.branch ? 'w-tree__item--branch' : 'w-tree__item--leaf']: true,
|
|
248
316
|
'w-tree__item--disabled': item[this.itemDisabledKey],
|
|
317
|
+
'w-tree__item--selected': item.selected,
|
|
249
318
|
'w-tree__item--empty': item.branch && !item.children,
|
|
250
319
|
'w-tree__item--unexpandable': item.branch && !item.children && this.unexpandableEmpty
|
|
251
320
|
}
|
|
@@ -299,13 +368,19 @@ $expand-icon-size: 20px;
|
|
|
299
368
|
right: - $base-increment - 2px;
|
|
300
369
|
border-radius: $border-radius;
|
|
301
370
|
}
|
|
302
|
-
&:hover:before {background-color:
|
|
303
|
-
&:focus:before {background-color:
|
|
371
|
+
&:hover:before {background-color: $primary;opacity: 0.1;}
|
|
372
|
+
&:focus-visible:before {background-color: $primary;opacity: 0.15;}
|
|
304
373
|
}
|
|
374
|
+
&.w-tree--selectable &__item-label {cursor: pointer;}
|
|
375
|
+
&.w-tree--selectable &__item--disabled &__item-label {cursor: auto;}
|
|
305
376
|
&__item--leaf &__item-label:before {
|
|
306
377
|
left: - $base-increment;
|
|
307
378
|
right: - $base-increment;
|
|
308
379
|
}
|
|
380
|
+
&__item--selected > &__item-label:before {
|
|
381
|
+
background-color: $primary;
|
|
382
|
+
opacity: 0.25;
|
|
383
|
+
}
|
|
309
384
|
&__item--disabled &__item-label {opacity: 0.5;}
|
|
310
385
|
&__item--disabled &__item-label:before {display: none;}
|
|
311
386
|
|
package/src/wave-ui/core.js
CHANGED
|
@@ -60,7 +60,7 @@ export default class WaveUI {
|
|
|
60
60
|
|
|
61
61
|
// Register a-la-carte components from the given list.
|
|
62
62
|
const { components = {} } = options || {}
|
|
63
|
-
for (
|
|
63
|
+
for (const id in components) {
|
|
64
64
|
const component = components[id]
|
|
65
65
|
// If presets are defined for this component inject them into the props defaults.
|
|
66
66
|
if (options.presets?.[component.name]) injectPresets(component, options.presets[component.name])
|