wave-ui 1.51.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.
Files changed (32) 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 +255 -156
  4. package/dist/wave-ui.umd.js +1 -1
  5. package/package.json +3 -2
  6. package/src/wave-ui/components/transitions/w-transition-expand.vue +1 -13
  7. package/src/wave-ui/components/w-accordion.vue +47 -24
  8. package/src/wave-ui/components/w-card.vue +12 -5
  9. package/src/wave-ui/components/w-checkbox.vue +11 -6
  10. package/src/wave-ui/components/w-checkboxes.vue +9 -19
  11. package/src/wave-ui/components/w-dialog.vue +18 -9
  12. package/src/wave-ui/components/w-divider.vue +10 -3
  13. package/src/wave-ui/components/w-drawer.vue +46 -21
  14. package/src/wave-ui/components/w-form-element.vue +19 -13
  15. package/src/wave-ui/components/w-form.vue +16 -11
  16. package/src/wave-ui/components/w-icon.vue +19 -17
  17. package/src/wave-ui/components/w-input.vue +14 -37
  18. package/src/wave-ui/components/w-menu.vue +8 -0
  19. package/src/wave-ui/components/w-notification.vue +3 -1
  20. package/src/wave-ui/components/w-overlay.vue +35 -8
  21. package/src/wave-ui/components/w-radio.vue +11 -6
  22. package/src/wave-ui/components/w-radios.vue +6 -15
  23. package/src/wave-ui/components/w-select.vue +13 -28
  24. package/src/wave-ui/components/w-slider.vue +21 -10
  25. package/src/wave-ui/components/w-switch.vue +44 -16
  26. package/src/wave-ui/components/w-tabs/index.vue +11 -1
  27. package/src/wave-ui/components/w-textarea.vue +15 -17
  28. package/src/wave-ui/components/w-timeline.vue +1 -1
  29. package/src/wave-ui/components/w-toolbar.vue +46 -6
  30. package/src/wave-ui/components/w-tooltip.vue +6 -1
  31. package/src/wave-ui/mixins/detachable.js +18 -17
  32. 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.51.0",
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.0",
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: 200 }
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(y)
42
- .w-accordion__item-content(v-if="item._expanded" :class="contentClass")
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" :index="i + 1")
48
- slot(v-else name="item-content" :item="getOriginalItem(item)" :expanded="item._expanded" :index="i + 1")
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:modelValue', 'focus', 'item-expand'],
86
+ emits: ['input', 'update:value', 'focus', 'item-expand', 'item-collapsed'],
77
87
 
78
- computed: {
79
- accordionItems () {
80
- const items = typeof this.items === 'number' ? Array(this.items).fill({}) : this.items || []
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:modelValue', expandedItems)
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,14 +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
+ })))
128
143
  }
129
144
  },
130
145
 
146
+ created () {
147
+ this.updateItems()
148
+ },
149
+
131
150
  watch: {
132
- value (array) {
133
- this.accordionItems.forEach((item, i) => {
134
- this.$set(item, 'expanded', (Array.isArray(array) && array[i]) || false)
135
- })
151
+ value () {
152
+ this.updateItems()
153
+ },
154
+ items: {
155
+ handler () {
156
+ this.updateItems()
157
+ },
158
+ deep: true
136
159
  }
137
160
  }
138
161
  }
@@ -1,5 +1,5 @@
1
1
  <template lang="pug">
2
- .w-card(:class="classes" :style="styles")
2
+ .w-card(:class="classes")
3
3
  .w-card__title(
4
4
  v-if="$slots.title"
5
5
  :class="{ 'w-card__title--has-toolbar': titleHasToolbar, ...titleClasses }")
@@ -71,10 +71,6 @@ export default {
71
71
  'w-card--tile': this.tile,
72
72
  'w-card--shadow': this.shadow
73
73
  }
74
- },
75
-
76
- styles () {
77
- return false
78
74
  }
79
75
  }
80
76
  }
@@ -107,6 +103,17 @@ export default {
107
103
  &__content {
108
104
  padding: 3 * $base-increment;
109
105
  flex-grow: 1;
106
+
107
+ // Only if there is no title bar.
108
+ &:first-child {
109
+ border-top-left-radius: inherit;
110
+ border-top-right-radius: inherit;
111
+ }
112
+ &:last-child {
113
+ // Only if there is no actions bar.
114
+ border-bottom-left-radius: inherit;
115
+ border-bottom-right-radius: inherit;
116
+ }
110
117
  }
111
118
 
112
119
  &__actions {
@@ -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(v-if="$slots.default" :for="`w-checkbox--${_uid}`")
26
- slot
27
- label.w-checkbox__label.w-form-el-shakable.pr2(v-else-if="label" :for="`w-checkbox--${_uid}`" v-html="label")
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(v-if="$slots.default" :for="`w-checkbox--${_uid}`")
33
- slot
34
- label.w-checkbox__label.w-form-el-shakable.pl2(v-else-if="label" :for="`w-checkbox--${_uid}`" v-html="label")
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="$scopedSlots[`item.${i + 1}`]"
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
- @closed="$emit('closed')"
7
+ @close="onClose"
8
8
  :bg-color="overlayColor"
9
9
  :opacity="overlayOpacity"
10
10
  :class="classes")
11
- transition(:name="transition" appear @after-leave="onClose")
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
- emits: ['input', 'update:modelValue', 'close', 'closed'],
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.onClose()
93
+ if (this.transition === 'fade') this.onBeforeClose()
85
94
  }
86
95
  },
87
- onClose () {
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
- // If value is true, mount the wrapper in DOM and open the dialog.
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
  }
@@ -1,5 +1,8 @@
1
1
  <template lang="pug">
2
- .w-divider(:class="classes")
2
+ .w-divider(
3
+ :class="classes"
4
+ role="presentation"
5
+ :aria-orientation="vertical ? 'vertical' : 'horizontal'")
3
6
  slot
4
7
  </template>
5
8
 
@@ -18,7 +21,7 @@ export default {
18
21
  classes () {
19
22
  return {
20
23
  [`w-divider--has-color ${this.color}`]: this.color,
21
- 'w-divider--vertical': this.vertical,
24
+ [`w-divider--${this.vertical ? 'vertical' : 'horizontal'}`]: true,
22
25
  'w-divider--has-content': this.$slots.default
23
26
  }
24
27
  }
@@ -34,10 +37,14 @@ export default {
34
37
  &--has-color {border-color: currentColor;}
35
38
 
36
39
  &--vertical {
40
+ align-self: stretch; // Fill up the available height.
37
41
  display: flex;
38
42
  border-top-width: 0;
39
43
  border-left-width: 1px;
40
- align-self: stretch;
44
+ }
45
+
46
+ .w-toolbar--vertical > &--horizontal {
47
+ align-self: stretch; // Fill up the available width.
41
48
  }
42
49
 
43
50
  // With a slot.
@@ -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(name="fade")
16
- .w-drawer(v-if="!unmountDrawer" :class="drawerClasses" :style="styles")
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(:name="transitionName" appear @after-leave="close")
29
- component.w-drawer(v-if="showDrawer" :is="tag || 'aside'" :class="drawerClasses" :style="styles")
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
- emits: ['input', 'update:modelValue', 'close'],
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.persistent) {
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.error(v-if="$slots['error-message']" class="w-form-el__error 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(v-else v-html="Validation.message" class="w-form-el__error w-form-el__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(@submit="onSubmit" @reset="reset" novalidate :class="classes")
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',