wave-ui 3.9.0 → 3.9.2

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.
@@ -1,176 +1,192 @@
1
1
  <template lang="pug">
2
- .w-table-wrap(:class="wrapClasses")
3
- table.w-table(
4
- :class="classes"
5
- @mousedown="onMouseDown"
6
- @mouseover="onMouseOver"
7
- @mouseout="onMouseOut")
8
- colgroup(ref="colgroup")
9
- col.w-table__col(
10
- v-for="(header, i) in headers"
11
- :key="i"
12
- :width="header.width || null"
13
- :class="colClasses[i]")
14
-
15
- //- Table header.
16
- thead(v-if="!noHeaders")
17
- tr
18
- th.w-table__header(
2
+ .w-table.w-table--wrap(:class="classes")
3
+ .w-table__scroll-wrap
4
+ table.w-table__table(
5
+ @mousedown="onMouseDown"
6
+ @mouseover="onMouseOver"
7
+ @mouseout="onMouseOut")
8
+ colgroup(ref="colgroup")
9
+ col.w-table__col(
19
10
  v-for="(header, i) in headers"
20
11
  :key="i"
21
- @click="!colResizing.dragging && header.sortable !== false && sortTable(header)"
22
- :class="headerClasses(header)")
23
- w-icon.w-table__header-sort(
24
- v-if="header.sortable !== false && header.align === 'right'"
25
- :class="headerSortClasses(header)") wi-arrow-down
26
- template(v-if="header.label")
27
- slot(
28
- v-if="$slots['header-label']"
29
- name="header-label"
30
- :header="header"
31
- :label="header.label"
32
- :index="i + 1") {{ header.label || '' }}
33
- span(v-else v-html="header.label || ''")
34
- w-icon.w-table__header-sort(
35
- v-if="header.sortable !== false && header.align !== 'right'"
36
- :class="headerSortClasses(header)") wi-arrow-down
37
- //- Notes: prevent click on header (`.stop`), which triggers sorting & DOM refresh.
38
- span.w-table__col-resizer(
39
- v-if="i < headers.length - 1 && resizableColumns"
40
- :class="{ 'w-table__col-resizer--hover': colResizing.hover === i, 'w-table__col-resizer--active': colResizing.columnIndex === i }"
41
- @click.stop)
42
- //- Progress bar only.
43
- w-transition-fade
44
- tr.w-table__progress-bar(v-if="loading === 'header'")
12
+ :width="header.width || null"
13
+ :class="colClasses[i]")
14
+
15
+ //- Table header.
16
+ thead(v-if="!noHeaders")
17
+ tr
18
+ th.w-table__header(
19
+ v-for="(header, i) in headers"
20
+ :key="i"
21
+ @click="!colResizing.dragging && header.sortable !== false && sortTable(header)"
22
+ :class="headerClasses(header)")
23
+ w-icon.w-table__header-sort(
24
+ v-if="header.sortable !== false && header.align === 'right'"
25
+ :class="headerSortClasses(header)") wi-arrow-down
26
+ template(v-if="header.label")
27
+ slot(
28
+ v-if="$slots['header-label']"
29
+ name="header-label"
30
+ :header="header"
31
+ :label="header.label"
32
+ :index="i + 1") {{ header.label || '' }}
33
+ span(v-else v-html="header.label || ''")
34
+ w-icon.w-table__header-sort(
35
+ v-if="header.sortable !== false && header.align !== 'right'"
36
+ :class="headerSortClasses(header)") wi-arrow-down
37
+ //- Notes: prevent click on header (`.stop`), which triggers sorting & DOM refresh.
38
+ span.w-table__col-resizer(
39
+ v-if="i < headers.length - 1 && resizableColumns"
40
+ :class="{ 'w-table__col-resizer--hover': colResizing.hover === i, 'w-table__col-resizer--active': colResizing.columnIndex === i }"
41
+ @click.stop)
42
+ //- Progress bar only.
43
+ w-transition-fade
44
+ tr.w-table__progress-bar(v-if="loading === 'header'")
45
+ td(:colspan="headers.length")
46
+ w-progress(tile)
47
+
48
+ //- Table body.
49
+ tbody
50
+ //- Progress bar & loading text.
51
+ tr.w-table__progress-bar(v-if="loading === true")
45
52
  td(:colspan="headers.length")
