wave-ui 1.52.0 → 1.53.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 +229 -144
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +3 -2
- package/src/wave-ui/components/transitions/w-transition-expand.vue +1 -13
- package/src/wave-ui/components/w-accordion.vue +51 -20
- package/src/wave-ui/components/w-checkbox.vue +11 -6
- package/src/wave-ui/components/w-checkboxes.vue +9 -19
- package/src/wave-ui/components/w-dialog.vue +18 -9
- package/src/wave-ui/components/w-divider.vue +4 -1
- package/src/wave-ui/components/w-drawer.vue +46 -21
- package/src/wave-ui/components/w-form-element.vue +19 -13
- package/src/wave-ui/components/w-form.vue +16 -11
- package/src/wave-ui/components/w-icon.vue +19 -17
- package/src/wave-ui/components/w-input.vue +14 -37
- package/src/wave-ui/components/w-menu.vue +8 -0
- package/src/wave-ui/components/w-notification.vue +3 -1
- package/src/wave-ui/components/w-overlay.vue +21 -15
- package/src/wave-ui/components/w-radio.vue +11 -6
- package/src/wave-ui/components/w-radios.vue +6 -15
- package/src/wave-ui/components/w-select.vue +13 -28
- package/src/wave-ui/components/w-slider.vue +21 -10
- package/src/wave-ui/components/w-switch.vue +44 -16
- package/src/wave-ui/components/w-tabs/index.vue +11 -1
- package/src/wave-ui/components/w-textarea.vue +15 -17
- package/src/wave-ui/components/w-toolbar.vue +2 -2
- package/src/wave-ui/mixins/detachable.js +17 -13
- package/src/wave-ui/mixins/form-elements.js +9 -0
|
@@ -13,15 +13,10 @@ component(
|
|
|
13
13
|
//- Left label.
|
|
14
14
|
template(v-if="labelPosition === 'left'")
|
|
15
15
|
label.w-input__label.w-input__label--left.w-form-el-shakable(
|
|
16
|
-
v-if="$slots.default"
|
|
16
|
+
v-if="$slots.default || label"
|
|
17
17
|
:for="`w-input--${_uid}`"
|
|
18
|
-
:class="
|
|
19
|
-
slot
|
|
20
|
-
label.w-input__label.w-input__label--left.w-form-el-shakable(
|
|
21
|
-
v-else-if="label"
|
|
22
|
-
:for="`w-input--${_uid}`"
|
|
23
|
-
:class="validationClasses"
|
|
24
|
-
v-html="label")
|
|
18
|
+
:class="labelClasses")
|
|
19
|
+
slot {{ label }}
|
|
25
20
|
|
|
26
21
|
//- Input wrapper.
|
|
27
22
|
.w-input__input-wrap(:class="inputWrapClasses")
|
|
@@ -81,15 +76,10 @@ component(
|
|
|
81
76
|
|
|
82
77
|
template(v-if="labelPosition === 'inside' && showLabelInside")
|
|
83
78
|
label.w-input__label.w-input__label--inside.w-form-el-shakable(
|
|
84
|
-
v-if="$slots.default"
|
|
85
|
-
:for="`w-input--${_uid}`"
|
|
86
|
-
:class="validationClasses")
|
|
87
|
-
slot
|
|
88
|
-
label.w-input__label.w-input__label--inside.w-form-el-shakable(
|
|
89
|
-
v-else-if="label"
|
|
79
|
+
v-if="$slots.default || label"
|
|
90
80
|
:for="`w-input--${_uid}`"
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
:class="labelClasses")
|
|
82
|
+
slot {{ label }}
|
|
93
83
|
w-icon.w-input__icon.w-input__icon--inner-right(
|
|
94
84
|
v-if="innerIconRight"
|
|
95
85
|
tag="label"
|
|
@@ -117,15 +107,10 @@ component(
|
|
|
117
107
|
//- Right label.
|
|
118
108
|
template(v-if="labelPosition === 'right'")
|
|
119
109
|
label.w-input__label.w-input__label--right.w-form-el-shakable(
|
|
120
|
-
v-if="$slots.default"
|
|
121
|
-
:for="`w-input--${_uid}`"
|
|
122
|
-
:class="validationClasses")
|
|
123
|
-
slot
|
|
124
|
-
label.w-input__label.w-input__label--right.w-form-el-shakable(
|
|
125
|
-
v-else-if="label"
|
|
110
|
+
v-if="$slots.default || label"
|
|
126
111
|
:for="`w-input--${_uid}`"
|
|
127
|
-
:class="
|
|
128
|
-
|
|
112
|
+
:class="labelClasses")
|
|
113
|
+
slot {{ label }}
|
|
129
114
|
</template>
|
|
130
115
|
|
|
131
116
|
<script>
|
|
@@ -146,12 +131,12 @@ export default {
|
|
|
146
131
|
labelPosition: { type: String, default: 'inside' },
|
|
147
132
|
innerIconLeft: { type: String },
|
|
148
133
|
innerIconRight: { type: String },
|
|
149
|
-
// When label is inside,
|
|
150
|
-
staticLabel: { type: Boolean },
|
|
134
|
+
staticLabel: { type: Boolean }, // When label is inside, fix the label above.
|
|
151
135
|
placeholder: { type: String },
|
|
152
136
|
color: { type: String, default: 'primary' },
|
|
153
|
-
progressColor: { type: String },
|
|
154
137
|
bgColor: { type: String },
|
|
138
|
+
labelColor: { type: String, default: 'primary' },
|
|
139
|
+
progressColor: { type: String },
|
|
155
140
|
minlength: { type: [Number, String] },
|
|
156
141
|
maxlength: { type: [Number, String] },
|
|
157
142
|
step: { type: [Number, String] },
|
|
@@ -237,7 +222,7 @@ export default {
|
|
|
237
222
|
},
|
|
238
223
|
|
|
239
224
|
overallFilesProgress () {
|
|
240
|
-
const progress = this.inputFiles.reduce((total, file) => total + file.progress, 0)
|
|
225
|
+
const progress = +this.inputFiles.reduce((total, file) => total + file.progress, 0)
|
|
241
226
|
const total = progress / this.inputFiles.length
|
|
242
227
|
this.$emit('update:overallProgress', this.inputFiles.length ? total : undefined)
|
|
243
228
|
|
|
@@ -269,15 +254,9 @@ export default {
|
|
|
269
254
|
}
|
|
270
255
|
},
|
|
271
256
|
|
|
272
|
-
validationClasses () {
|
|
273
|
-
return this.isFocused && {
|
|
274
|
-
[this.valid === false ? 'error' : this.color]: this.color || this.valid === false
|
|
275
|
-
}
|
|
276
|
-
},
|
|
277
|
-
|
|
278
257
|
inputWrapClasses () {
|
|
279
258
|
return {
|
|
280
|
-
[this.valid === false ?
|
|
259
|
+
[this.valid === false ? this.validationColor : this.color]: this.color || this.valid === false,
|
|
281
260
|
[`${this.bgColor}--bg`]: this.bgColor,
|
|
282
261
|
'w-input__input-wrap--file': this.type === 'file',
|
|
283
262
|
'w-input__input-wrap--round': this.round,
|
|
@@ -635,8 +614,6 @@ $inactive-color: #777;
|
|
|
635
614
|
.w-input--filled.w-input--floating-label.w-input--inner-icon-left & {left: 0;}
|
|
636
615
|
// Chrome & Safari - Must remain in a separated rule as Firefox discard the whole rule seeing -webkit-.
|
|
637
616
|
.w-input--floating-label.w-input--inner-icon-left .w-input__input:-webkit-autofill & {left: 0;}
|
|
638
|
-
|
|
639
|
-
.w-input--focused & {color: currentColor;}
|
|
640
617
|
}
|
|
641
618
|
}
|
|
642
619
|
</style>
|
|
@@ -88,6 +88,14 @@ export default {
|
|
|
88
88
|
// alignRight, noPosition, zIndex, activator.
|
|
89
89
|
},
|
|
90
90
|
|
|
91
|
+
provide () {
|
|
92
|
+
return {
|
|
93
|
+
// If a detachable is used inside a w-menu without an appendTo, default to the menu element
|
|
94
|
+
// instead of the w-app.
|
|
95
|
+
detachableDefaultRoot: () => this.$refs.detachable?.$el || this.$refs.detachable || null
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
91
99
|
emits: ['input', 'update:modelValue', 'open', 'close'],
|
|
92
100
|
|
|
93
101
|
data: () => ({
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
transition(:name="transitionName" appear)
|
|
3
3
|
.w-notification(v-if="show" :class="classes" :style="styles")
|
|
4
|
-
w-alert.white--bg(
|
|
4
|
+
w-alert.white--bg(
|
|
5
|
+
v-bind="alertProps"
|
|
6
|
+
@input="$emit('update:modelValue', false);$emit('input', false)")
|
|
5
7
|
slot
|
|
6
8
|
</template>
|
|
7
9
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
transition(name="fade" appear @after-leave="
|
|
2
|
+
transition(name="fade" appear @after-leave="onClose")
|
|
3
3
|
.w-overlay(
|
|
4
4
|
v-if="showOverlay"
|
|
5
|
-
|
|
6
|
-
:style="
|
|
5
|
+
ref="overlay"
|
|
6
|
+
:style="styles || null"
|
|
7
7
|
@keydown.escape.stop="onClick"
|
|
8
8
|
@click="onClick"
|
|
9
9
|
v-focus
|
|
@@ -25,7 +25,15 @@ export default {
|
|
|
25
25
|
persistentNoAnimation: { type: Boolean }
|
|
26
26
|
},
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
provide () {
|
|
29
|
+
return {
|
|
30
|
+
// If a detachable is used inside a w-overlay without an appendTo, default to the overlay element
|
|
31
|
+
// instead of the w-app.
|
|
32
|
+
detachableDefaultRoot: () => this.$refs.overlay || null
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
emits: ['input', 'update:modelValue', 'click', 'before-close', 'close'],
|
|
29
37
|
|
|
30
38
|
data: () => ({
|
|
31
39
|
persistentAnimate: false,
|
|
@@ -60,21 +68,19 @@ export default {
|
|
|
60
68
|
setTimeout(() => (this.persistentAnimate = false), 150) // Must match CSS animation duration.
|
|
61
69
|
}
|
|
62
70
|
else if (!this.persistent) {
|
|
63
|
-
this
|
|
64
|
-
this.$emit('
|
|
65
|
-
this.$emit('close')
|
|
71
|
+
this.showOverlay = false
|
|
72
|
+
this.$emit('before-close')
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
this.$emit('click', e)
|
|
69
76
|
},
|
|
70
77
|
|
|
71
|
-
// Wait until the end of the closing transition to unmount
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this
|
|
77
|
-
this.$emit('closed')
|
|
78
|
+
// Wait until the end of the closing transition (v-show) to completely unmount (v-if).
|
|
79
|
+
// The onClose method is called twice from the transition: once for the v-show, and once for the v-if.
|
|
80
|
+
onClose () {
|
|
81
|
+
this.$emit('update:modelValue', false)
|
|
82
|
+
this.$emit('input', false)
|
|
83
|
+
this.$emit('close') // Only emit once.
|
|
78
84
|
}
|
|
79
85
|
},
|
|
80
86
|
|
|
@@ -84,7 +90,7 @@ export default {
|
|
|
84
90
|
|
|
85
91
|
watch: {
|
|
86
92
|
value (bool) {
|
|
87
|
-
if (bool) this.showOverlay =
|
|
93
|
+
if (this.showOverlay !== bool) this.showOverlay = bool
|
|
88
94
|
}
|
|
89
95
|
}
|
|
90
96
|
}
|
|
@@ -20,16 +20,20 @@ component(
|
|
|
20
20
|
:aria-checked="inputValue || 'false'"
|
|
21
21
|
role="radio")
|
|
22
22
|
template(v-if="hasLabel && labelOnLeft")
|
|
23
|
-
label.w-radio__label.w-form-el-shakable.pr2(
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
label.w-radio__label.w-form-el-shakable.pr2(
|
|
24
|
+
v-if="$slots.default || label"
|
|
25
|
+
:for="`w-radio--${_uid}`"
|
|
26
|
+
:class="labelClasses")
|
|
27
|
+
slot {{ label }}
|
|
26
28
|
.w-radio__input(
|
|
27
29
|
@click="$refs.input.focus();$refs.input.click()"
|
|
28
30
|
:class="this.color")
|
|
29
31
|
template(v-if="hasLabel && !labelOnLeft")
|
|
30
|
-
label.w-radio__label.w-form-el-shakable.pl2(
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
label.w-radio__label.w-form-el-shakable.pl2(
|
|
33
|
+
v-if="$slots.default || label"
|
|
34
|
+
:for="`w-radio--${_uid}`"
|
|
35
|
+
:class="labelClasses")
|
|
36
|
+
slot {{ label }}
|
|
33
37
|
</template>
|
|
34
38
|
|
|
35
39
|
<script>
|
|
@@ -48,6 +52,7 @@ export default {
|
|
|
48
52
|
label: { type: String },
|
|
49
53
|
labelOnLeft: { type: Boolean },
|
|
50
54
|
color: { type: String, default: 'primary' },
|
|
55
|
+
labelColor: { type: String, default: 'primary' },
|
|
51
56
|
noRipple: { type: Boolean }
|
|
52
57
|
// Props from mixin: name, disabled, readonly, required, tabindex, validators.
|
|
53
58
|
// Computed from mixin: inputName, isDisabled & isReadonly.
|
|
@@ -15,26 +15,16 @@ component(
|
|
|
15
15
|
@focus="$emit('focus', $event)"
|
|
16
16
|
:name="inputName"
|
|
17
17
|
:value="item.value === value"
|
|
18
|
-
|
|
19
|
-
:label-on-left="labelOnLeft"
|
|
20
|
-
:color="item.color"
|
|
18
|
+
v-bind="{ label: item.label, color: item.color, labelOnLeft, labelColor }"
|
|
21
19
|
:disabled="isDisabled || null"
|
|
22
20
|
:readonly="isReadonly || null"
|
|
23
21
|
:class="{ mt1: !inline && i }")
|
|
24
22
|
slot(
|
|
25
|
-
v-if="$
|
|
26
|
-
:name="`item.${i + 1}`"
|
|
23
|
+
v-if="$slots[`item.${i + 1}`] || $slots.item"
|
|
24
|
+
:name="$slots[`item.${i + 1}`] ? `item.${i + 1}` : 'item'"
|
|
27
25
|
:item="getOriginalItem(item)"
|
|
28
26
|
:index="i + 1"
|
|
29
|
-
:checked="item.value === value"
|
|
30
|
-
v-html="item.label")
|
|
31
|
-
slot(
|
|
32
|
-
v-else-if="$scopedSlots.item"
|
|
33
|
-
name="item"
|
|
34
|
-
:item="getOriginalItem(item)"
|
|
35
|
-
:index="i + 1"
|
|
36
|
-
:checked="item.value === value"
|
|
37
|
-
v-html="item.label")
|
|
27
|
+
:checked="item.value === value")
|
|
38
28
|
</template>
|
|
39
29
|
|
|
40
30
|
<script>
|
|
@@ -52,7 +42,8 @@ export default {
|
|
|
52
42
|
itemValueKey: { type: String, default: 'value' },
|
|
53
43
|
itemColorKey: { type: String, default: 'color' }, // Support a different color per item.
|
|
54
44
|
inline: { type: Boolean },
|
|
55
|
-
color: { type: String, default: 'primary' }
|
|
45
|
+
color: { type: String, default: 'primary' },
|
|
46
|
+
labelColor: { type: String, default: 'primary' }
|
|
56
47
|
// Props from mixin: name, disabled, readonly, required, validators.
|
|
57
48
|
// Computed from mixin: inputName, isDisabled & isReadonly.
|
|
58
49
|
},
|
|
@@ -9,24 +9,19 @@ component(
|
|
|
9
9
|
:class="classes")
|
|
10
10
|
template(v-if="labelPosition === 'left'")
|
|
11
11
|
label.w-select__label.w-select__label--left.w-form-el-shakable(
|
|
12
|
-
v-if="$slots.default"
|
|
13
|
-
:for="`w-select--${_uid}`")
|
|
14
|
-
slot
|
|
15
|
-
label.w-select__label.w-select__label--left.w-form-el-shakable(
|
|
16
|
-
v-else-if="label"
|
|
12
|
+
v-if="$slots.default || label"
|
|
17
13
|
:for="`w-select--${_uid}`"
|
|
18
|
-
|
|
14
|
+
:class="labelClasses")
|
|
15
|
+
slot {{ label }}
|
|
19
16
|
|
|
20
17
|
w-menu(
|
|
21
18
|
v-model="showMenu"
|
|
22
19
|
:menu-class="`w-select__menu ${menuClass || ''}`"
|
|
23
20
|
transition="slide-fade-down"
|
|
24
|
-
:append-to="(menuProps || {}).appendTo !== undefined ? (menuProps || {}).appendTo :
|
|
21
|
+
:append-to="(menuProps || {}).appendTo !== undefined ? (menuProps || {}).appendTo : undefined"
|
|
25
22
|
align-left
|
|
26
23
|
custom
|
|
27
24
|
min-width="activator"
|
|
28
|
-
@mousedown="isFocused = true, selectingItem = true"
|
|
29
|
-
@mouseup="isFocused = true, selectingItem = false"
|
|
30
25
|
v-bind="menuProps || {}")
|
|
31
26
|
template(#activator="{ on }")
|
|
32
27
|
//- Input wrapper.
|
|
@@ -69,15 +64,10 @@ component(
|
|
|
69
64
|
:name="inputName + (multiple ? '[]' : '')")
|
|
70
65
|
template(v-if="labelPosition === 'inside' && showLabelInside")
|
|
71
66
|
label.w-select__label.w-select__label--inside.w-form-el-shakable(
|
|
72
|
-
v-if="$slots.default"
|
|
73
|
-
:for="`w-select--${_uid}`"
|
|
74
|
-
:class="isFocused && { [valid === false ? 'error' : color]: color || valid === false }")
|
|
75
|
-
slot
|
|
76
|
-
label.w-select__label.w-select__label--inside.w-form-el-shakable(
|
|
77
|
-
v-else-if="label"
|
|
67
|
+
v-if="$slots.default || label"
|
|
78
68
|
:for="`w-select--${_uid}`"
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
:class="labelClasses")
|
|
70
|
+
slot {{ label }}
|
|
81
71
|
w-icon.w-select__icon.w-select__icon--inner-right(
|
|
82
72
|
v-if="innerIconRight"
|
|
83
73
|
tag="label"
|
|
@@ -113,13 +103,10 @@ component(
|
|
|
113
103
|
|
|
114
104
|
template(v-if="labelPosition === 'right'")
|
|
115
105
|
label.w-select__label.w-select__label--right.w-form-el-shakable(
|
|
116
|
-
v-if="$slots.default"
|
|
117
|
-
:for="`w-select--${_uid}`")
|
|
118
|
-
slot
|
|
119
|
-
label.w-select__label.w-select__label--right.w-form-el-shakable(
|
|
120
|
-
v-else-if="label"
|
|
106
|
+
v-if="$slots.default || label"
|
|
121
107
|
:for="`w-select--${_uid}`"
|
|
122
|
-
|
|
108
|
+
:class="labelClasses")
|
|
109
|
+
slot {{ label }}
|
|
123
110
|
</template>
|
|
124
111
|
|
|
125
112
|
<script>
|
|
@@ -150,8 +137,9 @@ export default {
|
|
|
150
137
|
itemClass: { type: String },
|
|
151
138
|
menuClass: { type: String },
|
|
152
139
|
color: { type: String, default: 'primary' }, // Applies to all the items.
|
|
153
|
-
selectionColor: { type: String, default: 'primary' }, // Applies to the selected items only.
|
|
154
140
|
bgColor: { type: String }, // Applies to all the items.
|
|
141
|
+
labelColor: { type: String, default: 'primary' },
|
|
142
|
+
selectionColor: { type: String, default: 'primary' }, // Applies to the selected items only.
|
|
155
143
|
outline: { type: Boolean },
|
|
156
144
|
round: { type: Boolean },
|
|
157
145
|
shadow: { type: Boolean },
|
|
@@ -175,7 +163,6 @@ export default {
|
|
|
175
163
|
showMenu: false,
|
|
176
164
|
menuMinWidth: 0,
|
|
177
165
|
isFocused: false,
|
|
178
|
-
selectingItem: false,
|
|
179
166
|
selectionWrapRef: undefined
|
|
180
167
|
}),
|
|
181
168
|
|
|
@@ -213,7 +200,7 @@ export default {
|
|
|
213
200
|
'w-select--disabled': this.isDisabled,
|
|
214
201
|
'w-select--readonly': this.isReadonly,
|
|
215
202
|
[`w-select--${this.hasValue ? 'filled' : 'empty'}`]: true,
|
|
216
|
-
'w-select--focused': (this.isFocused || this.
|
|
203
|
+
'w-select--focused': (this.isFocused || this.showMenu) && !this.isReadonly,
|
|
217
204
|
'w-select--dark': this.dark,
|
|
218
205
|
'w-select--floating-label': this.hasLabel && this.labelPosition === 'inside' && !this.staticLabel,
|
|
219
206
|
'w-select--no-padding': !this.outline && !this.bgColor && !this.shadow && !this.round,
|
|
@@ -579,8 +566,6 @@ export default {
|
|
|
579
566
|
.w-select--filled.w-select--floating-label.w-select--inner-icon-left & {left: 0;}
|
|
580
567
|
// Chrome & Safari - Must remain in a separated rule as Firefox discard the whole rule seeing -webkit-.
|
|
581
568
|
.w-select--floating-label.w-select--inner-icon-left .w-select__select:-webkit-autofill & {left: 0;}
|
|
582
|
-
|
|
583
|
-
.w-select--focused &, .w-select--open & {color: currentColor;}
|
|
584
569
|
}
|
|
585
570
|
|
|
586
571
|
// Menu.
|
|
@@ -5,15 +5,17 @@ component(
|
|
|
5
5
|
v-bind="formRegister && { validators, inputValue: rangeValueScaled, disabled: isDisabled, readonly: isReadonly }"
|
|
6
6
|
:valid.sync="valid"
|
|
7
7
|
@reset="rangeValuePercent = 0;updateRangeValueScaled()"
|
|
8
|
-
wrap
|
|
8
|
+
:wrap="formRegister || null"
|
|
9
9
|
:class="wrapperClasses")
|
|
10
10
|
label.w-slider__label.w-slider__label--left.w-form-el-shakable(
|
|
11
11
|
v-if="$slots['label-left']"
|
|
12
|
-
:for="`button--${_uid}`"
|
|
12
|
+
:for="`button--${_uid}`"
|
|
13
|
+
:class="labelClasses")
|
|
13
14
|
slot(name="label-left")
|
|
14
15
|
label.w-slider__label.w-slider__label--left.w-form-el-shakable(
|
|
15
16
|
v-else-if="labelLeft"
|
|
16
17
|
:for="`button--${_uid}`"
|
|
18
|
+
:class="labelClasses"
|
|
17
19
|
v-html="labelLeft")
|
|
18
20
|
.w-slider__track-wrap
|
|
19
21
|
.w-slider__track(
|
|
@@ -39,6 +41,7 @@ component(
|
|
|
39
41
|
:disabled="isDisabled || null"
|
|
40
42
|
:readonly="isReadonly || null"
|
|
41
43
|
:aria-readonly="isReadonly ? 'true' : 'false'"
|
|
44
|
+
:tabindex="isDisabled || isReadonly ? -1 : null"
|
|
42
45
|
@keydown.left="onKeyDown($event, -1)"
|
|
43
46
|
@keydown.right="onKeyDown($event, 1)"
|
|
44
47
|
@focus="$emit('focus', $event)"
|
|
@@ -64,11 +67,13 @@ component(
|
|
|
64
67
|
style="left: 100%") {{ this.maxVal }}
|
|
65
68
|
label.w-slider__label.w-slider__label--right.w-form-el-shakable(
|
|
66
69
|
v-if="$slots['label-right']"
|
|
67
|
-
:for="`button--${_uid}`"
|
|
70
|
+
:for="`button--${_uid}`"
|
|
71
|
+
:class="labelClasses")
|
|
68
72
|
slot(name="label-right")
|
|
69
73
|
label.w-slider__label.w-slider__label--right.w-form-el-shakable(
|
|
70
74
|
v-else-if="labelRight"
|
|
71
75
|
:for="`button--${_uid}`"
|
|
76
|
+
:class="labelClasses"
|
|
72
77
|
v-html="labelRight")
|
|
73
78
|
</template>
|
|
74
79
|
|
|
@@ -83,6 +88,7 @@ export default {
|
|
|
83
88
|
value: { type: Number, default: 0 },
|
|
84
89
|
color: { type: String, default: 'primary' },
|
|
85
90
|
bgColor: { type: String },
|
|
91
|
+
labelColor: { type: String, default: 'primary' },
|
|
86
92
|
stepLabels: { type: [Boolean, Array] },
|
|
87
93
|
thumbLabel: { type: [Boolean, String] }, // One of true, false, 'droplet'.
|
|
88
94
|
thumbLabelClass: { type: String },
|
|
@@ -378,16 +384,17 @@ export default {
|
|
|
378
384
|
&:before, &:after {
|
|
379
385
|
content: '';
|
|
380
386
|
position: absolute;
|
|
387
|
+
border-radius: inherit;
|
|
388
|
+
@include default-transition;
|
|
381
389
|
}
|
|
390
|
+
// Colored border on thumb when hover and active - but with a transparency.
|
|
382
391
|
&:before {
|
|
383
392
|
left: 0;
|
|
384
393
|
right: 0;
|
|
385
394
|
top: 0;
|
|
386
395
|
bottom: 0;
|
|
387
396
|
opacity: 0.5;
|
|
388
|
-
border-radius: inherit;
|
|
389
397
|
border: 1px solid currentColor;
|
|
390
|
-
@include default-transition;
|
|
391
398
|
}
|
|
392
399
|
&:hover:before, &:focus:before {opacity: 0.7;}
|
|
393
400
|
&:active:before, .w-slider--dragging &:before {
|
|
@@ -398,13 +405,17 @@ export default {
|
|
|
398
405
|
.w-slider--disabled &:before,
|
|
399
406
|
.w-slider--readonly &:before {box-shadow: none;opacity: 0.4;}
|
|
400
407
|
|
|
401
|
-
//
|
|
408
|
+
// The outline when focused, but also a bigger reactive zone for fat fingers when not.
|
|
402
409
|
&:after {
|
|
403
|
-
left: -
|
|
404
|
-
right: -
|
|
405
|
-
top: -
|
|
406
|
-
bottom: -
|
|
410
|
+
left: -2 * $base-increment;
|
|
411
|
+
right: -2 * $base-increment;
|
|
412
|
+
top: -2 * $base-increment;
|
|
413
|
+
bottom: -2 * $base-increment;
|
|
414
|
+
opacity: 0;
|
|
415
|
+
background-color: currentColor;
|
|
407
416
|
}
|
|
417
|
+
&:focus:after {opacity: 0.15;}
|
|
418
|
+
.w-slider--dragging &:after, &:active:after {opacity: 0.1;transform: scale(1.2);}
|
|
408
419
|
}
|
|
409
420
|
|
|
410
421
|
// Thumb label.
|
|
@@ -22,17 +22,25 @@ component(
|
|
|
22
22
|
:aria-checked="isOn || 'false'"
|
|
23
23
|
role="switch")
|
|
24
24
|
template(v-if="hasLabel && labelOnLeft")
|
|
25
|
-
label.w-switch__label.w-form-el-shakable(
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
label.w-switch__label.w-switch__label--left.w-form-el-shakable(
|
|
26
|
+
v-if="$slots.default || label"
|
|
27
|
+
:for="`w-switch--${_uid}`"
|
|
28
|
+
:class="labelClasses")
|
|
29
|
+
slot {{ label }}
|
|
28
30
|
.w-switch__input(
|
|
29
31
|
@click="$refs.input.focus();$refs.input.click()"
|
|
30
32
|
v-on="$listeners"
|
|
31
33
|
:class="inputClasses")
|
|
34
|
+
.w-switch__track(v-if="$slots.track")
|
|
35
|
+
slot(name="track")
|
|
36
|
+
.w-switch__thumb(v-if="$slots.thumb")
|
|
37
|
+
slot(name="thumb")
|
|
32
38
|
template(v-if="hasLabel && !labelOnLeft")
|
|
33
|
-
label.w-switch__label.w-form-el-shakable(
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
label.w-switch__label.w-switch__label--right.w-form-el-shakable(
|
|
40
|
+
v-if="$slots.default || label"
|
|
41
|
+
:for="`w-switch--${_uid}`"
|
|
42
|
+
:class="labelClasses")
|
|
43
|
+
slot {{ label }}
|
|
36
44
|
</template>
|
|
37
45
|
|
|
38
46
|
<script>
|
|
@@ -47,6 +55,7 @@ export default {
|
|
|
47
55
|
label: { type: String, default: '' },
|
|
48
56
|
labelOnLeft: { type: Boolean },
|
|
49
57
|
color: { type: String, default: 'primary' },
|
|
58
|
+
labelColor: { type: String, default: 'primary' },
|
|
50
59
|
thin: { type: Boolean },
|
|
51
60
|
noRipple: { type: Boolean }
|
|
52
61
|
// Props from mixin: name, disabled, readonly, required, tabindex, validators.
|
|
@@ -77,6 +86,8 @@ export default {
|
|
|
77
86
|
'w-switch--disabled': this.isDisabled,
|
|
78
87
|
'w-switch--readonly': this.isReadonly,
|
|
79
88
|
'w-switch--ripple': this.ripple.start,
|
|
89
|
+
'w-switch--custom-thumb': this.$slots.thumb,
|
|
90
|
+
'w-switch--custom-track': this.$slots.track,
|
|
80
91
|
'w-switch--rippled': this.ripple.end
|
|
81
92
|
}
|
|
82
93
|
},
|
|
@@ -186,8 +197,18 @@ $disabled-color: #ddd;
|
|
|
186
197
|
}
|
|
187
198
|
}
|
|
188
199
|
|
|
189
|
-
//
|
|
190
|
-
&
|
|
200
|
+
// Track slot, if any.
|
|
201
|
+
&__track {
|
|
202
|
+
position: absolute;
|
|
203
|
+
left: 100%;
|
|
204
|
+
padding: 0 4px;
|
|
205
|
+
transform: translateX(-100%);
|
|
206
|
+
@include default-transition;
|
|
207
|
+
}
|
|
208
|
+
.w-switch--on &__track {left: 0;transform: translateX(0);}
|
|
209
|
+
|
|
210
|
+
// Thumb: show either the thumb slot if any, or :after otherwise.
|
|
211
|
+
&__thumb, &__input:after {
|
|
191
212
|
content: '';
|
|
192
213
|
position: absolute;
|
|
193
214
|
left: 0;
|
|
@@ -196,22 +217,28 @@ $disabled-color: #ddd;
|
|
|
196
217
|
height: $small-form-el-size;
|
|
197
218
|
background-color: #fff;
|
|
198
219
|
border-radius: 100%;
|
|
220
|
+
text-align: center;
|
|
199
221
|
@include default-transition;
|
|
200
222
|
|
|
201
223
|
.w-switch[class^="bdrs"] &, .w-switch[class*=" bdrs"] & {border-radius: inherit;}
|
|
202
224
|
|
|
203
|
-
|
|
225
|
+
.w-switch--on & {left: 100%;transform: translateX(-100%);}
|
|
204
226
|
|
|
205
227
|
.w-switch--thin & {
|
|
206
228
|
top: - round(0.15 * $small-form-el-size);
|
|
207
229
|
transform: scale(1.1);
|
|
208
230
|
box-shadow: $box-shadow;
|
|
209
231
|
}
|
|
210
|
-
.w-switch--thin
|
|
211
|
-
transform: translateX(100%) scale(1.1);
|
|
232
|
+
.w-switch--thin.w-switch--on & {
|
|
233
|
+
transform: translateX(-100%) scale(1.1);
|
|
212
234
|
background-color: currentColor;
|
|
213
235
|
}
|
|
214
236
|
}
|
|
237
|
+
&--custom-thumb &__input:after {display: none;}
|
|
238
|
+
&__thumb > * {
|
|
239
|
+
width: inherit;
|
|
240
|
+
height: inherit;
|
|
241
|
+
}
|
|
215
242
|
|
|
216
243
|
// The focus outline & ripple on switch activation.
|
|
217
244
|
&__input:before {
|
|
@@ -223,11 +250,12 @@ $disabled-color: #ddd;
|
|
|
223
250
|
height: $small-form-el-size;
|
|
224
251
|
background-color: currentColor;
|
|
225
252
|
border-radius: 100%;
|
|
226
|
-
transform: translateX(100%) scale(0);
|
|
227
253
|
opacity: 0;
|
|
228
254
|
pointer-events: none;
|
|
229
255
|
transition: 0.25s ease-in-out;
|
|
230
256
|
|
|
257
|
+
:checked ~ & {transform: translateX(-100%) scale(0);left: 100%;}
|
|
258
|
+
|
|
231
259
|
.w-switch[class^="bdrs"] &, .w-switch[class*=" bdrs"] & {border-radius: inherit;}
|
|
232
260
|
.w-switch--thin & {top: - round(0.15 * $small-form-el-size);}
|
|
233
261
|
}
|
|
@@ -242,14 +270,14 @@ $disabled-color: #ddd;
|
|
|
242
270
|
opacity: 0.2;
|
|
243
271
|
}
|
|
244
272
|
:focus:checked ~ &__input:before {
|
|
245
|
-
transform: translateX(100%) scale(1.8);
|
|
273
|
+
transform: translateX(-100%) scale(1.8);
|
|
246
274
|
}
|
|
247
275
|
|
|
248
276
|
// After ripple reset to default state, then remove the class via js and the
|
|
249
277
|
// `:focus ~ &__input:before` will re-transition to normal focused outline.
|
|
250
278
|
&--rippled &__input:before {
|
|
251
279
|
transition: none;
|
|
252
|
-
transform: translateX(100%) scale(0);
|
|
280
|
+
transform: translateX(-100%) scale(0);
|
|
253
281
|
opacity: 0;
|
|
254
282
|
}
|
|
255
283
|
|
|
@@ -264,7 +292,7 @@ $disabled-color: #ddd;
|
|
|
264
292
|
}
|
|
265
293
|
|
|
266
294
|
@keyframes w-switch-ripple {
|
|
267
|
-
0% {opacity: 0.8;transform: translateX(100%) scale(1);background-color: currentColor;} // Start with visible ripple.
|
|
268
|
-
100% {opacity: 0;transform: translateX(100%) scale(2.8);} // Propagate ripple to max radius and fade out.
|
|
295
|
+
0% {opacity: 0.8;transform: translateX(-100%) scale(1);background-color: currentColor;} // Start with visible ripple.
|
|
296
|
+
100% {opacity: 0;transform: translateX(-100%) scale(2.8);} // Propagate ripple to max radius and fade out.
|
|
269
297
|
}
|
|
270
298
|
</style>
|
|
@@ -65,6 +65,7 @@ export default {
|
|
|
65
65
|
titleClass: { type: String },
|
|
66
66
|
activeClass: { type: String, default: 'primary' },
|
|
67
67
|
noSlider: { type: Boolean },
|
|
68
|
+
pillSlider: { type: Boolean },
|
|
68
69
|
sliderColor: { type: String, default: 'primary' },
|
|
69
70
|
contentClass: { type: String },
|
|
70
71
|
transition: { type: [String, Boolean], default: '' },
|
|
@@ -122,6 +123,7 @@ export default {
|
|
|
122
123
|
return {
|
|
123
124
|
'w-tabs--card': this.card,
|
|
124
125
|
'w-tabs--no-slider': this.noSlider,
|
|
126
|
+
'w-tabs--pill-slider': this.pillSlider,
|
|
125
127
|
'w-tabs--fill-bar': this.fillBar,
|
|
126
128
|
'w-tabs--init': this.init
|
|
127
129
|
}
|
|
@@ -252,11 +254,11 @@ export default {
|
|
|
252
254
|
&__bar {
|
|
253
255
|
position: relative;
|
|
254
256
|
display: flex;
|
|
255
|
-
// align-items: center;
|
|
256
257
|
overflow-x: auto;
|
|
257
258
|
|
|
258
259
|
&--center {justify-content: center;}
|
|
259
260
|
&--right {justify-content: flex-end;}
|
|
261
|
+
.w-tabs--pill-slider & {padding-left: $base-increment;}
|
|
260
262
|
|
|
261
263
|
.w-tabs--card &:after {
|
|
262
264
|
content: '';
|
|
@@ -310,6 +312,7 @@ export default {
|
|
|
310
312
|
&:active:before {opacity: 0.08;}
|
|
311
313
|
&--disabled:before {display: none;}
|
|
312
314
|
}
|
|
315
|
+
&--pill-slider &__bar-item:before {display: none;}
|
|
313
316
|
|
|
314
317
|
// Bar Extra.
|
|
315
318
|
// ------------------------------------------------------
|
|
@@ -330,6 +333,13 @@ export default {
|
|
|
330
333
|
background-color: currentColor;
|
|
331
334
|
transition: $transition-duration ease-in-out;
|
|
332
335
|
}
|
|
336
|
+
&--pill-slider &__slider {
|
|
337
|
+
opacity: 0.1;
|
|
338
|
+
bottom: 15%;
|
|
339
|
+
height: 70%;
|
|
340
|
+
border-radius: 99em;
|
|
341
|
+
}
|
|
342
|
+
|
|
333
343
|
&--init &__slider {transition: none;}
|
|
334
344
|
|
|
335
345
|
// Content.
|