@carbon/vue 3.0.7-alpha.0 → 3.0.9-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 (91) hide show
  1. package/README.md +7 -0
  2. package/dist/carbon-vue-3.common.js +3850 -217
  3. package/dist/carbon-vue-3.common.js.map +1 -1
  4. package/dist/carbon-vue-3.umd.js +3850 -217
  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 +7 -4
  9. package/src/components/CvCheckbox/CvCheckbox.stories.js +18 -7
  10. package/src/components/CvCheckbox/CvCheckbox.vue +19 -3
  11. package/src/components/CvCheckbox/CvCheckboxSkeleton.vue +16 -0
  12. package/src/components/CvCheckbox/__tests__/__snapshots__/CvCheckboxSkeleton.spec.js.snap +3 -0
  13. package/src/components/CvCheckbox/index.js +2 -1
  14. package/src/components/CvDropdown/CvDropdown.vue +0 -2
  15. package/src/components/CvFileUploader/CvFileUploader.stories.mdx +333 -0
  16. package/src/components/CvFileUploader/CvFileUploader.vue +286 -0
  17. package/src/components/CvFileUploader/CvFileUploaderItem.vue +92 -0
  18. package/src/components/CvFileUploader/CvFileUploaderSkeleton.vue +16 -0
  19. package/src/components/CvFileUploader/const.js +10 -0
  20. package/src/components/CvFileUploader/index.js +5 -0
  21. package/src/components/CvMultiSelect/CvMultiSelect.stories.mdx +1 -1
  22. package/src/components/CvNotification/CvToastNotification.stories.js +71 -1
  23. package/src/components/CvNotification/CvToastNotification.vue +6 -4
  24. package/src/components/CvOverflowMenu/CvOverflowMenu.stories.mdx +68 -12
  25. package/src/components/CvOverflowMenu/CvOverflowMenu.vue +39 -45
  26. package/src/components/CvOverflowMenu/CvOverflowMenuItem.vue +6 -11
  27. package/src/components/CvOverflowMenu/index.js +2 -1
  28. package/src/components/CvProgress/CvProgress.stories.mdx +202 -0
  29. package/src/components/CvProgress/CvProgress.vue +78 -0
  30. package/src/components/CvProgress/CvProgressStep.vue +124 -0
  31. package/src/components/CvProgress/index.js +4 -0
  32. package/src/components/CvRadioButton/CvRadioButton.stories.js +166 -0
  33. package/src/components/CvRadioButton/CvRadioButton.vue +57 -0
  34. package/src/components/CvRadioButton/CvRadioGroup.vue +27 -0
  35. package/src/components/CvRadioButton/__tests__/__snapshots__/CvRadioButton.spec.js.snap +27 -0
  36. package/src/components/CvRadioButton/index.js +6 -0
  37. package/src/components/CvSearch/CvSearch.stories.mdx +168 -0
  38. package/src/components/CvSearch/CvSearch.vue +250 -0
  39. package/src/components/CvSearch/index.js +3 -0
  40. package/src/components/CvSelect/CvSelect.vue +27 -6
  41. package/src/components/CvSlider/CvSlider.stories.js +166 -0
  42. package/src/components/CvSlider/CvSlider.vue +324 -0
  43. package/src/components/CvSlider/CvSliderSkeleton.stories.js +26 -0
  44. package/src/components/CvSlider/CvSliderSkeleton.vue +18 -0
  45. package/src/components/CvSlider/__tests__/__snapshots__/CvSlider.spec.js.snap +13 -0
  46. package/src/components/CvSlider/__tests__/__snapshots__/CvSliderSkeleton.spec.js.snap +13 -0
  47. package/src/components/CvSlider/index.js +5 -0
  48. package/src/components/CvSlider/sbSliderPrefix.js +2 -0
  49. package/src/components/CvStructuredList/CvStructuredList.stories.js +141 -0
  50. package/src/components/CvStructuredList/CvStructuredList.vue +44 -0
  51. package/src/components/CvStructuredList/CvStructuredListData.vue +19 -0
  52. package/src/components/CvStructuredList/CvStructuredListHeading.vue +11 -0
  53. package/src/components/CvStructuredList/CvStructuredListItem.vue +47 -0
  54. package/src/components/CvStructuredList/CvStructuredListItemSelectable.vue +56 -0
  55. package/src/components/CvStructuredList/CvStructuredListItemStandard.vue +11 -0
  56. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredList.spec.js.snap +73 -0
  57. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListData.spec.js.snap +5 -0
  58. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListHeading.spec.js.snap +9 -0
  59. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListItem.spec.js.snap +7 -0
  60. package/src/components/CvStructuredList/index.js +12 -0
  61. package/src/components/CvTextArea/CvTextArea.stories.js +2 -2
  62. package/src/components/CvTextArea/CvTextAreaSkeleton.stories.js +29 -0
  63. package/src/components/CvTextArea/CvTextAreaSkeleton.vue +10 -0
  64. package/src/components/CvTextArea/StorybookGroupConst.js +1 -0
  65. package/src/components/CvTextArea/__tests__/__snapshots__/CvTextAreaSkeleton.spec.js.snap +7 -0
  66. package/src/components/CvTextArea/index.js +2 -1
  67. package/src/components/CvTimePicker/CvTimePicker.stories.mdx +325 -0
  68. package/src/components/CvTimePicker/CvTimePicker.vue +217 -0
  69. package/src/components/CvTimePicker/index.js +21 -0
  70. package/src/components/CvToggle/CvToggle-Skeleton.vue +27 -12
  71. package/src/components/CvToggle/CvToggle.stories.js +20 -3
  72. package/src/components/CvToggle/CvToggle.vue +22 -5
  73. package/src/components/CvToggle/__tests__/__snapshots__/CvToggle.spec.js.snap +3 -3
  74. package/src/components/CvTooltip/CvDefinitionTooltip.stories.js +80 -0
  75. package/src/components/CvTooltip/CvDefinitionTooltip.vue +61 -0
  76. package/src/components/CvTooltip/CvInteractiveTooltip.stories.js +90 -0
  77. package/src/components/CvTooltip/CvInteractiveTooltip.vue +267 -0
  78. package/src/components/CvTooltip/CvTooltip.stories.js +128 -0
  79. package/src/components/CvTooltip/CvTooltip.vue +44 -0
  80. package/src/components/CvTooltip/__tests__/__snapshots__/CvTooltip.spec.js.snap +525 -0
  81. package/src/components/CvTooltip/consts.js +15 -0
  82. package/src/components/CvTooltip/index.js +6 -0
  83. package/src/components/CvTooltip/sbTooltipPrefix.js +2 -0
  84. package/src/components/CvUIShell/CvSideNav.vue +10 -1
  85. package/src/components/CvUIShell/CvUIShell.stories.mdx +116 -50
  86. package/src/index.d.ts +6 -0
  87. package/src/index.js +11 -0
  88. package/src/use/cvCheck.js +3 -0
  89. package/src/use/index.js +2 -0
  90. package/src/use/useMethods.js +18 -0
  91. package/src/use/useRadio.js +24 -0
