wave-ui 2.47.0 → 2.48.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 +1094 -1023
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +1 -1
- package/src/wave-ui/components/transitions/w-transition-expand.vue +26 -15
- package/src/wave-ui/components/w-confirm.vue +2 -1
- package/src/wave-ui/components/w-list.vue +1 -1
- package/src/wave-ui/components/w-select.vue +9 -3
- package/src/wave-ui/components/w-table.vue +83 -6
- package/src/wave-ui/components/w-tree.vue +12 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.48.0",
|
|
4
4
|
"description": "An emerging UI framework for Vue.js (2 & 3) with only the bright side. :sunny:",
|
|
5
5
|
"author": "Antoni Andre <antoniandre.web@gmail.com>",
|
|
6
6
|
"homepage": "https://antoniandre.github.io/wave-ui",
|
|
@@ -27,6 +27,7 @@ export default {
|
|
|
27
27
|
|
|
28
28
|
data: () => ({
|
|
29
29
|
el: {
|
|
30
|
+
savedState: false,
|
|
30
31
|
originalStyles: '',
|
|
31
32
|
width: 0,
|
|
32
33
|
height: 0,
|
|
@@ -59,7 +60,7 @@ export default {
|
|
|
59
60
|
beforeAppear (el) {
|
|
60
61
|
// Only save original state once before a 'clean' transition start.
|
|
61
62
|
// Not when clicking very fast and mixing states order.
|
|
62
|
-
if (this.cleanTransitionCycle) this.
|
|
63
|
+
if (this.cleanTransitionCycle) this.saveOriginalInlineStyles(el)
|
|
63
64
|
this.cleanTransitionCycle = false
|
|
64
65
|
},
|
|
65
66
|
appear (el, done) {
|
|
@@ -76,7 +77,7 @@ export default {
|
|
|
76
77
|
beforeEnter (el) {
|
|
77
78
|
// Only save original state once before a 'clean' transition start.
|
|
78
79
|
// Not when clicking very fast and mixing states order.
|
|
79
|
-
if (this.cleanTransitionCycle) this.
|
|
80
|
+
if (this.cleanTransitionCycle) this.saveOriginalInlineStyles(el)
|
|
80
81
|
this.cleanTransitionCycle = false
|
|
81
82
|
},
|
|
82
83
|
enter (el, done) {
|
|
@@ -91,6 +92,9 @@ export default {
|
|
|
91
92
|
this.cleanTransitionCycle = false
|
|
92
93
|
},
|
|
93
94
|
beforeLeave (el) {
|
|
95
|
+
// When starting with an open item.
|
|
96
|
+
if (!this.el.savedState) this.saveComputedStyles(el)
|
|
97
|
+
|
|
94
98
|
this.beforeHide(el)
|
|
95
99
|
this.cleanTransitionCycle = false
|
|
96
100
|
},
|
|
@@ -102,6 +106,9 @@ export default {
|
|
|
102
106
|
afterLeave (el) {
|
|
103
107
|
this.applyOriginalStyles(el)
|
|
104
108
|
this.cleanTransitionCycle = true
|
|
109
|
+
// Reset for recomputing the next time we start the transition from an open state.
|
|
110
|
+
// In case there might be some changed styles from last closing.
|
|
111
|
+
this.el.savedState = false
|
|
105
112
|
},
|
|
106
113
|
|
|
107
114
|
applyHideStyles (el) {
|
|
@@ -151,11 +158,25 @@ export default {
|
|
|
151
158
|
applyOriginalStyles (el) {
|
|
152
159
|
el.style.cssText = this.el.originalStyles
|
|
153
160
|
},
|
|
154
|
-
|
|
155
|
-
// Keep
|
|
161
|
+
saveOriginalInlineStyles (el) {
|
|
162
|
+
// Keep any original inline styles to restore them after transition.
|
|
156
163
|
this.el.originalStyles = el.style.cssText
|
|
157
164
|
},
|
|
158
165
|
show (el, done) {
|
|
166
|
+
this.saveComputedStyles(el)
|
|
167
|
+
this.applyHideStyles(el)
|
|
168
|
+
|
|
169
|
+
setTimeout(() => this.applyShowStyles(el), 20)
|
|
170
|
+
setTimeout(done, this.duration)
|
|
171
|
+
},
|
|
172
|
+
beforeHide (el) {
|
|
173
|
+
this.applyShowStyles(el)
|
|
174
|
+
},
|
|
175
|
+
hide (el, done) {
|
|
176
|
+
setTimeout(() => this.applyHideStyles(el), 20)
|
|
177
|
+
setTimeout(done, this.duration)
|
|
178
|
+
},
|
|
179
|
+
saveComputedStyles (el) {
|
|
159
180
|
const computedStyles = window.getComputedStyle(el, null)
|
|
160
181
|
|
|
161
182
|
// Save the width & height then set them to 0 as the animation starting point.
|
|
@@ -177,17 +198,7 @@ export default {
|
|
|
177
198
|
this.el.borderTopWidth = computedStyles.getPropertyValue('borderTopWidth')
|
|
178
199
|
this.el.borderBottomWidth = computedStyles.getPropertyValue('borderBottomWidth')
|
|
179
200
|
}
|
|
180
|
-
this.
|
|
181
|
-
|
|
182
|
-
setTimeout(() => this.applyShowStyles(el), 20)
|
|
183
|
-
setTimeout(done, this.duration)
|
|
184
|
-
},
|
|
185
|
-
beforeHide (el) {
|
|
186
|
-
this.applyShowStyles(el)
|
|
187
|
-
},
|
|
188
|
-
hide (el, done) {
|
|
189
|
-
setTimeout(() => this.applyHideStyles(el), 20)
|
|
190
|
-
setTimeout(done, this.duration)
|
|
201
|
+
this.el.savedState = true
|
|
191
202
|
}
|
|
192
203
|
}
|
|
193
204
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
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-bind="{ ...$attrs, ...buttonProps, ...on }")
|
|
5
|
+
w-button.w-confirm__button(v-bind="{ ...$attrs, ...buttonProps, ...(disablePrompt ? {} : on) }")
|
|
6
6
|
slot
|
|
7
7
|
w-flex(:column="!inline" align-center)
|
|
8
8
|
div
|
|
@@ -32,6 +32,7 @@ export default {
|
|
|
32
32
|
bgColor: { type: String },
|
|
33
33
|
color: { type: String },
|
|
34
34
|
icon: { type: String },
|
|
35
|
+
disablePrompt: { type: Boolean }, // If true, the confirm button acts like a simple w-button.
|
|
35
36
|
mainButton: { type: Object }, // Allow passing down an object of props to the w-button component.
|
|
36
37
|
question: { type: String, default: 'Are you sure?' },
|
|
37
38
|
|
|
@@ -194,7 +194,7 @@ export default {
|
|
|
194
194
|
// eslint-disable-next-line vue/custom-event-name-casing
|
|
195
195
|
else if (e.keyCode === 27) this.$emit('keydown:escape')
|
|
196
196
|
// On arrow keys press, navigate to prev/next item.
|
|
197
|
-
else if (this.arrowsNavigation) {
|
|
197
|
+
else if (this.arrowsNavigation && [38, 40].includes(e.keyCode)) {
|
|
198
198
|
e.preventDefault()
|
|
199
199
|
if (e.keyCode === 38) this.focusPrevNextItem(li._index, false)
|
|
200
200
|
if (e.keyCode === 40) this.focusPrevNextItem(li._index, true)
|
|
@@ -60,7 +60,7 @@ component(
|
|
|
60
60
|
v-for="(val, i) in (inputValue.length ? inputValue : [{}])"
|
|
61
61
|
:key="i"
|
|
62
62
|
type="hidden"
|
|
63
|
-
:value="val.value
|
|
63
|
+
:value="val.value === undefined ? '' : val.value.toString()"
|
|
64
64
|
:name="inputName + (multiple ? '[]' : '')")
|
|
65
65
|
template(v-if="labelPosition === 'inside' && showLabelInside")
|
|
66
66
|
label.w-select__label.w-select__label--inside.w-form-el-shakable(
|
|
@@ -298,7 +298,8 @@ export default {
|
|
|
298
298
|
// Also accept objects if returnObject is true.
|
|
299
299
|
// In any case, always end up with an array.
|
|
300
300
|
checkSelection (items) {
|
|
301
|
-
|
|
301
|
+
console.log(items)
|
|
302
|
+
items = Array.isArray(items) ? items : (items !== undefined ? [items] : [])
|
|
302
303
|
// `selectItems` items always have a value.
|
|
303
304
|
const allValues = this.selectItems.map(item => item.value)
|
|
304
305
|
|
|
@@ -423,8 +424,10 @@ export default {
|
|
|
423
424
|
&__selection {
|
|
424
425
|
width: 100%;
|
|
425
426
|
height: 100%;
|
|
426
|
-
|
|
427
|
+
min-height: inherit;
|
|
428
|
+
font: inherit;
|
|
427
429
|
color: inherit;
|
|
430
|
+
text-align: inherit;
|
|
428
431
|
background: none;
|
|
429
432
|
border: none;
|
|
430
433
|
outline: none;
|
|
@@ -521,12 +524,15 @@ export default {
|
|
|
521
524
|
position: absolute;
|
|
522
525
|
top: 50%;
|
|
523
526
|
left: 0;
|
|
527
|
+
right: 0;
|
|
524
528
|
// Use margin instead of padding as the scale transformation bellow decreases the real padding
|
|
525
529
|
// size and misaligns the label.
|
|
526
530
|
margin-left: 2 * $base-increment;
|
|
527
531
|
transform: translateY(-50%);
|
|
528
532
|
pointer-events: none;
|
|
529
533
|
|
|
534
|
+
.w-select--inner-icon-right & {padding-right: 22px;}
|
|
535
|
+
|
|
530
536
|
.w-select--no-padding & {
|
|
531
537
|
left: 0;
|
|
532
538
|
margin-left: 0;
|
|
@@ -128,12 +128,34 @@
|
|
|
128
128
|
slot(name="extra-row")
|
|
129
129
|
|
|
130
130
|
//- Table footer.
|
|
131
|
-
tfoot.w-table__footer(v-if="$slots.footer || $slots['footer-row']")
|
|
131
|
+
tfoot.w-table__footer(v-if="$slots.footer || $slots['footer-row'] || pagination")
|
|
132
132
|
slot(v-if="$slots['footer-row']" name="footer-row")
|
|
133
|
-
tr.w-table__row(v-else)
|
|
133
|
+
tr.w-table__row(v-else-if="$slots.footer")
|
|
134
134
|
td.w-table__cell(:colspan="headers.length")
|
|
135
135
|
slot(name="footer")
|
|
136
|
-
|
|
136
|
+
tr.w-table__row.w-table__pagination-wrap(v-if="pagination && paginationConfig")
|
|
137
|
+
td.w-table__cell(:colspan="headers.length")
|
|
138
|
+
.w-table__pagination
|
|
139
|
+
w-select.pagination-number.pagination-number--items-per-page(
|
|
140
|
+
v-if="paginationConfig.itemsPerPageOptions"
|
|
141
|
+
v-model="paginationConfig.itemsPerPage"
|
|
142
|
+
:items="paginationConfig.itemsPerPageOptions"
|
|
143
|
+
label-position="left"
|
|
144
|
+
label="Items per page"
|
|
145
|
+
label-color="inherit")
|
|
146
|
+
span.pagination-number.pagination-number--results.
|
|
147
|
+
{{ paginationConfig.start }}-{{ paginationConfig.end }} of {{ paginationConfig.total }}
|
|
148
|
+
.pagination-arrows
|
|
149
|
+
w-button.pagination-arrow.pagination-arrow--prev(
|
|
150
|
+
@click="paginationConfig.page--"
|
|
151
|
+
icon="wi-chevron-left"
|
|
152
|
+
text
|
|
153
|
+
lg)
|
|
154
|
+
w-button.pagination-arrow.pagination-arrow--next(
|
|
155
|
+
@click="paginationConfig.page++"
|
|
156
|
+
icon="wi-chevron-right"
|
|
157
|
+
text
|
|
158
|
+
lg)
|
|
137
159
|
</template>
|
|
138
160
|
|
|
139
161
|
<script>
|
|
@@ -189,13 +211,28 @@ export default {
|
|
|
189
211
|
|
|
190
212
|
forceSelection: { type: Boolean },
|
|
191
213
|
|
|
192
|
-
// Useful to select or expand a row, and even after a filter, the same row will stay selected or
|
|
214
|
+
// Useful to select or expand a row, and even after a filter, the same row will stay selected or expanded.
|
|
193
215
|
uidKey: { type: String, default: 'id' },
|
|
194
216
|
|
|
195
217
|
filter: { type: Function },
|
|
196
218
|
sortFunction: { type: Function },
|
|
197
219
|
mobileBreakpoint: { type: Number, default: 0 },
|
|
198
|
-
resizableColumns: { type: Boolean }
|
|
220
|
+
resizableColumns: { type: Boolean },
|
|
221
|
+
|
|
222
|
+
pagination: {
|
|
223
|
+
type: [Boolean, Object, String],
|
|
224
|
+
validator: object => {
|
|
225
|
+
if (!object) return true // Accept any falsy value.
|
|
226
|
+
else if (typeof object === 'object' && (!object.itemsPerPage || (object.page && isNaN(object.page)))) {
|
|
227
|
+
consoleError(
|
|
228
|
+
'Wrong pagination config received in the w-table\'s `pagination` prop (received: `' + JSON.stringify(object) + '`). ' +
|
|
229
|
+
'\nExpected object: { itemsPerPage: Integer, page: Integer } or { itemsPerPage: Integer, start: Integer }.'
|
|
230
|
+
)
|
|
231
|
+
return false
|
|
232
|
+
}
|
|
233
|
+
return true
|
|
234
|
+
}
|
|
235
|
+
}
|
|
199
236
|
},
|
|
200
237
|
|
|
201
238
|
emits: [
|
|
@@ -222,7 +259,8 @@ export default {
|
|
|
222
259
|
nextColWidth: null,
|
|
223
260
|
columnEl: null,
|
|
224
261
|
nextColumnEl: null
|
|
225
|
-
}
|
|
262
|
+
},
|
|
263
|
+
paginationConfig: {}
|
|
226
264
|
}),
|
|
227
265
|
|
|
228
266
|
computed: {
|
|
@@ -490,6 +528,20 @@ export default {
|
|
|
490
528
|
this.colResizing.colWidth = null
|
|
491
529
|
this.colResizing.nextColWidth = null
|
|
492
530
|
}, 0)
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
updatePaginationConfig () {
|
|
534
|
+
const itemsPerPage = this.pagination?.itemsPerPage || 10
|
|
535
|
+
const total = this.pagination?.total || this.items.length
|
|
536
|
+
const page = this.pagination?.page || 1
|
|
537
|
+
this.paginationConfig = {
|
|
538
|
+
itemsPerPage,
|
|
539
|
+
itemsPerPageOptions: this.pagination?.itemsPerPageOptions || [{ label: '10', value: 10 }, { label: '100', value: 100 }, { label: 'All', value: 0 }],
|
|
540
|
+
page,
|
|
541
|
+
start: this.pagination?.start || 1,
|
|
542
|
+
end: total >= (itemsPerPage * page) ? (itemsPerPage * page) : (total % (itemsPerPage * page)),
|
|
543
|
+
total
|
|
544
|
+
}
|
|
493
545
|
}
|
|
494
546
|
},
|
|
495
547
|
|
|
@@ -499,6 +551,8 @@ export default {
|
|
|
499
551
|
|
|
500
552
|
if ((this.expandedRows || []).length) this.expandedRowsInternal = this.expandedRows
|
|
501
553
|
if ((this.selectedRows || []).length) this.selectedRowsInternal = this.selectedRows
|
|
554
|
+
|
|
555
|
+
if (this.pagination) this.updatePaginationConfig()
|
|
502
556
|
},
|
|
503
557
|
|
|
504
558
|
watch: {
|
|
@@ -739,6 +793,29 @@ $tr-border-top: 1px;
|
|
|
739
793
|
border-bottom: $border;
|
|
740
794
|
}
|
|
741
795
|
}
|
|
796
|
+
|
|
797
|
+
&__pagination {
|
|
798
|
+
display: flex;
|
|
799
|
+
align-items: center;
|
|
800
|
+
justify-content: flex-end;
|
|
801
|
+
padding-top: $base-increment;
|
|
802
|
+
padding-bottom: $base-increment;
|
|
803
|
+
|
|
804
|
+
.pagination-number--items-per-page {
|
|
805
|
+
margin-right: 6 * $base-increment;
|
|
806
|
+
flex-grow: 0;
|
|
807
|
+
text-align: right;
|
|
808
|
+
}
|
|
809
|
+
.pagination-number--of {
|
|
810
|
+
margin-left: $base-increment;
|
|
811
|
+
margin-right: $base-increment;
|
|
812
|
+
}
|
|
813
|
+
.w-select__selection {max-width: 60px;}
|
|
814
|
+
|
|
815
|
+
.pagination-arrows {
|
|
816
|
+
margin-left: 6 * $base-increment;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
742
819
|
}
|
|
743
820
|
|
|
744
821
|
// Mobile layout.
|
|
@@ -18,7 +18,7 @@ ul.w-tree(:class="classes")
|
|
|
18
18
|
text
|
|
19
19
|
sm)
|
|
20
20
|
slot(name="item-label" :item="item.originalItem" :depth="depth" :open="item.open")
|
|
21
|
-
w-icon(v-if="itemIcon(item)" class="w-tree__item-icon") {{ itemIcon(item) }}
|
|
21
|
+
w-icon(v-if="itemIcon(item)" class="w-tree__item-icon" :color="item.originalItem[itemIconColorKey] || iconColor") {{ itemIcon(item) }}
|
|
22
22
|
span {{ item.label }}
|
|
23
23
|
span.ml1(v-if="counts && (item.children || item.branch)").
|
|
24
24
|
({{ item.originalItem.children?.length || 0 }})
|
|
@@ -70,8 +70,11 @@ export default {
|
|
|
70
70
|
noTransition: { type: Boolean },
|
|
71
71
|
selectable: { type: Boolean },
|
|
72
72
|
// By default it only reacts to items count change (added or deleted items) not property of items change.
|
|
73
|
-
|
|
74
|
-
counts: { type: Boolean }
|
|
73
|
+
deepReactivity: { type: Boolean },
|
|
74
|
+
counts: { type: Boolean },
|
|
75
|
+
itemIconKey: { type: String, default: 'icon' }, // Support a different icon per item.
|
|
76
|
+
iconColor: { type: String }, // Applies a color on all the label item icons.
|
|
77
|
+
itemIconColorKey: { type: String, default: 'iconColor' } // Applies a specific color on each label item icons.
|
|
75
78
|
},
|
|
76
79
|
|
|
77
80
|
emits: ['update:model-value', 'before-open', 'open', 'before-close', 'close', 'click', 'select'],
|
|
@@ -105,7 +108,7 @@ export default {
|
|
|
105
108
|
children: !!item.children, // The children tree remains available in originalItem.
|
|
106
109
|
branch: item.branch,
|
|
107
110
|
depth: this.depth,
|
|
108
|
-
open: oldItems[i]?.open ||
|
|
111
|
+
open: !!(oldItems[i]?.open || this.expandAll)
|
|
109
112
|
})
|
|
110
113
|
})
|
|
111
114
|
},
|
|
@@ -168,6 +171,7 @@ export default {
|
|
|
168
171
|
treeTabbableItems[i + indexModifier] && treeTabbableItems[i + indexModifier].focus()
|
|
169
172
|
return true // Break the loop.
|
|
170
173
|
}
|
|
174
|
+
return false
|
|
171
175
|
})
|
|
172
176
|
}
|
|
173
177
|
}
|
|
@@ -182,6 +186,7 @@ export default {
|
|
|
182
186
|
* @param {String} selector any valid DOM selector to match the siblings.
|
|
183
187
|
*/
|
|
184
188
|
getPreviousSibling (node, selector) {
|
|
189
|
+
// eslint-disable-next-line no-unmodified-loop-condition
|
|
185
190
|
while (selector && (node = node.previousElementSibling)) {
|
|
186
191
|
if (node.matches(selector)) return node
|
|
187
192
|
}
|
|
@@ -195,6 +200,7 @@ export default {
|
|
|
195
200
|
* @param {String} selector any valid DOM selector to match the siblings.
|
|
196
201
|
*/
|
|
197
202
|
getNextSibling (node, selector) {
|
|
203
|
+
// eslint-disable-next-line no-unmodified-loop-condition
|
|
198
204
|
while (selector && (node = node.nextElementSibling)) {
|
|
199
205
|
if (node.matches(selector)) return node
|
|
200
206
|
}
|
|
@@ -207,7 +213,7 @@ export default {
|
|
|
207
213
|
|
|
208
214
|
itemIcon (item) {
|
|
209
215
|
return (
|
|
210
|
-
item.originalItem.
|
|
216
|
+
item.originalItem[this.itemIconKey] ||
|
|
211
217
|
(!item.children && !item.branch && this.leafIcon) ||
|
|
212
218
|
((item.children || item.branch) && ((item.open && this.branchOpenIcon) || this.branchIcon))
|
|
213
219
|
)
|
|
@@ -229,7 +235,7 @@ export default {
|
|
|
229
235
|
// The open property of each item has to be retained from this.currentDepthItems in order to stay
|
|
230
236
|
// in the same state after DOM repaint.
|
|
231
237
|
items => this.updateCurrentDepthTree(items, this.currentDepthItems),
|
|
232
|
-
{ deep: !!this.
|
|
238
|
+
{ deep: !!this.deepReactivity } // Deep watching is more resource consuming. Only enable on user demand.
|
|
233
239
|
)
|
|
234
240
|
},
|
|
235
241
|
|