@carbon/vue 3.0.6-alpha.0 → 3.0.8-alpha.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 (109) hide show
  1. package/README.md +7 -0
  2. package/dist/carbon-vue-3.common.js +16111 -9105
  3. package/dist/carbon-vue-3.common.js.map +1 -1
  4. package/dist/carbon-vue-3.umd.js +16111 -9105
  5. package/dist/carbon-vue-3.umd.js.map +1 -1
  6. package/dist/carbon-vue-3.umd.min.js +4 -4
  7. package/dist/carbon-vue-3.umd.min.js.map +1 -1
  8. package/package.json +9 -6
  9. package/src/components/CvAccordion/CvAccordion.stories.js +1 -0
  10. package/src/components/CvButton/CvButton.stories.js +3 -3
  11. package/src/components/CvButton/CvButtonSkeleton.stories.js +79 -0
  12. package/src/components/CvButton/CvButtonSkeleton.vue +19 -0
  13. package/src/components/CvButton/index.js +8 -1
  14. package/src/components/CvCheckbox/CvCheckbox.stories.js +18 -7
  15. package/src/components/CvCheckbox/CvCheckbox.vue +19 -3
  16. package/src/components/CvCheckbox/CvCheckboxSkeleton.vue +16 -0
  17. package/src/components/CvCheckbox/__tests__/__snapshots__/CvCheckboxSkeleton.spec.js.snap +3 -0
  18. package/src/components/CvCheckbox/index.js +2 -1
  19. package/src/components/CvDatePicker/CvDatePicker.vue +1 -1
  20. package/src/components/CvDropdown/CvDropdown.stories.mdx +407 -0
  21. package/src/components/CvDropdown/CvDropdown.vue +416 -0
  22. package/src/components/CvDropdown/CvDropdownItem.vue +86 -0
  23. package/src/components/CvDropdown/CvDropdownSkeleton.vue +17 -0
  24. package/src/components/CvDropdown/index.js +5 -0
  25. package/src/components/CvFileUploader/CvFileUploader.stories.mdx +333 -0
  26. package/src/components/CvFileUploader/CvFileUploader.vue +286 -0
  27. package/src/components/CvFileUploader/CvFileUploaderItem.vue +92 -0
  28. package/src/components/CvFileUploader/CvFileUploaderSkeleton.vue +16 -0
  29. package/src/components/CvFileUploader/const.js +10 -0
  30. package/src/components/CvFileUploader/index.js +5 -0
  31. package/src/components/CvForm/CvFormGroup.vue +1 -1
  32. package/src/components/CvInlineLoading/CvInlineLoading.stories.mdx +87 -0
  33. package/src/components/CvInlineLoading/CvInlineLoading.vue +144 -0
  34. package/src/components/CvInlineLoading/consts.js +9 -0
  35. package/src/components/CvInlineLoading/index.js +4 -0
  36. package/src/components/CvModal/CvModal.stories.mdx +4 -2
  37. package/src/components/CvModal/CvModal.vue +3 -5
  38. package/src/components/CvMultiSelect/CvMultiSelect.stories.mdx +333 -0
  39. package/src/components/CvMultiSelect/CvMultiSelect.vue +705 -0
  40. package/src/components/CvMultiSelect/consts.js +16 -0
  41. package/src/components/CvMultiSelect/index.js +3 -0
  42. package/src/components/CvNumberInput/CvNumberInput.stories.js +265 -0
  43. package/src/components/CvNumberInput/CvNumberInput.vue +227 -0
  44. package/src/components/CvNumberInput/CvNumberInputSkeleton.stories.js +30 -0
  45. package/src/components/CvNumberInput/CvNumberInputSkeleton.vue +10 -0
  46. package/src/components/CvNumberInput/StorybookGroupConst.js +1 -0
  47. package/src/components/CvNumberInput/__tests__/__snapshots__/CvNumberInput.spec.js.snap +21 -0
  48. package/src/components/CvNumberInput/index.js +5 -0
  49. package/src/components/CvProgress/CvProgress.stories.mdx +202 -0
  50. package/src/components/CvProgress/CvProgress.vue +78 -0
  51. package/src/components/CvProgress/CvProgressStep.vue +124 -0
  52. package/src/components/CvProgress/index.js +4 -0
  53. package/src/components/CvRadioButton/CvRadioButton.stories.js +166 -0
  54. package/src/components/CvRadioButton/CvRadioButton.vue +57 -0
  55. package/src/components/CvRadioButton/CvRadioGroup.vue +27 -0
  56. package/src/components/CvRadioButton/__tests__/__snapshots__/CvRadioButton.spec.js.snap +27 -0
  57. package/src/components/CvRadioButton/index.js +6 -0
  58. package/src/components/CvSearch/CvSearch.stories.mdx +168 -0
  59. package/src/components/CvSearch/CvSearch.vue +250 -0
  60. package/src/components/CvSearch/index.js +3 -0
  61. package/src/components/CvSelect/CvSelect.vue +27 -6
  62. package/src/components/CvSlider/CvSlider.stories.js +166 -0
  63. package/src/components/CvSlider/CvSlider.vue +324 -0
  64. package/src/components/CvSlider/CvSliderSkeleton.stories.js +26 -0
  65. package/src/components/CvSlider/CvSliderSkeleton.vue +18 -0
  66. package/src/components/CvSlider/__tests__/__snapshots__/CvSlider.spec.js.snap +13 -0
  67. package/src/components/CvSlider/__tests__/__snapshots__/CvSliderSkeleton.spec.js.snap +13 -0
  68. package/src/components/CvSlider/index.js +5 -0
  69. package/src/components/CvSlider/sbSliderPrefix.js +2 -0
  70. package/src/components/CvTabs/CvTab.vue +77 -0
  71. package/src/components/CvTabs/CvTabs.stories.mdx +175 -0
  72. package/src/components/CvTabs/CvTabs.vue +406 -0
  73. package/src/components/CvTabs/CvTabsSkeleton.vue +24 -0
  74. package/src/components/CvTabs/_SbContainer.vue +22 -0
  75. package/src/components/CvTabs/index.js +5 -0
  76. package/src/components/CvTextArea/CvTextArea.stories.js +2 -2
  77. package/src/components/CvTextArea/CvTextAreaSkeleton.stories.js +29 -0
  78. package/src/components/CvTextArea/CvTextAreaSkeleton.vue +10 -0
  79. package/src/components/CvTextArea/StorybookGroupConst.js +1 -0
  80. package/src/components/CvTextArea/__tests__/__snapshots__/CvTextAreaSkeleton.spec.js.snap +7 -0
  81. package/src/components/CvTextArea/index.js +2 -1
  82. package/src/components/CvTimePicker/CvTimePicker.stories.mdx +325 -0
  83. package/src/components/CvTimePicker/CvTimePicker.vue +217 -0
  84. package/src/components/CvTimePicker/index.js +21 -0
  85. package/src/components/CvToggle/CvToggle-Skeleton.vue +44 -0
  86. package/src/components/CvToggle/CvToggle.stories.js +249 -0
  87. package/src/components/CvToggle/CvToggle.vue +87 -0
  88. package/src/components/CvToggle/__tests__/__snapshots__/CvToggle.spec.js.snap +7 -0
  89. package/src/components/CvToggle/index.js +4 -0
  90. package/src/components/CvTooltip/CvDefinitionTooltip.stories.js +80 -0
  91. package/src/components/CvTooltip/CvDefinitionTooltip.vue +61 -0
  92. package/src/components/CvTooltip/CvInteractiveTooltip.stories.js +90 -0
  93. package/src/components/CvTooltip/CvInteractiveTooltip.vue +267 -0
  94. package/src/components/CvTooltip/CvTooltip.stories.js +128 -0
  95. package/src/components/CvTooltip/CvTooltip.vue +44 -0
  96. package/src/components/CvTooltip/__tests__/__snapshots__/CvTooltip.spec.js.snap +525 -0
  97. package/src/components/CvTooltip/consts.js +15 -0
  98. package/src/components/CvTooltip/index.js +6 -0
  99. package/src/components/CvTooltip/sbTooltipPrefix.js +2 -0
  100. package/src/components/CvUIShell/CvSideNav.vue +10 -1
  101. package/src/components/CvUIShell/CvUIShell.stories.mdx +116 -50
  102. package/src/global/storybook-utils/story-source-code.js +1 -0
  103. package/src/index.d.ts +6 -0
  104. package/src/index.js +11 -0
  105. package/src/use/cvCheck.js +3 -0
  106. package/src/use/cvInput.js +34 -0
  107. package/src/use/index.js +2 -0
  108. package/src/use/useMethods.js +18 -0
  109. package/src/use/useRadio.js +25 -0
