wave-ui 2.47.0 → 3.0.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.
Files changed (50) hide show
  1. package/dist/wave-ui.cjs.js +1 -1
  2. package/dist/wave-ui.css +1 -1
  3. package/dist/wave-ui.es.js +1920 -1638
  4. package/dist/wave-ui.umd.js +1 -1
  5. package/package.json +4 -3
  6. package/src/wave-ui/components/index.js +1 -0
  7. package/src/wave-ui/components/transitions/w-transition-expand.vue +26 -15
  8. package/src/wave-ui/components/w-accordion.vue +8 -2
  9. package/src/wave-ui/components/w-alert.vue +10 -4
  10. package/src/wave-ui/components/w-app.vue +2 -107
  11. package/src/wave-ui/components/w-badge.vue +7 -3
  12. package/src/wave-ui/components/w-button/button.vue +6 -2
  13. package/src/wave-ui/components/w-card.vue +14 -4
  14. package/src/wave-ui/components/w-checkbox.vue +15 -8
  15. package/src/wave-ui/components/w-confirm.vue +7 -2
  16. package/src/wave-ui/components/w-date-picker.vue +6 -0
  17. package/src/wave-ui/components/w-dialog.vue +9 -3
  18. package/src/wave-ui/components/w-divider.vue +9 -3
  19. package/src/wave-ui/components/w-drawer.vue +9 -3
  20. package/src/wave-ui/components/w-input.vue +4 -2
  21. package/src/wave-ui/components/w-list.vue +1 -1
  22. package/src/wave-ui/components/w-menu.vue +11 -4
  23. package/src/wave-ui/components/w-notification-manager.vue +18 -30
  24. package/src/wave-ui/components/w-notification.vue +7 -1
  25. package/src/wave-ui/components/w-progress.vue +2 -2
  26. package/src/wave-ui/components/w-radio.vue +8 -2
  27. package/src/wave-ui/components/w-rating.vue +11 -3
  28. package/src/wave-ui/components/w-scrollbar.vue +24 -0
  29. package/src/wave-ui/components/w-select.vue +18 -8
  30. package/src/wave-ui/components/w-slider.vue +13 -7
  31. package/src/wave-ui/components/w-steps.vue +14 -4
  32. package/src/wave-ui/components/w-switch.vue +14 -14
  33. package/src/wave-ui/components/w-table.vue +107 -16
  34. package/src/wave-ui/components/w-tabs/index.vue +8 -2
  35. package/src/wave-ui/components/w-tag.vue +15 -10
  36. package/src/wave-ui/components/w-textarea.vue +6 -2
  37. package/src/wave-ui/components/w-timeline.vue +18 -5
  38. package/src/wave-ui/components/w-toolbar.vue +8 -2
  39. package/src/wave-ui/components/w-tooltip.vue +10 -4
  40. package/src/wave-ui/components/w-tree.vue +57 -19
  41. package/src/wave-ui/core.js +117 -90
  42. package/src/wave-ui/scss/_base.scss +53 -2
  43. package/src/wave-ui/scss/_colors.scss +41 -17
  44. package/src/wave-ui/scss/_layout.scss +5 -12
  45. package/src/wave-ui/scss/_mixins.scss +24 -0
  46. package/src/wave-ui/scss/_variables.scss +100 -11
  47. package/src/wave-ui/utils/colors.js +60 -3
  48. package/src/wave-ui/utils/config.js +35 -11
  49. package/src/wave-ui/utils/dynamic-css.js +92 -30
  50. package/src/wave-ui/utils/notification-manager.js +39 -8
