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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.53.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
|
"main": "./dist/wave-ui.umd.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"*.vue"
|
|
44
44
|
],
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@babel/core": "^7.17.
|
|
46
|
+
"@babel/core": "^7.17.9",
|
|
47
47
|
"@babel/eslint-parser": "^7.17.0",
|
|
48
48
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
49
49
|
"@vitejs/plugin-vue": "^1.10.2",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"gsap": "^3.9.1",
|
|
62
62
|
"ionicons": "^4.6.3",
|
|
63
63
|
"material-design-icons": "^3.0.1",
|
|
64
|
+
"postcss": "^8.4.12",
|
|
64
65
|
"rollup-plugin-delete": "^2.0.0",
|
|
65
66
|
"sass": "^1.49.7",
|
|
66
67
|
"simple-syntax-highlighter": "^1.5.0",
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
transition(
|
|
3
3
|
name="expand"
|
|
4
4
|
mode="out-in"
|
|
5
|
-
v-bind="$props"
|
|
6
5
|
:css="false"
|
|
7
6
|
@before-appear="beforeAppear"
|
|
8
7
|
@appear="appear"
|
|
@@ -17,15 +16,13 @@ transition(
|
|
|
17
16
|
</template>
|
|
18
17
|
|
|
19
18
|
<script>
|
|
20
|
-
// const duration = 250 // ms.
|
|
21
|
-
|
|
22
19
|
export default {
|
|
23
20
|
name: 'w-transition-expand',
|
|
24
21
|
|
|
25
22
|
props: {
|
|
26
23
|
x: { type: Boolean },
|
|
27
24
|
y: { type: Boolean },
|
|
28
|
-
duration: { type: Number, default:
|
|
25
|
+
duration: { type: Number, default: 250 }
|
|
29
26
|
},
|
|
30
27
|
|
|
31
28
|
data: () => ({
|
|
@@ -64,56 +61,47 @@ export default {
|
|
|
64
61
|
// Not when clicking very fast and mixing states order.
|
|
65
62
|
if (this.cleanTransitionCycle) this.saveOriginalStyles(el)
|
|
66
63
|
this.cleanTransitionCycle = false
|
|
67
|
-
this.$emit('before-appear')
|
|
68
64
|
},
|
|
69
65
|
appear (el, done) {
|
|
70
66
|
this.show(el)
|
|
71
67
|
setTimeout(done, this.duration)
|
|
72
68
|
this.cleanTransitionCycle = false
|
|
73
|
-
this.$emit('appear')
|
|
74
69
|
},
|
|
75
70
|
afterAppear (el) {
|
|
76
71
|
this.applyOriginalStyles(el)
|
|
77
72
|
// May be transitioning with v-show, if so don't reapply display none.
|
|
78
73
|
el.style.cssText = el.style.cssText.replace('display: none;', '')
|
|
79
74
|
this.cleanTransitionCycle = false
|
|
80
|
-
this.$emit('after-appear')
|
|
81
75
|
},
|
|
82
76
|
beforeEnter (el) {
|
|
83
77
|
// Only save original state once before a 'clean' transition start.
|
|
84
78
|
// Not when clicking very fast and mixing states order.
|
|
85
79
|
if (this.cleanTransitionCycle) this.saveOriginalStyles(el)
|
|
86
80
|
this.cleanTransitionCycle = false
|
|
87
|
-
this.$emit('before-enter')
|
|
88
81
|
},
|
|
89
82
|
enter (el, done) {
|
|
90
83
|
this.show(el)
|
|
91
84
|
setTimeout(done, this.duration)
|
|
92
85
|
this.cleanTransitionCycle = false
|
|
93
|
-
this.$emit('enter')
|
|
94
86
|
},
|
|
95
87
|
afterEnter (el) {
|
|
96
88
|
this.applyOriginalStyles(el)
|
|
97
89
|
// May be transitioning with v-show, if so don't reapply display none.
|
|
98
90
|
el.style.cssText = el.style.cssText.replace('display: none;', '')
|
|
99
91
|
this.cleanTransitionCycle = false
|
|
100
|
-
this.$emit('after-enter')
|
|
101
92
|
},
|
|
102
93
|
beforeLeave (el) {
|
|
103
94
|
this.beforeHide(el)
|
|
104
95
|
this.cleanTransitionCycle = false
|
|
105
|
-
this.$emit('before-leave')
|
|
106
96
|
},
|
|
107
97
|
leave (el, done) {
|
|
108
98
|
this.hide(el)
|
|
109
99
|
setTimeout(done, this.duration)
|
|
110
100
|
this.cleanTransitionCycle = false
|
|
111
|
-
this.$emit('leave')
|
|
112
101
|
},
|
|
113
102
|
afterLeave (el) {
|
|
114
103
|
this.applyOriginalStyles(el)
|
|
115
104
|
this.cleanTransitionCycle = true
|
|
116
|
-
this.$emit('after-leave')
|
|
117
105
|
},
|
|
118
106
|
|
|
119
107
|
applyHideStyles (el) {
|
|
@@ -38,20 +38,29 @@
|
|
|
38
38
|
@click.stop="!item._disabled && toggleItem(item, $event)"
|
|
39
39
|
:class="{ 'w-accordion__expand-icon--expanded': item._expanded }")
|
|
40
40
|
//- Content.
|
|
41
|
-
w-transition-expand(
|
|
42
|
-
|
|
41
|
+
w-transition-expand(
|
|
42
|
+
y
|
|
43
|
+
@after-leave="onEndOfCollapse(item)"
|
|
44
|
+
:duration="duration")
|
|
45
|
+
.w-accordion__item-content(
|
|
46
|
+
v-if="item._expanded"
|
|
47
|
+
:class="contentClass")
|
|
43
48
|
slot(
|
|
44
49
|
v-if="$scopedSlots[`item-content.${item.id || i + 1}`]"
|
|
45
50
|
:name="`item-content.${item.id || i + 1}`"
|
|
46
51
|
:item="getOriginalItem(item)"
|
|
47
|
-
:expanded="item._expanded"
|
|
48
|
-
|
|
52
|
+
:expanded="item._expanded"
|
|
53
|
+
:index="i + 1")
|
|
54
|
+
slot(
|
|
55
|
+
v-else
|
|
56
|
+
name="item-content"
|
|
57
|
+
:item="getOriginalItem(item)"
|
|
58
|
+
:expanded="item._expanded"
|
|
59
|
+
:index="i + 1")
|
|
49
60
|
div(v-html="item[itemContentKey]")
|
|
50
61
|
</template>
|
|
51
62
|
|
|
52
63
|
<script>
|
|
53
|
-
import Vue from 'vue'
|
|
54
|
-
|
|
55
64
|
export default {
|
|
56
65
|
name: 'w-accordion',
|
|
57
66
|
|
|
@@ -70,23 +79,17 @@ export default {
|
|
|
70
79
|
expandIconRight: { type: Boolean },
|
|
71
80
|
expandSingle: { type: Boolean },
|
|
72
81
|
collapseIcon: { type: String },
|
|
73
|
-
shadow: { type: Boolean }
|
|
82
|
+
shadow: { type: Boolean },
|
|
83
|
+
duration: { type: Number, default: 250 }
|
|
74
84
|
},
|
|
75
85
|
|
|
76
|
-
emits: ['input', 'update:
|
|
86
|
+
emits: ['input', 'update:value', 'focus', 'item-expand', 'item-collapsed'],
|
|
77
87
|
|
|
78
|
-
|
|
79
|
-
accordionItems
|
|
80
|
-
|
|
81
|
-
// eslint-disable-next-line new-cap
|
|
82
|
-
return items.map((item, _index) => new Vue.observable({
|
|
83
|
-
...item,
|
|
84
|
-
_index,
|
|
85
|
-
_expanded: this.value && this.value[_index],
|
|
86
|
-
_disabled: !!item.disabled
|
|
87
|
-
}))
|
|
88
|
-
},
|
|
88
|
+
data: () => ({
|
|
89
|
+
accordionItems: []
|
|
90
|
+
}),
|
|
89
91
|
|
|
92
|
+
computed: {
|
|
90
93
|
accordionClasses () {
|
|
91
94
|
return {
|
|
92
95
|
[this.color]: this.color,
|
|
@@ -104,7 +107,7 @@ export default {
|
|
|
104
107
|
item._expanded = !item._expanded
|
|
105
108
|
if (this.expandSingle) this.accordionItems.forEach(obj => obj._index !== item._index && (obj._expanded = false))
|
|
106
109
|
const expandedItems = this.accordionItems.map(item => item._expanded || false)
|
|
107
|
-
this.$emit('update:
|
|
110
|
+
this.$emit('update:value', expandedItems)
|
|
108
111
|
this.$emit('input', expandedItems)
|
|
109
112
|
this.$emit('item-expand', { item, expanded: item._expanded })
|
|
110
113
|
|
|
@@ -114,6 +117,9 @@ export default {
|
|
|
114
117
|
e.target.blur()
|
|
115
118
|
setTimeout(() => e.target.focus(), 300)
|
|
116
119
|
},
|
|
120
|
+
onEndOfCollapse (item) {
|
|
121
|
+
this.$emit('item-collapsed', { item, expanded: item._expanded })
|
|
122
|
+
},
|
|
117
123
|
// Return the original accordion item (so there is no `_index`, etc.).
|
|
118
124
|
getOriginalItem (item) {
|
|
119
125
|
return this.items[item._index]
|
|
@@ -125,6 +131,31 @@ export default {
|
|
|
125
131
|
'w-accordion__item--disabled': item._disabled,
|
|
126
132
|
[item[this.itemColorKey]]: item[this.itemColorKey]
|
|
127
133
|
}
|
|
134
|
+
},
|
|
135
|
+
updateItems () {
|
|
136
|
+
const items = typeof this.items === 'number' ? Array(this.items).fill({}) : this.items || []
|
|
137
|
+
this.$set(this, 'accordionItems', items.map((item, _index) => ({
|
|
138
|
+
...item,
|
|
139
|
+
_index,
|
|
140
|
+
_expanded: this.value && this.value[_index],
|
|
141
|
+
_disabled: !!item.disabled
|
|
142
|
+
})))
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
created () {
|
|
147
|
+
this.updateItems()
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
watch: {
|
|
151
|
+
value () {
|
|
152
|
+
this.updateItems()
|
|
153
|
+
},
|
|
154
|
+
items: {
|
|
155
|
+
handler () {
|
|
156
|
+
this.updateItems()
|
|
157
|
+
},
|
|
158
|
+
deep: true
|
|
128
159
|
}
|
|
129
160
|
}
|
|
130
161
|
}
|
|
@@ -22,16 +22,20 @@ component(
|
|
|
22
22
|
:aria-checked="isChecked || 'false'"
|
|
23
23
|
role="checkbox")
|
|
24
24
|
template(v-if="hasLabel && labelOnLeft")
|
|
25
|
-
label.w-checkbox__label.w-form-el-shakable.pr2(
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
label.w-checkbox__label.w-form-el-shakable.pr2(
|
|
26
|
+
v-if="$slots.default || label"
|
|
27
|
+
:for="`w-checkbox--${_uid}`"
|
|
28
|
+
:class="labelClasses")
|
|
29
|
+
slot {{ label }}
|
|
28
30
|
.w-checkbox__input(@click="$refs.input.focus();$refs.input.click()" :class="this.color")
|
|
29
31
|
svg(width="11px" height="9px" viewbox="0 0 12 9")
|
|
30
32
|
polyline(points="1 5 4 8 10 2")
|
|
31
33
|
template(v-if="hasLabel && !labelOnLeft")
|
|
32
|
-
label.w-checkbox__label.w-form-el-shakable.pl2(
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
label.w-checkbox__label.w-form-el-shakable.pl2(
|
|
35
|
+
v-if="$slots.default || label"
|
|
36
|
+
:for="`w-checkbox--${_uid}`"
|
|
37
|
+
:class="labelClasses")
|
|
38
|
+
slot {{ label }}
|
|
35
39
|
</template>
|
|
36
40
|
|
|
37
41
|
<script>
|
|
@@ -50,6 +54,7 @@ export default {
|
|
|
50
54
|
label: { type: String },
|
|
51
55
|
labelOnLeft: { type: Boolean },
|
|
52
56
|
color: { type: String, default: 'primary' },
|
|
57
|
+
labelColor: { type: String, default: 'primary' },
|
|
53
58
|
noRipple: { type: Boolean },
|
|
54
59
|
indeterminate: { type: Boolean },
|
|
55
60
|
round: { type: Boolean }
|
|
@@ -11,31 +11,20 @@ component(
|
|
|
11
11
|
w-checkbox(
|
|
12
12
|
v-for="(item, i) in checkboxItems"
|
|
13
13
|
:key="i"
|
|
14
|
-
:name="`${name || `w-checkboxes--${_uid}`}[]`"
|
|
15
|
-
:label="item.label"
|
|
16
|
-
:label-on-left="labelOnLeft"
|
|
17
14
|
:value="item._isChecked"
|
|
18
|
-
:color="item.color"
|
|
19
|
-
:round="round"
|
|
20
|
-
:disabled="isDisabled || null"
|
|
21
|
-
:readonly="isReadonly || null"
|
|
22
15
|
@input="toggleCheck(item, $event)"
|
|
23
16
|
@focus="$emit('focus', $event)"
|
|
17
|
+
:name="`${inputName}[]`"
|
|
18
|
+
v-bind="{ label: item.label, color: item.color, labelOnLeft, labelColor, round }"
|
|
19
|
+
:disabled="isDisabled || null"
|
|
20
|
+
:readonly="isReadonly || null"
|
|
24
21
|
:class="{ mt1: !inline && i }")
|
|
25
22
|
slot(
|
|
26
|
-
v-if="$
|
|
27
|
-
:name="`item.${i + 1}`"
|
|
28
|
-
:item="getOriginalItem(item)"
|
|
29
|
-
:checked="!!item._isChecked"
|
|
30
|
-
:index="i + 1"
|
|
31
|
-
v-html="item.label")
|
|
32
|
-
slot(
|
|
33
|
-
v-else-if="$scopedSlots.item"
|
|
34
|
-
name="item"
|
|
23
|
+
v-if="$slots[`item.${i + 1}`] || $slots.item"
|
|
24
|
+
:name="$slots[`item.${i + 1}`] ? `item.${i + 1}` : 'item'"
|
|
35
25
|
:item="getOriginalItem(item)"
|
|
36
26
|
:checked="!!item._isChecked"
|
|
37
|
-
:index="i + 1"
|
|
38
|
-
v-html="item.label")
|
|
27
|
+
:index="i + 1")
|
|
39
28
|
</template>
|
|
40
29
|
|
|
41
30
|
<script>
|
|
@@ -55,7 +44,8 @@ export default {
|
|
|
55
44
|
itemColorKey: { type: String, default: 'color' }, // Support a different color per item.
|
|
56
45
|
inline: { type: Boolean },
|
|
57
46
|
round: { type: Boolean },
|
|
58
|
-
color: { type: String, default: 'primary' }
|
|
47
|
+
color: { type: String, default: 'primary' },
|
|
48
|
+
labelColor: { type: String, default: 'primary' }
|
|
59
49
|
// Props from mixin: name, disabled, readonly, required, validators.
|
|
60
50
|
// Computed from mixin: inputName, isDisabled & isReadonly.
|
|
61
51
|
},
|
|
@@ -4,13 +4,14 @@ w-overlay.w-dialog(
|
|
|
4
4
|
:persistent="persistent"
|
|
5
5
|
:persistent-no-animation="persistentNoAnimation"
|
|
6
6
|
@click="onOutsideClick"
|
|
7
|
-
@
|
|
7
|
+
@close="onClose"
|
|
8
8
|
:bg-color="overlayColor"
|
|
9
9
|
:opacity="overlayOpacity"
|
|
10
10
|
:class="classes")
|
|
11
|
-
transition(:name="transition" appear @after-leave="
|
|
11
|
+
transition(:name="transition" appear @after-leave="onBeforeClose")
|
|
12
12
|
w-card.w-dialog__content(
|
|
13
13
|
v-show="showContent"
|
|
14
|
+
ref="dialog"
|
|
14
15
|
no-border
|
|
15
16
|
:color="color"
|
|
16
17
|
:bg-color="bgColor"
|
|
@@ -48,7 +49,15 @@ export default {
|
|
|
48
49
|
overlayOpacity: { type: [Number, String, Boolean] }
|
|
49
50
|
},
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
provide () {
|
|
53
|
+
return {
|
|
54
|
+
// If a detachable is used inside a w-drawer without an appendTo, default to the drawer element
|
|
55
|
+
// instead of the w-app.
|
|
56
|
+
detachableDefaultRoot: () => this.$refs.dialog.$el || null
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
emits: ['input', 'update:modelValue', 'before-close', 'close'],
|
|
52
61
|
|
|
53
62
|
data () {
|
|
54
63
|
return {
|
|
@@ -81,11 +90,14 @@ export default {
|
|
|
81
90
|
this.showContent = false
|
|
82
91
|
// If fade transition close both dialog and overlay at the same time
|
|
83
92
|
// (don't need to wait for the end of the dialog transition).
|
|
84
|
-
if (this.transition === 'fade') this.
|
|
93
|
+
if (this.transition === 'fade') this.onBeforeClose()
|
|
85
94
|
}
|
|
86
95
|
},
|
|
87
|
-
|
|
96
|
+
onBeforeClose () {
|
|
88
97
|
this.showWrapper = false
|
|
98
|
+
this.$emit('before-close')
|
|
99
|
+
},
|
|
100
|
+
onClose () {
|
|
89
101
|
this.$emit('update:modelValue', false)
|
|
90
102
|
this.$emit('input', false)
|
|
91
103
|
this.$emit('close')
|
|
@@ -94,10 +106,7 @@ export default {
|
|
|
94
106
|
|
|
95
107
|
watch: {
|
|
96
108
|
value (value) {
|
|
97
|
-
|
|
98
|
-
// If value is false, keep the wrapper in DOM and close the dialog;
|
|
99
|
-
// At the end of the dialog transition the value is updated and wrapper removed from the DOM.
|
|
100
|
-
if (value) this.showWrapper = value
|
|
109
|
+
this.showWrapper = value
|
|
101
110
|
this.showContent = value
|
|
102
111
|
}
|
|
103
112
|
}
|
|
@@ -7,13 +7,22 @@
|
|
|
7
7
|
v-if="!noOverlay"
|
|
8
8
|
v-model="showDrawer"
|
|
9
9
|
@click="onOutsideClick"
|
|
10
|
+
@before-close="onBeforeClose"
|
|
10
11
|
:persistent="persistent"
|
|
11
12
|
persistent-no-animation
|
|
12
|
-
:bg-color="overlayColor"
|
|
13
|
+
:bg-color="overlayColor || 'transparent'"
|
|
13
14
|
:opacity="overlayOpacity")
|
|
14
15
|
slot(name="pushable")
|
|
15
|
-
transition(
|
|
16
|
-
|
|
16
|
+
transition(
|
|
17
|
+
name="fade"
|
|
18
|
+
@before-leave="noOverlay && onBeforeClose()"
|
|
19
|
+
@after-leave="onClose")
|
|
20
|
+
component.w-drawer(
|
|
21
|
+
v-if="showDrawer"
|
|
22
|
+
ref="drawer"
|
|
23
|
+
:is="tag || 'aside'"
|
|
24
|
+
:class="drawerClasses"
|
|
25
|
+
:style="styles")
|
|
17
26
|
slot
|
|
18
27
|
//- Other cases.
|
|
19
28
|
template(v-else)
|
|
@@ -21,12 +30,22 @@
|
|
|
21
30
|
v-if="!noOverlay"
|
|
22
31
|
v-model="showDrawer"
|
|
23
32
|
@click="onOutsideClick"
|
|
33
|
+
@before-close="onBeforeClose"
|
|
24
34
|
:persistent="persistent"
|
|
25
35
|
persistent-no-animation
|
|
26
36
|
:bg-color="overlayColor"
|
|
27
37
|
:opacity="overlayOpacity")
|
|
28
|
-
transition(
|
|
29
|
-
|
|
38
|
+
transition(
|
|
39
|
+
:name="transitionName"
|
|
40
|
+
appear
|
|
41
|
+
@before-leave="noOverlay && onBeforeClose()"
|
|
42
|
+
@after-leave="onClose")
|
|
43
|
+
component.w-drawer(
|
|
44
|
+
v-if="showDrawer"
|
|
45
|
+
ref="drawer"
|
|
46
|
+
:is="tag || 'aside'"
|
|
47
|
+
:class="drawerClasses"
|
|
48
|
+
:style="styles")
|
|
30
49
|
slot
|
|
31
50
|
</template>
|
|
32
51
|
|
|
@@ -62,7 +81,15 @@ export default {
|
|
|
62
81
|
tag: { type: String, default: 'aside' }
|
|
63
82
|
},
|
|
64
83
|
|
|
65
|
-
|
|
84
|
+
provide () {
|
|
85
|
+
return {
|
|
86
|
+
// If a detachable is used inside a w-drawer without an appendTo, default to the drawer element
|
|
87
|
+
// instead of the w-app.
|
|
88
|
+
detachableDefaultRoot: () => this.$refs.drawer || null
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
emits: ['input', 'update:modelValue', 'before-close', 'close'],
|
|
66
93
|
|
|
67
94
|
data () {
|
|
68
95
|
return {
|
|
@@ -113,7 +140,7 @@ export default {
|
|
|
113
140
|
// It moves inside the overflow hidden outer wrap.
|
|
114
141
|
trackStyles () {
|
|
115
142
|
return this.pushContent && this.showDrawer && {
|
|
116
|
-
transform: `translateX(${this.position === 'left' ? '' : '-'}${this.size})`
|
|
143
|
+
transform: `translateX(${this.position === 'left' ? '' : '-'}${this.size || '200px'})`
|
|
117
144
|
}
|
|
118
145
|
},
|
|
119
146
|
styles () {
|
|
@@ -133,24 +160,22 @@ export default {
|
|
|
133
160
|
},
|
|
134
161
|
|
|
135
162
|
methods: {
|
|
136
|
-
close () {
|
|
137
|
-
this.showWrapper = false
|
|
138
|
-
this.$emit('update:modelValue', false)
|
|
139
|
-
this.$emit('input', false)
|
|
140
|
-
this.$emit('close', false)
|
|
141
|
-
},
|
|
142
163
|
onOutsideClick () {
|
|
143
|
-
if (!this.
|
|
144
|
-
// The close method is called on animation end, except with pushContent
|
|
145
|
-
// (not using the same transition).
|
|
146
|
-
this.showDrawer = false
|
|
147
|
-
if (this.pushContent) this.close()
|
|
148
|
-
}
|
|
149
|
-
else if (!this.persistentNoAnimation) {
|
|
164
|
+
if (this.persistent && !this.persistentNoAnimation) {
|
|
150
165
|
this.persistentAnimate = true
|
|
151
166
|
setTimeout(() => (this.persistentAnimate = false), 200) // Must match CSS animation duration.
|
|
152
167
|
}
|
|
153
|
-
}
|
|
168
|
+
},
|
|
169
|
+
onBeforeClose () {
|
|
170
|
+
this.$emit('before-close')
|
|
171
|
+
this.showDrawer = false
|
|
172
|
+
},
|
|
173
|
+
onClose () {
|
|
174
|
+
this.showWrapper = false
|
|
175
|
+
this.$emit('update:modelValue', false)
|
|
176
|
+
this.$emit('input', false)
|
|
177
|
+
this.$emit('close')
|
|
178
|
+
},
|
|
154
179
|
},
|
|
155
180
|
|
|
156
181
|
watch: {
|
|
@@ -6,15 +6,31 @@ div(:class="classes")
|
|
|
6
6
|
//- Error message.
|
|
7
7
|
w-transition-expand(y)
|
|
8
8
|
template(v-if="Validation.message")
|
|
9
|
-
.w-form-el__error
|
|
9
|
+
.w-form-el__error(
|
|
10
|
+
v-if="$slots['error-message']"
|
|
11
|
+
:class="formProps.validationColor")
|
|
10
12
|
slot(name="error-message" :message="Validation.message")
|
|
11
|
-
.w-form-el__error.error(
|
|
13
|
+
.w-form-el__error.error(
|
|
14
|
+
v-else
|
|
15
|
+
v-html="Validation.message"
|
|
16
|
+
:class="formProps.validationColor")
|
|
12
17
|
</template>
|
|
13
18
|
|
|
14
19
|
<script>
|
|
15
20
|
export default {
|
|
16
21
|
name: 'w-form-element',
|
|
17
22
|
|
|
23
|
+
props: {
|
|
24
|
+
valid: { required: true },
|
|
25
|
+
disabled: { type: Boolean },
|
|
26
|
+
readonly: { type: Boolean },
|
|
27
|
+
inputValue: { required: true }, // The form element's input value.
|
|
28
|
+
validators: { type: Array },
|
|
29
|
+
isFocused: { default: false }, // Watched.
|
|
30
|
+
column: { default: false }, // Flex direction of the embedded component: column or row by default.
|
|
31
|
+
wrap: { default: false } // Flex-wrap if needed.
|
|
32
|
+
},
|
|
33
|
+
|
|
18
34
|
inject: {
|
|
19
35
|
formRegister: { default: null },
|
|
20
36
|
formUnregister: { default: null },
|
|
@@ -23,23 +39,13 @@ export default {
|
|
|
23
39
|
default: () => ({
|
|
24
40
|
noKeyupValidation: false,
|
|
25
41
|
noBlurValidation: false,
|
|
42
|
+
validationColor: 'error',
|
|
26
43
|
disabled: false,
|
|
27
44
|
readonly: false
|
|
28
45
|
})
|
|
29
46
|
}
|
|
30
47
|
},
|
|
31
48
|
|
|
32
|
-
props: {
|
|
33
|
-
valid: { required: true },
|
|
34
|
-
disabled: { type: Boolean },
|
|
35
|
-
readonly: { type: Boolean },
|
|
36
|
-
inputValue: { required: true }, // The form element's input value.
|
|
37
|
-
validators: { type: Array },
|
|
38
|
-
isFocused: { default: false }, // Watched.
|
|
39
|
-
column: { default: false }, // Flex direction of the embedded component: column or row by default.
|
|
40
|
-
wrap: { default: false } // Flex-wrap if needed.
|
|
41
|
-
},
|
|
42
|
-
|
|
43
49
|
emits: ['reset', 'update:valid'],
|
|
44
50
|
|
|
45
51
|
data: () => ({
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
form.w-form(
|
|
2
|
+
form.w-form(
|
|
3
|
+
@submit="onSubmit"
|
|
4
|
+
@reset="reset"
|
|
5
|
+
novalidate
|
|
6
|
+
:class="classes")
|
|
3
7
|
slot
|
|
4
8
|
</template>
|
|
5
9
|
|
|
@@ -16,6 +20,17 @@ const asyncSome = async (array, predicate) => {
|
|
|
16
20
|
export default {
|
|
17
21
|
name: 'w-form',
|
|
18
22
|
|
|
23
|
+
props: {
|
|
24
|
+
value: {},
|
|
25
|
+
allowSubmit: { type: Boolean },
|
|
26
|
+
noKeyupValidation: { type: Boolean },
|
|
27
|
+
noBlurValidation: { type: Boolean },
|
|
28
|
+
errorPlaceholders: { type: Boolean },
|
|
29
|
+
validationColor: { type: String, default: 'error' },
|
|
30
|
+
disabled: { type: Boolean },
|
|
31
|
+
readonly: { type: Boolean }
|
|
32
|
+
},
|
|
33
|
+
|
|
19
34
|
provide () {
|
|
20
35
|
return {
|
|
21
36
|
formRegister: this.register,
|
|
@@ -27,16 +42,6 @@ export default {
|
|
|
27
42
|
}
|
|
28
43
|
},
|
|
29
44
|
|
|
30
|
-
props: {
|
|
31
|
-
value: {},
|
|
32
|
-
allowSubmit: { type: Boolean },
|
|
33
|
-
noKeyupValidation: { type: Boolean },
|
|
34
|
-
noBlurValidation: { type: Boolean },
|
|
35
|
-
errorPlaceholders: { type: Boolean },
|
|
36
|
-
disabled: { type: Boolean },
|
|
37
|
-
readonly: { type: Boolean }
|
|
38
|
-
},
|
|
39
|
-
|
|
40
45
|
emits: [
|
|
41
46
|
'submit',
|
|
42
47
|
'before-validate',
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
component.w-icon(
|
|
3
3
|
:is="tag || 'i'"
|
|
4
|
-
:class="classes"
|
|
5
4
|
v-on="$listeners"
|
|
5
|
+
:class="classes"
|
|
6
6
|
role="icon"
|
|
7
7
|
aria-hidden="true"
|
|
8
|
-
:style="styles")
|
|
9
|
-
template(v-if="
|
|
8
|
+
:style="readIcon() /* Always reacting to slot change when called from template. */ && styles")
|
|
9
|
+
template(v-if="hasLigature") {{ icon }}
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
12
|
<script>
|
|
@@ -41,15 +41,13 @@ export default {
|
|
|
41
41
|
emits: [],
|
|
42
42
|
|
|
43
43
|
data: () => ({
|
|
44
|
-
icon: ''
|
|
44
|
+
icon: '',
|
|
45
|
+
fontName: ''
|
|
45
46
|
}),
|
|
46
47
|
|
|
47
48
|
computed: {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const [fontName, icon] = this.icon.split(' ')
|
|
52
|
-
return fontName === config.iconsLigature && { fontName, icon }
|
|
49
|
+
hasLigature () {
|
|
50
|
+
return config.iconsLigature === this.fontName
|
|
53
51
|
},
|
|
54
52
|
forcedSize () {
|
|
55
53
|
return this.size && (!isNaN(this.size) ? `${this.size}px` : this.size)
|
|
@@ -66,7 +64,8 @@ export default {
|
|
|
66
64
|
},
|
|
67
65
|
classes () {
|
|
68
66
|
return {
|
|
69
|
-
[this.
|
|
67
|
+
[this.fontName]: true,
|
|
68
|
+
[!this.hasLigature && this.icon]: !this.hasLigature && this.icon,
|
|
70
69
|
[this.color]: this.color,
|
|
71
70
|
[`${this.bgColor}--bg`]: this.bgColor,
|
|
72
71
|
[`size--${this.presetSize}`]: this.presetSize && !this.forcedSize,
|
|
@@ -80,8 +79,7 @@ export default {
|
|
|
80
79
|
'w-icon--rotate-90': this.rotate90a,
|
|
81
80
|
'w-icon--rotate-135': this.rotate135a,
|
|
82
81
|
'w-icon--flip-x': this.flipX,
|
|
83
|
-
'w-icon--flip-y': this.flipY
|
|
84
|
-
[this.ligature && this.ligature.fontName]: this.ligature
|
|
82
|
+
'w-icon--flip-y': this.flipY
|
|
85
83
|
}
|
|
86
84
|
},
|
|
87
85
|
styles () {
|
|
@@ -89,12 +87,15 @@ export default {
|
|
|
89
87
|
}
|
|
90
88
|
},
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
methods: {
|
|
91
|
+
readIcon () {
|
|
92
|
+
const { default: slot } = this.$slots
|
|
93
|
+
const [fontName = '', icon = ''] = slot[0].text.trim().split(' ') || []
|
|
94
|
+
this.fontName = fontName
|
|
95
|
+
this.icon = icon
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
return true // Always return true for styles to be applied (c.f. template styles).
|
|
98
|
+
}
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
</script>
|
|
@@ -108,6 +109,7 @@ export default {
|
|
|
108
109
|
justify-content: center;
|
|
109
110
|
vertical-align: middle;
|
|
110
111
|
user-select: none;
|
|
112
|
+
speak: never;
|
|
111
113
|
line-height: 1;
|
|
112
114
|
font-size: 1.2em;
|
|
113
115
|
width: 1em;
|