@carbon/vue 2.42.0 → 2.44.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 (54) hide show
  1. package/README.md +24 -2
  2. package/dist/carbon-vue.common.js +1103 -1007
  3. package/dist/carbon-vue.common.js.map +1 -1
  4. package/dist/carbon-vue.umd.js +1103 -1007
  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 +5 -5
  9. package/src/carbon.yml +388 -0
  10. package/src/components/cv-accordion/cv-accordion-skeleton.vue +1 -1
  11. package/src/components/cv-accordion/cv-accordion.vue +1 -1
  12. package/src/components/cv-aspect-ratio/cv-aspect-ratio.vue +3 -2
  13. package/src/components/cv-aspect-ratio/index.js +2 -2
  14. package/src/components/cv-breadcrumb/cv-breadcrumb-skeleton.vue +8 -1
  15. package/src/components/cv-button/button-mixin.js +7 -4
  16. package/src/components/cv-button/consts.js +14 -0
  17. package/src/components/cv-button/cv-icon-button.vue +2 -2
  18. package/src/components/cv-checkbox/cv-checkbox.vue +0 -1
  19. package/src/components/cv-code-snippet/_cv-code-snippet-inline.vue +2 -1
  20. package/src/components/cv-code-snippet/_cv-code-snippet-multiline.vue +2 -1
  21. package/src/components/cv-code-snippet/_cv-code-snippet-oneline.vue +2 -1
  22. package/src/components/cv-code-snippet/cv-code-snippet-skeleton.vue +1 -1
  23. package/src/components/cv-code-snippet/cv-code-snippet.vue +2 -1
  24. package/src/components/cv-data-table/cv-data-table-heading.vue +1 -1
  25. package/src/components/cv-data-table/cv-data-table-skeleton.vue +1 -2
  26. package/src/components/cv-data-table/cv-data-table.vue +45 -43
  27. package/src/components/cv-date-picker/plugins/monthSelectPlugin.js +1 -1
  28. package/src/components/cv-feedback-button/_cv-feedback-button.vue +1 -1
  29. package/src/components/cv-file-uploader/cv-file-uploader.vue +22 -12
  30. package/src/components/cv-inline-loading/cv-inline-loading.vue +1 -0
  31. package/src/components/cv-link/cv-link.vue +8 -1
  32. package/src/components/cv-loading/cv-loading.vue +4 -1
  33. package/src/components/cv-modal/cv-modal.vue +4 -3
  34. package/src/components/cv-multi-select/cv-multi-select.vue +9 -2
  35. package/src/components/cv-number-input/cv-number-input.vue +39 -31
  36. package/src/components/cv-overflow-menu/cv-overflow-menu.vue +3 -3
  37. package/src/components/cv-search/cv-search.vue +30 -14
  38. package/src/components/cv-slider/cv-slider.vue +1 -0
  39. package/src/components/cv-tabs/cv-tabs-skeleton.vue +7 -19
  40. package/src/components/cv-tabs/cv-tabs.vue +0 -2
  41. package/src/components/cv-tag/cv-tag-skeleton.vue +1 -3
  42. package/src/components/cv-tag/cv-tag.vue +6 -7
  43. package/src/components/cv-tag/index.js +3 -2
  44. package/src/components/cv-tile/_cv-tile-selectable.vue +0 -1
  45. package/src/components/cv-toggle/cv-toggle.vue +0 -1
  46. package/src/components/cv-tooltip/consts.js +2 -0
  47. package/src/components/cv-tooltip/cv-definition-tooltip.vue +5 -5
  48. package/src/components/cv-tooltip/cv-interactive-tooltip.vue +7 -7
  49. package/src/components/cv-tooltip/cv-tooltip.vue +5 -5
  50. package/src/components/cv-tooltip/index.js +1 -0
  51. package/src/components/cv-ui-shell/cv-header-global-action.vue +1 -1
  52. package/src/thumbnails/inline-notification.svg +23 -0
  53. package/src/thumbnails/skeleton-text.svg +15 -0
  54. package/src/thumbnails/toast-notification.svg +34 -0