@@ -0,0 +1,267 @@
1
+ <template>
2
+ <div class="cv-interactive-tooltip" ref="root">
3
+ <div :id="`${cvId}-label`" :class="`${carbonPrefix}--tooltip__label`">
4
+ <slot name="label"></slot>
5
+
6
+ <button
7
+ :aria-expanded="dataVisible ? 'true' : 'false'"
8
+ :aria-labelledby="`${cvId}-label`"
9
+ :class="`${carbonPrefix}--tooltip__trigger`"
10
+ :aria-controls="`${cvId}`"
11
+ aria-haspopup="true"
12
+ ref="trigger"
13
+ type="button"
14
+ @click="toggle(dataVisible)"
15
+ @keydown.tab="onTriggerTab"
16
+ @focusout="checkFocusOut"
17
+ >
18
+ <slot name="trigger">
19
+ <Information16 />
20
+ </slot>
21
+ </button>
22
+ </div>
23
+
24
+ <div
25
+ :id="cvId"
26
+ :aria-hidden="!dataVisible"
27
+ :data-floating-menu-direction="direction"
28
+ :class="[
29
+ `${carbonPrefix}--tooltip`,
30
+ {
31
+ [`${carbonPrefix}--tooltip--shown`]: dataVisible,
32
+ [`${carbonPrefix}--tooltip--${direction}`]: direction,
33
+ [`${carbonPrefix}--tooltip--align-${alignment}`]: alignment,
34
+ },
35
+ ]"
36
+ ref="popup"
37
+ role="dialog"
38
+ :aria-describedby="`${cvId}-body`"
39
+ :aria-labelledby="`${cvId}-label`"
40
+ @focusout="checkFocusOut"
41
+ :style="{ left: left + 'px', top: top + 'px' }"
42
+ tabindex="-1"
43
+ @mousedown.prevent="preventFocusOut"
44
+ >
45
+ <div
46
+ class="cv-interactive-tooltip__before-content"
47
+ ref="beforeContent"
48
+ tabindex="0"
49
+ style="position: absolute; left: -9999px; width: 1px; height: 1px"
50
+ @focus="focusBeforeContent"
51
+ />
52
+ <span :class="`${carbonPrefix}--tooltip__caret`"></span>
53
+ <div :class="`${carbonPrefix}--tooltip__content`">
54
+ <slot name="content"></slot>
55
+ </div>
56
+ <div
57
+ class="cv-interactive-tooltip__after-content"
58
+ ref="afterContent"
59
+ tabindex="0"
60
+ style="position: absolute; left: -9999px; width: 1px; height: 1px"
61
+ @focus="focusAfterContent"
62
+ />
63
+ </div>
64
+ </div>
65
+ </template>
66
+
67
+ <script setup>
68
+ import Information16 from '@carbon/icons-vue/es/information/16';
69
+ import {
70
+ ref,
71
+ computed,
72
+ watch,
73
+ onMounted,
74
+ onBeforeUnmount,
75
+ nextTick,
76
+ toRefs,
77
+ } from 'vue';
78
+ import { carbonPrefix } from '../../global/settings';
79
+ import { useCvId, props as propsCvId } from '../../use/cvId';
80
+ import { TipAlignments, alignments, TipDirections, directions } from './consts';
81
+
82
+ const props = defineProps({
83
+ alignment: {
84
+ type: String,
85
+ default: TipAlignments.center,
86
+ validator: val => alignments.includes(val),
87
+ },
88
+ direction: {
89
+ type: String,
90
+ default: TipDirections.top,
91
+ validator: val => directions.includes(val),
92
+ },
93
+ visible: {
94
+ type: Boolean,
95
+ default: false,
96
+ },
97
+ ...propsCvId,
98
+ });
99
+
100
+ const { direction, visible } = toRefs(props);
101
+ const cvId = useCvId(props);
102
+ const dataVisible = ref(false);
103
+ const left = ref(-9999); // position offscreen
104
+ const top = ref(0);
105
+ const root = ref(null);
106
+ let popupEl = ref(null);
107
+ const popup = ref(null);
108
+ const trigger = ref(null);
109
+ const beforeContent = ref(null);
110
+ const afterContent = ref(null);
111
+
112
+ const contentAfter = computed(() => {
113
+ return [TipDirections.right, TipDirections.bottom].includes(direction.value);
114
+ });
115
+
116
+ onMounted(() => {
117
+ // move popup out to body to ensure it appears above other elements
118
+ popupEl = document.body.appendChild(popup.value);
119
+ toggle(!visible.value);
120
+ });
121
+
122
+ watch(visible, newValue => {
123
+ toggle(!newValue);
124
+ });
125
+
126
+ watch(direction, () => {
127
+ if (!visible.value) return;
128
+ position();
129
+ });
130
+
131
+ function positionListen(on) {
132
+ if (on) {
133
+ window.addEventListener('scroll', position);
134
+ window.addEventListener('resize', position);
135
+ return;
136
+ }
137
+ window.removeEventListener('scroll', position);
138
+ window.removeEventListener('resize', position);
139
+ }
140
+
141
+ function position() {
142
+ const menuPosition = trigger.value.getBoundingClientRect();
143
+ const pixelsScrolledX = window.scrollX || window.pageXOffset;
144
+ const pixelsScrolledY = window.scrollY || window.pageYOffset;
145
+ const positioningMethod = [TipDirections.top, TipDirections.bottom].includes(
146
+ direction.value
147
+ )
148
+ ? positionForTopBottomDirections
149
+ : positionForLeftRightDirections;
150
+
151
+ positioningMethod({
152
+ menuPosition,
153
+ pixelsScrolledX,
154
+ pixelsScrolledY,
155
+ });
156
+ }
157
+
158
+ function positionForTopBottomDirections({
159
+ menuPosition,
160
+ pixelsScrolledX,
161
+ pixelsScrolledY,
162
+ }) {
163
+ top.value =
164
+ direction.value === TipDirections.bottom
165
+ ? menuPosition.bottom + 10 + pixelsScrolledY
166
+ : menuPosition.top - 15 - popup.value.offsetHeight + pixelsScrolledY;
167
+
168
+ left.value =
169
+ menuPosition.left +
170
+ 0.5 +
171
+ (trigger.value.offsetWidth - popup.value.offsetWidth) / 2 +
172
+ pixelsScrolledX;
173
+ }
174
+
175
+ function positionForLeftRightDirections({
176
+ menuPosition,
177
+ pixelsScrolledX,
178
+ pixelsScrolledY,
179
+ }) {
180
+ top.value =
181
+ menuPosition.top +
182
+ (trigger.value.offsetHeight - 0.5 - popup.value.offsetHeight) / 2 +
183
+ pixelsScrolledY;
184
+
185
+ left.value =
186
+ direction.value === TipDirections.left
187
+ ? menuPosition.left - 10 - popup.value.offsetWidth + pixelsScrolledX
188
+ : menuPosition.right + 15 + pixelsScrolledX;
189
+ }
190
+
191
+ async function show() {
192
+ dataVisible.value = true;
193
+ positionListen(true);
194
+
195
+ await nextTick(() => {
196
+ position();
197
+ trigger.value.focus();
198
+ });
199
+ }
200
+
201
+ function hide() {
202
+ dataVisible.value = false;
203
+ positionListen(true);
204
+ }
205
+
206
+ function toggle(isVisible) {
207
+ if (isVisible) {
208
+ hide();
209
+ return;
210
+ }
211
+ show();
212
+ }
213
+
214
+ function onTriggerTab(ev) {
215
+ if (!ev.shiftKey) {
216
+ if (contentAfter.value) {
217
+ // move focus before content before tab press
218
+ beforeContent.value.focus();
219
+ }
220
+ return;
221
+ }
222
+
223
+ if (contentAfter.value) return;
224
+ // move focus after content before tab press
225
+ afterContent.value.focus();
226
+ }
227
+
228
+ function checkFocusOut(ev) {
229
+ dataVisible.value =
230
+ ev.relatedTarget === trigger.value ||
231
+ popup.value.contains(ev.relatedTarget);
232
+ }
233
+
234
+ function focusBeforeContent(ev) {
235
+ if (contentAfter.value) {
236
+ if (popup.value.contains(ev.relatedTarget)) {
237
+ trigger.value.focus();
238
+ }
239
+ return;
240
+ }
241
+
242
+ trigger.value.focus();
243
+ dataVisible.value = contentAfter.value;
244
+ }
245
+
246
+ function focusAfterContent(ev) {
247
+ if (!contentAfter.value) {
248
+ if (popup.value.contains(ev.relatedTarget)) {
249
+ trigger.value.focus();
250
+ }
251
+ } else {
252
+ trigger.value.focus();
253
+ dataVisible.value = !contentAfter.value;
254
+ }
255
+ }
256
+
257
+ function preventFocusOut() {
258
+ // This is here to prevent focus being lost if the user clicks on the contents of the interactive tooltip
259
+ }
260
+
261
+ onBeforeUnmount(() => {
262
+ positionListen(false);
263
+ if (!popupEl.value) return;
264
+ // move back to where it came from
265
+ root.value.appendChild(popupEl.value);
266
+ });
267
+ </script>
@@ -0,0 +1,128 @@
1
+ import CvTooltip from './CvTooltip.vue';
2
+ import {
3
+ sbCompPrefix,
4
+ storyParametersObject,
5
+ } from '../../global/storybook-utils';
6
+ import { alignments, directions } from './consts';
7
+ import { sbTooltipPrefix } from './sbTooltipPrefix';
8
+
9
+ export default {
10
+ title: `${sbCompPrefix}/${sbTooltipPrefix}/CvTooltip`,
11
+ component: CvTooltip,
12
+ argTypes: {
13
+ alignment: {
14
+ control: {
15
+ type: 'select',
16
+ },
17
+ options: alignments,
18
+ defaultValue: CvTooltip.props.alignment.default,
19
+ },
20
+ direction: {
21
+ control: {
22
+ type: 'select',
23
+ },
24
+ options: directions,
25
+ defaultValue: CvTooltip.props.direction.default,
26
+ },
27
+ default: {
28
+ table: {
29
+ type: { summary: 'string | html | Component' },
30
+ category: 'slots',
31
+ },
32
+ description: 'Tooltip trigger slot.',
33
+ },
34
+ content: {
35
+ table: {
36
+ type: { summary: 'string | html | Component' },
37
+ category: 'slots',
38
+ },
39
+ description: 'Tooltip text slot',
40
+ },
41
+ },
42
+ };
43
+
44
+ const TipText = 'This is a tooltip';
45
+
46
+ const template = `<cv-tooltip v-bind="args" />`;
47
+
48
+ const Template = args => {
49
+ return {
50
+ components: { CvTooltip },
51
+ template,
52
+ setup() {
53
+ return {
54
+ args,
55
+ };
56
+ },
57
+ };
58
+ };
59
+
60
+ export const Default = Template.bind({});
61
+ Default.args = {
62
+ tip: TipText,
63
+ };
64
+ Default.parameters = storyParametersObject(
65
+ Default.parameters,
66
+ template,
67
+ Default.args
68
+ );
69
+
70
+ const triggerSlotTemplate = `
71
+ <cv-tooltip v-bind="args">
72
+ <svg width="16" height="12" viewBox="0 0 16 12">
73
+ <path d="M8.05 2a2.5 2.5 0 0 1 4.9 0H16v1h-3.05a2.5 2.5 0 0 1-4.9 0H0V2h8.05zm2.45 2a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM3.05 9a2.5 2.5 0 0 1 4.9 0H16v1H7.95a2.5 2.5 0 0 1-4.9 0H0V9h3.05zm2.45 2a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z" />
74
+ </svg>
75
+ </cv-tooltip>
76
+ `;
77
+
78
+ const TriggerSlotTemplate = args => {
79
+ return {
80
+ components: { CvTooltip },
81
+ template: triggerSlotTemplate,
82
+ setup() {
83
+ return {
84
+ args,
85
+ };
86
+ },
87
+ };
88
+ };
89
+
90
+ export const TriggerSlot = TriggerSlotTemplate.bind({});
91
+ TriggerSlot.args = {
92
+ tip: TipText,
93
+ };
94
+ TriggerSlot.parameters = storyParametersObject(
95
+ TriggerSlot.parameters,
96
+ triggerSlotTemplate,
97
+ TriggerSlot.args
98
+ );
99
+
100
+ const contentSlotTemplate = `
101
+ <cv-tooltip v-bind="args">
102
+ <template #content>
103
+ <div>
104
+ <p style="color:green;font-weight:bold;margin-bottom:5px;">Title</p>
105
+ <p>Lorem ipsum dolor</p>
106
+ </div>
107
+ </template>
108
+ </cv-tooltip>
109
+ `;
110
+
111
+ const ContentSlotTemplate = args => {
112
+ return {
113
+ components: { CvTooltip },
114
+ template: contentSlotTemplate,
115
+ setup() {
116
+ return {
117
+ args,
118
+ };
119
+ },
120
+ };
121
+ };
122
+
123
+ export const ContentSlot = ContentSlotTemplate.bind({});
124
+ ContentSlot.parameters = storyParametersObject(
125
+ ContentSlot.parameters,
126
+ contentSlotTemplate,
127
+ ContentSlot.args
128
+ );
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <button
3
+ :class="[
4
+ `cv-tooltip`,
5
+ `${carbonPrefix}--tooltip__trigger`,
6
+ `${carbonPrefix}--tooltip--a11y`,
7
+ `${carbonPrefix}--tooltip--${direction}`,
8
+ `${carbonPrefix}--tooltip--align-${alignment}`,
9
+ ]"
10
+ type="button"
11
+ >
12
+ <span :class="`${carbonPrefix}--assistive-text`">
13
+ <slot name="content">
14
+ {{ tip }}
15
+ </slot>
16
+ </span>
17
+ <slot>
18
+ <Information16 />
19
+ </slot>
20
+ </button>
21
+ </template>
22
+
23
+ <script setup>
24
+ import Information16 from '@carbon/icons-vue/es/information/16';
25
+ import { carbonPrefix } from '../../global/settings';
26
+ import { TipAlignments, alignments, TipDirections, directions } from './consts';
27
+
28
+ defineProps({
29
+ alignment: {
30
+ type: String,
31
+ default: TipAlignments.center,
32
+ validator: val => alignments.includes(val),
33
+ },
34
+ direction: {
35
+ type: String,
36
+ default: TipDirections.top,
37
+ validator: val => directions.includes(val),
38
+ },
39
+ tip: {
40
+ type: String,
41
+ default: '',
42
+ },
43
+ });
44
+ </script>