@@ -147,7 +147,6 @@ export default {
147
147
  step: { type: [Number, String] },
148
148
  min: { type: [Number, String] },
149
149
  max: { type: [Number, String] },
150
- dark: { type: Boolean },
151
150
  outline: { type: Boolean },
152
151
  round: { type: Boolean },
153
152
  shadow: { type: Boolean },
@@ -158,7 +157,9 @@ export default {
158
157
  showProgress: { type: [Boolean] }, // Only for file uploads.
159
158
  // Allow syncing the files 1 way: prefilling a file is not possible.
160
159
  // https://stackoverflow.com/questions/16365668/pre-populate-html-form-file-input
161
- files: { type: Array }
160
+ files: { type: Array },
161
+ dark: { type: Boolean },
162
+ light: { type: Boolean }
162
163
  // Props from mixin: name, disabled, readonly, required, tabindex, validators.
163
164
  // Computed from mixin: inputName, isDisabled & isReadonly.
164
165
  },
@@ -251,6 +252,7 @@ export default {
251
252
  [`w-input--${this.hasValue || this.isAutofilled ? 'filled' : 'empty'}`]: true,
252
253
  'w-input--focused': this.isFocused && !this.isReadonly,
253
254
  'w-input--dark': this.dark,
255
+ 'w-input--light': this.light,
254
256
  'w-input--floating-label': this.hasLabel && this.labelPosition === 'inside' && !this.staticLabel,
255
257
  'w-input--no-padding': !this.outline && !this.bgColor && !this.shadow && !this.round,
256
258
  'w-input--has-placeholder': this.placeholder,
@@ -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)
@@ -73,7 +73,9 @@ export default {
73
73
  overlayClass: { type: [String, Object, Array] },
74
74
  overlayProps: { type: Object }, // Allow passing down an object of props to the w-overlay component.
75
75
  persistent: { type: Boolean },
76
- delay: { type: Number }
76
+ delay: { type: Number },
77
+ dark: { type: Boolean },
78
+ light: { type: Boolean }
77
79
  // Other props in the detachable mixin:
78
80
  // detachTo, appendTo, fixed, top, bottom, left, right, alignTop, alignBottom, alignLeft,
79
81
  // alignRight, noPosition, zIndex, activator.
@@ -153,7 +155,9 @@ export default {
153
155
  'w-menu--round': this.round,
154
156
  'w-menu--arrow': this.arrow,
155
157
  'w-menu--shadow': this.shadow,
156
- 'w-menu--fixed': this.fixed
158
+ 'w-menu--fixed': this.fixed,
159
+ 'w-menu--dark': this.dark,
160
+ 'w-menu--light': this.light
157
161
  }
158
162
  },
159
163
 
@@ -272,9 +276,12 @@ export default {
272
276
  .w-menu {
273
277
  position: absolute;
274
278
  z-index: 100;
279
+ color: $menu-color;
280
+
281
+ @include themeable;
275
282
 
276
283
  &--fixed {position: fixed;z-index: 1000;}
277
- &--card {background-color: #fff;}
284
+ &--card {background-color: $menu-bg-color;}
278
285
  &--tile {border-radius: 0;}
279
286
  &--round {
280
287
  border-radius: 99em;
@@ -293,7 +300,7 @@ export default {
293
300
  &.w-menu--left {margin-left: -4 * $base-increment;}
294
301
  &.w-menu--right {margin-left: 4 * $base-increment;}
295
302
 
296
- @include triangle(var(--w-menu-bg-color), '.w-menu', 9px);
303
+ @include triangle($menu-bg-color, '.w-menu', 9px);
297
304
  }
298
305
  }
299
306
  </style>
@@ -1,36 +1,31 @@
1
1
  <template lang="pug">
2
- transition-group(
3
- tag="div"
4
- class="w-notification-manager"
5
- :class="{ 'w-notification-manager--left': conf.align === 'left' }"
6
- :name="transition"
7
- appear)
8
- template(v-for="notif in notifications")
9
- w-alert.white--bg(
10
- v-if="notif._value"
11
- :key="notif._uid"
12
- v-model="notif._value"
13
- @close="notifManager.dismiss(notif._uid)"
14
- v-bind="notifProps(notif)")
15
- div(v-html="notif.message")
2
+ teleport(to=".w-app")
3
+ transition-group(
4
+ tag="div"
5
+ class="w-notification-manager"
6
+ :class="{ 'w-notification-manager--left': conf.align === 'left' }"
7
+ :name="transition"
8
+ appear)
9
+ template(v-for="notif in notifications")
10
+ w-alert.white--bg(
11
+ v-if="notif._value"
12
+ :key="notif._uid"
13
+ v-model="notif._value"
14
+ @close="notif.dismiss"
15
+ v-bind="notifProps(notif)")
16
+ div(v-html="notif.message")
16
17
  </template>
17
18
 
18
19
  <script>
19
- import NotificationManager from '../utils/notification-manager'
20
-
21
20
  export default {
22
21
  name: 'w-notification-manager',
23
22
 
24
- data: () => ({
25
- notifManager: null
26
- }),
27
-
28
23
  computed: {
29
24
  conf () {
30
25
  return this.$waveui.config.notificationManager
31
26
  },
32
27
  notifications () {
33
- return this.notifManager?.notifications || []
28
+ return this.$waveui._notificationManager?.notifications
34
29
  },
35
30
  // Possible transitions: slide-fade-down, slide-fade-left, slide-fade-right,
36
31
  // slide-left, slide-right, bounce, twist, fade, scale, scale-fade.
@@ -44,17 +39,10 @@ export default {
44
39
  methods: {
45
40
  notifProps (notif) {
46
41
  const { _value, _uid, message, timeout, ...props } = notif
42
+ // Replace the dismiss function with bool as expected from the w-alert component.
43
+ if (props.dismiss) props.dismiss = true
47
44
  return props
48
45
  }
49
- },
50
-
51
- created () {
52
- this.notifManager = new NotificationManager()
53
- },
54
-
55
- beforeUnmount () {
56
- this.notifManager.notifications = []
57
- delete this.notifManager
58
46
  }
59
47
  }
60
48
  </script>
@@ -45,7 +45,9 @@ export default {
45
45
  sm: { type: Boolean },
46
46
  md: { type: Boolean },
47
47
  lg: { type: Boolean },
48
- xl: { type: Boolean }
48
+ xl: { type: Boolean },
49
+ dark: { type: Boolean },
50
+ light: { type: Boolean }
49
51
  },
50
52
 
51
53
  emits: ['input', 'update:modelValue', 'close'],
@@ -114,6 +116,8 @@ export default {
114
116
 
115
117
  classes () {
116
118
  return {
119
+ 'w-notification--dark': this.dark,
120
+ 'w-notification--light': this.light,
117
121
  'w-notification--absolute': this.absolute,
118
122
  [`w-notification--${this.position.join(' w-notification--')}`]: true
119
123
  }
@@ -170,6 +174,8 @@ export default {
170
174
  z-index: 300;
171
175
  pointer-events: none;
172
176
 
177
+ @include themeable;
178
+
173
179
  // Position.
174
180
  &--absolute {position: absolute;z-index: 400;}
175
181
  &--top {top: 0;padding-top: 2 * $base-increment;}
@@ -11,7 +11,7 @@
11
11
  //- Background first, in SVG there is no z-index.
12
12
  circle.bg(
13
13
  v-if="bgColor || this.progressValue > -1"
14
- :class="bgColor"
14
+ :class="bgColor || null"
15
15
  :cx="circleCenter"
16
16
  :cy="circleCenter"
17
17
  :r="circleRadius"
@@ -252,7 +252,7 @@ $circle-size: 40;
252
252
 
253
253
  svg {display: block;width: 100%;}
254
254
  circle.bg {stroke: currentColor;}
255
- &.w-progress--default-bg circle.bg {stroke: rgba(0, 0, 0, 0.1);}
255
+ &.w-progress--default-bg circle.bg {stroke: $progress-bg-color;}
256
256
 
257
257
  .w-progress__progress {
258
258
  transform-origin: 100% 100%;
@@ -63,7 +63,9 @@ export default {
63
63
  labelOnLeft: { type: Boolean },
64
64
  color: { type: String, default: 'primary' },
65
65
  labelColor: { type: String, default: 'primary' },
66
- noRipple: { type: Boolean }
66
+ noRipple: { type: Boolean },
67
+ dark: { type: Boolean },
68
+ light: { type: Boolean }
67
69
  // Props from mixin: name, disabled, readonly, required, tabindex, validators.
68
70
  // Computed from mixin: inputName, isDisabled & isReadonly.
69
71
  },
@@ -88,7 +90,9 @@ export default {
88
90
  [`w-radio w-radio--${this.inputValue ? 'checked' : 'unchecked'}`]: true,
89
91
  'w-radio--disabled': this.isDisabled,
90
92
  'w-radio--ripple': this.ripple.start,
91
- 'w-radio--rippled': this.ripple.end
93
+ 'w-radio--rippled': this.ripple.end,
94
+ 'w-radio--dark': this.ripple.dark,
95
+ 'w-radio--light': this.ripple.light
92
96
  }
93
97
  }
94
98
  },
@@ -146,6 +150,8 @@ $inactive-color: #666;
146
150
  cursor: pointer;
147
151
  -webkit-tap-highlight-color: transparent;
148
152
 
153
+ @include themeable;
154
+
149
155
  &--disabled {
150
156
  cursor: not-allowed;
151
157
  -webkit-tap-highlight-color: transparent;
@@ -39,14 +39,16 @@ export default {
39
39
  modelValue: {},
40
40
  max: { type: [Number, String], default: 5 },
41
41
  color: { type: String, default: 'primary' },
42
- bgColor: { type: String, default: 'grey-light4' },
42
+ bgColor: { type: String },
43
43
  icon: { type: String, default: 'wi-star' },
44
44
  xs: { type: Boolean },
45
45
  sm: { type: Boolean },
46
46
  md: { type: Boolean },
47
47
  lg: { type: Boolean },
48
48
  xl: { type: Boolean },
49
- noRipple: { type: Boolean }
49
+ noRipple: { type: Boolean },
50
+ dark: { type: Boolean },
51
+ light: { type: Boolean }
50
52
  // Props from mixin: name, disabled, readonly, required, validators.
51
53
  // Computed from mixin: inputName, isDisabled & isReadonly.
52
54
  },
@@ -79,6 +81,8 @@ export default {
79
81
  classes () {
80
82
  return {
81
83
  'w-rating': true,
84
+ 'w-rating--dark': this.dark,
85
+ 'w-rating--light': this.light,
82
86
  'w-rating--focus': this.hasFocus,
83
87
  'w-rating--hover': this.hover,
84
88
  'w-rating--disabled': this.isDisabled,
@@ -144,7 +148,8 @@ export default {
144
148
  'w-rating__button--half': isHalf,
145
149
  [this.icon]: true,
146
150
  [`size--${this.size}`]: true,
147
- [isOn ? this.color : this.bgColor]: true
151
+ [this.color]: isOn,
152
+ [this.bgColor]: this.bgColor && !isOn
148
153
  }
149
154
  }
150
155
  },
@@ -162,6 +167,8 @@ export default {
162
167
  display: inline-flex;
163
168
  align-items: center;
164
169
 
170
+ @include themeable;
171
+
165
172
  &__button {
166
173
  position: relative;
167
174
  width: 1.1em;
@@ -171,6 +178,7 @@ export default {
171
178
  justify-content: center;
172
179
  border: none;
173
180
  background: none;
181
+ color: $rating-bg-color;
174
182
  cursor: pointer;
175
183
  -webkit-tap-highlight-color: transparent;
176
184
  @include default-transition($fast-transition-duration);
@@ -0,0 +1,24 @@
1
+ <template lang="pug">
2
+ .w-scrollbar
3
+ </template>
4
+
5
+ <script>
6
+ export default {
7
+ name: 'w-scrollbar',
8
+ props: {
9
+
10
+ },
11
+
12
+ emits: [],
13
+
14
+ data: () => ({
15
+
16
+ })
17
+ }
18
+ </script>
19
+
20
+ <style lang="scss">
21
+ .w-scrollbar {
22
+
23
+ }
24
+ </style>
@@ -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(
@@ -143,12 +143,13 @@ export default {
143
143
  round: { type: Boolean },
144
144
  shadow: { type: Boolean },
145
145
  tile: { type: Boolean },
146
- dark: { type: Boolean },
147
146
  returnObject: { type: Boolean },
148
147
  // By default you can unselect a list item by re-selecting it.
149
148
  // Allow preventing that on single selection lists only.
150
149
  noUnselect: { type: Boolean },
151
- menuProps: { type: Object } // Allow passing down an object of props to the w-menu component.
150
+ menuProps: { type: Object }, // Allow passing down an object of props to the w-menu component.
151
+ dark: { type: Boolean },
152
+ light: { type: Boolean }
152
153
  // Props from mixin: name, disabled, readonly, required, tabindex, validators.
153
154
  // Computed from mixin: inputName, isDisabled & isReadonly.
154
155
  },
@@ -196,11 +197,12 @@ export default {
196
197
  classes () {
197
198
  return {
198
199
  'w-select': true,
200
+ 'w-select--dark': this.dark,
201
+ 'w-select--light': this.light,
199
202
  'w-select--disabled': this.isDisabled,
200
203
  'w-select--readonly': this.isReadonly,
201
204
  [`w-select--${this.hasValue ? 'filled' : 'empty'}`]: true,
202
205
  'w-select--focused': (this.isFocused || this.showMenu) && !this.isReadonly,
203
- 'w-select--dark': this.dark,
204
206
  'w-select--floating-label': this.hasLabel && this.labelPosition === 'inside' && !this.staticLabel,
205
207
  'w-select--no-padding': !this.outline && !this.bgColor && !this.shadow && !this.round,
206
208
  'w-select--has-placeholder': this.placeholder,
@@ -298,7 +300,8 @@ export default {
298
300
  // Also accept objects if returnObject is true.
299
301
  // In any case, always end up with an array.
300
302
  checkSelection (items) {
301
- items = Array.isArray(items) ? items : (items ? [items] : [])
303
+ console.log(items)
304
+ items = Array.isArray(items) ? items : (items !== undefined ? [items] : [])
302
305
  // `selectItems` items always have a value.
303
306
  const allValues = this.selectItems.map(item => item.value)
304
307
 
@@ -357,6 +360,8 @@ export default {
357
360
  align-items: center;
358
361
  font-size: $base-font-size;
359
362
 
363
+ @include themeable;
364
+
360
365
  &--disabled {
361
366
  color: $disabled-color;
362
367
  cursor: not-allowed;
@@ -423,8 +428,10 @@ export default {
423
428
  &__selection {
424
429
  width: 100%;
425
430
  height: 100%;
426
- font-size: inherit;
431
+ min-height: inherit;
432
+ font: inherit;
427
433
  color: inherit;
434
+ text-align: inherit;
428
435
  background: none;
429
436
  border: none;
430
437
  outline: none;
@@ -521,12 +528,15 @@ export default {
521
528
  position: absolute;
522
529
  top: 50%;
523
530
  left: 0;
524
- // Use margin instead of padding as the scale transformation bellow decreases the real padding
531
+ right: 0;
532
+ // Use margin instead of padding as the scale transformation below decreases the real padding
525
533
  // size and misaligns the label.
526
534
  margin-left: 2 * $base-increment;
527
535
  transform: translateY(-50%);
528
536
  pointer-events: none;
529
537
 
538
+ .w-select--inner-icon-right & {padding-right: 22px;}
539
+
530
540
  .w-select--no-padding & {
531
541
  left: 0;
532
542
  margin-left: 0;
@@ -573,7 +583,7 @@ export default {
573
583
  margin: 0;
574
584
  max-height: 300px;
575
585
  overflow: auto;
576
- background-color: #fff;
586
+ background-color: $base-bg-color;
577
587
  border: $border;
578
588
  border-radius: $border-radius;
579
589
 
@@ -98,7 +98,9 @@ export default {
98
98
  max: { type: [Number, String], default: 100 },
99
99
  step: { type: [Number, String] },
100
100
  labelLeft: { type: String },
101
- labelRight: { type: String }
101
+ labelRight: { type: String },
102
+ dark: { type: Boolean },
103
+ light: { type: Boolean }
102
104
  // Props from mixin: name, disabled, readonly, required, validators.
103
105
  // Computed from mixin: inputName, isDisabled & isReadonly.
104
106
  },
@@ -165,6 +167,8 @@ export default {
165
167
  wrapperClasses () {
166
168
  return {
167
169
  'w-slider': true,
170
+ 'w-slider--dark': this.dark,
171
+ 'w-slider--light': this.light,
168
172
  'w-slider--dragging': this.dragging,
169
173
  'w-slider--disabled': this.isDisabled,
170
174
  'w-slider--readonly': this.isReadonly,
@@ -264,6 +268,8 @@ export default {
264
268
  align-items: center;
265
269
  user-select: none;
266
270
 
271
+ @include themeable;
272
+
267
273
  // Slider label, left & right.
268
274
  // ------------------------------------------------------
269
275
  &__label--left {margin-right: 3 * $base-increment;}
@@ -284,7 +290,7 @@ export default {
284
290
  transform: translateX(-50%);
285
291
  font-size: 0.8em;
286
292
  padding-top: 2 * $base-increment;
287
- color:rgba(0, 0, 0, 0.5);
293
+ color: $slider-step-label-color;
288
294
  z-index: 1;
289
295
  cursor: pointer;
290
296
 
@@ -296,7 +302,7 @@ export default {
296
302
  top: 0;
297
303
  width: $base-increment;
298
304
  aspect-ratio: 1;
299
- background-color: rgba(0, 0, 0, 0.2);
305
+ background-color: $slider-step-label-bg-color;
300
306
  border-radius: 99em;
301
307
  // box-shadow: 0 0 0 1px #fff;
302
308
  box-sizing: border-box;
@@ -377,7 +383,7 @@ export default {
377
383
  border: none;
378
384
  border-radius: 99em;
379
385
  cursor: pointer;
380
- background-color: #fff;
386
+ background-color: $slider-thumb-button-bg-color;
381
387
 
382
388
  .w-slider--disabled &, .w-slider--readonly & {cursor: auto;}
383
389
 
@@ -427,12 +433,12 @@ export default {
427
433
  margin-bottom: round(3 * $base-increment);
428
434
  transform: translateX(-50%);
429
435
  padding: round(0.75 * $base-increment) (2 * $base-increment);
430
- background-color: #fff;
436
+ background-color: $slider-thumb-label-bg-color;
431
437
  border-radius: $border-radius;
432
438
  border: $border;
433
439
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
434
440
  font-size: 0.85em;
435
- color:rgba(0, 0, 0, 0.7);
441
+ color: $slider-thumb-label-color;
436
442
 
437
443
  &:before, &:after {
438
444
  content: '';
@@ -446,7 +452,7 @@ export default {
446
452
  }
447
453
 
448
454
  &:before {border-width: 7px;border-top-color: inherit;}
449
- &:after {border-width: 6px;border-top-color: #fff;}
455
+ &:after {border-width: 6px;border-top-color: $slider-thumb-label-bg-color;}
450
456
 
451
457
  &--droplet {
452
458
  transform: translateX(-50%) rotate(-45deg);
@@ -1,24 +1,34 @@
1
1
  <template lang="pug">
2
- .w-steps
2
+ .w-steps(:class="classes")
3
3
  </template>
4
4
 
5
5
  <script>
6
6
  export default {
7
7
  name: 'w-steps',
8
8
  props: {
9
-
9
+ dark: { type: Boolean },
10
+ light: { type: Boolean }
10
11
  },
11
12
 
12
13
  emits: [],
13
14
 
14
15
  data: () => ({
15
16
 
16
- })
17
+ }),
18
+
19
+ computed: {
20
+ classes () {
21
+ return {
22
+ 'w-steps--dark': this.dark,
23
+ 'w-steps--light': this.light
24
+ }
25
+ }
26
+ }
17
27
  }
18
28
  </script>
19
29
 
20
30
  <style lang="scss">
21
31
  .w-steps {
22
-
32
+ @include themeable;
23
33
  }
24
34
  </style>
@@ -38,7 +38,7 @@ component(
38
38
  v-if="loading"
39
39
  circle
40
40
  color="inherit"
41
- v-bind="typeof loading === 'number' ? { 'model-value': loading } : {}")
41
+ v-bind="typeof loading === 'number' && { 'model-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(
@@ -63,7 +63,9 @@ export default {
63
63
  labelColor: { type: String, default: 'primary' },
64
64
  thin: { type: Boolean },
65
65
  noRipple: { type: Boolean },
66
- loading: { type: [Boolean, Number], default: false }
66
+ loading: { type: [Boolean, Number], default: false },
67
+ dark: { type: Boolean },
68
+ light: { type: Boolean }
67
69
  // Props from mixin: name, disabled, readonly, required, tabindex, validators.
68
70
  // Computed from mixin: inputName, isDisabled & isReadonly.
69
71
  },
@@ -95,7 +97,9 @@ export default {
95
97
  'w-switch--custom-thumb': this.$slots.thumb,
96
98
  'w-switch--custom-track': this.$slots.track,
97
99
  'w-switch--loading': this.loading,
98
- 'w-switch--rippled': this.ripple.end
100
+ 'w-switch--rippled': this.ripple.end,
101
+ 'w-switch--dark': this.dark,
102
+ 'w-switch--light': this.light
99
103
  }
100
104
  },
101
105
  inputClasses () {
@@ -140,8 +144,6 @@ export default {
140
144
 
141
145
  <style lang="scss">
142
146
  $outline-width: 2px;
143
- $inactive-color: #ccc;
144
- $disabled-color: #ddd;
145
147
 
146
148
  .w-switch {
147
149
  display: inline-flex;
@@ -149,6 +151,8 @@ $disabled-color: #ddd;
149
151
  vertical-align: middle;
150
152
  cursor: pointer;
151
153
 
154
+ @include themeable;
155
+
152
156
  &--loading {cursor: wait;}
153
157
  &--disabled, &--readonly {
154
158
  cursor: not-allowed;
@@ -173,9 +177,9 @@ $disabled-color: #ddd;
173
177
  flex: 0 0 auto; // Prevent stretching width or height.
174
178
  align-items: center;
175
179
  justify-content: center;
176
- border: $outline-width solid $inactive-color;
180
+ border: $outline-width solid transparent;
177
181
  border-radius: 3em;
178
- background-color: $inactive-color;
182
+ background-color: $switch-inactive-color;
179
183
  cursor: inherit;
180
184
  @include default-transition;
181
185
 
@@ -194,15 +198,11 @@ $disabled-color: #ddd;
194
198
  width: 2 * $small-form-el-size;
195
199
  height: round(0.7 * $small-form-el-size);
196
200
  }
197
- .w-switch--thin :checked ~ & {
198
- background-color: $inactive-color;
199
- }
201
+ .w-switch--thin :checked ~ & {background-color: $switch-inactive-color;}
200
202
 
201
203
  // Disabled.
202
204
  .w-switch--disabled & {color: $disabled-color;}
203
- .w-switch--disabled :checked ~ & {
204
- opacity: 0.5;
205
- }
205
+ .w-switch--disabled :checked ~ & {opacity: 0.5;}
206
206
  }
207
207
 
208
208
  // Track slot, if any.
@@ -223,7 +223,7 @@ $disabled-color: #ddd;
223
223
  top: 0;
224
224
  width: $small-form-el-size;
225
225
  height: $small-form-el-size;
226
- background-color: #fff;
226
+ background-color: $switch-thumb-color;
227
227
  border-radius: 100%;
228
228
  text-align: center;
229
229
  @include default-transition;