wave-ui 2.46.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-ui",
3
- "version": "2.46.0",
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",
@@ -48,7 +48,7 @@
48
48
  "lint": "vite lint"
49
49
  },
50
50
  "devDependencies": {
51
- "@babel/core": "^7.20.2",
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": "^5.9.55",
@@ -57,7 +57,7 @@
57
57
  "autoprefixer": "^10.4.13",
58
58
  "axios": "^0.25.0",
59
59
  "eslint": "^7.32.0",
60
- "eslint-plugin-vue": "^9.7.0",
60
+ "eslint-plugin-vue": "^9.8.0",
61
61
  "font-awesome": "^4.7.0",
62
62
  "gsap": "^3.11.3",
63
63
  "ionicons": "^4.6.3",
@@ -69,7 +69,7 @@
69
69
  "simple-syntax-highlighter": "^2.2.5",
70
70
  "splitpanes": "^3.1.5",
71
71
  "standard": "^17.0.0",
72
- "vite": "^3.2.3",
72
+ "vite": "^3.2.5",
73
73
  "vue": "^3.2.45",
74
74
  "vue-router": "^4.1.6",
75
75
  "vueperslides": "^3.5.1",
@@ -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.saveOriginalStyles(el)
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.saveOriginalStyles(el)
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
- saveOriginalStyles (el) {
155
- // Keep the original styles to restore them after transition.
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.applyHideStyles(el)
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
 
@@ -123,7 +123,7 @@ export default {
123
123
  overflow: auto;
124
124
  background-color: #fff;
125
125
 
126
- .w-dialog--fullscreen & {
126
+ .w-dialog--fullscreen > & {
127
127
  flex: 1 1 auto;
128
128
  height: 100%;
129
129
  max-width: none;
@@ -76,6 +76,7 @@ export default {
76
76
  absolute: { type: Boolean },
77
77
  overlayColor: { type: String },
78
78
  overlayOpacity: { type: [Number, String, Boolean] },
79
+ drawerClass: { type: String },
79
80
  tag: { type: String, default: 'aside' }
80
81
  },
81
82
 
@@ -125,6 +126,7 @@ export default {
125
126
  },
126
127
  drawerClasses () {
127
128
  return {
129
+ [this.drawerClass]: true,
128
130
  [this.color]: this.color,
129
131
  [`${this.bgColor}--bg`]: this.bgColor,
130
132
  '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] }
@@ -457,7 +457,7 @@ $inactive-color: #777;
457
457
  &__input {
458
458
  width: 100%;
459
459
  height: 100%;
460
- font-size: inherit;
460
+ font: inherit;
461
461
  color: inherit;
462
462
  text-align: inherit;
463
463
  display: inline-flex;
@@ -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
- items = Array.isArray(items) ? items : (items ? [items] : [])
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
- font-size: inherit;
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
- //- .pagination
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 exanded.
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.