@carbon/vue 2.18.0-canary.0 → 2.19.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 (31) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/carbon-vue.common.js +520 -194
  3. package/dist/carbon-vue.common.js.map +1 -1
  4. package/dist/carbon-vue.umd.js +520 -194
  5. package/dist/carbon-vue.umd.js.map +1 -1
  6. package/dist/carbon-vue.umd.min.js +3 -3
  7. package/dist/carbon-vue.umd.min.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/components/cv-combo-box/cv-combo-box.vue +15 -11
  10. package/src/components/cv-data-table/_cv-data-table-row-inner.vue +11 -3
  11. package/src/components/cv-data-table/cv-data-table-action.vue +1 -1
  12. package/src/components/cv-data-table/cv-data-table-row.vue +4 -2
  13. package/src/components/cv-data-table/cv-data-table-skeleton.vue +24 -3
  14. package/src/components/cv-data-table/cv-data-table.vue +17 -10
  15. package/src/components/cv-date-picker/cv-date-picker.vue +13 -7
  16. package/src/components/cv-dropdown/cv-dropdown.vue +11 -6
  17. package/src/components/cv-modal/cv-modal.vue +18 -12
  18. package/src/components/cv-multi-select/cv-multi-select.vue +27 -11
  19. package/src/components/cv-number-input/cv-number-input.vue +13 -6
  20. package/src/components/cv-overflow-menu/cv-overflow-menu-item.vue +3 -1
  21. package/src/components/cv-select/cv-select.vue +16 -7
  22. package/src/components/cv-tabs/cv-tabs.vue +160 -51
  23. package/src/components/cv-text-area/cv-text-area.vue +18 -5
  24. package/src/components/cv-text-input/cv-text-input.vue +13 -6
  25. package/src/components/cv-time-picker/cv-time-picker.vue +17 -6
  26. package/src/components/cv-toggle/cv-toggle-skeleton.vue +21 -0
  27. package/src/components/cv-toggle/index.js +2 -1
  28. package/src/components/cv-ui-shell/cv-header.vue +9 -1
  29. package/src/components/cv-ui-shell/cv-side-nav-link.vue +9 -1
  30. package/src/components/cv-ui-shell/cv-side-nav-menu.vue +9 -1
  31. package/src/index.js +2 -2
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/vue",
3
3
  "description": "A collection of components for the Carbon Design System built using Vue.js",
4
- "version": "2.18.0-canary.0",
4
+ "version": "2.19.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -73,5 +73,5 @@
73
73
  "eslint-plugin-prettier": "^3.1.1",
74
74
  "vue-template-compiler": "^2.6.10"
75
75
  },
76
- "gitHead": "4535ef7a894bdb3c0244eea916a3cd50a152b748"
76
+ "gitHead": "f18fa788d7082e80cba1bed19b0da020bc9ba346"
77
77
  }
@@ -47,7 +47,7 @@
47
47
  role="combobox"
48
48
  :aria-expanded="open"
49
49
  autocomplete="off"
50
- placeholder="Filter"
50
+ :placeholder="label"
51
51
  v-model="filter"
52
52
  @input="onInput"
53
53
  @focus="inputFocus"
@@ -138,6 +138,8 @@ export default {
138
138
  dataValue: this.value,
139
139
  dataHighlighted: null,
140
140
  dataFilter: null,
141
+ isHelper: false,
142
+ isInvalid: false,
141
143
  };
142
144
  },