46
53
  w-progress(tile)
47
-
48
- //- Table body.
49
- tbody
50
- //- Progress bar & loading text.
51
- tr.w-table__progress-bar(v-if="loading === true")
52
- td(:colspan="headers.length")
53
- w-progress(tile)
54
- .w-table__loading-text
55
- slot(name="loading") Loading...
56
- //- No data.
57
- tr.no-data(v-else-if="!tableItems.length")
58
- td.w-table__cell.text-center(:colspan="headers.length")
59
- slot(name="no-data") No data to show.
60
-
61
- //- Normal rows.
62
- template(v-if="tableItems.length && loading !== true")
63
- template(v-for="(item, i) in paginatedItems" :key="i")
64
- //- Fully custom tr (`item` slot).
65
- slot(
66
- v-if="$slots.item"
67
- name="item"
68
- :item="item"
69
- :index="i + 1"
70
- :select="() => doSelectRow(item, i)"
71
- :classes="{ 'w-table__row': true, 'w-table__row--selected': selectedRowsByUid[item._uid] !== undefined, 'w-table__row--expanded': expandedRowsByUid[item._uid] !== undefined }")
72
-
73
- tr.w-table__row(
74
- v-else
75
- @click="doSelectRow(item, i)"
76
- :class="{ 'w-table__row--selected': selectedRowsByUid[item._uid] !== undefined, 'w-table__row--expanded': expandedRowsByUid[item._uid] !== undefined }")
77
- template(v-for="(header, j) in headers")
78
- td.w-table__cell(
79
- v-if="$slots[`item-cell.${header.key}`] || $slots[`item-cell.${j + 1}`] || $slots['item-cell']"
80
- :key="`${j}-a`"
81
- :data-label="header.label"
82
- :class="{ [`text-${header.align || 'left'}`]: true, 'w-table__cell--sticky': header.sticky }")
83
- slot(
84
- v-if="$slots[`item-cell.${header.key}`]"
85
- :name="`item-cell.${header.key}`"
86
- :header="header"
87
- :item="item"
88
- :label="item[header.key] || ''"
89
- :index="i + 1")
90
- slot(
91
- v-else-if="$slots[`item-cell.${j + 1}`]"
92
- :name="`item-cell.${j + 1}`"
93
- :header="header"
94
- :item="item"
95
- :label="item[header.key] || ''"
96
- :index="i + 1")
97
- slot(
98
- v-else-if="$slots['item-cell']"
99
- name="item-cell"
100
- :header="header"
101
- :item="item"
102
- :label="item[header.key] || ''"
103
- :index="i + 1")
104
- span.w-table__col-resizer(
105
- v-if="j < headers.length - 1 && resizableColumns"
106
- :class="{ 'w-table__col-resizer--hover': colResizing.hover === j, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
107
-
108
- td.w-table__cell(
109
- v-else
110
- :key="`${j}-b`"
111
- :data-label="header.label"
112
- :class="{ [`text-${header.align || 'left'}`]: true, 'w-table__cell--sticky': header.sticky }")
113
- div(v-html="item[header.key] || ''")
114
- span.w-table__col-resizer(
115
- v-if="j < headers.length - 1 && resizableColumns"
116
- :class="{ 'w-table__col-resizer--hover': colResizing.hover === j, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
117
-
118
- //- Expanded row.
119
- tr.w-table__row.w-table__row--expansion(v-if="expandedRowsByUid[item._uid]")
120
- td.w-table__cell(:colspan="headers.length")
121
- w-transition-expand(y)
122
- div(v-if="expandedRowsByUid[item._uid]")
123
- slot(name="row-expansion" :item="item" :index="i + 1")
124
- span.w-table__col-resizer(
125
- v-if="i < headers.length - 1 && resizableColumns"
126
- :class="{ 'w-table__col-resizer--hover': colResizing.hover === i, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
127
- //- Extra row.
128
- .w-table__extra-row(v-if="$slots['extra-row']")
129
- slot(name="extra-row")
130
-
131
- //- Table footer.
132
- tfoot.w-table__footer(v-if="$slots.footer || $slots['footer-row'] || pagination")
133
- slot(v-if="$slots['footer-row']" name="footer-row")
134
- tr.w-table__row(v-else-if="$slots.footer")
135
- td.w-table__cell(:colspan="headers.length")
136
- slot(name="footer")
137
- tr.w-table__row.w-table__pagination-wrap(v-if="pagination && paginationConfig")
138
- td.w-table__cell(:colspan="headers.length")
139
- .w-table__pagination.w-pagination
54
+ .w-table__loading-text
55
+ slot(name="loading") Loading...
56
+ //- No data.
57
+ tr.no-data(v-else-if="!tableItems.length")
58
+ td.w-table__cell.text-center(:colspan="headers.length")
59
+ slot(name="no-data") No data to show.
60
+
61
+ //- Normal rows.
62
+ template(v-if="tableItems.length && loading !== true")
63
+ template(v-for="(item, i) in paginatedItems" :key="i")
64
+ //- Fully custom tr (`item` slot).
140
65
  slot(
141
- name="pagination"
142
- :range="`${paginationConfig.start}-${paginationConfig.end}`"
143
- :total="paginationConfig.total")
144
- w-select.w-pagination__items-per-page(
145
- v-if="paginationConfig.itemsPerPageOptions"
146
- v-model="paginationConfig.itemsPerPage"
147
- @input="updatePaginationConfig({ itemsPerPage: paginationConfig.itemsPerPage })"
148
- :items="paginationConfig.itemsPerPageOptions"
149
- label-position="left"
150
- label="Items per page"
151
- label-color="inherit")
152
- .pages-wrap
153
- w-button.w-pagination__arrow.w-pagination__arrow--prev(
154
- @click="goToPage('-1')"
155
- :disabled="paginationConfig.page <= 1"
156
- icon="wi-chevron-left"
157
- text
158
- lg)
159
- w-button.w-pagination__page(
160
- v-for="i in paginationConfig.pagesCount"
161
- :key="i"
162
- @click="i !== paginationConfig.page && goToPage(i)"
163
- :class="{ 'w-pagination__page--active': i === paginationConfig.page }"
164
- round
165
- lg) {{ i }}
166
- w-button.w-pagination__arrow.w-pagination__arrow--next(
167
- @click="goToPage('+1')"
168
- :disabled="paginationConfig.page >= paginationConfig.pagesCount"
169
- icon="wi-chevron-right"
170
- text
171
- lg)
172
- span.w-pagination__results.
173
- {{ paginationConfig.start }}-{{ paginationConfig.end || paginationConfig.total }} of {{ paginationConfig.total }}
66
+ v-if="$slots.item"
67
+ name="item"
68
+ :item="item"
69
+ :index="i + 1"
70
+ :select="() => doSelectRow(item, i)"
71
+ :classes="{ 'w-table__row': true, 'w-table__row--selected': selectedRowsByUid[item._uid] !== undefined, 'w-table__row--expanded': expandedRowsByUid[item._uid] !== undefined }")
72
+
73
+ tr.w-table__row(
74
+ v-else
75
+ @click="doSelectRow(item, i)"
76
+ :class="{ 'w-table__row--selected': selectedRowsByUid[item._uid] !== undefined, 'w-table__row--expanded': expandedRowsByUid[item._uid] !== undefined }")
77
+ template(v-for="(header, j) in headers")
78
+ td.w-table__cell(
79
+ v-if="$slots[`item-cell.${header.key}`] || $slots[`item-cell.${j + 1}`] || $slots['item-cell']"
80
+ :key="`${j}-a`"
81
+ :data-label="header.label"
82
+ :class="{ [`text-${header.align || 'left'}`]: true, 'w-table__cell--sticky': header.sticky }")
83
+ slot(
84
+ v-if="$slots[`item-cell.${header.key}`]"
85
+ :name="`item-cell.${header.key}`"
86
+ :header="header"
87
+ :item="item"
88
+ :label="item[header.key] || ''"
89
+ :index="i + 1")
90
+ slot(
91
+ v-else-if="$slots[`item-cell.${j + 1}`]"
92
+ :name="`item-cell.${j + 1}`"
93
+ :header="header"
94
+ :item="item"
95
+ :label="item[header.key] || ''"
96
+ :index="i + 1")
97
+ slot(
98
+ v-else-if="$slots['item-cell']"
99
+ name="item-cell"
100
+ :header="header"
101
+ :item="item"
102
+ :label="item[header.key] || ''"
103
+ :index="i + 1")
104
+ span.w-table__col-resizer(
105
+ v-if="j < headers.length - 1 && resizableColumns"
106
+ :class="{ 'w-table__col-resizer--hover': colResizing.hover === j, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
107
+
108
+ td.w-table__cell(
109
+ v-else
110
+ :key="`${j}-b`"
111
+ :data-label="header.label"
112
+ :class="{ [`text-${header.align || 'left'}`]: true, 'w-table__cell--sticky': header.sticky }")
113
+ div(v-html="item[header.key] || ''")
114
+ span.w-table__col-resizer(
115
+ v-if="j < headers.length - 1 && resizableColumns"
116
+ :class="{ 'w-table__col-resizer--hover': colResizing.hover === j, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
117
+
118
+ //- Expanded row.
119
+ tr.w-table__row.w-table__row--expansion(v-if="expandedRowsByUid[item._uid]")
120
+ td.w-table__cell(:colspan="headers.length")
121
+ w-transition-expand(y)
122
+ div(v-if="expandedRowsByUid[item._uid]")
123
+ slot(name="row-expansion" :item="item" :index="i + 1")
124
+ span.w-table__col-resizer(
125
+ v-if="i < headers.length - 1 && resizableColumns"
126
+ :class="{ 'w-table__col-resizer--hover': colResizing.hover === i, 'w-table__col-resizer--active': colResizing.columnIndex === j }")
127
+ //- Extra row.
128
+ .w-table__extra-row(v-if="$slots['extra-row']")
129
+ slot(name="extra-row")
130
+
131
+ //- Table footer.
132
+ tfoot.w-table__footer(v-if="$slots.footer || $slots['footer-row']")
133
+ slot(v-if="$slots['footer-row']" name="footer-row")
134
+ tr.w-table__row(v-else-if="$slots.footer")
135
+ td.w-table__cell(:colspan="headers.length")
136
+ slot(name="footer")
137
+ .w-table__pagination.w-pagination(v-if="pagination && paginationConfig")
138
+ slot(
139
+ name="pagination"
140
+ :range="`${paginationConfig.start}-${paginationConfig.end}`"
141
+ :total="paginationConfig.total"
142
+ :pages-count="paginationConfig.pagesCount"
143
+ :page="paginationConfig.page"
144
+ :goToPage="goToPage")
145
+ w-select.w-pagination__items-per-page(
146
+ v-if="paginationConfig.itemsPerPageOptions"
147
+ v-model="paginationConfig.itemsPerPage"
148
+ @input="updatePaginationConfig({ itemsPerPage: paginationConfig.itemsPerPage })"
149
+ :items="paginationConfig.itemsPerPageOptions"
150
+ label-position="left"
151
+ label="Items per page"
152
+ label-color="inherit")
153
+ .pages-wrap
154
+ w-button.w-pagination__arrow.w-pagination__arrow--prev(
155
+ @click="goToPage('-1')"
156
+ :disabled="paginationConfig.page <= 1"
157
+ icon="wi-chevron-left"
158
+ text
159
+ lg)
160
+ template(v-if="paginationConfig.pagesCount > 7")
161
+ template(v-for="i in paginationConfig.pagesCount" :key="i")
162
+ w-button.w-pagination__page(
163
+ v-if="[1, paginationConfig.pagesCount, paginationConfig.page - 1, paginationConfig.page, paginationConfig.page + 1].includes(i)"
164
+ @click="i !== paginationConfig.page && goToPage(i)"
165
+ :class="{ 'w-pagination__page--active': i === paginationConfig.page }"
166
+ round
167
+ lg) {{ i }}
168
+ w-button.w-pagination__page(
169
+ v-else-if="[1, paginationConfig.pagesCount, paginationConfig.page - 1, paginationConfig.page, paginationConfig.page + 1].includes(i - 1)"
170
+ @click="i !== paginationConfig.page && goToPage(i)"
171
+ :class="{ 'w-pagination__page--active': i === paginationConfig.page }"
172
+ round
173
+ lg) ...
174
+ template(v-else)
175
+ w-button.w-pagination__page(
176
+ v-for="i in paginationConfig.pagesCount"
177
+ :key="i"
178
+ @click="i !== paginationConfig.page && goToPage(i)"
179
+ :class="{ 'w-pagination__page--active': i === paginationConfig.page }"
180
+ round
181
+ lg) {{ i }}
182
+ w-button.w-pagination__arrow.w-pagination__arrow--next(
183
+ @click="goToPage('+1')"
184
+ :disabled="paginationConfig.page >= paginationConfig.pagesCount"
185
+ icon="wi-chevron-right"
186
+ text
187
+ lg)
188
+ span.w-pagination__results.
189
+ {{ paginationConfig.start }}-{{ paginationConfig.end || paginationConfig.total }} of {{ paginationConfig.total }}
174
190
  </template>
175
191
 
176
192
  <script>
@@ -337,18 +353,6 @@ export default {
337
353
  }, {})
338
354
  },
339
355
 
340
- wrapClasses () {
341
- return {
342
- 'w-table-wrap--loading': this.loading
343
- }
344
- },
345
-
346
- colClasses () {
347
- return this.headers.map(header => {
348
- return { 'w-table__col--highlighted': this.activeSortingKeys[header.key] }
349
- }) || []
350
- },
351
-
352
356
  classes () {
353
357
  return {
354
358
  'w-table--loading': this.loading,
@@ -365,6 +369,12 @@ export default {
365
369
  }
366
370
  },
367
371
 
372
+ colClasses () {
373
+ return this.headers.map(header => {
374
+ return { 'w-table__col--highlighted': this.activeSortingKeys[header.key] }
375
+ }) || []
376
+ },
377
+
368
378
  isMobile () {
369
379
  return ~~this.mobileBreakpoint && this.$waveui.breakpoint.width <= ~~this.mobileBreakpoint
370
380
  },
@@ -562,7 +572,7 @@ export default {
562
572
  // (releasing the mouse on table header triggers a click event captured by the sorting feature)
563
573
  setTimeout(() => {
564
574
  // On Mouse up, emit an event containing all the new widths of the columns.
565
- const widths = [...this.$refs.colgroup.childNodes].map(column => column.style?.width || column.offsetWidth)
575
+ const widths = [...this.$refs.colgroup.children].map(column => column.style?.width || column.offsetWidth)
566
576
  this.$emit('column-resize', { index: this.colResizing.columnIndex, widths })
567
577
 
568
578
  this.colResizing.dragging = false
@@ -604,8 +614,8 @@ export default {
604
614
  if (itemsPerPage !== undefined) {
605
615
  this.paginationConfig.itemsPerPage = itemsPerPage
606
616
  itemsPerPage = itemsPerPage || this.paginationConfig.total // If `0`, take all the results.
607
- this.paginationConfig.page = 1;
608
- ({ page } = this.paginationConfig) // Shorthand var for next lines.
617
+ this.paginationConfig.page = page || this.paginationConfig.page || 1
618
+ page = this.paginationConfig.page // Shorthand var for next lines.
609
619
  total = this.paginationConfig.total // Shorthand var for next lines.
610
620
  this.paginationConfig.start = 1
611
621
  this.paginationConfig.end = total >= (itemsPerPage * page) ? (itemsPerPage * page) : (total % (itemsPerPage * page))
@@ -697,31 +707,35 @@ export default {
697
707
  <style lang="scss">
698
708
  $tr-border-top: 1px;
699
709
 
700
- .w-table-wrap {
710
+ .w-table {
701
711
  position: relative;
712
+ display: flex;
713
+ flex-direction: column;
702
714
  border-radius: $border-radius;
703
715
  border: $border;
704
- overflow: auto;
705
716
 
706
717
  &--loading {overflow: hidden;}
707
- }
708
718
 
709
- .w-table {
710
- width: 100%;
711
- min-height: 100%;
712
- border-collapse: collapse;
713
- border: none;
719
+ &--resizing {
720
+ user-select: none;
714
721
 
715
- @include themeable;
722
+ &, * {cursor: col-resize;}
723
+ }
716
724
 
717
- &--fixed-layout {
718
- table-layout: fixed; // Allow resizing beyond the cell minimum text width.
725
+ &__scroll-wrap {
726
+ overflow: auto;
727
+ min-height: 100%;
719
728
  }
720
729
 
721
- &--resizing {
722
- &, * {cursor: col-resize;}
730
+ &__table {
731
+ width: 100%;
732
+ min-height: 100%;
733
+ border-collapse: collapse;
734
+ border: none;
723
735
 
724
- user-select: none;
736
+ @include themeable;
737
+
738
+ &--fixed-layout & {table-layout: fixed;} // Allow resizing beyond the cell minimum text width.
725
739
  }
726
740
 
727
741
  // Table columns.
@@ -917,6 +931,8 @@ $tr-border-top: 1px;
917
931
  display: flex;
918
932
  align-items: center;
919
933
  justify-content: flex-end;
934
+ gap: 2 * $base-increment;
935
+ padding: $base-increment 2 * $base-increment;
920
936
 
921
937
  .w-pagination__items-per-page {
922
938
  flex: 0 0 auto;
@@ -924,18 +940,18 @@ $tr-border-top: 1px;
924
940
  }
925
941
 
926
942
  .pages-wrap {
927
- margin-left: 3 * $base-increment;
928
- margin-right: 3 * $base-increment;
943
+ display: flex;
929
944
  padding-left: 1px; // Prevent overflow causing scrollbar.
930
945
  padding-right: 1px;
931
- overflow: auto;
932
946
  max-height: 4.5em;
947
+ gap: 0.5 * $base-increment;
948
+ overflow-y: hidden;
933
949
  }
934
950
 
935
951
  .w-pagination__page {
936
- margin: 0.5 * $base-increment;
937
952
  font-size: 0.9em;
938
953
  aspect-ratio: 1;
954
+ min-width: 0; // Safari ratio fix (e.g. losing ratio if height is set and side padding are added).
939
955
  overflow: hidden;
940
956
  color: rgba(var(--w-base-color-rgb), 0.65);
941
957
  background-color: rgba(var(--w-base-bg-color-rgb), 0.4);
@@ -961,10 +977,7 @@ $tr-border-top: 1px;
961
977
  }
962
978
 
963
979
  .w-pagination__results {
964
- margin-left: $base-increment;
965
- margin-right: $base-increment;
966
980
  white-space: nowrap;
967
- min-width: 90px;
968
981
  text-align: right;
969
982
  }
970
983
  }
@@ -66,6 +66,7 @@ export default {
66
66
  border: 1px solid currentColor;
67
67
  width: $base-font-size;
68
68
  aspect-ratio: 1;
69
+ min-width: 0; // Safari ratio fix (e.g. losing ratio if height is set and side padding are added).
69
70
  transform: translateX(-50%);
70
71
  z-index: 1;
71
72
  }