@carbon/vue 3.0.29 → 3.0.31
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.
- package/dist/carbon-vue-3.common.js +129 -34
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.css +1 -1
- package/dist/carbon-vue-3.umd.js +129 -34
- package/dist/carbon-vue-3.umd.js.map +1 -1
- package/dist/carbon-vue-3.umd.min.js +4 -4
- package/dist/carbon-vue-3.umd.min.js.map +1 -1
- package/dist/web-types.json +1 -1
- package/package.json +1 -1
- package/src/components/CvContentSwitcher/CvContentSwitcher.stories.mdx +2 -2
- package/src/components/CvContentSwitcher/CvContentSwitcher.vue +17 -3
- package/src/components/CvDropdown/CvDropdown.vue +26 -2
- package/src/components/CvOverflowMenu/CvOverflowMenu.vue +2 -1
- package/src/components/CvTabs/CvTabs.vue +22 -7
- package/src/components/CvTabs/__tests__/__snapshots__/CvTabs.spec.js.snap +3 -3
- package/src/components/CvUIShell/CvSideNav.vue +5 -2
package/dist/web-types.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbon/vue",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.31",
|
|
5
5
|
"description": "A collection of components for the Carbon Design System built using Vue.js",
|
|
6
6
|
"packageManager": "yarn@3.2.0",
|
|
7
7
|
"main": "dist/carbon-vue-3.umd.min.js",
|
|
@@ -77,7 +77,7 @@ const domTemplate = `
|
|
|
77
77
|
const domCode = domTemplate.replace("v-bind='args'", '');
|
|
78
78
|
const multipleTemplate = `
|
|
79
79
|
<div>
|
|
80
|
-
<cv-content-switcher aria-label='Choose content' v-bind='args' @selected="onSelected" id="star-wars">
|
|
80
|
+
<cv-content-switcher tabindex="0" aria-label='Choose content' v-bind='args' @selected="onSelected" id="star-wars">
|
|
81
81
|
<cv-content-switcher-button parent-switcher="star-wars" owner-id="episode-1" :selected="selectedIndex === 0">Episode 1</cv-content-switcher-button>
|
|
82
82
|
<cv-content-switcher-button parent-switcher="star-wars" owner-id="episode-2" :selected="selectedIndex === 1">Episode 2</cv-content-switcher-button>
|
|
83
83
|
<cv-content-switcher-button parent-switcher="star-wars" :icon="iconSample" owner-id="episode-3" :selected="selectedIndex === 2">Episode 3</cv-content-switcher-button>
|
|
@@ -96,7 +96,7 @@ const multipleTemplate = `
|
|
|
96
96
|
<p>Yoda</p>
|
|
97
97
|
</cv-content-switcher-content>
|
|
98
98
|
</section>
|
|
99
|
-
<cv-content-switcher aria-label='Choose content' v-bind='args' @selected="onSelected" id="LotR">
|
|
99
|
+
<cv-content-switcher tabindex="1" aria-label='Choose content' v-bind='args' @selected="onSelected" id="LotR">
|
|
100
100
|
<cv-content-switcher-button parent-switcher="LotR" owner-id="book-1" :selected="selectedIndex === 0">Book 1</cv-content-switcher-button>
|
|
101
101
|
<cv-content-switcher-button parent-switcher="LotR" owner-id="book-2" :selected="selectedIndex === 1">Book 2</cv-content-switcher-button>
|
|
102
102
|
<cv-content-switcher-button parent-switcher="LotR" :icon="iconSample" owner-id="book-3" :selected="selectedIndex === 2">Book 3</cv-content-switcher-button>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { carbonPrefix } from '../../global/settings';
|
|
19
19
|
import { props as propsCvId, useCvId } from '../../use/cvId';
|
|
20
20
|
import { useIsLight, props as propsTheme } from '../../use/cvTheme';
|
|
21
|
-
import { onUnmounted, watch } from 'vue';
|
|
21
|
+
import { onUnmounted, watch, onMounted, nextTick } from 'vue';
|
|
22
22
|
import store from './cvContentSwitcherStore';
|
|
23
23
|
|
|
24
24
|
const emit = defineEmits(['selected']);
|
|
@@ -36,14 +36,26 @@ const cvId = useCvId(props, true);
|
|
|
36
36
|
const isLight = useIsLight(props);
|
|
37
37
|
store.addParent(cvId.value);
|
|
38
38
|
store.setContentSelected('global', undefined);
|
|
39
|
+
|
|
40
|
+
// Check for initial selection after child components have set up
|
|
41
|
+
let hadInitialSelection = null;
|
|
42
|
+
onMounted(async () => {
|
|
43
|
+
// Use nextTick to ensure child components have mounted and set their initial state
|
|
44
|
+
await nextTick();
|
|
45
|
+
hadInitialSelection =
|
|
46
|
+
store.state[cvId.value]?.selected !== undefined &&
|
|
47
|
+
store.state[cvId.value]?.selected !== '';
|
|
48
|
+
});
|
|
49
|
+
|
|
39
50
|
onUnmounted(() => {
|
|
40
51
|
store.removeParent(cvId.value);
|
|
41
52
|
});
|
|
53
|
+
|
|
42
54
|
watch(
|
|
43
55
|
() => store.state.global.latest,
|
|
44
56
|
(val, prev) => {
|
|
45
57
|
// if previous is not set, do not emit. This mimics the current v2 behaviour where the initial content does not generate an event
|
|
46
|
-
if (prev) emit('selected', val);
|
|
58
|
+
if (prev || (val && hadInitialSelection === false)) emit('selected', val);
|
|
47
59
|
}
|
|
48
60
|
);
|
|
49
61
|
|
|
@@ -53,7 +65,9 @@ watch(
|
|
|
53
65
|
val => {
|
|
54
66
|
if (ourLatest !== val?.latest) {
|
|
55
67
|
// if ourLatest is not set, do not emit. This mimics the current v2 behaviour where the initial content does not generate an event
|
|
56
|
-
if (
|
|
68
|
+
// However, if there was no initial selection (selectedIndex=-1), we should emit on first click
|
|
69
|
+
if (ourLatest || (val?.latest && hadInitialSelection === false))
|
|
70
|
+
emit('selected', val?.latest);
|
|
57
71
|
ourLatest = val?.latest;
|
|
58
72
|
}
|
|
59
73
|
},
|
|
@@ -36,8 +36,9 @@
|
|
|
36
36
|
`${carbonPrefix}--label`,
|
|
37
37
|
{ [`${carbonPrefix}--label--disabled`]: disabled },
|
|
38
38
|
]"
|
|
39
|
-
>{{ label }}</label
|
|
40
39
|
>
|
|
40
|
+
{{ label }}
|
|
41
|
+
</label>
|
|
41
42
|
|
|
42
43
|
<div
|
|
43
44
|
ref="listBox"
|
|
@@ -110,7 +111,10 @@
|
|
|
110
111
|
ref="dropList"
|
|
111
112
|
:aria-hidden="!open ? 'true' : 'false'"
|
|
112
113
|
:aria-labelledby="`${uid}-label`"
|
|
113
|
-
:class="
|
|
114
|
+
:class="[
|
|
115
|
+
`${carbonPrefix}--list-box__menu`,
|
|
116
|
+
{ 'cv-dropdown__menu--transition-done': transitionDone },
|
|
117
|
+
]"
|
|
114
118
|
role="menu"
|
|
115
119
|
tabindex="-1"
|
|
116
120
|
>
|
|
@@ -268,6 +272,7 @@ provide('dropdown-caption', dataCaption);
|
|
|
268
272
|
const itemsList = ref([]);
|
|
269
273
|
provide('dropdown-items', itemsList);
|
|
270
274
|
const open = ref(false);
|
|
275
|
+
const transitionDone = ref(false);
|
|
271
276
|
const data = reactive({
|
|
272
277
|
isHelper: false,
|
|
273
278
|
isInvalid: undefined,
|
|
@@ -301,6 +306,15 @@ watch(dataValue, () => {
|
|
|
301
306
|
});
|
|
302
307
|
watch(open, () => {
|
|
303
308
|
focusItem.value = '';
|
|
309
|
+
if (open.value) {
|
|
310
|
+
// Wait for the transition to complete before allowing overflow
|
|
311
|
+
transitionDone.value = false;
|
|
312
|
+
setTimeout(() => {
|
|
313
|
+
transitionDone.value = true;
|
|
314
|
+
}, 200); // Increase delay to ensure animation completes
|
|
315
|
+
} else {
|
|
316
|
+
transitionDone.value = false;
|
|
317
|
+
}
|
|
304
318
|
});
|
|
305
319
|
const ariaLabeledBy = computed(() => {
|
|
306
320
|
if (props.label) {
|
|
@@ -432,3 +446,13 @@ function onClick(ev) {
|
|
|
432
446
|
}
|
|
433
447
|
}
|
|
434
448
|
</script>
|
|
449
|
+
|
|
450
|
+
<style lang="scss">
|
|
451
|
+
.bx--list-box .bx--list-box__menu {
|
|
452
|
+
overflow-y: hidden !important;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.bx--list-box--expanded .bx--list-box__menu.cv-dropdown__menu--transition-done {
|
|
456
|
+
overflow-y: auto !important;
|
|
457
|
+
}
|
|
458
|
+
</style>
|
|
@@ -229,7 +229,8 @@ function doFocus() {
|
|
|
229
229
|
!(
|
|
230
230
|
tryOn.classList.contains('cv-overflow-menu__before-content') ||
|
|
231
231
|
tryOn.classList.contains('cv-overflow-menu__after-content') ||
|
|
232
|
-
tryOn.tabindex < 0
|
|
232
|
+
tryOn.tabindex < 0 ||
|
|
233
|
+
tryOn.disabled
|
|
233
234
|
)
|
|
234
235
|
) {
|
|
235
236
|
focusOn = tryOn;
|
|
@@ -11,14 +11,16 @@
|
|
|
11
11
|
},
|
|
12
12
|
]"
|
|
13
13
|
role="navigation"
|
|
14
|
-
|
|
14
|
+
:aria-label="attrs['aria-label'] || 'Tabs'"
|
|
15
|
+
v-bind="attrsWithoutAriaLabel"
|
|
15
16
|
@keydown.right.prevent.stop="onRight"
|
|
16
17
|
@keydown.left.prevent.stop="onLeft"
|
|
17
18
|
>
|
|
18
19
|
<button
|
|
19
20
|
ref="elLeftOverflow"
|
|
20
|
-
aria-
|
|
21
|
-
|
|
21
|
+
:aria-label="
|
|
22
|
+
leftOverflowNavButtonHidden ? undefined : 'Scroll tabs left'
|
|
23
|
+
"
|
|
22
24
|
:class="[
|
|
23
25
|
{
|
|
24
26
|
[`${carbonPrefix}--tab--overflow-nav-button`]: horizontalOverflow,
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
leftOverflowNavButtonHidden,
|
|
27
29
|
},
|
|
28
30
|
]"
|
|
29
|
-
tabIndex="-1"
|
|
31
|
+
:tabIndex="leftOverflowNavButtonHidden ? -1 : 0"
|
|
30
32
|
type="button"
|
|
31
33
|
@click.stop.prevent="e => onOverflowClick(e, { direction: -1 })"
|
|
32
34
|
@mousedown.stop.prevent="e => onOverflowMouseDown(e, { direction: -1 })"
|
|
@@ -89,8 +91,9 @@
|
|
|
89
91
|
/>
|
|
90
92
|
<button
|
|
91
93
|
ref="elRightOverflow"
|
|
92
|
-
aria-
|
|
93
|
-
|
|
94
|
+
:aria-label="
|
|
95
|
+
rightOverflowNavButtonHidden ? undefined : 'Scroll tabs right'
|
|
96
|
+
"
|
|
94
97
|
:class="[
|
|
95
98
|
{
|
|
96
99
|
[`${carbonPrefix}--tab--overflow-nav-button`]: horizontalOverflow,
|
|
@@ -98,7 +101,7 @@
|
|
|
98
101
|
rightOverflowNavButtonHidden,
|
|
99
102
|
},
|
|
100
103
|
]"
|
|
101
|
-
tabIndex="-1"
|
|
104
|
+
:tabIndex="rightOverflowNavButtonHidden ? -1 : 0"
|
|
102
105
|
type="button"
|
|
103
106
|
@click="e => onOverflowClick(e, { direction: 1 })"
|
|
104
107
|
@mousedown="e => onOverflowMouseDown(e, { direction: 1 })"
|
|
@@ -117,15 +120,21 @@
|
|
|
117
120
|
import { carbonPrefix } from '../../global/settings';
|
|
118
121
|
import { ChevronLeft16, ChevronRight16 } from '@carbon/icons-vue';
|
|
119
122
|
import {
|
|
123
|
+
computed,
|
|
120
124
|
nextTick,
|
|
121
125
|
onBeforeUnmount,
|
|
122
126
|
onMounted,
|
|
123
127
|
onUpdated,
|
|
124
128
|
provide,
|
|
125
129
|
ref,
|
|
130
|
+
useAttrs,
|
|
126
131
|
watch,
|
|
127
132
|
} from 'vue';
|
|
128
133
|
|
|
134
|
+
defineOptions({
|
|
135
|
+
inheritAttrs: false,
|
|
136
|
+
});
|
|
137
|
+
|
|
129
138
|
const OVERFLOW_BUTTON_OFFSET = 40;
|
|
130
139
|
|
|
131
140
|
const props = defineProps({
|
|
@@ -152,6 +161,12 @@ const props = defineProps({
|
|
|
152
161
|
});
|
|
153
162
|
const emit = defineEmits(['tab-selected', 'tab-selected-id']);
|
|
154
163
|
|
|
164
|
+
const attrs = useAttrs();
|
|
165
|
+
const attrsWithoutAriaLabel = computed(() => {
|
|
166
|
+
const { 'aria-label': _, ...rest } = attrs;
|
|
167
|
+
return rest;
|
|
168
|
+
});
|
|
169
|
+
|
|
155
170
|
const selectedId = ref('');
|
|
156
171
|
provide('tab-selected', selectedId);
|
|
157
172
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`CvTabs CvTabs - test slotted tab buttons to match snapshot 1`] = `
|
|
4
|
-
<div class="cv-tabs
|
|
5
|
-
<div data-tabs="" class="cv-tab bx--tabs--scrollable ABC-class-123" role="navigation" aria-label="ABC-aria-label-123"><button
|
|
4
|
+
<div class="cv-tabs" style="width: 100%;">
|
|
5
|
+
<div data-tabs="" class="cv-tab bx--tabs--scrollable ABC-class-123" role="navigation" aria-label="ABC-aria-label-123"><button class="bx--tab--overflow-nav-button--hidden" tabindex="-1" type="button"><svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
|
|
6
6
|
<path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path>
|
|
7
7
|
</svg></button>
|
|
8
8
|
<!--v-if-->
|
|
@@ -11,7 +11,7 @@ exports[`CvTabs CvTabs - test slotted tab buttons to match snapshot 1`] = `
|
|
|
11
11
|
<li class="cv-tabs-button bx--tabs--scrollable__nav-item" role="presentation"><button id="tab-2-link" class="bx--tabs--scrollable__nav-link" role="tab" aria-controls="tab-2" aria-selected="false" tabindex="-1" type="button">Origin<strong style="color: orange;">(!)</strong></button></li>
|
|
12
12
|
<li class="cv-tabs-button bx--tabs--scrollable__nav-item" role="presentation"><button id="tab-3-link" class="bx--tabs--scrollable__nav-link" role="tab" aria-controls="tab-3" aria-selected="false" tabindex="-1" type="button">Tab 3 label</button></li>
|
|
13
13
|
</ul>
|
|
14
|
-
<!--v-if--><button
|
|
14
|
+
<!--v-if--><button class="bx--tab--overflow-nav-button--hidden" tabindex="-1" type="button"><svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
|
|
15
15
|
<path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path>
|
|
16
16
|
</svg></button>
|
|
17
17
|
</div>
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
[`${carbonPrefix}--side-nav--ux`]: isChildOfHeader,
|
|
14
14
|
},
|
|
15
15
|
]"
|
|
16
|
-
:aria-hidden="
|
|
17
|
-
:inert="
|
|
16
|
+
:aria-hidden="isHidden ? 'true' : 'false'"
|
|
17
|
+
:inert="isHidden"
|
|
18
18
|
@focusout="onFocusout"
|
|
19
19
|
@mousedown="onMouseDown"
|
|
20
20
|
@mouseenter="onHoverToggle(true)"
|
|
@@ -79,6 +79,9 @@ const panelExpanded = computed({
|
|
|
79
79
|
data.dataExpanded = val;
|
|
80
80
|
},
|
|
81
81
|
});
|
|
82
|
+
const isHidden = computed(() => {
|
|
83
|
+
return !panelExpanded.value && !props.fixed && !props.rail;
|
|
84
|
+
});
|
|
82
85
|
/**
|
|
83
86
|
* @type {CvHeaderPanel}
|
|
84
87
|
*/
|