@carbon/vue 3.0.8-alpha.0 → 3.0.9
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/README.md +60 -21
- package/dist/carbon-vue-3.common.js +539 -69
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.umd.js +539 -69
- 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/package.json +2 -2
- package/src/components/CvFileUploader/CvFileUploader.stories.mdx +24 -6
- package/src/components/CvFileUploader/CvFileUploader.vue +58 -19
- package/src/components/CvNotification/CvToastNotification.stories.js +71 -1
- package/src/components/CvNotification/CvToastNotification.vue +6 -4
- package/src/components/CvOverflowMenu/CvOverflowMenu.stories.mdx +68 -12
- package/src/components/CvOverflowMenu/CvOverflowMenu.vue +39 -45
- package/src/components/CvOverflowMenu/CvOverflowMenuItem.vue +6 -11
- package/src/components/CvOverflowMenu/index.js +2 -1
- package/src/components/CvStructuredList/CvStructuredList.stories.js +141 -0
- package/src/components/CvStructuredList/CvStructuredList.vue +44 -0
- package/src/components/CvStructuredList/CvStructuredListData.vue +19 -0
- package/src/components/CvStructuredList/CvStructuredListHeading.vue +11 -0
- package/src/components/CvStructuredList/CvStructuredListItem.vue +47 -0
- package/src/components/CvStructuredList/CvStructuredListItemSelectable.vue +56 -0
- package/src/components/CvStructuredList/CvStructuredListItemStandard.vue +11 -0
- package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredList.spec.js.snap +73 -0
- package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListData.spec.js.snap +5 -0
- package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListHeading.spec.js.snap +9 -0
- package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListItem.spec.js.snap +7 -0
- package/src/components/CvStructuredList/index.js +12 -0
- package/src/components/CvTabs/CvTabs.stories.mdx +84 -3
- package/src/components/CvTabs/CvTabs.vue +3 -1
- package/src/components/CvTabs/__tests__/__snapshots__/CvTabs.spec.js.snap +24 -0
- package/src/components/CvTag/CvTag.stories.js +2 -1
- package/src/components/CvTag/CvTag.vue +10 -5
- package/src/components/CvTag/CvTagSkeleton.stories.js +39 -0
- package/src/components/CvTag/CvTagSkeleton.vue +20 -0
- package/src/components/CvTag/index.js +2 -1
- package/src/use/useRadio.js +0 -1
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.9",
|
|
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",
|
|
@@ -206,5 +206,5 @@
|
|
|
206
206
|
"url": "git+https://github.com/carbon-design-system/carbon-components-vue.git"
|
|
207
207
|
},
|
|
208
208
|
"sideEffects": true,
|
|
209
|
-
"gitHead": "
|
|
209
|
+
"gitHead": "746ba85d1d2060314ea9bb7f8ae9c45783572efc"
|
|
210
210
|
}
|
|
@@ -48,7 +48,7 @@ const skeletonTemplate = `
|
|
|
48
48
|
</div>
|
|
49
49
|
`;
|
|
50
50
|
|
|
51
|
-
export const
|
|
51
|
+
export const argTypes = {
|
|
52
52
|
// attributes
|
|
53
53
|
multiple: {
|
|
54
54
|
type: 'boolean',
|
|
@@ -61,6 +61,7 @@ export const args = {
|
|
|
61
61
|
// props
|
|
62
62
|
accept: {
|
|
63
63
|
type: 'string',
|
|
64
|
+
defaultValue: '.jpg,.png',
|
|
64
65
|
table: {
|
|
65
66
|
type: { summary: 'string' },
|
|
66
67
|
category: 'props',
|
|
@@ -106,6 +107,14 @@ export const args = {
|
|
|
106
107
|
},
|
|
107
108
|
description: 'Reset file list when files are added',
|
|
108
109
|
},
|
|
110
|
+
disabled: {
|
|
111
|
+
type: 'boolean',
|
|
112
|
+
table: {
|
|
113
|
+
type: { summary: 'boolean' },
|
|
114
|
+
category: 'props',
|
|
115
|
+
},
|
|
116
|
+
description: 'Disables input',
|
|
117
|
+
},
|
|
109
118
|
dropTargetLabel: {
|
|
110
119
|
type: 'string',
|
|
111
120
|
table: {
|
|
@@ -122,6 +131,14 @@ export const args = {
|
|
|
122
131
|
},
|
|
123
132
|
description: 'Helper text positioned below label',
|
|
124
133
|
},
|
|
134
|
+
initialStateUploading: {
|
|
135
|
+
type: 'boolean',
|
|
136
|
+
table: {
|
|
137
|
+
type: { summary: 'boolean' },
|
|
138
|
+
category: 'props',
|
|
139
|
+
},
|
|
140
|
+
description: 'Set "UPLOADING" state to new files',
|
|
141
|
+
},
|
|
125
142
|
kind: {
|
|
126
143
|
type: 'string',
|
|
127
144
|
control: 'select',
|
|
@@ -235,7 +252,7 @@ Migration notes:
|
|
|
235
252
|
helperText: 'Select the files you want to upload',
|
|
236
253
|
removable: true,
|
|
237
254
|
}}
|
|
238
|
-
argTypes={
|
|
255
|
+
argTypes={argTypes}
|
|
239
256
|
>
|
|
240
257
|
{Template.bind({})}
|
|
241
258
|
</Story>
|
|
@@ -263,11 +280,12 @@ Migration notes:
|
|
|
263
280
|
helperText: 'Select the files you want to upload',
|
|
264
281
|
kind: KINDS.BUTTON,
|
|
265
282
|
removable: true,
|
|
283
|
+
dropTargetLabel: 'Add file',
|
|
266
284
|
}}
|
|
267
285
|
argTypes={{
|
|
268
|
-
...
|
|
286
|
+
...argTypes,
|
|
269
287
|
kind: {
|
|
270
|
-
...
|
|
288
|
+
...argTypes.kind,
|
|
271
289
|
control: 'none',
|
|
272
290
|
},
|
|
273
291
|
}}
|
|
@@ -299,9 +317,9 @@ Migration notes:
|
|
|
299
317
|
removable: true,
|
|
300
318
|
}}
|
|
301
319
|
argTypes={{
|
|
302
|
-
...
|
|
320
|
+
...argTypes,
|
|
303
321
|
kind: {
|
|
304
|
-
...
|
|
322
|
+
...argTypes.kind,
|
|
305
323
|
control: 'none',
|
|
306
324
|
},
|
|
307
325
|
}}
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<cv-form-item class="cv-file-uploader">
|
|
3
|
-
<p
|
|
4
|
-
|
|
3
|
+
<p
|
|
4
|
+
:class="[
|
|
5
|
+
`${carbonPrefix}--file--label`,
|
|
6
|
+
{ [`${carbonPrefix}--file--label--disabled`]: disabled },
|
|
7
|
+
]"
|
|
8
|
+
>
|
|
9
|
+
{{ label }}
|
|
10
|
+
</p>
|
|
11
|
+
<p
|
|
12
|
+
:class="[
|
|
13
|
+
`${carbonPrefix}--label-description`,
|
|
14
|
+
{ [`${carbonPrefix}--label-description--disabled`]: disabled },
|
|
15
|
+
]"
|
|
16
|
+
>
|
|
17
|
+
{{ helperText }}
|
|
18
|
+
</p>
|
|
5
19
|
<div v-if="kind === 'button'" :class="`${carbonPrefix}--file`" data-file>
|
|
6
20
|
<label
|
|
7
21
|
:for="cvId"
|
|
8
|
-
:class="
|
|
22
|
+
:class="[
|
|
23
|
+
buttonClasses,
|
|
24
|
+
{ [`${carbonPrefix}--btn--disabled`]: disabled },
|
|
25
|
+
]"
|
|
9
26
|
tabindex="0"
|
|
10
27
|
@keydown.enter.prevent="onKeyHit"
|
|
11
28
|
@keydown.space.prevent="onKeyHit"
|
|
@@ -17,6 +34,7 @@
|
|
|
17
34
|
ref="fileInput"
|
|
18
35
|
:class="`${carbonPrefix}--file-input`"
|
|
19
36
|
:accept="accept"
|
|
37
|
+
:disabled="disabled"
|
|
20
38
|
type="file"
|
|
21
39
|
v-bind="$attrs"
|
|
22
40
|
data-file-uploader
|
|
@@ -34,8 +52,10 @@
|
|
|
34
52
|
`${carbonPrefix}--file-browse-btn`,
|
|
35
53
|
`${carbonPrefix}--file__drop-container`,
|
|
36
54
|
{
|
|
37
|
-
[`${carbonPrefix}--file__drop-container--drag-over`]:
|
|
55
|
+
[`${carbonPrefix}--file__drop-container--drag-over`]:
|
|
56
|
+
allowDrop && !disabled,
|
|
38
57
|
},
|
|
58
|
+
{ [`${carbonPrefix}--file-browse-btn--disabled`]: disabled },
|
|
39
59
|
]"
|
|
40
60
|
@dragover="onDragEvent"
|
|
41
61
|
@dragleave="onDragEvent"
|
|
@@ -50,6 +70,7 @@
|
|
|
50
70
|
ref="fileInput"
|
|
51
71
|
:class="`${carbonPrefix}--file-input`"
|
|
52
72
|
:accept="accept"
|
|
73
|
+
:disabled="disabled"
|
|
53
74
|
type="file"
|
|
54
75
|
v-bind="$attrs"
|
|
55
76
|
tabindex="-1"
|
|
@@ -107,8 +128,10 @@ const props = defineProps({
|
|
|
107
128
|
},
|
|
108
129
|
buttonSize: commonCvButtonProps.size,
|
|
109
130
|
clearOnReselect: Boolean,
|
|
131
|
+
disabled: Boolean,
|
|
110
132
|
dropTargetLabel: String,
|
|
111
133
|
helperText: String,
|
|
134
|
+
initialStateUploading: Boolean,
|
|
112
135
|
kind: {
|
|
113
136
|
type: String,
|
|
114
137
|
default: KINDS.DRAG_TARGET,
|
|
@@ -178,7 +201,7 @@ function addFiles(files) {
|
|
|
178
201
|
const newFile = createInternalFile(internalFile?.file || file);
|
|
179
202
|
|
|
180
203
|
if (internalFile) {
|
|
181
|
-
internalFile.state = newFile.
|
|
204
|
+
internalFile.state = newFile.state;
|
|
182
205
|
internalFile.invalidMessageTitle = newFile.invalidMessageTitle;
|
|
183
206
|
internalFile.invalidMessage = newFile.invalidMessage;
|
|
184
207
|
} else {
|
|
@@ -216,6 +239,11 @@ function onChange(ev) {
|
|
|
216
239
|
}
|
|
217
240
|
|
|
218
241
|
function onDragEvent(evt) {
|
|
242
|
+
if (props.disabled) {
|
|
243
|
+
evt.preventDefault();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
219
247
|
if (Array.prototype.indexOf.call(evt.dataTransfer.types, 'Files') === -1) {
|
|
220
248
|
return;
|
|
221
249
|
}
|
|
@@ -249,7 +277,7 @@ function onDragEvent(evt) {
|
|
|
249
277
|
|
|
250
278
|
function onItemRemove(index) {
|
|
251
279
|
internalFiles.value.splice(index, 1);
|
|
252
|
-
emit('update:modelValue',
|
|
280
|
+
emit('update:modelValue', internalFiles.value);
|
|
253
281
|
}
|
|
254
282
|
|
|
255
283
|
function onKeyHit() {
|
|
@@ -262,20 +290,31 @@ onMounted(() => {
|
|
|
262
290
|
});
|
|
263
291
|
|
|
264
292
|
// exposed methods
|
|
293
|
+
function clear() {
|
|
294
|
+
internalFiles.value = [];
|
|
295
|
+
emit('update:modelValue', internalFiles.value);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function remove(index) {
|
|
299
|
+
onItemRemove(index);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function setInvalidMessage(index, message) {
|
|
303
|
+
internalFiles.value[index].invalidMessage = message;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function setState(index, state) {
|
|
307
|
+
if ([STATES.COMPLETE, STATES.UPLOADING, STATES.NONE].includes(state)) {
|
|
308
|
+
internalFiles.value[index].state = state;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// exposing methods
|
|
265
313
|
defineExpose({
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
},
|
|
271
|
-
clear() {
|
|
272
|
-
internalFiles.value = [];
|
|
273
|
-
emit('update:modelValue', internalFiles);
|
|
274
|
-
},
|
|
275
|
-
setInvalidMessage(index, message) {
|
|
276
|
-
internalFiles.value[index].invalidMessage = message;
|
|
277
|
-
},
|
|
278
|
-
remove: onItemRemove,
|
|
314
|
+
clear,
|
|
315
|
+
remove,
|
|
316
|
+
setInvalidMessage,
|
|
317
|
+
setState,
|
|
279
318
|
});
|
|
280
319
|
</script>
|
|
281
320
|
|
|
@@ -58,10 +58,56 @@ export default {
|
|
|
58
58
|
lowContrast: {
|
|
59
59
|
control: { type: 'boolean' },
|
|
60
60
|
},
|
|
61
|
+
// slots
|
|
62
|
+
default: {
|
|
63
|
+
table: {
|
|
64
|
+
type: { summary: 'string | html | Component' },
|
|
65
|
+
category: 'slots',
|
|
66
|
+
},
|
|
67
|
+
description: 'Slot for additional custom content.',
|
|
68
|
+
},
|
|
69
|
+
'title ': {
|
|
70
|
+
table: {
|
|
71
|
+
type: { summary: 'string | html | Component' },
|
|
72
|
+
category: 'slots',
|
|
73
|
+
},
|
|
74
|
+
description: 'Title slot for more custom content.',
|
|
75
|
+
},
|
|
76
|
+
subtitle: {
|
|
77
|
+
table: {
|
|
78
|
+
type: { summary: 'string | html | Component' },
|
|
79
|
+
category: 'slots',
|
|
80
|
+
},
|
|
81
|
+
description: 'Subtitle slot for more custom content.',
|
|
82
|
+
},
|
|
83
|
+
'caption ': {
|
|
84
|
+
table: {
|
|
85
|
+
type: { summary: 'string | html | Component' },
|
|
86
|
+
category: 'slots',
|
|
87
|
+
},
|
|
88
|
+
description: 'Caption slot for more custom content.',
|
|
89
|
+
},
|
|
61
90
|
},
|
|
62
91
|
};
|
|
63
92
|
|
|
64
|
-
const template =
|
|
93
|
+
const template = `
|
|
94
|
+
<cv-toast-notification v-bind="args" @close="onClose" >
|
|
95
|
+
<template v-if="args.titleSlot" #title>
|
|
96
|
+
<strong style="color: orange; font-size: 1.25rem;">Custom</strong> <span style="color: yellow;">title</span>
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<template v-if="args.subtitleSlot" #subtitle>
|
|
100
|
+
Some <strong style="color: orange; font-size: 1.25rem;">custom</strong> <span style="color: yellow;">subtitle</span>
|
|
101
|
+
</template>
|
|
102
|
+
|
|
103
|
+
<template v-if="args.captionSlot" #caption>
|
|
104
|
+
Some <span style="color: green;">custom</span> <strong style="color: orange; font-size: 0.75rem;">caption</strong>
|
|
105
|
+
</template>
|
|
106
|
+
|
|
107
|
+
<template v-if="args.defaultSlot">
|
|
108
|
+
Default slot content.
|
|
109
|
+
</template>
|
|
110
|
+
</cv-toast-notification>`;
|
|
65
111
|
const Template = args => {
|
|
66
112
|
return {
|
|
67
113
|
components: { CvToastNotification },
|
|
@@ -106,3 +152,27 @@ export const Error = Template.bind({});
|
|
|
106
152
|
Error.args = {
|
|
107
153
|
kind: CvNotificationConsts.notificationKinds[5],
|
|
108
154
|
};
|
|
155
|
+
|
|
156
|
+
export const SlotDefault = Template.bind({});
|
|
157
|
+
SlotDefault.args = {
|
|
158
|
+
kind: CvNotificationConsts.notificationKinds[4],
|
|
159
|
+
defaultSlot: true,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const SlotTitle = Template.bind({});
|
|
163
|
+
SlotTitle.args = {
|
|
164
|
+
kind: CvNotificationConsts.notificationKinds[0],
|
|
165
|
+
titleSlot: true,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const SlotSubtitle = Template.bind({});
|
|
169
|
+
SlotSubtitle.args = {
|
|
170
|
+
kind: CvNotificationConsts.notificationKinds[3],
|
|
171
|
+
subtitleSlot: true,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const SlotCaption = Template.bind({});
|
|
175
|
+
SlotCaption.args = {
|
|
176
|
+
kind: CvNotificationConsts.notificationKinds[1],
|
|
177
|
+
captionSlot: true,
|
|
178
|
+
};
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
:class="`${carbonPrefix}--toast-notification__icon`"
|
|
14
14
|
/>
|
|
15
15
|
<div :class="`${carbonPrefix}--toast-notification__details`">
|
|
16
|
-
<h3 :class="`${carbonPrefix}--toast-notification__title`">
|
|
16
|
+
<h3 :class="`${carbonPrefix}--toast-notification__title`">
|
|
17
|
+
<slot name="title">{{ title }}</slot>
|
|
18
|
+
</h3>
|
|
17
19
|
<div :class="`${carbonPrefix}--toast-notification__subtitle`">
|
|
18
|
-
{{ subTitle }}
|
|
20
|
+
<slot name="subtitle">{{ subTitle }}</slot>
|
|
19
21
|
</div>
|
|
20
22
|
<div :class="`${carbonPrefix}--toast-notification__caption`">
|
|
21
|
-
{{ caption }}
|
|
23
|
+
<slot name="caption">{{ caption }}</slot>
|
|
22
24
|
</div>
|
|
23
25
|
<slot />
|
|
24
26
|
</div>
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
:class="`${carbonPrefix}--toast-notification__close-button`"
|
|
29
31
|
@click="$emit('close')"
|
|
30
32
|
>
|
|
31
|
-
<close20 :class="`${carbonPrefix}--
|
|
33
|
+
<close20 :class="`${carbonPrefix}--toast-notification__close-icon`" />
|
|
32
34
|
</button>
|
|
33
35
|
</div>
|
|
34
36
|
</template>
|
|
@@ -25,18 +25,20 @@ export const Template = args => ({
|
|
|
25
25
|
template: args.template,
|
|
26
26
|
});
|
|
27
27
|
const defaultTemplate = `
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</cv-overflow-menu>
|
|
28
|
+
<div style="padding: 100px;">
|
|
29
|
+
<cv-overflow-menu
|
|
30
|
+
:flip-menu="flipMenu"
|
|
31
|
+
:up="up"
|
|
32
|
+
:offset="offset"
|
|
33
|
+
:label="label"
|
|
34
|
+
:tip-position="tipPosition"
|
|
35
|
+
:tip-alignment="tipAlignment"
|
|
36
|
+
@change=onChange>
|
|
37
|
+
<cv-overflow-menu-item value="item 1" primary-focus>list item 1</cv-overflow-menu-item>
|
|
38
|
+
<cv-overflow-menu-item value="item 2" disabled>list item 2</cv-overflow-menu-item>
|
|
39
|
+
<cv-overflow-menu-item value="item 3" danger>list item 3</cv-overflow-menu-item>
|
|
40
|
+
</cv-overflow-menu>
|
|
41
|
+
</div>
|
|
40
42
|
`;
|
|
41
43
|
const slotsTemplate = `
|
|
42
44
|
<cv-overflow-menu
|
|
@@ -117,3 +119,57 @@ Use slots for more control over the display.
|
|
|
117
119
|
{Template.bind({})}
|
|
118
120
|
</Story>
|
|
119
121
|
</Canvas>
|
|
122
|
+
|
|
123
|
+
<Canvas>
|
|
124
|
+
<Story
|
|
125
|
+
name="Flipped"
|
|
126
|
+
parameters={{
|
|
127
|
+
controls: {
|
|
128
|
+
exclude: ['default', 'template', 'trigger', 'change'],
|
|
129
|
+
},
|
|
130
|
+
docs: { source: { code: defaultTemplate } },
|
|
131
|
+
}}
|
|
132
|
+
args={{
|
|
133
|
+
template: defaultTemplate,
|
|
134
|
+
label: 'Overflow menu',
|
|
135
|
+
flipMenu: true,
|
|
136
|
+
up: undefined,
|
|
137
|
+
offset: undefined,
|
|
138
|
+
tipPosition: undefined,
|
|
139
|
+
tipAlignment: undefined,
|
|
140
|
+
}}
|
|
141
|
+
argTypes={{
|
|
142
|
+
tipPosition: { control: 'select', default: 'right', options: ['top', 'left', 'bottom', 'right'] },
|
|
143
|
+
tipAlignment: { control: 'select', default: 'center', options: ['start', 'center', 'end'] },
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
{Template.bind({})}
|
|
147
|
+
</Story>
|
|
148
|
+
</Canvas>
|
|
149
|
+
|
|
150
|
+
<Canvas>
|
|
151
|
+
<Story
|
|
152
|
+
name="Up"
|
|
153
|
+
parameters={{
|
|
154
|
+
controls: {
|
|
155
|
+
exclude: ['default', 'template', 'trigger', 'change'],
|
|
156
|
+
},
|
|
157
|
+
docs: { source: { code: defaultTemplate } },
|
|
158
|
+
}}
|
|
159
|
+
args={{
|
|
160
|
+
template: defaultTemplate,
|
|
161
|
+
label: 'Overflow menu',
|
|
162
|
+
flipMenu: undefined,
|
|
163
|
+
up: true,
|
|
164
|
+
offset: undefined,
|
|
165
|
+
tipPosition: undefined,
|
|
166
|
+
tipAlignment: undefined,
|
|
167
|
+
}}
|
|
168
|
+
argTypes={{
|
|
169
|
+
tipPosition: { control: 'select', default: 'right', options: ['top', 'left', 'bottom', 'right'] },
|
|
170
|
+
tipAlignment: { control: 'select', default: 'center', options: ['start', 'center', 'end'] },
|
|
171
|
+
}}
|
|
172
|
+
>
|
|
173
|
+
{Template.bind({})}
|
|
174
|
+
</Story>
|
|
175
|
+
</Canvas>
|
|
@@ -38,40 +38,42 @@
|
|
|
38
38
|
/>
|
|
39
39
|
</slot>
|
|
40
40
|
</button>
|
|
41
|
-
<
|
|
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="
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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,
|
|
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
|
-
|
|
139
|
-
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
42
|
+
emitClick(attrs.value);
|
|
48
43
|
}
|
|
49
44
|
function onEsc() {
|
|
50
|
-
|
|
45
|
+
emitClose();
|
|
51
46
|
}
|
|
52
47
|
</script>
|