@@ -31,55 +31,52 @@
31
31
  </p>
32
32
  </div>
33
33
  </div>
34
-
35
34
  <div :class="`${carbonPrefix}--toolbar-content`">
36
35
  <div
37
36
  v-if="$listeners.search"
38
- :class="{
39
- [`${carbonPrefix}--toolbar-search-container-active`]: searchActive || searchValue.length > 0,
40
- [`${carbonPrefix}--toolbar-search-container-persistent`]: !expandingSearch,
41
- [`${carbonPrefix}--toolbar-search-container-expandable`]: expandingSearch,
42
- }"
37
+ :aria-labelledby="`${uid}-search`"
38
+ :class="[
39
+ `${carbonPrefix}--search ${carbonPrefix}--search--xl`,
40
+ {
41
+ [`${carbonPrefix}--toolbar-search-container-active`]: searchActive || searchValue.length > 0,
42
+ [`${carbonPrefix}--toolbar-search-container-persistent`]: !expandingSearch,
43
+ [`${carbonPrefix}--toolbar-search-container-expandable`]: expandingSearch,
44
+ },
45
+ ]"
46
+ role="search"
43
47
  ref="searchContainer"
44
48
  >
45
- <div data-search :class="`${carbonPrefix}--search ${carbonPrefix}--search--sm`" role="search">
46
- <div
47
- :class="`${carbonPrefix}--search-magnifier`"
48
- tabindex="0"
49
- @click="checkSearchExpand(true)"
50
- @keydown.enter.prevent="checkSearchExpand(true)"
51
- @keydown.space.prevent
52
- @keyup.space.prevent="checkSearchExpand(true)"
53
- ref="magnifier"
54
- >
55
- <Search16 :class="`${carbonPrefix}--toolbar-action__icon`" />
56
- </div>
57
- <label :for="uid" :class="`${carbonPrefix}--label`">{{ searchLabel }}</label>
58
- <input
59
- :class="`${carbonPrefix}--search-input`"
60
- type="text"
61
- :id="uid"
62
- role="search"
63
- :placeholder="searchPlaceholder"
64
- :aria-labelledby="uid"
65
- ref="search"
66
- v-model="searchValue"
67
- @input="onSearch"
68
- @keydown.esc.prevent="checkSearchExpand(false)"
69
- />
70
- <button
71
- :class="[
72
- `${carbonPrefix}--search-close`,
73
- { [`${carbonPrefix}--search-close--hidden`]: !clearSearchVisible },
74
- ]"
75
- :title="searchClearLabel"
76
- :aria-label="searchClearLabel"
77
- @click="onClearClick"
78
- type="button"
79
- >
80
- <Close16 />
81
- </button>
49
+ <div :class="`${carbonPrefix}--search-magnifier`" ref="magnifier">
50
+ <Search16 :class="`${carbonPrefix}--search-magnifier-icon`" />
82
51
  </div>
52
+ <label :id="`${uid}-search`" :for="uid" :class="`${carbonPrefix}--label`">{{ searchLabel }}</label>
53
+ <input
54
+ :class="`${carbonPrefix}--search-input`"
55
+ type="text"
56
+ :id="uid"
57
+ role="search"
58
+ :placeholder="searchPlaceholder"
59
+ :aria-labelledby="uid"
60
+ ref="search"
61
+ v-model="searchValue"
62
+ @input="onSearch"
63
+ @click="checkSearchExpand(true)"
64
+ @keydown.esc.prevent="checkSearchExpand(false)"
65
+ @focus="checkSearchExpand(true)"
66
+ @blur="checkSearchExpand(false)"
67
+ />
68
+ <button
69
+ :class="[
70
+ `${carbonPrefix}--search-close`,
71
+ { [`${carbonPrefix}--search-close--hidden`]: !clearSearchVisible },
72
+ ]"
73
+ :title="searchClearLabel"
74
+ :aria-label="searchClearLabel"
75
+ @click="onClearClick"
76
+ type="button"
77
+ >
78
+ <Close16 />
79
+ </button>
83
80
  </div>
84
81
  <slot name="actions" />
