@carbon/vue 1.0.2 → 1.1.3

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 (89) hide show
  1. package/CHANGELOG.md +192 -0
  2. package/README.md +156 -211
  3. package/dist/carbon-vue.common.js +10567 -12509
  4. package/dist/carbon-vue.common.js.map +1 -1
  5. package/dist/carbon-vue.umd.js +10567 -12509
  6. package/dist/carbon-vue.umd.js.map +1 -1
  7. package/dist/carbon-vue.umd.min.js +31 -7
  8. package/dist/carbon-vue.umd.min.js.map +1 -1
  9. package/dist/demo.html +2 -2
  10. package/package.json +17 -157
  11. package/src/components/cv-accordion/_cv-accordion-item-skeleton.vue +3 -13
  12. package/src/components/cv-accordion/cv-accordion-item.vue +2 -9
  13. package/src/components/cv-breadcrumb/cv-breadcrumb-item.vue +3 -1
  14. package/src/components/cv-button/cv-button-skeleton.vue +1 -6
  15. package/src/components/cv-button/cv-button.vue +15 -37
  16. package/src/components/cv-checkbox/cv-checkbox.vue +42 -26
  17. package/src/components/cv-code-snippet/_cv-code-snippet-multiline.vue +13 -23
  18. package/src/components/cv-code-snippet/_cv-code-snippet-oneline.vue +11 -5
  19. package/src/components/cv-code-snippet/_cv-feedback-button.vue +1 -3
  20. package/src/components/cv-code-snippet/cv-code-snippet.vue +2 -7
  21. package/src/components/cv-content-switcher/cv-content-switcher-button.vue +20 -4
  22. package/src/components/cv-content-switcher/cv-content-switcher.vue +3 -10
  23. package/src/components/cv-data-table/cv-data-table-row.vue +15 -11
  24. package/src/components/cv-data-table/cv-data-table.vue +30 -28
  25. package/src/components/cv-date-picker/cv-date-picker.vue +53 -47
  26. package/src/components/cv-dropdown/_cv-dropdown-inner-c10.vue +226 -0
  27. package/src/components/cv-dropdown/_cv-dropdown-inner.vue +201 -0
  28. package/src/components/cv-dropdown/cv-dropdown-item.vue +6 -8
  29. package/src/components/cv-dropdown/cv-dropdown-skeleton.vue +1 -5
  30. package/src/components/cv-dropdown/cv-dropdown.vue +22 -169
  31. package/src/components/cv-file-uploader/cv-file-uploader.vue +44 -22
  32. package/src/components/cv-inline-loading/cv-inline-loading.vue +37 -0
  33. package/src/components/cv-inline-notification/cv-inline-notification.vue +22 -19
  34. package/src/components/cv-link/cv-link.vue +1 -6
  35. package/src/components/cv-loading/cv-loading.vue +13 -4
  36. package/src/components/cv-modal/cv-modal.vue +17 -15
  37. package/src/components/cv-number-input/cv-number-input.vue +20 -32
  38. package/src/components/cv-overflow-menu/cv-overflow-menu.vue +13 -19
  39. package/src/components/cv-pagination/cv-pagination.vue +61 -42
  40. package/src/components/cv-progress/_cv-progress-step-complete.vue +3 -12
  41. package/src/components/cv-progress/cv-progress-step.vue +97 -0
  42. package/src/components/cv-progress/cv-progress.vue +68 -13
  43. package/src/components/cv-radio-button/cv-radio-button.vue +1 -0
  44. package/src/components/cv-search/cv-search.vue +144 -15
  45. package/src/components/cv-select/cv-select-option.vue +3 -1
  46. package/src/components/cv-select/cv-select.vue +147 -15
  47. package/src/components/cv-slider/cv-slider.vue +14 -43
  48. package/src/components/cv-structured-list/_cv-structured-list-item-selectable.vue +18 -6
  49. package/src/components/cv-structured-list/cv-structured-list-item.vue +1 -3
  50. package/src/components/cv-structured-list/cv-structured-list.vue +10 -2
  51. package/src/components/cv-tabs/cv-tabs.vue +31 -15
  52. package/src/components/cv-tag/cv-tag.vue +23 -13
  53. package/src/components/cv-text-area/cv-text-area.vue +23 -10
  54. package/src/components/cv-text-input/cv-text-input.vue +80 -10
  55. package/src/components/cv-tile/_cv-tile-clickable.vue +1 -5
  56. package/src/components/cv-tile/_cv-tile-expandable.vue +11 -15
  57. package/src/components/cv-tile/_cv-tile-selectable.vue +14 -3
  58. package/src/components/cv-tile/cv-tile.vue +1 -4
  59. package/src/components/cv-time-picker/cv-time-picker.vue +27 -29
  60. package/src/components/cv-toast-notification/cv-toast-notification.vue +32 -6
  61. package/src/components/cv-toggle/cv-toggle.vue +3 -7
  62. package/src/components/cv-toolbar/cv-toolbar-option.vue +1 -4
  63. package/src/components/cv-toolbar/cv-toolbar-search.vue +5 -0
  64. package/src/components/cv-tooltip/cv-definition-tooltip.vue +1 -3
  65. package/src/components/cv-tooltip/cv-interactive-tooltip.vue +13 -28
  66. package/src/components/cv-tooltip/cv-tooltip.vue +11 -15
  67. package/src/components/cv-wrapper/_cv-wrapper.js +33 -0
  68. package/src/index-components-vue.js +1 -3
  69. package/src/index.js +1 -5
  70. package/src/{_internal/_feature-flags.js → internal/feature-flags.js} +30 -2
  71. package/dist/carbon-data-viz-vue.common.js +0 -23907
  72. package/dist/carbon-data-viz-vue.common.js.map +0 -1
  73. package/dist/carbon-data-viz-vue.css +0 -1
  74. package/dist/carbon-data-viz-vue.umd.js +0 -23917
  75. package/dist/carbon-data-viz-vue.umd.js.map +0 -1
  76. package/dist/carbon-data-viz-vue.umd.min.js +0 -2
  77. package/dist/carbon-data-viz-vue.umd.min.js.map +0 -1
  78. package/src/assets/styles/_carbon-helpers.scss +0 -8
  79. package/src/components/cv-checkbox/_cv-checkbox-inner-form-item.vue +0 -19
  80. package/src/components/cv-checkbox/_cv-checkbox-inner.vue +0 -59
  81. package/src/components/cv-progress/_cv-progress-step.vue +0 -51
  82. package/src/components/cv-search/_cv-search-inner-form-item.vue +0 -22
  83. package/src/components/cv-search/_cv-search-inner.vue +0 -162
  84. package/src/components/cv-select/_cv-select-inner-form-item.vue +0 -22
  85. package/src/components/cv-select/_cv-select-inner.vue +0 -78
  86. package/src/data-viz/cv-bar-graph/cv-bar-graph.vue +0 -495
  87. package/src/data-viz/cv-gauge/cv-gauge.vue +0 -196
  88. package/src/data-viz/cv-pie-chart/cv-pie-chart.vue +0 -194
  89. package/src/index-data-viz.js +0 -29