143
145
  model: {
@@ -163,17 +165,12 @@ export default {
163
165
  mounted() {
164
166
  this.filter = this.value;
165
167
  this.highlighted = this.value ? this.value : this.highlight; // override highlight with value if provided
166
- console.warn(
167
- `${this.$vnode.componentOptions.Ctor.extendOptions.name} - Under review. This component isn't quite ready. Hopefully no features will get broken but this cannot be guarenteed.`
168
- );
168
+ this.checkSlots();
169
+ },
170
+ beforeUpdate() {
171
+ this.checkSlots();
169
172
  },
170
173
  computed: {
171
- isInvalid() {
172
- return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
173
- },
174
- isHelper() {
175
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
176
- },
177
174
  highlighted: {
178
175
  get() {
179
176
  return this.dataHighlighted;
@@ -205,11 +202,18 @@ export default {
205
202
  },
206
203
  },
207
204
  methods: {
205
+ checkSlots() {
206
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
207
+ this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
208
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
209
+ },
208
210
  clearFilter() {
211
+ this.internalUpdateValue('');
209
212
  this.filter = '';
210
213
  this.$refs.input.focus();
211
214
  this.doOpen(true);
212
215
  this.updateOptions();
216
+ this.$emit('change', this.dataValue);
213
217
  },
214
218
  checkHighlightPosition(newHiglight) {
215
219
  if (this.$refs.list && this.$refs.option) {
@@ -250,7 +254,7 @@ export default {
250
254
  }
251
255
  },
252
256
  updateOptions() {
253
- if (this.autoFilter) {
257
+ if (this.autoFilter && this.filter) {
254
258
  const escFilter = this.filter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
255
259
  const pat = new RegExp(escFilter, 'iu');
256
260
  this.dataOptions = this.options.filter(opt => pat.test(opt.label)).slice(0);
@@ -58,8 +58,15 @@ export default {
58
58
  dataChecked: this.checked,
59
59
  dataExpanded: this.expanded,
60
60
  dataSomeExpandingRows: this.someExpandingRows,
61
+ hasOverflowMenu: false,
61
62
  };
62
63
  },
64
+ mounted: function() {
65
+ this.checkSlots();
66
+ },
67
+ beforeUpdate() {
68
+ this.checkSlots();
69
+ },
63
70
  watch: {
64
71
  checked() {
65
72
  this.dataChecked = this.checked;
@@ -75,9 +82,6 @@ export default {
75
82
  isCvDataTableRow() {
76
83
  return true;
77
84
  },
78
- hasOverflowMenu() {
79
- return (this.overflowMenu && this.overflowMenu.length) || this.$slots['overflow-menu'];
80
- },
81
85
  hasBatchActions() {
82
86
  return this.$parent.$parent.hasBatchActions;
83
87
  },
@@ -86,6 +90,10 @@ export default {
86
90
  },
87
91
  },
88
92
  methods: {
93
+ checkSlots() {
94
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
95
+ this.hasOverflowMenu = !!((this.overflowMenu && this.overflowMenu.length) || this.$slots['overflow-menu']);
96
+ },
89
97
  onChange() {
90
98
  this.$parent.$parent.onRowCheckChange(this.value, this.dataChecked);
91
99
  },
@@ -9,7 +9,7 @@ export default {
9
9
  name: 'cv-data-table-action',
10
10
  mounted() {
11
11
  // ensure SVG has
12
- this.$el.children[0].classList.add('class="bx--toolbar-action__icon');
12
+ this.$el.children[0].classList.add('bx--toolbar-action__icon');
13
13
  },
14
14
  };
15
15
  </script>
@@ -37,7 +37,7 @@ export default {
37
37
  },
38
38
  data() {
39
39
  return {
40
- dataExpandable: this.$slots.expandedContent !== undefined,
40
+ dataExpandable: false,
41
41
  dataSomeExpandingRows: false,
42
42
  dataExpanded: this.expanded,
43
43
  };
@@ -50,10 +50,12 @@ export default {
50
50
  },
51
51
  },
52
52
  mounted() {
53
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
54
+ this.dataExpandable = !!this.$slots.expandedContent;
53
55
  this.$parent.$emit('cv:mounted', this);
54
56
  },
55
57
  updated() {
56
- this.dataExpandable = this.$slots.expandedContent !== undefined;
58
+ this.dataExpandable = !!this.$slots.expandedContent;
57
59
  },
58
60
  beforeDestroy() {
59
61
  this.$parent.$emit('cv:beforeDestroy', this);
@@ -1,14 +1,14 @@
1
1
  <template>
2
2
  <cv-data-table skeleton :data="data" :columns="cols" v-on="$listeners" v-bind="$attrs">
3
- <template v-if="$slots['helper-text']" slot="helper-text">
3
+ <template v-if="hasBatchActions" slot="helper-text">
4
4
  <slot name="helper-text" />
5
5
  </template>
6
6
 
7
- <template v-if="$slots['batch-actions']" slot="batch-actions">
7
+ <template v-if="hasBatchActions" slot="batch-actions">
8
8
  <slot name="batch-actions" />
9
9
  </template>
10
10
 
11
- <template v-if="$slots.actions" slot="actions">
11
+ <template v-if="hasActions" slot="actions">
12
12
  <slot name="actions" />
13
13
  </template>
14
14
  </cv-data-table>
@@ -32,6 +32,19 @@ export default {
32
32
  hasExpandables: Boolean,
33
33
  rows: { type: Number, default: DEFAULTS.ROWS },
34
34
  },
35
+ data() {
36
+ return {
37
+ hasActions: false,
38
+ hasHelperText: false,
39
+ hasBatchActions: false,
40
+ };
41
+ },
42
+ mounted() {
43
+ this.checkSlots();
44
+ },
45
+ beforeUpdate() {
46
+ this.checkSlots();
47
+ },
35
48
  computed: {
36
49
  data() {
37
50
  return [...Array(Math.max(this.rows, 1))].map(item => Array(this.cols.length).fill(''));
@@ -40,5 +53,13 @@ export default {
40
53
  return typeof this.columns !== 'number' ? this.columns : Array(Math.max(this.columns, 1)).fill('');
41
54
  },
42
55
  },
56
+ methods: {
57
+ checkSlots() {
58
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
59
+ this.hasBatchActions = !!this.$slots['batch-actions'];
60
+ this.hasHelperText = !!this.$slots['helper-text'];
61
+ this.hasActions = !!this.$slots['actions'];
62
+ },
63
+ },
43
64
  };
44
65
  </script>
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
  </div>
34
34
 
35
- <div v-if="($slots.actions || $listeners.search) && !batchActive" class="bx--toolbar-content">
35
+ <div v-if="(hasActions || $listeners.search) && !batchActive" class="bx--toolbar-content">
36
36
  <div
37
37
  v-if="$listeners.search"
38
38
  :class="{
@@ -235,6 +235,10 @@ export default {
235
235
  order: 'none',
236
236
  }))
237
237
  : this.columns,
238
+ hasBatchActions: false,
239
+ hasActions: false,
240
+ hasToolbar: false,
241
+ isHelper: false,
238
242
  batchActive: false,
239
243
  headingChecked: false,
240
244
  dataRowsSelected: this.rowsSelected,
@@ -263,17 +267,16 @@ export default {
263
267
  },
264
268
  mounted() {
265
269
  this.updateRowsSelected();
270
+ this.checkSlots();
271
+ },
272
+ beforeUpdate() {
273
+ this.checkSlots();
266
274
  },
267
275
  computed: {
268
- hasBatchActions() {
269
- return this.$slots['batch-actions'];
270
- },
271
276
  hasTableHeader() {
272
277
  return this.title || this.isHelper;
273
278
  },
274
- hasToolbar() {
275
- return this.$slots.actions || this.$listeners.search || this.$slots['batch-actions'];
276
- },
279
+
277
280
  hasExpandables() {
278
281
  return this.registeredRows.some(item => item.expandable);
279
282
  },
@@ -317,11 +320,15 @@ export default {
317
320
  selectedRows() {
318
321
  return this.dataRowsSelected;
319
322
  },
320
- isHelper() {
321
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
322
- },
323
323
  },
324
324
  methods: {
325
+ checkSlots() {
326
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
327
+ this.hasBatchActions = !!this.$slots['batch-actions'];
328
+ this.hasActions = !!this.$slots.actions;
329
+ this.hasToolbar = !!(this.$slots.actions || this.$listeners.search || this.$slots['batch-actions']);
330
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
331
+ },
325
332
  onCvMount(row) {
326
333
  this.registeredRows.push(row);
327
334
  row.$on('cv:expanded-change', this.onCvExpandedChange);
@@ -130,6 +130,7 @@ export default {
130
130
  return {
131
131
  dataValue: '',
132
132
  dataOptions: {},
133
+ isInvalid: false,
133
134
  };
134
135
  },
135
136
  watch: {
@@ -178,13 +179,6 @@ export default {
178
179
  }
179
180
  }
180
181
  },
181
- isInvalid() {
182
- return (
183
- this.$slots['invalid-message'] !== undefined ||
184
- (this.invalidMessage && this.invalidMessage.length) ||
185
- (this.invalidDateMessage && this.invalidDateMessage.length)
186
- );
187
- },
188
182
  isRange() {
189
183
  return this.kind === 'range';
190
184
  },
@@ -193,6 +187,14 @@ export default {
193
187
  },
194
188
  },
195
189
  methods: {
190
+ checkSlots() {
191
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
192
+ this.isInvalid = !!(
193
+ this.$slots['invalid-message'] ||
194
+ (this.invalidMessage && this.invalidMessage.length) ||
195
+ (this.invalidDateMessage && this.invalidDateMessage.length)
196
+ );
197
+ },
196
198
  initFlatpickr() {
197
199
  if (['single', 'range'].includes(this.kind)) {
198
200
  // no need to call set value as it's done through getOptions
@@ -300,6 +302,7 @@ export default {
300
302
  },
301
303
  mounted() {
302
304
  this.initFlatpickr();
305
+ this.checkSlots();
303
306
  // this.cal.setDate([Date.now(), Date.now()]);
304
307
  // setTimeout(() => {
305
308
  // let curDate = new Date();
@@ -308,6 +311,9 @@ export default {
308
311
  // this.cal.setDate([curDate, anotherDate], true);
309
312
  // }, 2000);
310
313
  },
314
+ beforeUpdate() {
315
+ this.checkSlots();
316
+ },
311
317
  beforeDestroy() {
312
318
  if (this.cal) {
313
319
  this.cal.destroy();
@@ -122,6 +122,8 @@ export default {
122
122
  return {
123
123
  open: false,
124
124
  dataValue: this.value,
125
+ isHelper: false,
126
+ isInvalid: false,
125
127
  };
126
128
  },
127
129
  created() {
@@ -136,6 +138,10 @@ export default {
136
138
  }
137
139
  });
138
140
  this.internalValue = this.internalValue; // forces update of value
141
+ this.checkSlots();
142
+ },
143
+ beforeUpdate() {
144
+ this.checkSlots();
139
145
  },
140
146
  model: {
141
147
  prop: 'value',
@@ -147,12 +153,6 @@ export default {
147
153
  },
148
154
  },
149
155
  computed: {
150
- isInvalid() {
151
- return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
152
- },
153
- isHelper() {
154
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
155
- },
156
156
  internalValue: {
157
157
  get() {
158
158
  return this.dataValue;
@@ -198,6 +198,11 @@ export default {
198
198
  },
199
199
  },
200
200
  methods: {
201
+ checkSlots() {
202
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
203
+ this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
204
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
205
+ },
201
206
  onCvMount(srcComponent) {
202
207
  if (srcComponent.internalSelected) {
203
208
  this.internalValue = srcComponent.value;
@@ -20,7 +20,7 @@
20
20
  @focus="focusBeforeContent"
21
21
  />
22
22
  <div class="bx--modal-header">
23
- <h4 class="bx--modal-header__label" v-if="$slots.label">
23
+ <h4 class="bx--modal-header__label" v-if="hasHeaderLabel">
24
24
  <slot name="label">label (Optional)</slot>
25
25
  </h4>
26
26
  <h2 class="bx--modal-header__heading">
@@ -41,13 +41,7 @@
41
41
  </div>
42
42
 
43
43
  <div class="bx--modal-footer" v-if="hasFooter">
44
- <cv-button
45
- type="button"
46
- :kind="secondaryKind"
47
- @click="onSecondaryClick"
48
- v-if="this.$slots['secondary-button']"
49
- ref="secondary"
50
- >
44
+ <cv-button type="button" :kind="secondaryKind" @click="onSecondaryClick" v-if="hasSecondary" ref="secondary">
51
45
  <slot name="secondary-button">Secondary button</slot>
52
46
  </cv-button>
53
47
  <cv-button
@@ -55,7 +49,7 @@
55
49
  type="button"
56
50
  :kind="primaryKind"
57
51
  @click="onPrimaryClick"
58
- v-if="this.$slots['primary-button']"
52
+ v-if="hasPrimary"
59
53
  ref="primary"
60
54
  >
61
55
  <slot name="primary-button">Primary button</slot>
@@ -98,12 +92,20 @@ export default {
98
92
  return {
99
93
  dataVisible: false,
100
94
  scrollable: false,
95
+ hasFooter: false,
96
+ hasHeaderLabel: false,
97
+ hasPrimary: false,
98
+ hasSecondary: false,
101
99
  };
102
100
  },
103
101
  mounted() {
104
102
  if (this.visible) {
105
103
  this.show();
106
104
  }
105
+ this.checkSlots();
106
+ },
107
+ beforeUpdate() {
108
+ this.checkSlots();
107
109
  },
108
110
  watch: {
109
111
  visible(val) {
@@ -125,15 +127,19 @@ export default {
125
127
  secondaryKind() {
126
128
  return 'secondary';
127
129
  },
128
- hasFooter() {
129
- return this.$slots['primary-button'] || this.$slots['secondary-button'];
130
- },
131
130
  },
132
131
  model: {
133
132
  event: 'modelEvent',
134
133
  prop: 'visible',
135
134
  },
136
135
  methods: {
136
+ checkSlots() {
137
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
138
+ this.hasFooter = !!(this.$slots['primary-button'] || this.$slots['secondary-button']);
139
+ this.hasHeaderLabel = !!this.$slots.label;
140
+ this.hasSecondary = !!this.$slots['secondary-button'];
141
+ this.hasPrimary = !!this.$slots['primary-button'];
142
+ },
137
143
  focusBeforeContent() {
138
144
  if (this.$slots['primary-button']) {
139
145
  this.$refs.primary.$el.focus();
@@ -37,6 +37,7 @@
37
37
  @keydown.up.prevent="onUp"
38
38
  @keydown.enter.prevent="onEnter"
39
39
  @keydown.esc.prevent="onEsc"
40
+ @keydown="otherKey"
40
41
  @click="onClick"
41
42
  >
42
43
  <WarningFilled16 v-if="isInvalid" class="bx--list-box__invalid-icon" />
@@ -199,6 +200,8 @@ export default {
199
200
  dataValue: '',
200
201
  dataHighlighted: null,
201
202
  dataFilter: '',
203
+ isHelper: false,
204
+ isInvalid: false,
202
205
  };
203
206
  },
204
207
  model: {
@@ -225,17 +228,12 @@ export default {
225
228
  },
226
229
  mounted() {
227
230
  this.highlighted = this.value ? this.value : this.highlight; // override highlight with value if provided
228
- console.warn(
229
- `${this.$vnode.componentOptions.Ctor.extendOptions.name} - Under review. This component isn't quite ready. Hopefully no features will get broken but this cannot be guarenteed.`
230
- );
231
+ this.checkSlots();
232
+ },
233
+ beforeUpdate() {
234
+ this.checkSlots();
231
235
  },
232
236
  computed: {
233
- isInvalid() {
234
- return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
235
- },
236
- isHelper() {
237
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
238
- },
239
237
  highlighted: {
240
238
  get() {
241
239
  return this.dataHighlighted;
@@ -271,6 +269,11 @@ export default {
271
269
  },
272
270
  },
273
271
  methods: {
272
+ checkSlots() {
273
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
274
+ this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
275
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
276
+ },
274
277
  clearFilter() {
275
278
  this.filter = '';
276
279
  this.$refs.input.focus();
@@ -399,8 +402,16 @@ export default {
399
402
  if (this.disabled) {
400
403
  ev.preventDefault();
401
404
  } else {
402
- this.doOpen(!this.open);
403
- this.inputOrButtonFocus();
405
+ if (this.open) {
406
+ this.inputOrButtonFocus();
407
+ // done this way round otherwise will auto open on focus.
408
+ this.$nextTick(() => {
409
+ this.doOpen(false);
410
+ });
411
+ } else {
412
+ this.doOpen(true);
413
+ this.inputOrButtonFocus();
414
+ }
404
415
  }
405
416
  },
406
417
  clearValues() {
@@ -437,6 +448,11 @@ export default {
437
448
  inputFocus() {
438
449
  this.doOpen(true);
439
450
  },
451
+ otherKey(ev) {
452
+ if (!['Escape', 'ArrowUp', 'ArrowDown', 'Enter'].includes(ev.code)) {
453
+ console.log(ev.code);
454
+ }
455
+ },
440
456
  },
441
457
  };
442
458
  </script>
@@ -78,8 +78,16 @@ export default {
78
78
  data() {
79
79
  return {
80
80
  internalValue: this.valueAsString(this.value),
81
+ isHelper: false,
82
+ isInvalid: false,
81
83
  };
82
84
  },
85
+ mounted() {
86
+ this.checkSlots();
87
+ },
88
+ beforeUpdate() {
89
+ this.checkSlots();
90
+ },
83
91
  watch: {
84
92
  value() {
85
93
  this.internalValue = this.valueAsString(this.value);
@@ -102,14 +110,13 @@ export default {
102
110
  }
103
111
  return intVal;
104
112
  },
105
- isInvalid() {
106
- return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
107
- },
108
- isHelper() {
109
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
110
- },
111
113
  },
112
114
  methods: {
115
+ checkSlots() {
116
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
117
+ this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
118
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
119
+ },
113
120
  doUp() {
114
121
  this.internalValue = `${this.internalIntValue + 1}`;
115
122
  this.emitValue();
@@ -15,7 +15,9 @@
15
15
  v-on="$listeners"
16
16
  @click="onClick"
17
17
  >
18
- <slot></slot>
18
+ <span class="bx--overflow-menu-options__option-content">
19
+ <slot></slot>
20
+ </span>
19
21
  </button>
20
22
  </li>
21
23
  </template>
@@ -92,7 +92,11 @@ export default {
92
92
  delete this.$attrs.multiple;
93
93
  },
94
94
  data() {
95
- return { dataValue: undefined };
95
+ return {
96
+ dataValue: undefined,
97
+ isHelper: false,
98
+ isInvalid: false,
99
+ };
96
100
  },
97
101
  mounted() {
98
102
  // this is needed to ensure selected for an option when no value is supplied
@@ -104,6 +108,10 @@ export default {
104
108
  }
105
109
  }
106
110
  }
111
+ this.checkSlots();
112
+ },
113
+ beforeUpdate() {
114
+ this.checkSlots();
107
115
  },
108
116
  watch: {
109
117
  value() {
@@ -128,15 +136,16 @@ export default {
128
136
  input: event => this.$emit('input', event.target.value),
129
137
  };
130
138
  },
131
- isInvalid() {
132
- return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
133
- },
134
- isHelper() {
135
- return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
136
- },
137
139
  internalValue() {
138
140
  return this.dataValue ? this.dataValue : this.value;
139
141
  },
140
142
  },
143
+ methods: {
144
+ checkSlots() {
145
+ // NOTE: this.$slots is not reactive so needs to be managed on beforeUpdate
146
+ this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
147
+ this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
148
+ },
149
+ },
141
150
  };
142
151
  </script>