wave-ui 3.0.5 → 3.1.1
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 +653 -611
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +10 -9
- package/src/wave-ui/components/w-input.vue +4 -1
- package/src/wave-ui/components/w-select.vue +27 -16
- package/src/wave-ui/components/w-table.vue +75 -32
- package/src/wave-ui/components/w-textarea.vue +1 -0
- package/src/wave-ui/scss/_variables.scss +1 -1
- package/src/wave-ui/utils/dynamic-css.js +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
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",
|
|
@@ -49,24 +49,25 @@
|
|
|
49
49
|
"lint": "vite lint"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@babel/core": "^7.21.
|
|
53
|
-
"@babel/eslint-parser": "^7.
|
|
52
|
+
"@babel/core": "^7.21.3",
|
|
53
|
+
"@babel/eslint-parser": "^7.21.3",
|
|
54
54
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
55
|
+
"@faker-js/faker": "^7.6.0",
|
|
55
56
|
"@mdi/font": "^5.9.55",
|
|
56
57
|
"@vitejs/plugin-vue": "^3.2.0",
|
|
57
58
|
"@vue/compiler-sfc": "3.2.45",
|
|
58
|
-
"autoprefixer": "^10.4.
|
|
59
|
-
"axios": "^
|
|
60
|
-
"eslint": "^
|
|
61
|
-
"eslint-plugin-vue": "^9.
|
|
59
|
+
"autoprefixer": "^10.4.14",
|
|
60
|
+
"axios": "^1.3.4",
|
|
61
|
+
"eslint": "^8.36.0",
|
|
62
|
+
"eslint-plugin-vue": "^9.10.0",
|
|
62
63
|
"font-awesome": "^4.7.0",
|
|
63
|
-
"gsap": "^3.11.
|
|
64
|
+
"gsap": "^3.11.5",
|
|
64
65
|
"ionicons": "^4.6.3",
|
|
65
66
|
"material-design-icons": "^3.0.1",
|
|
66
67
|
"postcss": "^8.4.21",
|
|
67
68
|
"pug": "^3.0.2",
|
|
68
69
|
"rollup-plugin-delete": "^2.0.0",
|
|
69
|
-
"sass": "^1.
|
|
70
|
+
"sass": "^1.60.0",
|
|
70
71
|
"simple-syntax-highlighter": "^2.2.5",
|
|
71
72
|
"splitpanes": "^3.1.5",
|
|
72
73
|
"standard": "^17.0.0",
|
|
@@ -119,7 +119,9 @@ component(
|
|
|
119
119
|
|
|
120
120
|
<script>
|
|
121
121
|
/**
|
|
122
|
-
* @todo
|
|
122
|
+
* @todo
|
|
123
|
+
* - Share the common parts between w-input, w-textarea & w-select.
|
|
124
|
+
* - option to fit to the content using contenteditable div
|
|
123
125
|
**/
|
|
124
126
|
|
|
125
127
|
import FormElementMixin from '../mixins/form-elements'
|
|
@@ -581,6 +583,7 @@ $inactive-color: #777;
|
|
|
581
583
|
top: 50%;
|
|
582
584
|
left: 0;
|
|
583
585
|
padding-left: 2 * $base-increment;
|
|
586
|
+
white-space: nowrap;
|
|
584
587
|
transform: translateY(-50%);
|
|
585
588
|
pointer-events: none;
|
|
586
589
|
|
|
@@ -40,21 +40,19 @@ component(
|
|
|
40
40
|
.w-select__selection-slot(v-if="$slots.selection")
|
|
41
41
|
//- inputValue is always an array.
|
|
42
42
|
slot(name="selection" :item="multiple ? inputValue : inputValue[0]")
|
|
43
|
-
|
|
43
|
+
.w-select__selection(
|
|
44
44
|
ref="selection-input"
|
|
45
|
-
|
|
46
|
-
:value="$slots.selection ? '' : selectionString"
|
|
45
|
+
:contenteditable="isDisabled || isReadonly ? 'false' : 'true'"
|
|
47
46
|
@focus="!isDisabled && !isReadonly && onFocus($event)"
|
|
48
47
|
@blur="onBlur"
|
|
49
48
|
@keydown="!isDisabled && !isReadonly && onKeydown($event)"
|
|
50
49
|
:id="`w-select--${_.uid}`"
|
|
51
|
-
:
|
|
50
|
+
:class="{ 'w-select__selection--placeholder': !$slots.selection && !selectionString && placeholder }"
|
|
52
51
|
:disabled="isDisabled || null"
|
|
53
52
|
readonly
|
|
54
53
|
aria-readonly="true"
|
|
55
|
-
:required="required || null"
|
|
56
54
|
:tabindex="tabindex || null"
|
|
57
|
-
|
|
55
|
+
v-html="$slots.selection ? '' : selectionString || placeholder")
|
|
58
56
|
//- For standard HTML form submission.
|
|
59
57
|
input(
|
|
60
58
|
v-for="(val, i) in (inputValue.length ? inputValue : [{}])"
|
|
@@ -149,7 +147,8 @@ export default {
|
|
|
149
147
|
noUnselect: { type: Boolean },
|
|
150
148
|
menuProps: { type: Object }, // Allow passing down an object of props to the w-menu component.
|
|
151
149
|
dark: { type: Boolean },
|
|
152
|
-
light: { type: Boolean }
|
|
150
|
+
light: { type: Boolean },
|
|
151
|
+
fitToContent: { type: Boolean }
|
|
153
152
|
// Props from mixin: name, disabled, readonly, required, tabindex, validators.
|
|
154
153
|
// Computed from mixin: inputName, isDisabled & isReadonly.
|
|
155
154
|
},
|
|
@@ -200,6 +199,7 @@ export default {
|
|
|
200
199
|
'w-select--dark': this.dark,
|
|
201
200
|
'w-select--light': this.light,
|
|
202
201
|
'w-select--disabled': this.isDisabled,
|
|
202
|
+
'w-select--fit-to-content': this.fitToContent,
|
|
203
203
|
'w-select--readonly': this.isReadonly,
|
|
204
204
|
[`w-select--${this.hasValue ? 'filled' : 'empty'}`]: true,
|
|
205
205
|
'w-select--focused': (this.isFocused || this.showMenu) && !this.isReadonly,
|
|
@@ -230,6 +230,7 @@ export default {
|
|
|
230
230
|
onFocus (e) {
|
|
231
231
|
this.isFocused = true
|
|
232
232
|
this.$emit('focus', e)
|
|
233
|
+
return false
|
|
233
234
|
},
|
|
234
235
|
|
|
235
236
|
onBlur (e) {
|
|
@@ -238,6 +239,11 @@ export default {
|
|
|
238
239
|
},
|
|
239
240
|
|
|
240
241
|
onKeydown (e) {
|
|
242
|
+
// Forbid typing in contenteditable element.
|
|
243
|
+
// Note: using contenteditable rather than input in order to be able to fit the select list
|
|
244
|
+
// to its content with CSS. Only contenteditable divs/non-interactive elements can react to focus/blur ).
|
|
245
|
+
e.preventDefault()
|
|
246
|
+
|
|
241
247
|
if ([13, 27, 38, 40].includes(e.keyCode)) e.preventDefault()
|
|
242
248
|
|
|
243
249
|
if (e.keyCode === 27) this.closeMenu() // Escape.
|
|
@@ -300,7 +306,6 @@ export default {
|
|
|
300
306
|
// Also accept objects if returnObject is true.
|
|
301
307
|
// In any case, always end up with an array.
|
|
302
308
|
checkSelection (items) {
|
|
303
|
-
console.log(items)
|
|
304
309
|
items = Array.isArray(items) ? items : (items !== undefined ? [items] : [])
|
|
305
310
|
// `selectItems` items always have a value.
|
|
306
311
|
const allValues = this.selectItems.map(item => item.value)
|
|
@@ -368,6 +373,11 @@ export default {
|
|
|
368
373
|
-webkit-tap-highlight-color: transparent;
|
|
369
374
|
}
|
|
370
375
|
|
|
376
|
+
&--fit-to-content {
|
|
377
|
+
display: inline-flex;
|
|
378
|
+
flex-grow: 0;
|
|
379
|
+
}
|
|
380
|
+
|
|
371
381
|
// Selection wrapper.
|
|
372
382
|
// ------------------------------------------------------
|
|
373
383
|
&__selection-wrap {
|
|
@@ -423,21 +433,21 @@ export default {
|
|
|
423
433
|
}
|
|
424
434
|
}
|
|
425
435
|
|
|
426
|
-
//
|
|
436
|
+
// Selection (contenteditable) field.
|
|
437
|
+
// Using contenteditable instead of readonly input in order to be able to fit to content.
|
|
438
|
+
// Then disable typing and hide caret.
|
|
427
439
|
// ------------------------------------------------------
|
|
428
440
|
&__selection {
|
|
429
441
|
width: 100%;
|
|
430
442
|
height: 100%;
|
|
431
443
|
min-height: inherit;
|
|
432
|
-
font: inherit;
|
|
433
|
-
color: inherit;
|
|
434
|
-
text-align: inherit;
|
|
435
|
-
background: none;
|
|
436
|
-
border: none;
|
|
437
444
|
outline: none;
|
|
438
445
|
padding-left: 2 * $base-increment;
|
|
439
446
|
padding-right: 2 * $base-increment;
|
|
447
|
+
display: flex;
|
|
448
|
+
align-items: center;
|
|
440
449
|
cursor: pointer;
|
|
450
|
+
caret-color: transparent;
|
|
441
451
|
|
|
442
452
|
.w-select__selection-slot + & {
|
|
443
453
|
position: absolute;
|
|
@@ -463,9 +473,9 @@ export default {
|
|
|
463
473
|
-webkit-tap-highlight-color: transparent;
|
|
464
474
|
}
|
|
465
475
|
|
|
466
|
-
.w-select--disabled input::placeholder {color: inherit;}
|
|
467
|
-
|
|
468
476
|
.w-select--readonly & {cursor: auto;}
|
|
477
|
+
|
|
478
|
+
&--placeholder {color: #888;}
|
|
469
479
|
}
|
|
470
480
|
|
|
471
481
|
&__selection-slot {
|
|
@@ -529,6 +539,7 @@ export default {
|
|
|
529
539
|
top: 50%;
|
|
530
540
|
left: 0;
|
|
531
541
|
right: 0;
|
|
542
|
+
white-space: nowrap;
|
|
532
543
|
// Use margin instead of padding as the scale transformation below decreases the real padding
|
|
533
544
|
// size and misaligns the label.
|
|
534
545
|
margin-left: 2 * $base-increment;
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
|
|
60
60
|
//- Normal rows.
|
|
61
61
|
template(v-if="tableItems.length && loading !== true")
|
|
62
|
-
template(v-for="(item, i) in
|
|
62
|
+
template(v-for="(item, i) in paginatedItems" :key="i")
|
|
63
63
|
//- Fully custom tr (`item` slot).
|
|
64
64
|
slot(
|
|
65
65
|
v-if="$slots.item"
|
|
@@ -136,26 +136,41 @@
|
|
|
136
136
|
tr.w-table__row.w-table__pagination-wrap(v-if="pagination && paginationConfig")
|
|
137
137
|
td.w-table__cell(:colspan="headers.length")
|
|
138
138
|
.w-table__pagination
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
139
|
+
| {{ paginationConfig }}
|
|
140
|
+
slot(
|
|
141
|
+
name="pagination"
|
|
142
|
+
:range="`${paginationConfig.start}-${paginationConfig.end} of ${paginationConfig.total}`"
|
|
143
|
+
:total="paginationConfig.total")
|
|
144
|
+
w-select.pagination-number.pagination-number--items-per-page(
|
|
145
|
+
v-if="paginationConfig.itemsPerPageOptions"
|
|
146
|
+
v-model="paginationConfig.itemsPerPage"
|
|
147
|
+
@input="updatePaginationConfig"
|
|
148
|
+
:items="paginationConfig.itemsPerPageOptions"
|
|
149
|
+
label-position="left"
|
|
150
|
+
label="Items per page"
|
|
151
|
+
label-color="inherit")
|
|
152
|
+
.pagination-arrows
|
|
153
|
+
w-button.pagination-arrow.pagination-arrow--prev(
|
|
154
|
+
@click="goToPage('-1')"
|
|
155
|
+
:disabled="paginationConfig.page <= 1"
|
|
156
|
+
icon="wi-chevron-left"
|
|
157
|
+
text
|
|
158
|
+
lg)
|
|
159
|
+
w-button.pagination-arrow.pagination-arrow--prev(
|
|
160
|
+
v-for="i in paginationConfig.pagesCount"
|
|
161
|
+
:key="i"
|
|
162
|
+
@click="goToPage(i)"
|
|
163
|
+
round
|
|
164
|
+
text
|
|
165
|
+
lg) {{ i }}
|
|
166
|
+
w-button.pagination-arrow.pagination-arrow--next(
|
|
167
|
+
@click="goToPage('+1')"
|
|
168
|
+
:disabled="paginationConfig.page >= paginationConfig.pagesCount"
|
|
169
|
+
icon="wi-chevron-right"
|
|
170
|
+
text
|
|
171
|
+
lg)
|
|
172
|
+
span.pagination-number.pagination-number--results.
|
|
173
|
+
{{ paginationConfig.start }}-{{ paginationConfig.end }} of {{ paginationConfig.total }}
|
|
159
174
|
</template>
|
|
160
175
|
|
|
161
176
|
<script>
|
|
@@ -339,6 +354,10 @@ export default {
|
|
|
339
354
|
// Faster lookup than array.includes(uid) and also cached.
|
|
340
355
|
expandedRowsByUid () {
|
|
341
356
|
return this.expandedRowsInternal.reduce((obj, uid) => (obj[uid] = true) && obj, {})
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
paginatedItems () {
|
|
360
|
+
return this.sortedItems.slice(this.paginationConfig.start, this.paginationConfig.end)
|
|
342
361
|
}
|
|
343
362
|
},
|
|
344
363
|
|
|
@@ -535,17 +554,32 @@ export default {
|
|
|
535
554
|
},
|
|
536
555
|
|
|
537
556
|
updatePaginationConfig () {
|
|
538
|
-
const itemsPerPage = this.pagination?.itemsPerPage ||
|
|
557
|
+
const itemsPerPage = this.pagination?.itemsPerPage || 20
|
|
558
|
+
const itemsPerPageOptions = this.pagination?.itemsPerPageOptions || [20, 100, { label: 'All', value: 0 }]
|
|
539
559
|
const total = this.pagination?.total || this.items.length
|
|
560
|
+
const itemsPerPageOrTotal = itemsPerPage || total
|
|
540
561
|
const page = this.pagination?.page || 1
|
|
541
562
|
this.paginationConfig = {
|
|
542
563
|
itemsPerPage,
|
|
543
|
-
itemsPerPageOptions:
|
|
564
|
+
itemsPerPageOptions: itemsPerPageOptions.map(item => ({
|
|
565
|
+
label: ['string', 'number'].includes(typeof item) ? item.toString() : (item.label || item.value),
|
|
566
|
+
value: ['string', 'number'].includes(typeof item) ? ~~item : (item.value ?? item.label)
|
|
567
|
+
})),
|
|
544
568
|
page,
|
|
545
569
|
start: this.pagination?.start || 1,
|
|
546
|
-
end: total >= (
|
|
547
|
-
total
|
|
570
|
+
end: total >= (itemsPerPageOrTotal * page) ? (itemsPerPageOrTotal * page) : (total % (itemsPerPageOrTotal * page)),
|
|
571
|
+
total,
|
|
572
|
+
pagesCount: Math.ceil(total / itemsPerPageOrTotal)
|
|
548
573
|
}
|
|
574
|
+
},
|
|
575
|
+
|
|
576
|
+
goToPage (page) {
|
|
577
|
+
if (['-1', '+1'].includes(page)) this.paginationConfig.page += +page
|
|
578
|
+
else this.paginationConfig.page = page
|
|
579
|
+
const { itemsPerPage } = this.paginationConfig
|
|
580
|
+
this.paginationConfig.page = Math.max(1, this.paginationConfig.page)
|
|
581
|
+
this.paginationConfig.start = (itemsPerPage * (this.paginationConfig.page - 1)) + 1
|
|
582
|
+
this.paginationConfig.end = (this.paginationConfig.start - 1) + itemsPerPage
|
|
549
583
|
}
|
|
550
584
|
},
|
|
551
585
|
|
|
@@ -581,6 +615,11 @@ export default {
|
|
|
581
615
|
|
|
582
616
|
selectedRows (array) {
|
|
583
617
|
this.selectedRowsInternal = Array.isArray(array) && array.length ? this.selectedRows : []
|
|
618
|
+
},
|
|
619
|
+
|
|
620
|
+
pagination: {
|
|
621
|
+
handler () { this.updatePaginationConfig() },
|
|
622
|
+
deep: true
|
|
584
623
|
}
|
|
585
624
|
}
|
|
586
625
|
}
|
|
@@ -800,27 +839,31 @@ $tr-border-top: 1px;
|
|
|
800
839
|
}
|
|
801
840
|
}
|
|
802
841
|
|
|
842
|
+
// Pagination.
|
|
843
|
+
// ------------------------------------------------------
|
|
844
|
+
&__pagination-wrap {
|
|
845
|
+
border-top: $border;
|
|
846
|
+
}
|
|
803
847
|
&__pagination {
|
|
804
848
|
display: flex;
|
|
805
849
|
align-items: center;
|
|
806
850
|
justify-content: flex-end;
|
|
807
|
-
padding-top: $base-increment;
|
|
808
|
-
padding-bottom: $base-increment;
|
|
809
851
|
|
|
810
852
|
.pagination-number--items-per-page {
|
|
811
|
-
margin-right: 6 * $base-increment;
|
|
812
853
|
flex-grow: 0;
|
|
813
854
|
text-align: right;
|
|
814
855
|
}
|
|
856
|
+
|
|
857
|
+
.pagination-arrows {
|
|
858
|
+
margin-left: 3 * $base-increment;
|
|
859
|
+
margin-right: 3 * $base-increment;
|
|
860
|
+
}
|
|
861
|
+
|
|
815
862
|
.pagination-number--of {
|
|
816
863
|
margin-left: $base-increment;
|
|
817
864
|
margin-right: $base-increment;
|
|
818
865
|
}
|
|
819
866
|
.w-select__selection {max-width: 60px;}
|
|
820
|
-
|
|
821
|
-
.pagination-arrows {
|
|
822
|
-
margin-left: 6 * $base-increment;
|
|
823
|
-
}
|
|
824
867
|
}
|
|
825
868
|
}
|
|
826
869
|
|
|
@@ -48,7 +48,7 @@ $base-font-size: 14px !default; // Must be a px unit.
|
|
|
48
48
|
$base-increment: round(divide($base-font-size, 4)) !default;
|
|
49
49
|
$layout-padding: $base-increment * 4 !default; // Applied on the .content-wrap tag.
|
|
50
50
|
$border-radius: 3px !default;
|
|
51
|
-
$border-color: rgba(var(--w-contrast-bg-color-rgb), 0.
|
|
51
|
+
$border-color: rgba(var(--w-contrast-bg-color-rgb), 0.12) !default;
|
|
52
52
|
$border: 1px solid $border-color !default;
|
|
53
53
|
$transition-duration: 0.25s !default;
|
|
54
54
|
$fast-transition-duration: 0.15s !default;
|
|
@@ -275,8 +275,10 @@ export const injectColorsCSSInDOM = themeColors => {
|
|
|
275
275
|
css.id = 'wave-ui-colors'
|
|
276
276
|
css.innerHTML = generateColors(themeColors)
|
|
277
277
|
|
|
278
|
-
|
|
279
|
-
|
|
278
|
+
// Keep the injected colors at the end of other styles.
|
|
279
|
+
// This should have priority over the user rules that have the same specificity.
|
|
280
|
+
const styles = document.head.querySelectorAll('style,link[rel="stylesheet"]')
|
|
281
|
+
if (styles.length) styles[styles.length - 1].after(css)
|
|
280
282
|
else document.head.appendChild(css)
|
|
281
283
|
}
|
|
282
284
|
}
|