@@ -0,0 +1,97 @@
1
+ <template>
2
+ <li class="cv-progress-step bx--progress-step" :class="stateClass" :aria-disabled="disabled">
3
+ <cv-wrapper v-if="componentsX">
4
+ <svg v-if="isCurrent">
5
+ <path d="M 7, 7 m -7, 0 a 7,7 0 1,0 14,0 a 7,7 0 1,0 -14,0"></path>
6
+ </svg>
7
+ <Warning16 v-else-if="!isComplete && invalid" class="bx--progress__warning" />
8
+ <svg v-else-if="!isComplete">
9
+ <path
10
+ d="M8 1C4.1 1 1 4.1 1 8s3.1 7 7 7 7-3.1 7-7-3.1-7-7-7zm0 13c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6z"
11
+ ></path>
12
+ </svg>
13
+ <CheckmarkOutline16 v-else-if="isComplete" />
14
+ </cv-wrapper>
15
+ <cv-wrapper v-else>
16
+ <cv-progress-step-complete v-if="isComplete" />
17
+ <cv-progress-step-incomplete v-if="!isComplete" :is-current="isCurrent" />
18
+ </cv-wrapper>
19
+ <cv-tooltip v-show="componentsX" direction="bottom" :tip="label">
20
+ <p class="bx--progress-label">{{ label }}</p>
21
+ </cv-tooltip>
22
+ <p v-if="!componentsX" class="bx--progress-label">{{ label }}</p>
23
+
24
+ <p class="bx--progress-optional" v-if="componentsX && additionalInfo">{{ additionalInfo }}</p>
25
+ <span class="bx--progress-line"></span>
26
+ </li>
27
+ </template>
28
+
29
+ <script>
30
+ import CvProgressStepComplete from './_cv-progress-step-complete';
31
+ import CvProgressStepIncomplete from './_cv-progress-step-incomplete';
32
+ import { componentsX } from '../../internal/feature-flags';
33
+ import CvTooltip from '../cv-tooltip/cv-tooltip';
34
+ import CvWrapper from '../cv-wrapper/_cv-wrapper';
35
+ import CheckmarkOutline16 from '@carbon/icons-vue/lib/checkmark--outline/16';
36
+ import Warning16 from '@carbon/icons-vue/lib/warning/16';
37
+
38
+ const states = ['incomplete', 'current', 'complete'];
39
+
40
+ export default {
41
+ name: 'CvProgressStep',
42
+ components: {
43
+ CvProgressStepComplete,
44
+ CvProgressStepIncomplete,
45
+ CvTooltip,
46
+ CvWrapper,
47
+ CheckmarkOutline16,
48
+ Warning16,
49
+ },
50
+ props: {
51
+ additionalInfo: String,
52
+ disabled: Boolean,
53
+ invalid: Boolean,
54
+ label: String,
55
+ complete: Boolean,
56
+ },
57
+ data() {
58
+ return {
59
+ componentsX,
60
+ state: -1,
61
+ };
62
+ },
63
+ mounted() {
64
+ this.$_CvProgressStep = true; // for use by parent with $children
65
+ this.$parent.$emit('cv:mounted');
66
+ },
67
+ beforeDestroy() {
68
+ this.$parent.$emit('cv:beforeDestroy');
69
+ },
70
+ watch: {
71
+ complete() {
72
+ this.$parent.$emit('cv:completed');
73
+ },
74
+ },
75
+ computed: {
76
+ internalState: {
77
+ get() {
78
+ return this.state;
79
+ },
80
+ set(val) {
81
+ this.state = Math.sign(val);
82
+ },
83
+ },
84
+ isComplete() {
85
+ return this.state > 0;
86
+ },
87
+ isCurrent() {
88
+ return this.state === 0;
89
+ },
90
+ stateClass() {
91
+ const disabledClass = this.disabled ? ' bx--progress-step--disabled' : '';
92
+ const invalidClass = this.invalid ? ' bx--progress-step--invalid' : '';
93
+ return `bx--progress-step--${states[this.state + 1]}${disabledClass}${invalidClass}`;
94
+ },
95
+ },
96
+ };
97
+ </script>
@@ -1,17 +1,19 @@
1
1
  <template>