@@ -38,40 +38,42 @@
38
38
  />
39
39
  </slot>
40
40
  </button>
41
- <div
42
- :class="[
43
- `${carbonPrefix}--overflow-menu-options`,
44
- {
45
- [`${carbonPrefix}--overflow-menu--flip`]: flipMenu,
46
- [`${carbonPrefix}--overflow-menu-options--open`]: open,
47
- },
48
- ]"
49
- tabindex="-1"
50
- ref="popup"
51
- :aria-labelledby="`${uid}-trigger`"
52
- :id="`${uid}-menu`"
53
- :style="{ left: left + 'px', top: top + 'px' }"
54
- @focusout="checkFocusOut"
55
- @mousedown.prevent="preventFocusOut"
56
- >
41
+ <Teleport to="body">
57
42
  <div
58
- class="cv-overflow-menu__before-content"
59
- ref="beforeContent"
60
- tabindex="0"
61
- style="position: absolute; height: 1px; width: 1px; left: -9999px"
62
- @focus="focusBeforeContent"
63
- />
64
- <ul :class="`${carbonPrefix}--overflow-menu-options__content`">
65
- <slot></slot>
66
- </ul>
67
- <div
68
- class="cv-overflow-menu__after-content"
69
- ref="afterContent"
70
- tabindex="0"
71
- style="position: absolute; height: 1px; width: 1px; left: -9999px"
72
- @focus="focusAfterContent"
73
- />
74
- </div>
43
+ :class="[
44
+ `${carbonPrefix}--overflow-menu-options`,
45
+ {
46
+ [`${carbonPrefix}--overflow-menu--flip`]: flipMenu,
47
+ [`${carbonPrefix}--overflow-menu-options--open`]: open,
48
+ },
49
+ ]"
50
+ tabindex="-1"
51
+ ref="popup"
52
+ :aria-labelledby="`${uid}-trigger`"
53
+ :id="`${uid}-menu`"
54
+ :style="{ left: left + 'px', top: top + 'px' }"
55
+ @focusout="checkFocusOut"
56
+ @mousedown.prevent="preventFocusOut"
57
+ >
58
+ <div
59
+ class="cv-overflow-menu__before-content"
60
+ ref="beforeContent"
61
+ tabindex="0"
62
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
63
+ @focus="focusBeforeContent"
64
+ />
65
+ <ul :class="`${carbonPrefix}--overflow-menu-options__content`">
66
+ <slot></slot>
67
+ </ul>
68
+ <div
69
+ class="cv-overflow-menu__after-content"
70
+ ref="afterContent"
71
+ tabindex="0"
72
+ style="position: absolute; height: 1px; width: 1px; left: -9999px"
73
+ @focus="focusAfterContent"
74
+ />
75
+ </div>
76
+ </Teleport>
75
77
  </div>
