@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
@@ -0,0 +1,286 @@
1
+ <template>
2
+ <cv-form-item class="cv-file-uploader">
3
+ <p :class="`${carbonPrefix}--file--label`">{{ label }}</p>
4
+ <p :class="`${carbonPrefix}--label-description`">{{ helperText }}</p>
5
+ <div v-if="kind === 'button'" :class="`${carbonPrefix}--file`" data-file>
6
+ <label
7
+ :for="cvId"
8
+ :class="buttonClasses"
9
+ tabindex="0"
10
+ @keydown.enter.prevent="onKeyHit"
11
+ @keydown.space.prevent="onKeyHit"
12
+ >
13
+ <slot name="drop-target">{{ internalDropTargetLabel }}</slot>
14
+ </label>
15
+ <input
16
+ :id="cvId"
17
+ ref="fileInput"
18
+ :class="`${carbonPrefix}--file-input`"
19
+ :accept="accept"
20
+ type="file"
21
+ v-bind="$attrs"
22
+ data-file-uploader
23
+ data-target="[data-file-container]"
24
+ @change="onChange"
25
+ />
26
+ </div>
27
+ <div v-else :class="`${carbonPrefix}--file`" data-file>
28
+ <label :for="cvId">
29
+ <div
30
+ role="button"
31
+ tabindex="0"
32
+ data-file-drop-container
33
+ :class="[
34
+ `${carbonPrefix}--file-browse-btn`,
35
+ `${carbonPrefix}--file__drop-container`,
36
+ {
37
+ [`${carbonPrefix}--file__drop-container--drag-over`]: allowDrop,
38
+ },
39
+ ]"
40
+ @dragover="onDragEvent"
41
+ @dragleave="onDragEvent"
42
+ @drop="onDragEvent"
43
+ @keydown.enter.prevent="onKeyHit"
44
+ @keydown.space.prevent="onKeyHit"
45
+ >
46
+ <slot name="drop-target">{{ internalDropTargetLabel }}</slot>
47
+ </div>
48
+ <input
49
+ :id="cvId"
50
+ ref="fileInput"
51
+ :class="`${carbonPrefix}--file-input`"
52
+ :accept="accept"
53
+ type="file"
54
+ v-bind="$attrs"
55
+ tabindex="-1"
56
+ data-file-uploader
57
+ data-target="[data-file-container]"
58
+ @change="onChange"
59
+ />
60
+ </label>
61
+ </div>
62
+ <div
63
+ :class="`${carbonPrefix}--file ${carbonPrefix}--file-container`"
64
+ data-file-container
65
+ >
66
+ <cv-file-uploader-item
67
+ v-for="(item, index) in internalFiles"
68
+ :key="item.file.name"
69
+ :item="item"
70
+ :removable="removable"
71
+ :removeAriaLabel="removeAriaLabel"
72
+ @remove="onItemRemove(index)"
73
+ />
74
+ </div>
75
+ </cv-form-item>
76
+ </template>
77
+
78
+ <script setup>
79
+ import { ref, computed, onMounted, watch } from 'vue';
80
+ import CvFileUploaderItem from './CvFileUploaderItem.vue';
81
+ import { carbonPrefix } from '../../global/settings';
82
+ import { CvFormItem } from '../CvForm';
83
+ import { useCvId, props as cvIdProps } from '../../use/cvId';
84
+ import { KINDS, STATES } from './const';
85
+ import {
86
+ props as commonCvButtonProps,
87
+ useCvButtonCommon,
88
+ } from '../CvButton/CvButtonCommon';
89
+
90
+ const emit = defineEmits(['update:modelValue']);
91
+
92
+ const props = defineProps({
93
+ accept: String,
94
+ buttonKind: commonCvButtonProps.kind,
95
+ buttonLabel: {
96
+ type: String,
97
+ default: undefined,
98
+ deprecated: true,
99
+ validator: val => {
100
+ if (val !== undefined && process.env.NODE_ENV === 'development') {
101
+ console.warn(
102
+ 'CvFileUploader: button-label prop deprecated in favour of drop-target-label'
103
+ );
104
+ }
105
+ return true;
106
+ },
107
+ },
108
+ buttonSize: commonCvButtonProps.size,
109
+ clearOnReselect: Boolean,
110
+ dropTargetLabel: String,
111
+ helperText: String,
112
+ kind: {
113
+ type: String,
114
+ default: KINDS.DRAG_TARGET,
115
+ validator: val => {
116
+ const validValues = Object.values(KINDS);
117
+ if (!validValues.includes(val)) {
118
+ console.warn(
119
+ `CvFileUploader: valid values for 'kind' are ${validValues}`
120
+ );
121
+ }
122
+ return true;
123
+ },
124
+ },
125
+ label: String,
126
+ modelValue: Array,
127
+ removable: Boolean,
128
+ removeAriaLabel: String,
129
+ ...cvIdProps,
130
+ });
131
+
132
+ // DOM Elements
133
+ const fileInput = ref(null);
134
+
135
+ // Data
136
+ const allowDrop = ref(false);
137
+ const internalFiles = ref([]);
138
+
139
+ // Computed
140
+ const { buttonClasses } = useCvButtonCommon(props.buttonKind, props.buttonSize);
141
+ const cvId = useCvId(props);
142
+ const internalDropTargetLabel = computed(() => {
143
+ return (
144
+ props.dropTargetLabel ||
145
+ props.buttonLabel ||
146
+ 'Drag and drop files here or upload'
147
+ );
148
+ });
149
+ const isFileTypeAllowed = computed(() => {
150
+ const acceptAny = !props.accept;
151
+ const allowedTypes = props.accept
152
+ ? props.accept.split(',').map(x => x.trim())
153
+ : [];
154
+ if (allowedTypes.includes('.jpg')) {
155
+ allowedTypes.push('.jpeg');
156
+ }
157
+ return file => {
158
+ if (acceptAny) return true;
159
+ const extension = '.' + file.name.split('.').pop();
160
+ return allowedTypes.includes(file.type) || allowedTypes.includes(extension);
161
+ };
162
+ });
163
+
164
+ // Watchers
165
+ watch(
166
+ () => props.modelValue,
167
+ newValue => {
168
+ internalFiles.value = newValue || [];
169
+ }
170
+ );
171
+
172
+ // Methods
173
+ function addFiles(files) {
174
+ for (const file of files) {
175
+ const internalFile = internalFiles.value.find(
176
+ item => item.file.name === file.name
177
+ );
178
+ const newFile = createInternalFile(internalFile?.file || file);
179
+
180
+ if (internalFile) {
181
+ internalFile.state = newFile.initialState;
182
+ internalFile.invalidMessageTitle = newFile.invalidMessageTitle;
183
+ internalFile.invalidMessage = newFile.invalidMessage;
184
+ } else {
185
+ internalFiles.value.push(newFile);
186
+ }
187
+ }
188
+ // clear input we do not need to maintain it
189
+ fileInput.value.value = '';
190
+ emit('update:modelValue', internalFiles.value);
191
+ }
192
+
193
+ function createInternalFile(file) {
194
+ const initialState = props.initialStateUploading
195
+ ? STATES.UPLOADING
196
+ : STATES.NONE;
197
+ const isTypeNotAllowed = !isFileTypeAllowed.value(file);
198
+ const invalidMessageTitle = isTypeNotAllowed ? 'Invalid file type' : '';
199
+ const invalidMessage = isTypeNotAllowed
200
+ ? `"${file.name}" does not have a valid file type.`
201
+ : '';
202
+
203
+ return {
204
+ state: initialState,
205
+ file,
206
+ invalidMessageTitle,
207
+ invalidMessage,
208
+ };
209
+ }
210
+
211
+ function onChange(ev) {
212
+ if (ev.target.files.length !== 0 && props.clearOnReselect) {
213
+ internalFiles.value = [];
214
+ }
215
+ addFiles(ev.target.files);
216
+ }
217
+
218
+ function onDragEvent(evt) {
219
+ if (Array.prototype.indexOf.call(evt.dataTransfer.types, 'Files') === -1) {
220
+ return;
221
+ }
222
+
223
+ if (evt.type === 'dragleave') {
224
+ allowDrop.value = false;
225
+ return;
226
+ }
227
+
228
+ if (evt.type === 'dragover') {
229
+ evt.preventDefault();
230
+ const dropEffect = 'copy';
231
+ if (Array.isArray(evt.dataTransfer.types)) {
232
+ try {
233
+ // IE11 throws a "permission denied" error accessing `.effectAllowed`
234
+ evt.dataTransfer.effectAllowed = dropEffect;
235
+ } catch (e) {
236
+ // ignore
237
+ }
238
+ }
239
+ evt.dataTransfer.dropEffect = dropEffect;
240
+ allowDrop.value = true;
241
+ }
242
+
243
+ if (evt.type === 'drop') {
244
+ evt.preventDefault();
245
+ addFiles(evt.dataTransfer.files);
246
+ allowDrop.value = false;
247
+ }
248
+ }
249
+
250
+ function onItemRemove(index) {
251
+ internalFiles.value.splice(index, 1);
252
+ emit('update:modelValue', this.internalFiles);
253
+ }
254
+
255
+ function onKeyHit() {
256
+ fileInput.value.click();
257
+ }
258
+
259
+ // Lifecycle Hooks
260
+ onMounted(() => {
261
+ internalFiles.value = props.modelValue || [];
262
+ });
263
+
264
+ // exposed methods
265
+ defineExpose({
266
+ setState(index, state) {
267
+ if ([STATES.COMPLETE, STATES.UPLOADING, STATES.NONE].includes(state)) {
268
+ internalFiles.value[index].state = state;
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,
279
+ });
280
+ </script>
281
+
282
+ <script>
283
+ export default {
284
+ inheritAttrs: false,
285
+ };
286
+ </script>
@@ -0,0 +1,92 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ `${carbonPrefix}--file__selected-file`,
5
+ { [`${carbonPrefix}--file__selected-file--invalid`]: isInvalid },
6
+ ]"
7
+ >
8
+ <p :class="`${carbonPrefix}--file-filename`" :title="item.file?.name">
9
+ {{ item.file?.name }}
10
+ </p>
11
+ <span :class="`${carbonPrefix}--file__state-container`">
12
+ <div
13
+ v-if="item.state === 'uploading'"
14
+ :class="`${carbonPrefix}--inline-loading__animation`"
15
+ >
16
+ <div
17
+ data-inline-loading-spinner
18
+ :class="`${carbonPrefix}--loading ${carbonPrefix}--loading--small`"
19
+ >
20
+ <svg
21
+ :class="`${carbonPrefix}--loading__svg`"
22
+ viewBox="-75 -75 150 150"
23
+ >
24
+ <circle
25
+ :class="`${carbonPrefix}--loading__background`"
26
+ cx="0"
27
+ cy="0"
28
+ r="37.5"
29
+ />
30
+ <circle
31
+ :class="`${carbonPrefix}--loading__stroke`"
32
+ cx="0"
33
+ cy="0"
34
+ r="37.5"
35
+ />
36
+ </svg>
37
+ </div>
38
+ </div>
39
+ <CheckmarkFilled16
40
+ v-if="item.state === 'complete'"
41
+ :class="`${carbonPrefix}--file-complete`"
42
+ />
43
+ <WarningFilled16
44
+ v-if="isInvalid"
45
+ :class="`${carbonPrefix}--file--invalid`"
46
+ />
47
+ <button
48
+ v-if="removable"
49
+ type="button"
50
+ :class="`${carbonPrefix}--file-close`"
51
+ :alt="removeAriaLabel"
52
+ :arial-label="removeAriaLabel"
53
+ @click="emit('remove', item)"
54
+ >
55
+ <Close16 />
56
+ <span :class="`${carbonPrefix}--visually-hidden`">
57
+ {{ removeAriaLabel }}
58
+ </span>
59
+ </button>
60
+ </span>
61
+ <!-- check role (alert) and id / accessibility -->
62
+ <div v-if="isInvalid" :class="`${carbonPrefix}--form-requirement`">
63
+ <div :class="`${carbonPrefix}--form-requirement__title`">
64
+ {{ item.invalidMessageTitle || 'Invalid file' }}
65
+ </div>
66
+ <p :class="`${carbonPrefix}--form-requirement__supplement`">
67
+ {{ item.invalidMessage }}
68
+ </p>
69
+ </div>
70
+ </div>
71
+ </template>
72
+
73
+ <script setup>
74
+ import { computed } from 'vue';
75
+ import { carbonPrefix } from '../../global/settings';
76
+ import CheckmarkFilled16 from '@carbon/icons-vue/es/checkmark--filled/16';
77
+ import WarningFilled16 from '@carbon/icons-vue/es/warning--filled/16';
78
+ import Close16 from '@carbon/icons-vue/es/close/16';
79
+
80
+ const emit = defineEmits(['remove']);
81
+
82
+ const props = defineProps({
83
+ item: Object,
84
+ removable: Boolean,
85
+ removeAriaLabel: { type: String, default: 'Remove selected file' },
86
+ });
87
+
88
+ // Computed
89
+ const isInvalid = computed(() => {
90
+ return props.item.invalidMessage && props.item.invalidMessage.length;
91
+ });
92
+ </script>
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div :class="`${carbonPrefix}--form-item`">
3
+ <cv-skeleton-text heading width="100px" />
4
+ <cv-skeleton-text
5
+ width="225px"
6
+ :class="`${carbonPrefix}--label-description`"
7
+ />
8
+ <cv-button-skeleton />
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+ import CvSkeletonText from '../CvSkeletonText';
14
+ import { CvButtonSkeleton } from '../CvButton';
15
+ import { carbonPrefix } from '../../global/settings';
16
+ </script>
@@ -0,0 +1,10 @@
1
+ export const STATES = {
2
+ NONE: '',
3
+ UPLOADING: 'uploading',
4
+ COMPLETE: 'complete',
5
+ };
6
+
7
+ export const KINDS = {
8
+ DRAG_TARGET: 'drag-target',
9
+ BUTTON: 'button',
10
+ };
@@ -0,0 +1,5 @@
1
+ import CvFileUploader from './CvFileUploader.vue';
2
+ import CvFileUploaderSkeleton from './CvFileUploaderSkeleton.vue';
3
+
4
+ export { CvFileUploader, CvFileUploaderSkeleton };
5
+ export default CvFileUploader;
@@ -176,6 +176,7 @@ Migration notes:
176
176
  label: 'Choose replicants',
177
177
  helperText: 'Do Androids Dream of Electric Sheep?',
178
178
  title: 'Characters',
179
+ disabled: false,
179
180
  }}
180
181
  argTypes={{
181
182
  filterTagKind: {
@@ -231,7 +232,6 @@ Migration notes:
231
232
  'autoHighlight',
232
233
  'change',
233
234
  'direction',
234
- 'disabled',
235
235
  'filter',
236
236
  'filterTagKind',
237
237
  'filterable',
@@ -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 = `<cv-toast-notification v-bind="args" @close="onClose" />`;
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`">{{ title }}</h3>
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}--inline-notification__close-icon`" />
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
- <cv-overflow-menu
29
- :flip-menu="flipMenu"
30
- :up="up"
31
- :offset="offset"
32
- :label="label"
33
- :tip-position="tipPosition"
34
- :tip-alignment="tipAlignment"
35
- @change=onChange>
36
- <cv-overflow-menu-item value="item 1" primary-focus>list item 1</cv-overflow-menu-item>
37
- <cv-overflow-menu-item value="item 2" disabled>list item 2</cv-overflow-menu-item>
38
- <cv-overflow-menu-item value="item 3" danger>list item 3</cv-overflow-menu-item>
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>