2
2
  <ul data-progress data-progress-current class="cv-progress bx--progress">
3
- <cv-progress-step
4
- v-for="(step, index) in steps"
5
- :key="index"
6
- :label="step"
7
- :state="state(index)"
8
- ref="steps"
9
- />
3
+ <slot>
4
+ <cv-progress-step
5
+ v-for="(step, index) in steps"
6
+ :key="`step:${index}`"
7
+ :label="step"
8
+ :complete="initialStep > index"
9
+ ref="steps"
10
+ />
11
+ </slot>
10
12
  </ul>
11
13
  </template>
12
14
 
13
15
  <script>
14
- import CvProgressStep from './_cv-progress-step';
16
+ import CvProgressStep from './cv-progress-step';
15
17
 
16
18
  export default {
17
19
  name: 'CvProgress',
@@ -20,26 +22,41 @@ export default {
20
22
  },
21
23
  props: {
22
24
  initialStep: { type: Number, default: 0 },
23
- steps: { type: Array, required: true },
25
+ steps: Array,
24
26
  },
25
27
  data() {
26
28
  return {
27
29
  // TODO: Manage current step or leave this to user?
28
30
  // NOTE: Decision impacts on whether or not methods are useful
29
- currentStep: 0,
31
+ currentStep: -1,
30
32
  };
31
33
  },
34
+ created() {
35
+ // add these on created otherwise cv:mounted is too late.
36
+ this.$on('cv:completed', srcComponent => this.onCvCompleted(srcComponent));
37
+ this.$on('cv:mounted', srcComponent => this.onCvMount(srcComponent));
38
+ this.$on('cv:beforeDestroy', srcComponent => this.onCvBeforeDestroy(srcComponent));
39
+ },
32
40
  mounted() {
33
41
  this.currentStep = this.initialStep;
34
42
  },
35
43
  watch: {
36
- initialStep() {
37
- this.currentStep = this.initialStep;
38
- },
44
+ // initialStep() {
45
+ // if (!this.$slots.default) {
46
+ // // only works if no slot passed
47
+ // // this.currentStep = this.initialStep;
48
+ // this.processState();
49
+ // }
50
+ // },
39
51
  },
40
52
  computed: {
41
53
  state() {
42
54
  return step => {
55
+ if (this.componentsX) {
56
+ console.warn('CvProgress: method deprecated');
57
+ return;
58
+ }
59
+
43
60
  if (step > this.currentStep) {
44
61
  return 'incomplete';
45
62
  } else {
@@ -49,10 +66,43 @@ export default {
49
66
  },
50
67
  },
51
68
  methods: {
69
+ onCvMount() {
70
+ this.processState();
71
+ },
72
+ onCvBeforeDestroy() {
73
+ this.processState();
74
+ },
75
+ onCvCompleted() {
76
+ console.log('completed');
77
+ this.processState();
78
+ },
79
+ processState() {
80
+ const steps = this.$children.filter(child => child.$_CvProgressStep);
81
+ let newCurrentStep = -1;
82
+ for (let i = 0; i < steps.length; i++) {
83
+ if (!steps[i].complete && newCurrentStep < 0) {
84
+ newCurrentStep = i;
85
+ steps[i].internalState = 0;
86
+ } else {
87
+ steps[i].internalState = newCurrentStep < 0 ? 1 : -1;
88
+ }
89
+ }
90
+ this.currentStep = newCurrentStep;
91
+ },
52
92
  getCurrent() {
93
+ if (this.componentsX) {
94
+ console.warn('CvProgress: method deprecated');
95
+ return;
96
+ }
97
+
53
98
  return { order: current + 1, component: this.$refs.steps[current] };
54
99
  },
55
100
  getSteps() {
101
+ if (this.componentsX) {
102
+ console.warn('CvProgress: method deprecated');
103
+ return;
104
+ }
105
+
56
106
  let index = 1;
57
107
  const steps = [];
58
108
  for (let step of this.$refs.steps) {
@@ -62,6 +112,11 @@ export default {
62
112
  return steps;
63
113
  },
64
114
  setCurrent(step) {
115
+ if (this.componentsX) {
116
+ console.warn('CvProgress: method deprecated');
117
+ return;
118
+ }
119
+
65
120
  if (step > this.steps.length) {
66
121
  this.currentStep = this.steps.length - 1;
67
122
  } else {
@@ -24,6 +24,7 @@ import radioMixin from '../../mixins/radio-mixin';
24
24
 
25
25
  export default {
26
26
  name: 'CvRadioButton',
27
+ inheritAttrs: false,
27
28
  mixins: [uidMixin, radioMixin],
28
29
  };
29
30
  </script>
@@ -1,30 +1,159 @@
1
1
  <template>
2
- <component
3
- :is="tagType"
4
- v-bind="$attrs"
5
- v-on="$listeners"
6
- :value="value"
7
- class="cv-search"
8
- >
9
- <slot></slot>
10
- </component>
2
+ <cv-wrapper :tag-type="formItem ? 'div' : ''" class="cv-search bx--form-item">
3
+ <div class="bx--search" :class="[searchClasses, { 'cv-search': !formItem }]" role="search" ref="search">
4
+ <label :for="uid" class="bx--label">{{ label }}</label>
5
+
6
+ <input
7
+ :id="uid"
8
+ class="bx--search-input"
9
+ v-bind="$attrs"
10
+ v-model="internalValue"
11
+ v-on="inputListeners"
12
+ type="text"
13
+ role="search"
14
+ ref="input"
15
+ :placeholder="placeholder"
16
+ :aria-labelledby="uid"
17
+ @focusout="checkFocus"
18
+ />
19
+
20
+ <button
21
+ type="button"
22
+ v-if="isToolbarKind"
23
+ class="bx--toolbar-search__btn"
24
+ aria-label="Toolbar search"
25
+ @click="toggleActive(true)"
26
+ @focusout="checkFocus"
27
+ >
28
+ <Search16 v-if="componentsX" class="bx--search-magnifier" />
29
+ <svg v-else class="bx--search-magnifier" width="16" height="16" viewBox="0 0 16 16">
30
+ <path
31
+ d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm4.936-1.27l4.563 4.557-.707.708-4.563-4.558a6.5 6.5 0 1 1 .707-.707z"
32
+ fill-rule="nonzero"
33
+ ></path>
34
+ </svg>
35
+ </button>
36
+ <Search16 v-if="componentsX" class="bx--search-magnifier" />
37
+ <svg
38
+ v-if="!componentsX && !isToolbarKind"
39
+ class="bx--search-magnifier"
40
+ width="16"
41
+ height="16"
42
+ viewBox="0 0 16 16"
43
+ >
44
+ <path
45
+ d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm4.936-1.27l4.563 4.557-.707.708-4.563-4.558a6.5 6.5 0 1 1 .707-.707z"
46
+ fill-rule="nonzero"
47
+ ></path>
48
+ </svg>
49
+
50
+ <button
51
+ type="button"
52
+ class="bx--search-close"
53
+ :class="{ 'bx--search-close--hidden': !clearVisible }"
54
+ title="Clear search input"
55
+ aria-label="Clear search input"
56
+ @click="onClearClick"
57
+ >
58
+ <Close16 v-if="componentsX" />
59
+ <svg v-else width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
60
+ <path
61
+ d="M8 6.586L5.879 4.464 4.464 5.88 6.586 8l-2.122 2.121 1.415 1.415L8 9.414l2.121 2.122 1.415-1.415L9.414 8l2.122-2.121-1.415-1.415L8 6.586zM8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"
62
+ fill-rule="evenodd"
63
+ ></path>
64
+ </svg>
65
+ </button>
66
+ </div>
67
+ </cv-wrapper>
11
68
  </template>
12
69
 
13
70
  <script>
14
- import CvSearchInnerFormItem from './_cv-search-inner-form-item';
15
- import CvSearchInner from './_cv-search-inner';
71
+ import uidMixin from '../../mixins/uid-mixin';
72
+ import themeMixin from '../../mixins/theme-mixin';
73
+ import { componentsX } from '../../internal/feature-flags';
74
+ import Search16 from '@carbon/icons-vue/lib/search/16';
75
+ import Close16 from '@carbon/icons-vue/lib/close/16';
76
+ import CvWrapper from '../cv-wrapper/_cv-wrapper';
16
77
 
17
78
  export default {
18
79
  name: 'CvSearch',
19
- components: { CvSearchInnerFormItem, CvSearchInner },
80
+ mixins: [uidMixin, themeMixin],
81
+ components: { Close16, Search16, CvWrapper },
20
82
  inheritAttrs: false,
21
83
  props: {
22
- value: String,
23
84
  formItem: { type: Boolean, default: true },
85
+ kind: { type: String, default: null },
86
+ label: String,
87
+ large: Boolean,
88
+ value: String,
89
+ placeholder: { type: String, default: 'Search' },
90
+ },
91
+ data() {
92
+ return {
93
+ componentsX,
94
+ clearVisible: this.value ? this.value.length : false,
95
+ internalValue: this.value,
96
+ toolbarActive: false,
97
+ };
98
+ },
99
+ watch: {
100
+ value() {
101
+ this.clearVisible = this.value ? this.value.length : false;
102
+ this.internalValue = this.value;
103
+ },
24
104
  },
25
105
  computed: {
26
- tagType() {
27
- return this.formItem ? 'cv-search-inner-form-item' : 'cv-search-inner';
106
+ // Bind listeners at the component level to the embedded input element and
107
+ // add our own input listener to service the v-model. See:
108
+ // https://vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model
109
+ inputListeners() {
110
+ return {
111
+ ...this.$listeners,
112
+ input: this.onInput,
113
+ };
114
+ },
115
+ searchClasses() {
116
+ const themeClass = this.theme.length ? `bx--search--${this.theme}` : '';
117
+ const sizeClass = `bx--search--${this.large ? 'lg' : 'sm'}`;
118
+ let toolbarClasses = '';
119
+ if (this.isToolbarKind) {
120
+ toolbarClasses = this.toolbarActive ? 'bx--toolbar-search bx--toolbar-search--active' : 'bx--toolbar-search';
121
+ }
122
+ return `${themeClass} ${sizeClass} ${toolbarClasses}`;
123
+ },
124
+ closeHiddenClass() {
125
+ return this.clearVisible ? '' : 'bx--search-close--hidden';
126
+ },
127
+ isToolbarKind() {
128
+ return this.kind === 'toolbar';
129
+ },
130
+ },
131
+ methods: {
132
+ onClearClick() {
133
+ this.internalValue = '';
134
+ this.clearVisible = false;
135
+ this.$emit('input', this.internalValue);
136
+ },
137
+ onInput() {
138
+ this.clearVisible = this.internalValue.length > 0;
139
+ return this.$emit('input', this.internalValue);
140
+ },
141
+ toggleActive(force) {
142
+ if (typeof force === 'boolean') {
143
+ this.toolbarActive = force;
144
+ } else {
145
+ this.toolbarActive = !this.toolbarActive;
146
+ }
147
+ if (this.toolbarActive) {
148
+ this.$refs.input.focus();
149
+ }
150
+ },
151
+ checkFocus(ev) {
152
+ if (this.isToolbarKind) {
153
+ if (!this.$el.contains(ev.relatedTarget)) {
154
+ this.toolbarActive = false;
155
+ }
156
+ }
28
157
  },
29
158
  },
30
159
  };
@@ -1,5 +1,7 @@
1
1
  <template>
2
- <option class="cv-select-option bx--select-option"> <slot></slot> </option>
2
+ <option class="cv-select-option bx--select-option">
3
+ <slot></slot>
4
+ </option>
3
5
  </template>
4
6
 
5
7
  <script>
@@ -1,30 +1,162 @@
1
1
  <template>
2
- <component
3
- :is="tagType"
4
- v-bind="$attrs"
5
- v-on="$listeners"
6
- :value="value"
7
- class="cv-select"
8
- >
9
- <slot></slot>
10
- </component>
2
+ <cv-wrapper :tag-type="formItem ? 'div' : ''" class="cv-select bx--form-item">
3
+ <div
4
+ class="bx--select"
5
+ :class="{
6
+ 'cv-select': !formItem,
7
+ 'bx--select--inline': inline,
8
+ 'bx--select--light': theme === 'light',
9
+ 'bx--select--invalid': isInvalid,
10
+ 'bx--select--disabled': $attrs.disabled,
11
+ }"
12
+ >
13
+ <label
14
+ :for="uid"
15
+ class="bx--label"
16
+ :class="{ 'bx--visually-hidden': hideLabel, 'bx--label--disabled': $attrs.disabled }"
17
+ >{{ label }}</label
18
+ >
19
+
20
+ <div v-if="!inline && isHelper" class="bx--form__helper-text">
21
+ <slot name="helper-text">{{ helperText }}</slot>
22
+ </div>
23
+
24
+ <cv-wrapper :tag-type="inline && componentsX ? 'div' : ''" class="bx--select-input--inline__wrapper">
25
+ <div v-if="componentsX" class="bx--select-input__wrapper" :data-invalid="isInvalid">
26
+ <select
27
+ v-bind="$attrs"
28
+ :id="uid"
29
+ class="bx--select-input"
30
+ v-on="inputListeners"
31
+ ref="select"
32
+ :value="internalValue"
33
+ >
34
+ <slot></slot>
35
+ </select>
36
+ <chevron-down-glyph v-if="componentsX" class="bx--select__arrow" />
37
+ <warning-filled-16 v-if="componentsX && isInvalid" class="bx--select__invalid-icon" />
38
+ </div>
39
+
40
+ <div v-if="componentsX && isInvalid" class="bx--form-requirement">
41
+ <slot name="invalid-message">{{ invalidMessage }}</slot>
42
+ </div>
43
+ <!-- cv-wrapper div bx--select-input--inline__wrapper -->
44
+ </cv-wrapper>
45
+
46
+ <!-- NOTE componentsX -->
47
+ <select
48
+ v-if="!componentsX"
49
+ v-bind="$attrs"
50
+ :id="uid"
51
+ class="bx--select-input"
52
+ v-on="inputListeners"
53
+ ref="select"
54
+ :value="value"
55
+ :data-invalid="isInvalid"
56
+ >
57
+ <slot></slot>
58
+ </select>
59
+ <svg v-if="!componentsX" class="bx--select__arrow" width="10" height="5" viewBox="0 0 10 5">
60
+ <path d="M0 0l5 4.998L10 0z" fill-rule="evenodd"></path>
61
+ </svg>
62
+
63
+ <div v-if="inline && isHelper" class="bx--form__helper-text">
64
+ <slot name="helper-text">{{ helperText }}</slot>
65
+ </div>
66
+
67
+ <div v-if="!componentsX && isInvalid" class="bx--form-requirement">
68
+ <slot name="invalid-message">{{ invalidMessage }}</slot>
69
+ </div>
70
+ </div>
71
+ <!-- cv-wrapper div bx--form-item -->
72
+ </cv-wrapper>
11
73
  </template>
12
74
 
13
75
  <script>
14
- import CvSelectInnerFormItem from './_cv-select-inner-form-item';
15
- import CvSelectInner from './_cv-select-inner';
76
+ import uidMixin from '../../mixins/uid-mixin';
77
+ import themeMixin from '../../mixins/theme-mixin';
78
+ import { componentsX } from '../../internal/feature-flags';
79
+ import CvWrapper from '../cv-wrapper/_cv-wrapper';
80
+ import ChevronDownGlyph from '@carbon/icons-vue/lib/chevron--down/index';
81
+ import WarningFilled16 from '@carbon/icons-vue/lib/warning--filled/16';
16
82
 
17
83
  export default {
18
84
  name: 'CvSelect',
19
- components: { CvSelectInnerFormItem, CvSelectInner },
20
85
  inheritAttrs: false,
86
+ components: { CvWrapper, ChevronDownGlyph, WarningFilled16 },
87
+ mixins: [uidMixin, themeMixin],
21
88
  props: {
22
- value: String,
89
+ inline: Boolean,
90
+ invalidMessage: { type: String, default: null },
91
+ helperText: { type: String, default: null },
23
92
  formItem: { type: Boolean, default: true },
93
+ hideLabel: Boolean,
94
+ label: { type: String, required: true },
95
+ // *********************
96
+ // declare here to prevent the following from being added to the select
97
+ // *********************
98
+ // multiple does not work with styling from carbon-components 9.20
99
+ multiple: {
100
+ type: String,
101
+ validator: () => {
102
+ console.warn('property multiple not supported in CvSelect');
103
+ return false;
104
+ },
105
+ },
106
+ value: { type: String, default: null },
107
+ },
108
+ beforeCreate() {
109
+ // *********************
110
+ // delete here to prevent the following from being added to the select
111
+ // *********************
112
+ // multiple does not work with styling from carbon-components 9.20
113
+ delete this.$attrs.multiple;
114
+ },
115
+ data() {
116
+ return { componentsX, dataValue: null };
117
+ },
118
+ mounted() {
119
+ // this is needed to ensure selected for an option when no value is supplied
120
+ if (this.value === null) {
121
+ let options = this.$el.querySelectorAll('option');
122
+ for (let i = 0; i < options.length; i++) {
123
+ if (options[i].attributes.selected) {
124
+ this.dataValue = options[i].value;
125
+ }
126
+ }
127
+ }
128
+ },
129
+ watch: {
130
+ value() {
131
+ // this is needed to ensure selected for an option when no value is supplied
132
+ if (this.value === null) {
133
+ let options = this.$el.querySelectorAll('option');
134
+ for (let i = 0; i < options.length; i++) {
135
+ if (options[i].attributes.selected) {
136
+ this.dataValue = options[i].value;
137
+ }
138
+ }
139
+ }
140
+ },
24
141
  },
25
142
  computed: {
26
- tagType() {
27
- return this.formItem ? 'cv-select-inner-form-item' : 'cv-select-inner';
143
+ // Bind listeners at the component level to the embedded input element and
144
+ // add our own input listener to service the v-model. See:
145
+ // https://vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model
146
+ inputListeners() {
147
+ return {
148
+ ...this.$listeners,
149
+ input: event => this.$emit('input', event.target.value),
150
+ };
151
+ },
152
+ isInvalid() {
153
+ return this.$slots['invalid-message'] !== undefined || (this.invalidMessage && this.invalidMessage.length);
154
+ },
155
+ isHelper() {
156
+ return this.$slots['helper-text'] !== undefined || (this.helperText && this.helperText.length);
157
+ },
158
+ internalValue() {
159
+ return this.dataValue ? this.dataValue : this.value;
28
160
  },
29
161
  },
30
162
  };