wave-ui 1.60.1 → 1.62.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 +1148 -853
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +2 -2
- package/src/wave-ui/components/index.js +1 -1
- package/src/wave-ui/components/transitions/w-transition-expand.vue +26 -15
- package/src/wave-ui/components/w-confirm.vue +4 -1
- package/src/wave-ui/components/w-dialog.vue +1 -1
- package/src/wave-ui/components/w-drawer.vue +2 -0
- package/src/wave-ui/components/w-icon.vue +1 -0
- package/src/wave-ui/components/w-image.vue +4 -2
- package/src/wave-ui/components/w-input.vue +1 -1
- package/src/wave-ui/components/w-list.vue +1 -1
- package/src/wave-ui/components/w-select.vue +8 -3
- package/src/wave-ui/components/w-switch.vue +1 -1
- package/src/wave-ui/components/w-table.vue +83 -6
- package/src/wave-ui/components/w-tree.vue +300 -0
- package/src/wave-ui/core.js +3 -3
- package/src/wave-ui/scss/_colors.scss +66 -15
- package/src/wave-ui/utils/colors.js +229 -190
- package/src/wave-ui/utils/dynamic-css.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.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",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"lint": "vite lint"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@babel/core": "^7.20.
|
|
51
|
+
"@babel/core": "^7.20.5",
|
|
52
52
|
"@babel/eslint-parser": "^7.19.1",
|
|
53
53
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
54
54
|
"@mdi/font": "^6.9.96",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// Keep all the `.vue` extensions for Vite & Rollup.
|
|
2
1
|
export { default as WAccordion } from './w-accordion.vue'
|
|
3
2
|
export { default as WAlert } from './w-alert.vue'
|
|
4
3
|
export { default as WApp } from './w-app.vue'
|
|
@@ -49,3 +48,4 @@ export { default as WTransitionScaleFade } from './transitions/w-transition-scal
|
|
|
49
48
|
export { default as WTransitionSlide } from './transitions/w-transition-slide.vue'
|
|
50
49
|
export { default as WTransitionSlideFade } from './transitions/w-transition-slide-fade.vue'
|
|
51
50
|
export { default as WTransitionTwist } from './transitions/w-transition-twist.vue'
|
|
51
|
+
export { default as WTree } from './w-tree.vue'
|
|
@@ -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,9 @@
|
|
|
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(
|
|
5
|
+
w-button.w-confirm__button(
|
|
6
|
+
v-on="{ ...$listeners, ...(disablePrompt ? {} : on) }"
|
|
7
|
+
v-bind="buttonProps")
|
|
6
8
|
slot
|
|
7
9
|
w-flex(:column="!inline" align-center)
|
|
8
10
|
div
|
|
@@ -32,6 +34,7 @@ export default {
|
|
|
32
34
|
bgColor: { type: String },
|
|
33
35
|
color: { type: String },
|
|
34
36
|
icon: { type: String },
|
|
37
|
+
disablePrompt: { type: Boolean }, // If true, the confirm button acts like a simple w-button.
|
|
35
38
|
mainButton: { type: Object }, // Allow passing down an object of props to the w-button component.
|
|
36
39
|
question: { type: String, default: 'Are you sure?' },
|
|
37
40
|
|
|
@@ -78,6 +78,7 @@ export default {
|
|
|
78
78
|
absolute: { type: Boolean },
|
|
79
79
|
overlayColor: { type: String },
|
|
80
80
|
overlayOpacity: { type: [Number, String, Boolean] },
|
|
81
|
+
drawerClass: { type: String },
|
|
81
82
|
tag: { type: String, default: 'aside' }
|
|
82
83
|
},
|
|
83
84
|
|
|
@@ -127,6 +128,7 @@ export default {
|
|
|
127
128
|
},
|
|
128
129
|
drawerClasses () {
|
|
129
130
|
return {
|
|
131
|
+
[this.drawerClass]: true,
|
|
130
132
|
[this.color]: this.color,
|
|
131
133
|
[`${this.bgColor}--bg`]: this.bgColor,
|
|
132
134
|
'w-drawer--open': !!this.showDrawer,
|
|
@@ -128,6 +128,7 @@ export default {
|
|
|
128
128
|
.w-button.size--lg &, .w-alert.size--lg & {font-size: round(1.7 * $base-font-size);}
|
|
129
129
|
.w-button.size--xl &, .w-alert.size--xl & {font-size: 2 * $base-font-size;}
|
|
130
130
|
|
|
131
|
+
&:before {transition: transform $transition-duration;}
|
|
131
132
|
&--spin:before {animation: w-icon--spin 2s infinite linear;}
|
|
132
133
|
&--spin-a:before {animation: w-icon--spin-a 2s infinite linear;}
|
|
133
134
|
&--rotate45:before {transform: rotate(45deg);}
|
|
@@ -9,7 +9,7 @@ component.w-image-wrap(:is="wrapperTag" :class="wrapperClasses" :style="wrapperS
|
|
|
9
9
|
:src="tag === 'img' ? imgSrc : null")
|
|
10
10
|
.w-image__loader(v-if="!noSpinner && loading")
|
|
11
11
|
slot(v-if="$slots.loading" name="loading")
|
|
12
|
-
w-progress(v-else circle indeterminate)
|
|
12
|
+
w-progress(v-else circle indeterminate v-bind="spinnerColor ? { color: spinnerColor } : {}")
|
|
13
13
|
component.w-image__content(v-if="$slots.default" :is="wrapperTag" :class="contentClass")
|
|
14
14
|
slot
|
|
15
15
|
</template>
|
|
@@ -22,9 +22,10 @@ component.w-image-wrap(:is="wrapperTag" :class="wrapperClasses" :style="wrapperS
|
|
|
22
22
|
* - adaptive size: given ratio + width 100% (use bg)
|
|
23
23
|
* - adaptive size: given ratio + height 100% (use bg)
|
|
24
24
|
* - adaptive & locked size: given width or height and using <img>
|
|
25
|
+
*
|
|
26
|
+
* @todo handle figure, captions, srcset, webp.
|
|
25
27
|
**/
|
|
26
28
|
|
|
27
|
-
// @todo handle figure, captions, srcset, webp.
|
|
28
29
|
import { consoleWarn } from '../utils/console'
|
|
29
30
|
|
|
30
31
|
export default {
|
|
@@ -40,6 +41,7 @@ export default {
|
|
|
40
41
|
fixed: { type: Boolean },
|
|
41
42
|
contain: { type: Boolean },
|
|
42
43
|
noSpinner: { type: Boolean },
|
|
44
|
+
spinnerColor: { type: String },
|
|
43
45
|
fallback: { type: String },
|
|
44
46
|
transition: { type: String, default: 'fade' },
|
|
45
47
|
contentClass: { type: [String, Array, Object] }
|
|
@@ -302,7 +302,7 @@ export default {
|
|
|
302
302
|
// eslint-disable-next-line vue/custom-event-name-casing
|
|
303
303
|
else if (e.keyCode === 27) this.$emit('keydown:escape')
|
|
304
304
|
// On arrow keys press, navigate to prev/next item.
|
|
305
|
-
else if (this.arrowsNavigation) {
|
|
305
|
+
else if (this.arrowsNavigation && [38, 40].includes(e.keyCode)) {
|
|
306
306
|
e.preventDefault()
|
|
307
307
|
if (e.keyCode === 38) this.focusPrevNextItem(li._index, false)
|
|
308
308
|
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(
|
|
@@ -299,7 +299,7 @@ export default {
|
|
|
299
299
|
// Also accept objects if returnObject is true.
|
|
300
300
|
// In any case, always end up with an array.
|
|
301
301
|
checkSelection (items) {
|
|
302
|
-
items = Array.isArray(items) ? items : (items ? [items] : [])
|
|
302
|
+
items = Array.isArray(items) ? items : (items !== undefined ? [items] : [])
|
|
303
303
|
// `selectItems` items always have a value.
|
|
304
304
|
const allValues = this.selectItems.map(item => item.value)
|
|
305
305
|
|
|
@@ -424,8 +424,10 @@ export default {
|
|
|
424
424
|
&__selection {
|
|
425
425
|
width: 100%;
|
|
426
426
|
height: 100%;
|
|
427
|
-
|
|
427
|
+
min-height: inherit;
|
|
428
|
+
font: inherit;
|
|
428
429
|
color: inherit;
|
|
430
|
+
text-align: inherit;
|
|
429
431
|
background: none;
|
|
430
432
|
border: none;
|
|
431
433
|
outline: none;
|
|
@@ -522,12 +524,15 @@ export default {
|
|
|
522
524
|
position: absolute;
|
|
523
525
|
top: 50%;
|
|
524
526
|
left: 0;
|
|
527
|
+
right: 0;
|
|
525
528
|
// Use margin instead of padding as the scale transformation bellow decreases the real padding
|
|
526
529
|
// size and misaligns the label.
|
|
527
530
|
margin-left: 2 * $base-increment;
|
|
528
531
|
transform: translateY(-50%);
|
|
529
532
|
pointer-events: none;
|
|
530
533
|
|
|
534
|
+
.w-select--inner-icon-right & {padding-right: 22px;}
|
|
535
|
+
|
|
531
536
|
.w-select--no-padding & {
|
|
532
537
|
left: 0;
|
|
533
538
|
margin-left: 0;
|
|
@@ -38,7 +38,7 @@ component(
|
|
|
38
38
|
v-if="loading"
|
|
39
39
|
circle
|
|
40
40
|
color="inherit"
|
|
41
|
-
v-bind="typeof loading === 'number' ? {
|
|
41
|
+
v-bind="typeof loading === 'number' ? { value: loading } : {}")
|
|
42
42
|
slot(v-else name="thumb")
|
|
43
43
|
template(v-if="hasLabel && !labelOnLeft")
|
|
44
44
|
label.w-switch__label.w-switch__label--right.w-form-el-shakable(
|
|
@@ -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.
|