85
82
  </div>
@@ -196,6 +193,7 @@ import { uidMixin, carbonPrefixMixin } from '../../mixins';
196
193
  import Search16 from '@carbon/icons-vue/es/search/16';
197
194
  import Close16 from '@carbon/icons-vue/es/close/16';
198
195
  import ChevronRight16 from '@carbon/icons-vue/es/chevron--right/16';
196
+ import clickout from '../../directives/clickout';
199
197
  export default {
200
198
  name: 'CvDataTable',
201
199
  components: {
@@ -210,6 +208,7 @@ export default {
210
208
  Close16,
211
209
  ChevronRight16,
212
210
  },
211
+ directives: { clickout },
213
212
  mixins: [uidMixin, carbonPrefixMixin],
214
213
  props: {
215
214
  actionBarAriaLabel: { type: String, default: 'Table Action Bar' },
@@ -363,6 +362,9 @@ export default {
363
362
  this.hasToolbar = !!(this.$slots.actions || this.$listeners.search || this.$slots['batch-actions']);
364
363
  this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
365
364
  },
365
+ onClickout(ev) {
366
+ this.checkSearchExpand(false);
367
+ },
366
368
  onCvMount(thing) {
367
369
  if (thing.$_CvDataTableHeading) {
368
370
  this.registeredHeadings = this.$children.filter(item => item.$_CvDataTableHeading);
@@ -21,7 +21,7 @@ const monthToStr = (monthNumber, shorthand, locale) => locale.months[shorthand ?
21
21
  */
22
22
  export default config => fp => {
23
23
  const setupElements = () => {
24
- if (!fp.monthElements) {
24
+ if (!fp.monthElements || fp.monthElements.length < 1) {
25
25
  return;
26
26
  }
27
27
  fp.monthElements.forEach(elem => {
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <button
3
- aria-label="ariaLabel"
3
+ :aria-label="ariaLabel"
4
4
  type="button"
5
5
  class="cv-feedback-button"
6
6
  v-bind="$attrs"
@@ -12,7 +12,6 @@
12
12
  [`${carbonPrefix}--btn--primary`]: kind === 'button',
13
13
  },
14
14
  ]"
15
- role="button"
16
15
  tabindex="0"
17
16
  ref="focusTarget"
18
17
  @keydown.enter.prevent="onShow()"
@@ -148,6 +147,7 @@ export default {
148
147
  buttonLabel: {
149
148
  type: String,
150
149
  default: undefined,
150
+ deprecated: true,
151
151
  validator: val => {
152
152
  if (val !== undefined && process.env.NODE_ENV === 'development') {
153
153
  console.warn('CvFileUploader: button-label prop deprecated in favour of drop-target-label');
@@ -213,20 +213,30 @@ export default {
213
213
  },
214
214
  addFiles(files) {
215
215
  for (const file of files) {
216
- const internalFile = {
217
- state: this.initialStateUploading ? STATES.UPLOADING : STATES.NONE,
218
- file,
219
- invalidMessageTitle: '',
220
- invalidMessage: '',
221
- };
216
+ const internalFile = this.internalFiles.find(item => item.file.name === file.name);
222
217
 
223
- if (file.messageBundle) {
224
- internalFile.invalidMessageTitle = file.messageBundle.invalidMessageTitle;
225
- internalFile.invalidMessage = file.messageBundle.invalidMessage;
226
- delete file.messageBundle;
218
+ if (internalFile) {
219
+ internalFile.state = this.initialStateUploading ? STATES.UPLOADING : STATES.NONE;
220
+ internalFile.invalidMessageTitle = '';
221
+ internalFile.invalidMessage = '';
222
+ } else {
223
+ const internalFile = {
224
+ state: this.initialStateUploading ? STATES.UPLOADING : STATES.NONE,
225
+ file,
226
+ invalidMessageTitle: '',
227
+ invalidMessage: '',
228
+ };
229
+
230
+ if (file.messageBundle) {
231
+ internalFile.invalidMessageTitle = file.messageBundle.invalidMessageTitle;
232
+ internalFile.invalidMessage = file.messageBundle.invalidMessage;
233
+ delete file.messageBundle;
234
+ }
235
+ this.internalFiles.push(internalFile);
227
236
  }
228
- this.internalFiles.push(internalFile);
229
237
  }
238
+ // clear input we do not need to maintain it
239
+ this.$refs['file-input'].value = '';
230
240
  this.$emit('change', this.internalFiles);
231
241
  },
232
242
  onChange(ev) {
@@ -40,6 +40,7 @@ export default {
40
40
  active: {
41
41
  type: Boolean,
42
42
  default: undefined,
43
+ deprecated: true,
43
44
  validator: val => {
44
45
  if (val !== undefined && process.env.NODE_ENV === 'development') {
45
46
  console.warn('CvInlineLoading: active prop deprecated in favour of state prop');
@@ -4,7 +4,13 @@
4
4
  v-on="$listeners"
5
5
  v-bind="linkProps"
6
6
  class="cv-link"
7
- :class="[`${carbonPrefix}--link`, { [`${carbonPrefix}--link--inline`]: inline }]"
7
+ :class="[
8
+ `${carbonPrefix}--link`,
9
+ {
10
+ [`${carbonPrefix}--link--disabled`]: disabled,
11
+ [`${carbonPrefix}--link--inline`]: inline,
12
+ },
13
+ ]"
8
14
  >
9
15
  <slot></slot>
10
16
  </component>
@@ -17,6 +23,7 @@ export default {
17
23
  name: 'CvLink',
18
24
  mixins: [linkMixin, carbonPrefixMixin],
19
25
  props: {
26
+ disabled: Boolean,
20
27
  inline: Boolean,
21
28
  },
22
29
  };
@@ -5,7 +5,7 @@
5
5
  :class="{
6
6
  'cv-loading': !overlay,
7
7
  [`${carbonPrefix}--loading`]: active || stopping,
8
- [`${carbonPrefix}--loading--stop`]: !active && stopping,
8
+ [`${carbonPrefix}--loading--stop`]: (!active && stopping) || stopped,
9
9
  [`${carbonPrefix}--loading--small`]: small,
10
10
  }"
11
11
  ref="loading"
@@ -55,6 +55,7 @@ export default {
55
55
  },
56
56
  data() {
57
57
  return {
58
+ stopped: false,
58
59
  stopping: false,
59
60
  };
60
61
  },
@@ -69,10 +70,12 @@ export default {
69
70
  this.$refs.loading.removeEventListener('animationend', this.onEnd);
70
71
 
71
72
  this.stopping = false;
73
+ this.stopped = true;
72
74
  this.$emit('loading-end');
73
75
  }
74
76
  },
75
77
  onActiveUpdate(newValue) {
78
+ this.stopped = false;
76
79
  this.stopping = !newValue;
77
80
  if (!newValue) {
78
81
  this.$refs.loading.addEventListener('animationend', this.onEnd);
@@ -149,15 +149,16 @@ export default {
149
149
  computed: {
150
150
  dialogAttrs() {
151
151
  const passive = !this.hasFooter;
152
- const attrs = { role: 'dialog' };
153
-
152
+ const attrs = {};
153
+ attrs['aria-label'] = this.$slots.title[0].text;
154
154
  if (this.alert) {
155
155
  if (passive) {
156
156
  attrs.role = 'alert';
157
157
  } else {
158
158
  attrs.role = 'alertdialog';
159
- attrs['aria-describedBy'] = this.uid;
160
159
  }
160
+ } else {
161
+ attrs.role = 'dialog';
161
162
  }
162
163
  return attrs;
163
164
  },
@@ -13,12 +13,13 @@
13
13
  >
14
14
  <label
15
15
  v-if="title"
16
- :for="uid"
16
+ :id="`${uid}-label`"
17
17
  :class="[`${carbonPrefix}--label`, { [`${carbonPrefix}--label--disabled`]: disabled }]"
18
18
  >{{ title }}</label
19
19
  >
20
20
 
21
21
  <div
22
+ :aria-labelledby="`${uid}-label`"
22
23
  role="listbox"
23
24
  tabindex="-1"
24
25
  :class="[
@@ -109,7 +110,13 @@
109
110
  </div>
110
111
  </div>
111
112
 
112
- <div :id="uid" :class="`${carbonPrefix}--list-box__menu`" role="listbox" ref="list">
113
+ <div
114
+ :id="uid"
115
+ :aria-labelledby="`${uid}-label`"
116
+ :class="`${carbonPrefix}--list-box__menu`"
117
+ role="listbox"
118
+ ref="list"
119
+ >
113
120
  <div
114
121
  v-for="(item, index) in dataOptions"
115
122
  :key="`multi-select-${index}`"
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <cv-wrapper :tag-type="formItem ? 'div' : ''" class="cv-number-input" :class="`${carbonPrefix}--form-item`">
3
3
  <div
4
- data-numberinput
5
4
  :class="[
6
5
  `${carbonPrefix}--number`,
7
6
  {
@@ -13,21 +12,13 @@
13
12
  ]"
14
13
  :data-invalid="isInvalid"
15
14
  >
16
- <label :for="uid" :class="`${carbonPrefix}--label`">{{ label }}</label>
17
- <div :class="`${carbonPrefix}--form__helper-text`" v-if="isHelper && mobile">
18
- <slot name="helper-text">{{ helperText }}</slot>
19
- </div>
20
- <div :class="`${carbonPrefix}--number__input-wrapper`">
21
- <button
22
- v-if="mobile"
23
- :class="`${carbonPrefix}--number__control-btn down-icon`"
24
- @click="doDown"
25
- type="button"
26
- :aria-label="ariaLabelForDownButton"
27
- :disabled="disabled"
28
- >
29
- <Subtract16 />
30
- </button>
15
+ <label v-show="label" :for="uid" :class="`${carbonPrefix}--label`">{{ label }}</label>
16
+ <div
17
+ :class="[
18
+ `${carbonPrefix}--number__input-wrapper`,
19
+ { [`${carbonPrefix}--number__input-wrapper--warning`]: isWarn },
20
+ ]"
21
+ >
31
22
  <input
32
23
  :data-invalid="isInvalid"
33
24
  :id="uid"
@@ -41,8 +32,9 @@
41
32
  :max="max"
42
33
  ref="input"
43
34
  />
44
- <WarningFilled16 v-if="isInvalid && !mobile" :class="`${carbonPrefix}--number__invalid`" />
45
- <div :class="`${carbonPrefix}--number__controls`" v-if="!mobile">
35
+ <WarningFilled16 v-if="isInvalid" :class="iconClasses" />
36
+ <WarningAltFilled16 v-if="isWarn && !isInvalid" :class="iconClasses" />
37
+ <div :class="`${carbonPrefix}--number__controls`">
46
38
  <button
47
39
  :class="`${carbonPrefix}--number__control-btn down-icon`"
48
40
  @click="doDown"
@@ -68,21 +60,14 @@
68
60
  </button>
69
61
  <div :class="`${carbonPrefix}--number__rule-divider`" />
70
62
  </div>
71
- <button
72
- v-else
73
- :class="`${carbonPrefix}--number__control-btn up-icon`"
74
- @click="doUp"
75
- type="button"
76
- :aria-label="ariaLabelForUpButton"
77
- :disabled="disabled"
78
- >
79
- <Add16 />
80
- </button>
81
63
  </div>
82
64
  <div :class="`${carbonPrefix}--form-requirement`" v-if="isInvalid">
83
65
  <slot name="invalid-message">{{ invalidMessage }}</slot>
84
66
  </div>
85
- <div :class="`${carbonPrefix}--form__helper-text`" v-if="!isInvalid && isHelper && !mobile">
67
+ <div :class="`${carbonPrefix}--form-requirement`" v-if="isWarn && !isInvalid">
68
+ <slot name="warn-text">{{ warnText }}</slot>
69
+ </div>
70
+ <div :class="`${carbonPrefix}--form__helper-text`" v-if="!(isInvalid || isWarn) && isHelper">
86
71
  <slot name="helper-text">{{ helperText }}</slot>
87
72
  </div>
88
73
  </div>
@@ -94,12 +79,13 @@ import { uidMixin, themeMixin, carbonPrefixMixin, methodsMixin } from '../../mix
94
79
  import Add16 from '@carbon/icons-vue/es/add/16';
95
80
  import Subtract16 from '@carbon/icons-vue/es/subtract/16';
96
81
  import WarningFilled16 from '@carbon/icons-vue/es/warning--filled/16';
82
+ import WarningAltFilled16 from '@carbon/icons-vue/es/warning--alt--filled/16';
97
83
  import CvWrapper from '../cv-wrapper/_cv-wrapper';
98
84
 
99
85
  export default {
100
86
  name: 'CvNumberInput',
101
87
  mixins: [uidMixin, themeMixin, carbonPrefixMixin, methodsMixin({ input: ['blur', 'focus'] })],
102
- components: { Add16, Subtract16, WarningFilled16, CvWrapper },
88
+ components: { Add16, Subtract16, WarningFilled16, WarningAltFilled16, CvWrapper },
103
89
  inheritAttrs: false,
104
90
  props: {
105
91
  disabled: Boolean,
@@ -111,6 +97,7 @@ export default {
111
97
  invalid: /* deprecate */ {
112
98
  type: Boolean,
113
99
  default: undefined,
100
+ deprecated: true,
114
101
  validator(val) {
115
102
  if (val !== undefined && process.env.NODE_ENV === 'development') {
116
103
  console.warn('CvNumberInput: invalid prop deprecated in favour of invalidMessage');
@@ -123,13 +110,25 @@ export default {
123
110
  min: { type: [String, Number], default: undefined },
124
111
  max: { type: [String, Number], default: undefined },
125
112
  step: { type: [String, Number], default: undefined },
126
- mobile: Boolean,
113
+ mobile: /* deprecate */ {
114
+ type: Boolean,
115
+ default: undefined,
116
+ deprecated: true,
117
+ validator(val) {
118
+ if (val !== undefined) {
119
+ console.warn('CvNumberInput: mobile prop deprecated as no longer different to standard number input.');
120
+ }
121
+ return true;
122
+ },
123
+ },
124
+ warnText: { type: String, default: undefined },
127
125
  },
128
126
  data() {
129
127
  return {
130
128
  internalValue: 0,
131
129
  isHelper: false,
132
130
  isInvalid: false,
131
+ isWarn: false,
133
132
  };
134
133
  },
135
134
  mounted() {
@@ -159,6 +158,14 @@ export default {
159
158
  input: ev => this.onInput(ev.target.value),
160
159
  });
161
160
  },
161
+ iconClasses() {
162
+ const classes = [];
163
+ (this.isInvalid || this.isWarn) && classes.push(`${this.carbonPrefix}--number__invalid`);
164
+ this.isWarn && !this.isInvalid && classes.push(`${this.carbonPrefix}--number__invalid--warning`);
165
+ this.readOnly && classes.push(`${this.carbonPrefix}--number__readonly-icon`);
166
+
167
+ return classes.join(' ');
168
+ },
162
169
  },
163
170
  methods: {
164
171
  onInput(val) {
@@ -168,6 +175,7 @@ export default {
168
175
  checkSlots() {
169
176
  // NOTE: this.$slots is not reactive so needs to be managed on updated
170
177
  this.isInvalid = !!(this.$slots['invalid-message'] || (this.invalidMessage && this.invalidMessage.length));
178
+ this.isWarn = !!(this.$slots['warn-text'] || (this.warnText && this.warnText.length));
171
179
  this.isHelper = !!(this.$slots['helper-text'] || (this.helperText && this.helperText.length));
172
180
  },
173
181
  doUp() {
@@ -48,7 +48,7 @@
48
48
  class="cv-overflow-menu__before-content"
49
49
  ref="beforeContent"
50
50
  tabindex="0"
51
- style="position: absolute; height: 1px; width: 1px; left: -9999px;"
51
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
52
52
  @focus="focusBeforeContent"
53
53
  />
54
54
  <ul :class="`${carbonPrefix}--overflow-menu-options__content`">
@@ -58,7 +58,7 @@
58
58
  class="cv-overflow-menu__after-content"
59
59
  ref="afterContent"
60
60
  tabindex="0"
61
- style="position: absolute; height: 1px; width: 1px; left: -9999px;"
61
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
62
62
  @focus="focusAfterContent"
63
63
  />
64
64
  </div>
@@ -87,7 +87,7 @@ export default {
87
87
  tipPosition: {
88
88
  type: String,
89
89
  default: 'right',
90
- validator: val => ['top', 'left', 'bottom', 'right'.includes(val)],
90
+ validator: val => ['top', 'left', 'bottom', 'right'].includes(val),
91
91
  },
92
92
  tipAlignment: { type: String, default: 'center', validator: val => ['start', 'center', 'end'].includes(val) },
93
93
  },
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <cv-wrapper :tag-type="formItem ? 'div' : ''" :class="`cv-search ${carbonPrefix}--form-item`">
3
3
  <div
4
+ v-bind="wrapperAttrs"
4
5
  :class="[
5
6
  `${carbonPrefix}--search`,
6
7
  {
@@ -14,7 +15,22 @@
14
15
  role="search"
15
16
  ref="search"
16
17
  >
17
- <label :for="uid" :class="`${carbonPrefix}--label`">{{ label }}</label>
18
+ <button
19
+ type="button"
20
+ v-if="isToolbarKind"
21
+ :class="`${carbonPrefix}--toolbar-search__btn`"
22
+ :aria-label="toolbarAriaLabel"
23
+ @click="toggleActive(true)"
24
+ @blur="checkFocus"
25
+ >
26
+ <component :is="icon" :class="`${carbonPrefix}--search-magnifier`" />
27
+ </button>
28
+
29
+ <div v-if="!isToolbarKind" :class="`${carbonPrefix}--search-magnifier`">
30
+ <Search20 :class="`${carbonPrefix}--search-magnifier-icon`" />
31
+ </div>
32
+
33
+ <label v-show="label" :for="uid" :class="`${carbonPrefix}--label`">{{ label }}</label>
18
34
 
19
35
  <input
20
36
  :id="uid"
@@ -23,24 +39,12 @@
23
39
  v-model="internalValue"
24
40
  v-on="inputListeners"
25
41
  type="text"
26
- role="search"
27
42
  ref="input"
28
43
  :placeholder="placeholder"
29
44
  :aria-labelledby="uid"
30
45
  @blur="checkFocus"
31
46
  />
32
47
 
33
- <button
34
- type="button"
35
- v-if="isToolbarKind"
36
- :class="`${carbonPrefix}--toolbar-search__btn`"
37
- :aria-label="toolbarAriaLabel"
38
- @click="toggleActive(true)"
39
- @blur="checkFocus"
40
- >
41
- <component :is="icon" :class="`${carbonPrefix}--search-magnifier`" />
42
- </button>
43
- <component v-if="!isToolbarKind" :is="icon" :class="`${carbonPrefix}--search-magnifier`" />
44
48
  <button
45
49
  type="button"
46
50
  :class="[`${carbonPrefix}--search-close`, { [`${carbonPrefix}--search-close--hidden`]: !clearVisible }]"
@@ -64,9 +68,10 @@ import CvWrapper from '../cv-wrapper/_cv-wrapper';
64
68
  export default {
65
69
  name: 'CvSearch',
66
70
  mixins: [uidMixin, themeMixin, carbonPrefixMixin, methodsMixin({ input: ['blur', 'focus'] })],
67
- components: { Close16, CvWrapper },
71
+ components: { Close16, CvWrapper, Search20 },
68
72
  inheritAttrs: false,
69
73
  props: {
74
+ ariaLabel: String,
70
75
  clearAriaLabel: { type: String, default: 'Clear search input' },
71
76
  formItem: { type: Boolean, default: true },
72
77
  kind: { type: String, default: undefined },
@@ -110,6 +115,17 @@ export default {
110
115
  },
111
116
  },
112
117
  computed: {
118
+ wrapperAttrs() {
119
+ const attrs = {};
120
+ if (this.ariaLabel) {
121
+ attrs['aria-label'] = this.ariaLabel;
122
+ } else if (this.label) {
123
+ attrs['aria-labelledby'] = this.uid;
124
+ } else {
125
+ attrs['aria-label'] = 'Search box';
126
+ }
127
+ return attrs;
128
+ },
113
129
  // Bind listeners at the component level to the embedded input element and
114
130
  // add our own input listener to service the v-model. See:
115
131
  // https://vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div :class="`cv-slider ${carbonPrefix}--form-item`">
3
3
  <label
4
+ v-show="label"
4
5
  :for="uid"
5
6
  :class="[`${carbonPrefix}--label`, { [`${carbonPrefix}--label--disabled`]: disabled }]"
6
7
  :id="labelId"
@@ -1,23 +1,8 @@
1
1
  <template>
2
- <div :class="`cv-tabs ${carbonPrefix}--tabs ${carbonPrefix}--skeleton`">
3
- <div :class="`${carbonPrefix}--tabs-trigger`">
4
- <div :class="`${carbonPrefix}--tabs-trigger-text`">&nbsp;</div>
5
- <svg width="10" height="5" viewBox="0 0 10 5" fill-rule="evenodd">
6
- <path d="M10 0L5 5 0 0z" />
7
- </svg>
8
- </div>
9
- <ul :class="`${carbonPrefix}--tabs__nav ${carbonPrefix}--tabs__nav--hidden`">
10
- <li :class="`cv-tab ${carbonPrefix}--tabs__nav-item ${carbonPrefix}--tabs__nav-item--selected`">
11
- <div :class="`${carbonPrefix}--tabs__nav-link`">&nbsp;</div>
12
- </li>
13
- <li :class="`cv-tab ${carbonPrefix}--tabs__nav-item`">
14
- <div :class="`${carbonPrefix}--tabs__nav-link`">&nbsp;</div>
15
- </li>
16
- <li :class="`cv-tab ${carbonPrefix}--tabs__nav-item`">
17
- <div :class="`${carbonPrefix}--tabs__nav-link`">&nbsp;</div>
18
- </li>
19
- <li :class="`cv-tab ${carbonPrefix}--tabs__nav-item`">
20
- <div :class="`${carbonPrefix}--tabs__nav-link`">&nbsp;</div>
2
+ <div :class="`cv-tabs ${carbonPrefix}--tabs ${carbonPrefix}--skeleton ${carbonPrefix}--tabs--scrollable`">
3
+ <ul :class="`${carbonPrefix}--tabs--scrollable__nav`">
4
+ <li v-for="index in tabCount" :key="index" :class="`${carbonPrefix}--tabs--scrollable__nav-item`">
5
+ <div :class="`${carbonPrefix}--tabs__nav-link`"><span></span></div>
21
6
  </li>
22
7
  </ul>
23
8
  </div>
@@ -28,5 +13,8 @@ import { carbonPrefixMixin } from '../../mixins';
28
13
  export default {
29
14
  name: 'CvTabsSkeleton',
30
15
  mixins: [carbonPrefixMixin],
16
+ props: {
17
+ tabCount: { type: Number, default: 5 },
18
+ },
31
19
  };
32
20
  </script>
@@ -44,8 +44,6 @@
44
44
  },
45
45
  ]"
46
46
  role="presentation"
47
- :aria-selected="selectedId == tab.uid ? 'true' : 'false'"
48
- :aria-disabled="disabledTabs.indexOf(tab.uid) !== -1"
49
47
  >
50
48
  <button
51
49
  :class="`${carbonPrefix}--tabs--scrollable__nav-link`"
@@ -12,9 +12,7 @@ export default {
12
12
  props: {
13
13
  size: {
14
14
  type: String,
15
- validator(val) {
16
- return !val || val == 'sm';
17
- },
15
+ validator: val => ['sm', ''].includes(val),
18
16
  },
19
17
  },
20
18
  };