@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,416 @@
1
+ <!--
2
+ Carbon Style Dropdown
3
+
4
+ Attributes:
5
+ placeholder: Placeholder text displayed before any selection is made.
6
+
7
+ Usage:
8
+ <cv-dropdown placeholder="Choose an option">
9
+ <cv-dropdown-item value="10">Option 1</cv-dropdown-item>
10
+ <cv-dropdown-item value="20">Option 2</cv-dropdown-item>
11
+ <cv-dropdown-item value="30">Option 3</cv-dropdown-item>
12
+ <cv-dropdown-item value="40">Option 4</cv-dropdown-item>
13
+ <cv-dropdown-item value="50">Option 5</cv-dropdown-item>
14
+ </cv-dropdown>
15
+
16
+ -->
17
+
18
+ <template>
19
+ <div :id="uid" ref="el" :class="{ [`${carbonPrefix}--form-item`]: formItem }">
20
+ <div
21
+ :class="[
22
+ `${carbonPrefix}--dropdown__wrapper`,
23
+ `${carbonPrefix}--list-box__wrapper`,
24
+ {
25
+ [`${carbonPrefix}--dropdown__wrapper--inline`]: inline,
26
+ [`${carbonPrefix}--list-box__wrapper--inline`]: inline,
27
+ 'cv-dropdown': !formItem,
28
+ },
29
+ ]"
30
+ :style="wrapperStyleOverride"
31
+ >
32
+ <label
33
+ v-if="label"
34
+ :id="`${uid}-label`"
35
+ :class="[
36
+ `${carbonPrefix}--label`,
37
+ { [`${carbonPrefix}--label--disabled`]: disabled },
38
+ ]"
39
+ >{{ label }}</label
40
+ >
41
+
42
+ <div
43
+ ref="listBox"
44
+ :aria-label="ariaLabel"
45
+ :class="[
46
+ `${carbonPrefix}--dropdown`,
47
+ `${carbonPrefix}--dropdown--${size}`,
48
+ {
49
+ [`${carbonPrefix}--dropdown--show-selected`]: !hideSelected,
50
+ [`${carbonPrefix}--dropdown--warning`]: isWarning,
51
+ [`${carbonPrefix}--list-box--warning`]: isWarning,
52
+ [`${carbonPrefix}--dropdown--invalid`]: data.isInvalid,
53
+ [`${carbonPrefix}--list-box`]: true,
54
+ [`${carbonPrefix}--dropdown--light`]: isLight,
55
+ [`${carbonPrefix}--list-box--up`]: up,
56
+ [`${carbonPrefix}--dropdown--open`]: open,
57
+ [`${carbonPrefix}--list-box--expanded`]: open,
58
+ [`${carbonPrefix}--dropdown--disabled`]: disabled,
59
+ [`${carbonPrefix}--dropdown--inline`]: inline,
60
+ },
61
+ ]"
62
+ :data-invalid="data.isInvalid"
63
+ :data-value="dataValue"
64
+ data-dropdown
65
+ v-bind="$attrs"
66
+ @click="onClick"
67
+ @keydown.down.prevent="onDown"
68
+ @keydown.up.prevent="onUp"
69
+ @keydown.enter.prevent="onClick"
70
+ @keydown.esc.prevent="onEsc"
71
+ @keydown.tab="onTab"
72
+ >
73
+ <button
74
+ ref="button"
75
+ :aria-controls="`${uid}-menu`"
76
+ :aria-disabled="disabled"
77
+ :aria-expanded="open ? 'true' : 'false'"
78
+ :aria-labelledby="ariaLabeledBy"
79
+ :class="`${carbonPrefix}--list-box__field`"
80
+ :disabled="disabled"
81
+ aria-haspopup="true"
82
+ type="button"
83
+ >
84
+ <warning-alt-filled
85
+ v-if="isWarning"
86
+ :class="`${carbonPrefix}--list-box__invalid-icon ${carbonPrefix}--list-box__invalid-icon--warning`"
87
+ />
88
+ <warning-filled
89
+ v-else-if="data.isInvalid"
90
+ :class="`${carbonPrefix}--list-box__invalid-icon`"
91
+ />
92
+ <span
93
+ :id="`${uid}-value`"
94
+ :class="`${carbonPrefix}--list-box__label`"
95
+ data-test="internalCaption"
96
+ >
97
+ <slot name="internal-caption">{{ internalCaption }}</slot>
98
+ </span>
99
+ <div
100
+ :class="[
101
+ `${carbonPrefix}--list-box__menu-icon`,
102
+ { [`${carbonPrefix}--list-box__menu-icon--open`]: open },
103
+ ]"
104
+ >
105
+ <chevron-down :aria-label="open ? 'Close menu' : 'Open menu'" />
106
+ </div>
107
+ </button>
108
+ <ul
109
+ :id="`${uid}-menu`"
110
+ ref="dropList"
111
+ :aria-hidden="!open ? 'true' : 'false'"
112
+ :aria-labelledby="`${uid}-label`"
113
+ :class="`${carbonPrefix}--list-box__menu`"
114
+ role="menu"
115
+ tabindex="-1"
116
+ >
117
+ <slot>
118
+ <cv-dropdown-item
119
+ v-for="item in items"
120
+ v-bind:key="item"
121
+ :value="item"
122
+ >{{ item }}</cv-dropdown-item
123
+ >
124
+ </slot>
125
+ </ul>
126
+ </div>
127
+ <div v-if="data.isInvalid" :class="`${carbonPrefix}--form-requirement`">
128
+ <slot name="invalid-message">{{ invalidMessage }}</slot>
129
+ </div>
130
+ <div v-else-if="isWarning" :class="`${carbonPrefix}--form-requirement`">
131
+ <slot name="warning-message">{{ warningMessage }}</slot>
132
+ </div>
133
+ <div
134
+ v-else-if="data.isHelper"
135
+ :aria-disabled="disabled"
136
+ :class="[
137
+ `${carbonPrefix}--form__helper-text`,
138
+ { [`${carbonPrefix}--form__helper-text--disabled`]: disabled },
139
+ ]"
140
+ >
141
+ <slot name="helper-text">{{ helperText }}</slot>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </template>
146
+
147
+ <script setup>
148
+ import { carbonPrefix } from '../../global/settings';
149
+ import { props as propsCvId, useCvId } from '../../use/cvId';
150
+ import { props as propsCvTheme, useIsLight } from '../../use/cvTheme';
151
+ import CvDropdownItem from './CvDropdownItem.vue';
152
+ import ChevronDown from '@carbon/icons-vue/es/chevron--down/16';
153
+ import WarningFilled from '@carbon/icons-vue/es/warning--filled/16';
154
+ import WarningAltFilled from '@carbon/icons-vue/es/warning--alt--filled/16';
155
+ import {
156
+ computed,
157
+ nextTick,
158
+ onMounted,
159
+ onUpdated,
160
+ provide,
161
+ reactive,
162
+ ref,
163
+ useSlots,
164
+ watch,
165
+ } from 'vue';
166
+ import { onClickOutside } from '@vueuse/core';
167
+
168
+ const props = defineProps({
169
+ /**
170
+ * 'aria-label' of the ListBox component.
171
+ */
172
+ ariaLabel: { type: String, default: 'Dropdown' },
173
+ /**
174
+ * Disable the control
175
+ */
176
+ disabled: { type: Boolean, default: false },
177
+ /**
178
+ * Add carbon form classes to the dropdown list
179
+ */
180
+ formItem: { type: Boolean, default: true },
181
+ /**
182
+ * Provide helper text that is used alongside the control label for additional help
183
+ */
184
+ helperText: { type: String, default: undefined },
185
+ /**
186
+ * Not documented in react. Removes `dropdown--show-selected` class from component.
187
+ */
188
+ hideSelected: { type: Boolean, default: false },
189
+ /**
190
+ * Specify whether you want the inline version of this control
191
+ */
192
+ inline: { type: Boolean, default: false },
193
+ /**
194
+ * Message which is displayed if the value is invalid.
195
+ */
196
+ invalidMessage: { type: String, default: undefined },
197
+ /**
198
+ * an array of strings to display as choices.
199
+ */
200
+ items: {
201
+ type: Array,
202
+ validator(arr) {
203
+ if (!Array.isArray(arr)) {
204
+ console.warn('CvDropdown - items must be in array');
205
+ }
206
+ return arr;
207
+ },
208
+ },
209
+ /**
210
+ * Generic label that will be used as the textual representation of what this field is for
211
+ */
212
+ label: String,
213
+ /**
214
+ * Value shown when nothing has been selected
215
+ */
216
+ placeholder: {
217
+ type: String,
218
+ default: 'Choose an option',
219
+ },
220
+ /**
221
+ * Specify the size of the ListBox. Currently, supports either `sm`, `md` or `lg` as an option.
222
+ * @values sm,md,lg
223
+ */
224
+ size: {
225
+ type: String,
226
+ default: 'md',
227
+ validator: val => ['sm', 'md', 'lg'].includes(val),
228
+ },
229
+ /**
230
+ * Specify the direction of the dropdown. Can be either true (top) or (false) bottom.
231
+ */
232
+ up: { type: Boolean, default: false },
233
+ /**
234
+ * Render with a value already selected. Available as `v-model:value`.
235
+ */
236
+ value: String,
237
+ /**
238
+ * Provide the text that is displayed and put the control in warning state
239
+ */
240
+ warningMessage: { type: String, default: undefined },
241
+ /**
242
+ * @deprecated - use v-model:value
243
+ */
244
+ modelValue: {
245
+ type: String,
246
+ validator: val => {
247
+ console.warn(
248
+ `v-model for cv-dropdown is deprecated. Specify "v-model:value" instead [${val}]`
249
+ );
250
+ return true;
251
+ },
252
+ default: undefined,
253
+ },
254
+
255
+ ...propsCvId,
256
+ ...propsCvTheme,
257
+ });
258
+ const uid = useCvId(props, true);
259
+ const isLight = useIsLight(props);
260
+ const dataValue = ref(props.value);
261
+ provide('dropdown-selected', dataValue);
262
+ const focusItem = ref(undefined);
263
+ provide('dropdown-focus', focusItem);
264
+ const dataCaption = ref(undefined);
265
+ provide('dropdown-caption', dataCaption);
266
+ /**
267
+ * List of children values
268
+ * @type {Ref<UnwrapRef<[{value:string}]>>}
269
+ */
270
+ const itemsList = ref([]);
271
+ provide('dropdown-items', itemsList);
272
+ const open = ref(false);
273
+ const data = reactive({
274
+ isHelper: false,
275
+ isInvalid: undefined,
276
+ isWarning: false,
277
+ });
278
+ const slots = useSlots();
279
+ function checkSlots() {
280
+ // NOTE: slots is not reactive so needs to be managed on updated
281
+ data.isInvalid =
282
+ !!(slots['invalid-message'] || props.invalidMessage?.length) || undefined;
283
+ data.isWarning = !!(slots['warning-message'] || props.warningMessage?.length);
284
+ data.isHelper = !!(slots['helper-text'] || props.helperText?.length);
285
+ }
286
+ const isWarning = computed(() => {
287
+ if (data.isInvalid) return false;
288
+ else return !!data.isWarning;
289
+ });
290
+ onMounted(checkSlots);
291
+ onUpdated(checkSlots);
292
+ const emit = defineEmits(['update:value', 'update:modelValue', 'change']);
293
+ watch(
294
+ () => props.value,
295
+ () => {
296
+ dataValue.value = props.value;
297
+ }
298
+ );
299
+ watch(dataValue, () => {
300
+ emit('change', dataValue.value);
301
+ emit('update:value', dataValue.value);
302
+ emit('update:modelValue', dataValue.value);
303
+ });
304
+ watch(open, () => {
305
+ focusItem.value = '';
306
+ });
307
+ const ariaLabeledBy = computed(() => {
308
+ if (props.label) {
309
+ return `${uid}-label ${uid}-value`;
310
+ } else {
311
+ return `${uid}-value`;
312
+ }
313
+ });
314
+ const internalCaption = computed(() => {
315
+ if (dataCaption.value) {
316
+ return dataCaption.value;
317
+ } else {
318
+ return props.placeholder;
319
+ }
320
+ });
321
+
322
+ const wrapperStyleOverride = computed(() => {
323
+ // ensures correct width when used inside tabs component
324
+ return { width: '100%' };
325
+ });
326
+ const el = ref(null);
327
+ function onClickOut() {
328
+ open.value = false;
329
+ }
330
+ onClickOutside(el, onClickOut);
331
+
332
+ /**
333
+ * Set the focus on one of the items in the dropdown list
334
+ * @param {boolean} up - Direction to move focus
335
+ */
336
+ function doMove(up) {
337
+ // re-query could have changed
338
+ const currentFocusEl = el.value?.querySelector('.cv-dropdown-item :focus');
339
+ const numChildren = itemsList.value.length || 0;
340
+
341
+ const currentFocusValue =
342
+ currentFocusEl?.parentNode?.getAttribute('data-value');
343
+
344
+ const currentFocusIndex = itemsList.value?.findIndex(
345
+ child => child.value === currentFocusValue
346
+ );
347
+
348
+ const direction = up ? -1 : 1;
349
+ let nextFocusIndex = currentFocusIndex + direction;
350
+ if (nextFocusIndex >= numChildren) nextFocusIndex = 0;
351
+ else if (nextFocusIndex < 0) nextFocusIndex = numChildren - 1;
352
+ focusItem.value = itemsList.value[nextFocusIndex]?.value;
353
+ }
354
+ const dropList = ref(null);
355
+ function doFocus() {
356
+ nextTick(() => {
357
+ if (open.value) {
358
+ dropList.value?.focus();
359
+ } else {
360
+ focus();
361
+ }
362
+ });
363
+ }
364
+ function onDown() {
365
+ if (!open.value) {
366
+ open.value = true;
367
+ } else {
368
+ doMove(false);
369
+ }
370
+ }
371
+ function onUp() {
372
+ if (open.value) {
373
+ doMove(true);
374
+ }
375
+ }
376
+ function onEsc() {
377
+ open.value = false;
378
+ doFocus();
379
+ }
380
+ const button = ref(null);
381
+ const listBox = ref(null);
382
+ function onTab(ev) {
383
+ if (open.value) {
384
+ if (button.value === ev.target) {
385
+ // button has focus ensure we are closed
386
+ open.value = false;
387
+ } else if (ev.target === null || listBox.value?.contains(ev.target)) {
388
+ // list has focus, close and return focus to dropdown
389
+ open.value = false;
390
+ doFocus();
391
+ ev.preventDefault();
392
+ }
393
+ }
394
+ }
395
+ function onClick(ev) {
396
+ if (props.disabled) {
397
+ ev.preventDefault();
398
+ } else {
399
+ open.value = !open.value;
400
+ doFocus(); // open or close (Some browsers do not focus on button when clicked)
401
+
402
+ let target = ev.target;
403
+ while (
404
+ !target.classList.contains(`${carbonPrefix}--dropdown-link`) &&
405
+ dropList.value?.contains(target)
406
+ ) {
407
+ target = target.parentNode; // try next one up
408
+ }
409
+
410
+ if (target.classList.contains(`${carbonPrefix}--dropdown-link`)) {
411
+ const targetItemEl = target.parentNode;
412
+ dataValue.value = targetItemEl.getAttribute('data-value');
413
+ }
414
+ }
415
+ }
416
+ </script>
@@ -0,0 +1,86 @@
1
+ <!--
2
+ Carbon dropdown item
3
+
4
+ Attributes:
5
+ value: The value for the item. Optional.
6
+
7
+ Usage:
8
+ See dropdown.vue
9
+
10
+ -->
11
+
12
+ <template>
13
+ <li
14
+ data-option
15
+ :data-value="value"
16
+ :class="[
17
+ `cv-dropdown-item ${carbonPrefix}--dropdown-item`,
18
+ { [`${carbonPrefix}--dropdown--selected`]: dataSelected },
19
+ ]"
20
+ role="menuitem"
21
+ >
22
+ <a
23
+ :aria-checked="dataSelected"
24
+ :class="`${carbonPrefix}--dropdown-link`"
25
+ href="javascript:void(0)"
26
+ ref="link"
27
+ role="menuitemradio"
28
+ tabindex="-1"
29
+ >
30
+ <slot></slot>
31
+ </a>
32
+ </li>
33
+ </template>
34
+
35
+ <script setup>
36
+ import { carbonPrefix } from '../../global/settings';
37
+ import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';
38
+ const props = defineProps({
39
+ value: {
40
+ type: String,
41
+ required: true,
42
+ },
43
+ selected: { type: Boolean, default: false },
44
+ });
45
+ const dataSelected = ref(props.selected);
46
+ /**
47
+ * @type {Ref<string>}
48
+ */
49
+ const parentSelected = inject('dropdown-selected');
50
+ /**
51
+ * @type {Ref<string>}
52
+ */
53
+ const parentFocus = inject('dropdown-focus');
54
+ const parentCaption = inject('dropdown-caption');
55
+ watch(
56
+ () => props.selected,
57
+ () => {
58
+ dataSelected.value = props.selected;
59
+ }
60
+ );
61
+ watch(parentSelected, () => {
62
+ dataSelected.value = props.value === parentSelected.value;
63
+ });
64
+ const link = ref(null);
65
+ watch(parentFocus, () => {
66
+ if (props.value === parentFocus.value) link.value?.focus();
67
+ });
68
+ watch(dataSelected, val => {
69
+ if (val) {
70
+ parentSelected.value = props.value;
71
+ parentCaption.value = link.value?.text || props.value;
72
+ }
73
+ });
74
+ const parentList = inject('dropdown-items');
75
+ onMounted(() => {
76
+ dataSelected.value = props.value === parentSelected.value;
77
+ parentList.value?.push({
78
+ value: props.value,
79
+ selected: props.selected,
80
+ });
81
+ });
82
+ onBeforeUnmount(() => {
83
+ const index = parentList.value?.findIndex(item => item.value === props.value);
84
+ if (index > -1) parentList.value?.splice(index, 1);
85
+ });
86
+ </script>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <div
3
+ disabled
4
+ :class="[
5
+ `${carbonPrefix}--list-box ${carbonPrefix}--dropdown ${carbonPrefix}--skeleton`,
6
+ { [`${carbonPrefix}--list-box--inline`]: inline },
7
+ ]"
8
+ ></div>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { carbonPrefix } from '../../global/settings';
13
+
14
+ defineProps({
15
+ inline: { type: Boolean, default: false },
16
+ });
17
+ </script>
@@ -0,0 +1,5 @@
1
+ import CvDropdown from './CvDropdown.vue';
2
+ import CvDropdownItem from './CvDropdownItem.vue';
3
+ import CvDropdownSkeleton from './CvDropdownSkeleton.vue';
4
+
5
+ export { CvDropdown, CvDropdownItem, CvDropdownSkeleton };