76
78
  </template>
77
79
 
@@ -79,8 +81,7 @@
79
81
  import { carbonPrefix } from '../../global/settings';
80
82
  import { props as propsCvId, useCvId } from '../../use/cvId';
81
83
  import OverflowMenuVertical16 from '@carbon/icons-vue/es/overflow-menu--vertical/16';
82
- import { computed, nextTick, onBeforeMount, onUnmounted, ref } from 'vue';
83
- import { getBus, removeBus } from '../../global/component-utils/event-bus';
84
+ import { computed, nextTick, provide, ref } from 'vue';
84
85
  const props = defineProps({
85
86
  /**
86
87
  * assistive text shown as a tooltip
@@ -135,15 +136,8 @@ const offsetTop = computed(() => {
135
136
  return props.offset ? props.offset.top : 0;
136
137
  });
137
138
 
138
- let bus = undefined;
139
- onBeforeMount(() => {
140
- bus = getBus(uid.value);
141
- bus.on('cv:close', doClose);
142
- bus.on('cv:click', menuItemClick);
143
- });
144
- onUnmounted(() => {
145
- removeBus(uid.value);
146
- });
139
+ provide('cv:close', doClose);
140
+ provide('cv:click', menuItemClick);
147
141
 
148
142
  const trigger = ref(null);
149
143
  const popup = ref(null);
@@ -216,7 +210,7 @@ async function positionMenu() {
216
210
  popup.value.offsetHeight +
217
211
  pixelsScrolledY;
218
212
  } else {
219
- top.value = menuPosition.left + offsetLeft.value + pixelsScrolledX;
213
+ top.value = menuPosition.bottom + offsetTop.value + pixelsScrolledY;
220
214
  }
221
215
  });
222
216
  }
@@ -26,27 +26,22 @@
26
26
 
27
27
  <script setup>
28
28
  import { carbonPrefix } from '../../global/settings';
29
- import { onMounted, ref, useAttrs } from 'vue';
30
- import { getBus } from '../../global/component-utils/event-bus';
29
+ import { ref, useAttrs, inject } from 'vue';
31
30
 
32
31
  defineProps({
33
32
  primaryFocus: Boolean,
34
33
  disabled: Boolean,
35
34
  danger: Boolean,
36
35
  });
37
- let bus = undefined;
38
36
  const el = ref(null);
39
- onMounted(() => {
40
- const pe = el.value.closest('[data-overflow-menu]');
41
- const parent = pe?.getAttribute('id');
42
- if (parent) bus = getBus(parent);
43
- else console.warn('overflow menu not found');
44
- });
37
+ const emitClick = inject('cv:click');
38
+ const emitClose = inject('cv:close');
39
+
45
40
  const attrs = useAttrs();
46
41
  function onClick() {
47
- bus?.emit('cv:click', attrs.value);
42
+ emitClick(attrs.value);
48
43
  }
49
44
  function onEsc() {
50
- bus?.emit('cv:close');
45
+ emitClose();
51
46
  }
52
47
  </script>
@@ -1,3 +1,4 @@
1
1
  import CvOverflowMenu from './CvOverflowMenu.vue';
2
- export { CvOverflowMenu };
2
+ import CvOverflowMenuItem from './CvOverflowMenuItem.vue';
3
+ export { CvOverflowMenu, CvOverflowMenuItem };
3
4
  export default CvOverflowMenu;
@@ -0,0 +1,202 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs';
2
+ import { CvProgress, CvProgressStep } from '.';
3
+ import { Time20 as TimeIcon } from '@carbon/icons-vue';
4
+ // noinspection ES6PreferShortImport
5
+ import { sbCompPrefix } from '../../global/storybook-utils';
6
+ import { action } from '@storybook/addon-actions';
7
+
8
+ <Meta title={`${sbCompPrefix}/CvProgress`} component={CvProgress} />
9
+
10
+ export const Template = args => ({
11
+ // Components used in your story `template` are defined in the `components` object
12
+ components: {
13
+ CvProgress,
14
+ CvProgressStep,
15
+ TimeIcon,
16
+ },
17
+ // The story's `args` need to be mapped into the template through the `setup()` method
18
+ setup() {
19
+ return {
20
+ initialStep: args.initialStep,
21
+ steps: args.steps,
22
+ vertical: args.vertical,
23
+ spaceEqually: args.spaceEqually,
24
+ step1: args.step1,
25
+ step2: args.step2,
26
+ step3: args.step3,
27
+ step4: args.step4,
28
+ step5: args.step5,
29
+ completeIds: args.completeIds,
30
+ invalidIds: args.invalidIds,
31
+ disabledIds: args.disabledIds,
32
+ onStepClicked: action('step-clicked'),
33
+ };
34
+ },
35
+ // And then the `args` are bound to your component with `v-bind="args"`
36
+ template: args.template,
37
+ });
38
+ const defaultTemplate = `
39
+ <cv-progress
40
+ :initial-step="initialStep"
41
+ :steps="steps"
42
+ :vertical="vertical"
43
+ :space-equally="spaceEqually"
44
+ @step-clicked="onStepClicked">
45
+ </cv-progress>
46
+ `;
47
+ const slotTemplate = `
48
+ <cv-progress
49
+ :initial-step="initialStep"
50
+ :vertical="vertical"
51
+ :spaceEqually="spaceEqually"
52
+ >
53
+ <cv-progress-step
54
+ id="step-1"
55
+ :label="step1"
56
+ :complete="completeIds.includes('step-1')"
57
+ :invalid="invalidIds.includes('step-1')"
58
+ :disabled="disabledIds.includes('step-1')"
59
+ additionalInfo="with Meg Murry"
60
+ description="time icon description"
61
+ @step-clicked="onStepClicked"
62
+ >
63
+ <template v-slot:step-icon>
64
+ <time-icon :class="[{['bx--progress__warning']:invalidIds.includes('step-1')}]"/>
65
+ </template>
66
+ </cv-progress-step>
67
+ <cv-progress-step
68
+ id="step-2"
69
+ :label="step2"
70
+ :complete="completeIds.includes('step-2')"
71
+ :invalid="invalidIds.includes('step-2')"
72
+ :disabled="disabledIds.includes('step-2')"
73
+ additionalInfo="save Charles Wallace"
74
+ @step-clicked="onStepClicked"
75
+ >
76
+ </cv-progress-step>
77
+ <cv-progress-step
78
+ id="step-3"
79
+ :label="step3"
80
+ :complete="completeIds.includes('step-3')"
81
+ :invalid="invalidIds.includes('step-3')"
82
+ :disabled="disabledIds.includes('step-3')"
83
+ additionalInfo="save the world"
84
+ @step-clicked="onStepClicked"
85
+ >
86
+ </cv-progress-step>
87
+ <cv-progress-step
88
+ id="step-4"
89
+ :label="step4"
90
+ :complete="completeIds.includes('step-4')"
91
+ :invalid="invalidIds.includes('step-4')"
92
+ :disabled="disabledIds.includes('step-4')"
93
+ additionalInfo="Twins Dennys and Sandy"
94
+ @step-clicked="onStepClicked"
95
+ >
96
+ </cv-progress-step>
97
+ <cv-progress-step
98
+ id="step-5"
99
+ :label="step5"
100
+ :complete="completeIds.includes('step-5')"
101
+ :invalid="invalidIds.includes('step-5')"
102
+ :disabled="disabledIds.includes('step-5')"
103
+ additionalInfo="with Polyhymnia O'Keefe"
104
+ @step-clicked="onStepClicked"
105
+ >
106
+ </cv-progress-step>
107
+ </cv-progress>
108
+ `;
109
+
110
+ # CvProgress
111
+
112
+ **Migration notes:**
113
+
114
+ - The "current" icon is updated to match Carbon React
115
+ - Added the property `spaceEqually` to match Carbon React
116
+ - The property name `initialStep` is misleading. It is treated as the Current progress (currentIndex).
117
+ - To override the default icons, provide an icon in the `step-icon` slot in the `cv-progress-step`
118
+
119
+ <Canvas>
120
+ <Story
121
+ name="Default"
122
+ parameters={{
123
+ controls: {
124
+ exclude: ['default', 'template', 'step-clicked'],
125
+ },
126
+ docs: { source: { code: defaultTemplate } },
127
+ }}
128
+ args={{
129
+ template: defaultTemplate,
130
+ steps: [
131
+ 'Planet Uriel',
132
+ 'The Happy Medium',
133
+ 'The Black Thing',
134
+ 'Rescue Dr. Murry',
135
+ 'Rescue Charles Wallace',
136
+ 'Back to Earth',
137
+ ],
138
+ }}
139
+ argTypes={{
140
+ initialStep: {
141
+ control: {
142
+ type: 'number',
143
+ min: -1,
144
+ max: 6,
145
+ },
146
+ },
147
+ }}
148
+ >
149
+ {Template.bind({})}
150
+ </Story>
151
+ </Canvas>
152
+
153
+ # Slotted
154
+
155
+ Use `cv-progress-step` for more control over the display.
156
+
157
+ <Canvas>
158
+ <Story
159
+ name="slotted"
160
+ parameters={{
161
+ controls: {
162
+ exclude: ['default', 'template', 'step-clicked', 'steps'],
163
+ },
164
+ docs: { source: { code: slotTemplate } },
165
+ }}
166
+ args={{
167
+ template: slotTemplate,
168
+ step1: 'A Wrinkle in Time',
169
+ step2: 'A Wind in the Door',
170
+ step3: 'A Swiftly Tilting Planet',
171
+ step4: 'Many Waters',
172
+ step5: 'An Acceptable Time',
173
+ vertical: true,
174
+ completeIds: [],
175
+ invalidIds: [],
176
+ disabledIds: [],
177
+ }}
178
+ argTypes={{
179
+ initialStep: {
180
+ control: {
181
+ type: 'number',
182
+ min: -1,
183
+ max: 6,
184
+ },
185
+ },
186
+ disabledIds: {
187
+ control: 'multi-select',
188
+ options: ['step-1', 'step-2', 'step-3', 'step-4', 'step-5'],
189
+ },
190
+ completeIds: {
191
+ control: 'multi-select',
192
+ options: ['step-1', 'step-2', 'step-3', 'step-4', 'step-5'],
193
+ },
194
+ invalidIds: {
195
+ control: 'multi-select',
196
+ options: ['step-1', 'step-2', 'step-3', 'step-4', 'step-5'],
197
+ },
198
+ }}
199
+ >
200
+ {Template.bind({})}
201
+ </Story>
202
+ </Canvas>
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <ul
3
+ data-progress
4
+ data-progress-current
5
+ :class="[
6
+ `cv-progress ${carbonPrefix}--progress`,
7
+ { [`${carbonPrefix}--progress--space-equal`]: isEqual },
8
+ { [`${carbonPrefix}--progress--vertical`]: vertical },
9
+ ]"
10
+ >
11
+ <slot>
12
+ <cv-progress-step
13
+ v-for="(step, index) in steps"
14
+ :key="`step:${index}:${initialStep > index}`"
15
+ :label="step"
16
+ :complete="initialStep > index"
17
+ @step-clicked="emit('step-clicked', { ...$event, index })"
18
+ />
19
+ </slot>
20
+ </ul>
21
+ </template>
22
+
23
+ <script setup>
24
+ // noinspection ES6PreferShortImport
25
+ import { carbonPrefix } from '../../global/settings';
26
+ import CvProgressStep from './CvProgressStep.vue';
27
+ import { computed, onMounted, provide, ref, watch } from 'vue';
28
+
29
+ const props = defineProps({
30
+ /**
31
+ * Optionally specify the current step array index
32
+ */
33
+ initialStep: { type: Number, default: 0 },
34
+ /**
35
+ * An array of labels for the steps. Use `cv-progress-step` components for more control over the step logic.
36
+ */
37
+ steps: Array,
38
+ /**
39
+ * Determines whether the ProgressIndicator should be rendered vertically.
40
+ */
41
+ vertical: { type: Boolean, default: false },
42
+ /**
43
+ * Specify whether the progress steps should be split equally in size in the div
44
+ */
45
+ spaceEqually: { type: Boolean, default: false },
46
+ });
47
+ const emit = defineEmits(['step-clicked']);
48
+
49
+ const isEqual = computed(() => props.spaceEqually && !props.vertical);
50
+ provide('progress-space-equally', isEqual);
51
+ const completedSteps = ref(new Set());
52
+ provide('progress-completed-steps', completedSteps);
53
+
54
+ /**
55
+ * @typedef ProgressStepData
56
+ * @type {string} uid
57
+ * @type {string} label
58
+ */
59
+ /**
60
+ * @type {Ref<UnwrapRef<Array<ProgressStepData>>>}
61
+ */
62
+ const progressSteps = ref([]);
63
+ provide('progress-steps', progressSteps);
64
+
65
+ const currentStep = ref('');
66
+ provide('progress-current-step', currentStep);
67
+ function updateSteps() {
68
+ if (
69
+ props.initialStep > -1 &&
70
+ props.initialStep < progressSteps.value.length
71
+ ) {
72
+ const step = progressSteps.value[props.initialStep];
73
+ currentStep.value = step.uid;
74
+ } else currentStep.value = '';
75
+ }
76
+ onMounted(updateSteps);
77
+ watch(() => props.initialStep, updateSteps);
78
+ </script>
@@ -0,0 +1,124 @@
1
+ <!--suppress HtmlUnknownTag -->
2
+ <template>
3
+ <li
4
+ :class="[
5
+ `cv-progress-step ${carbonPrefix}--progress-step`,
6
+ `${carbonPrefix}--progress-step--${internalState}`,
7
+ ]"
8
+ :id="uid"
9
+ :aria-disabled="disabled"
10
+ >
11
+ <button
12
+ type="button"
13
+ :class="[
14
+ `${carbonPrefix}--progress-step-button`,
15
+ { [`${carbonPrefix}--progress-step-button--unclickable`]: isCurrent },
16
+ ]"
17
+ tabindex="-1"
18
+ :title="label"
19
+ @click.prevent="emit('step-clicked', { uid })"
20
+ >
21
+ <span v-if="isCurrent" :class="`${carbonPrefix}--assistive-text`"
22
+ >Current</span
23
+ >
24
+ <slot name="step-icon">
25
+ <component :is="stepIcon" :class="stepClass">
26
+ <title>{{ description }}</title>
27
+ </component>
28
+ </slot>
29
+ <div
30
+ :class="`${carbonPrefix}--progress-text`"
31
+ :style="{ maxWidth: isEqual ? 'calc(100% - 1rem)' : undefined }"
32
+ >
33
+ <!-- todo: add tooltip when tooltip is implemented -->
34
+ <!-- <cv-tooltip v-if="tipText" ... v-else -->
35
+ <div :class="[`${carbonPrefix}--progress-label`]">
36
+ {{ label }}
37
+ </div>
38
+ <p v-if="additionalInfo" class="bx--progress-optional">
39
+ {{ additionalInfo }}
40
+ </p>
41
+ </div>
42
+ <span :class="`${carbonPrefix}--progress-line`"></span>
43
+ </button>
44
+ </li>
45
+ </template>
46
+
47
+ <script setup>
48
+ import {
49
+ Incomplete16,
50
+ CheckmarkOutline16,
51
+ Warning16,
52
+ CircleDash16,
53
+ } from '@carbon/icons-vue';
54
+ // noinspection ES6PreferShortImport
55
+ import { carbonPrefix } from '../../global/settings';
56
+ import { useCvId, props as propsCvId } from '../../use/cvId';
57
+ import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';
58
+
59
+ const STEP_CURRENT = 'current';
60
+ const STEP_COMPLETE = 'complete';
61
+ const STEP_INCOMPLETE = 'incomplete';
62
+ const STEP_DISABLED = 'disabled';
63
+
64
+ const props = defineProps({
65
+ additionalInfo: String,
66
+ description: String,
67
+ disabled: Boolean,
68
+ invalid: Boolean,
69
+ label: String,
70
+ tipText: String,
71
+ complete: Boolean,
72
+ ...propsCvId,
73
+ });
74
+ const uid = useCvId(props, true);
75
+ const isEqual = inject('progress-space-equally');
76
+
77
+ const emit = defineEmits(['step-clicked']);
78
+
79
+ const internalState = ref(STEP_INCOMPLETE);
80
+ /**
81
+ * @type {Ref<UnwrapRef<string>>}
82
+ */
83
+ const currentStep = inject('progress-current-step');
84
+ const isCurrent = computed(() => {
85
+ return uid.value === currentStep.value;
86
+ });
87
+ /**
88
+ * @type {Ref<UnwrapRef<Array<ProgressStepData>>>}
89
+ */
90
+ const progressSteps = inject('progress-steps');
91
+ /**
92
+ * @type {Ref<UnwrapRef<Set<string>>>}
93
+ */
94
+ const completedSteps = inject('progress-completed-steps');
95
+ function checkCurrentStep() {
96
+ if (props.disabled) internalState.value = STEP_DISABLED;
97
+ else if (isCurrent.value) internalState.value = STEP_CURRENT;
98
+ else if (props.complete) internalState.value = STEP_COMPLETE;
99
+ else internalState.value = STEP_INCOMPLETE;
100
+
101
+ const stepData = { uid: uid.value, state: internalState.value };
102
+ const index = progressSteps.value.findIndex(step => step.uid === uid.value);
103
+ if (index > -1) progressSteps.value.splice(index, 1, stepData);
104
+ else progressSteps.value.push(stepData);
105
+ }
106
+ onMounted(checkCurrentStep);
107
+ watch(currentStep, checkCurrentStep);
108
+ watch(completedSteps, checkCurrentStep);
109
+
110
+ onBeforeUnmount(() => {
111
+ const index = progressSteps.value.findIndex(step => step.uid === uid.value);
112
+ if (index > -1) progressSteps.value.splice(index, 1);
113
+ });
114
+ const stepClass = computed(() => {
115
+ return props.invalid ? `${carbonPrefix}--progress__warning` : '';
116
+ });
117
+
118
+ const stepIcon = computed(() => {
119
+ if (props.invalid) return Warning16;
120
+ else if (internalState.value === STEP_CURRENT) return Incomplete16;
121
+ else if (internalState.value === STEP_COMPLETE) return CheckmarkOutline16;
122
+ else return CircleDash16;
123
+ });
124
+ </script>
@@ -0,0 +1,4 @@
1
+ import CvProgress from './CvProgress.vue';
2
+ import CvProgressStep from './CvProgressStep.vue';
3
+
4
+ export { CvProgress, CvProgressStep };