@carbon/vue 3.0.8-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 (26) hide show
  1. package/dist/carbon-vue-3.common.js +412 -40
  2. package/dist/carbon-vue-3.common.js.map +1 -1
  3. package/dist/carbon-vue-3.umd.js +412 -40
  4. package/dist/carbon-vue-3.umd.js.map +1 -1
  5. package/dist/carbon-vue-3.umd.min.js +4 -4
  6. package/dist/carbon-vue-3.umd.min.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/components/CvNotification/CvToastNotification.stories.js +71 -1
  9. package/src/components/CvNotification/CvToastNotification.vue +6 -4
  10. package/src/components/CvOverflowMenu/CvOverflowMenu.stories.mdx +68 -12
  11. package/src/components/CvOverflowMenu/CvOverflowMenu.vue +39 -45
  12. package/src/components/CvOverflowMenu/CvOverflowMenuItem.vue +6 -11
  13. package/src/components/CvOverflowMenu/index.js +2 -1
  14. package/src/components/CvStructuredList/CvStructuredList.stories.js +141 -0
  15. package/src/components/CvStructuredList/CvStructuredList.vue +44 -0
  16. package/src/components/CvStructuredList/CvStructuredListData.vue +19 -0
  17. package/src/components/CvStructuredList/CvStructuredListHeading.vue +11 -0
  18. package/src/components/CvStructuredList/CvStructuredListItem.vue +47 -0
  19. package/src/components/CvStructuredList/CvStructuredListItemSelectable.vue +56 -0
  20. package/src/components/CvStructuredList/CvStructuredListItemStandard.vue +11 -0
  21. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredList.spec.js.snap +73 -0
  22. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListData.spec.js.snap +5 -0
  23. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListHeading.spec.js.snap +9 -0
  24. package/src/components/CvStructuredList/__tests__/__snapshots__/CvStructuredListItem.spec.js.snap +7 -0
  25. package/src/components/CvStructuredList/index.js +12 -0
  26. 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.8-alpha.0",
4
+ "version": "3.0.9-alpha.0",
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": "15a95f30d38d6b600fd1b70274502895e777e02c"
209
+ "gitHead": "39dd5beb19a710758bd9c2b44a413f9cc296d31b"
210
210
  }
@@ -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>
@@ -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,141 @@
1
+ import { action } from '@storybook/addon-actions';
2
+ import { ref } from 'vue';
3
+ import {
4
+ sbCompPrefix,
5
+ storyParametersObject,
6
+ } from '../../global/storybook-utils';
7
+ import {
8
+ CvStructuredList,
9
+ CvStructuredListHeading,
10
+ CvStructuredListData,
11
+ CvStructuredListItem,
12
+ } from '.';
13
+
14
+ export default {
15
+ title: `${sbCompPrefix}/CvStructuredList`,
16
+ component: CvStructuredList,
17
+ argTypes: {
18
+ selectable: {
19
+ type: 'boolean',
20
+ table: {
21
+ type: { summary: 'boolean' },
22
+ category: 'props',
23
+ },
24
+ description:
25
+ 'Makes list items selectable (prop on cv-structured-list component)',
26
+ },
27
+ condensed: {
28
+ type: 'boolean',
29
+ table: {
30
+ type: { summary: 'boolean' },
31
+ category: 'props',
32
+ },
33
+ description:
34
+ 'Condense spacing of the structured list (prop on cv-structured-list component)',
35
+ },
36
+ noWrap: {
37
+ type: 'boolean',
38
+ table: {
39
+ type: { summary: 'boolean' },
40
+ category: 'props',
41
+ },
42
+ description:
43
+ 'Prevent text wrapping in list data (prop on cv-structured-list-data component)',
44
+ },
45
+ },
46
+ };
47
+
48
+ const DefaultListItems = [
49
+ {
50
+ id: 'item-1',
51
+ data: [
52
+ 'Item_1',
53
+ 'Item_1',
54
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque vulputate nisl a porttitor interdum.',
55
+ ],
56
+ },
57
+ {
58
+ id: 'item-2',
59
+ data: [
60
+ 'Item_2',
61
+ 'Item_2',
62
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc dui magna, finibus id tortor sed, aliquet bibendum augue. Aenean posuere sem vel euismod dignissim. Nulla ut cursus dolor. Pellentesque vulputate nisl a porttitor interdum.',
63
+ ],
64
+ },
65
+ ];
66
+
67
+ const template = `
68
+ <div>
69
+ <cv-structured-list v-bind="args">
70
+ <template v-slot:headings>
71
+ <cv-structured-list-heading>
72
+ Heading 1
73
+ </cv-structured-list-heading>
74
+ <cv-structured-list-heading>
75
+ Heading 2
76
+ </cv-structured-list-heading>
77
+ <cv-structured-list-heading>
78
+ Heading 3
79
+ </cv-structured-list-heading>
80
+ </template>
81
+
82
+ <template v-slot:items>
83
+ <cv-structured-list-item v-for="({id, data}, index) in DefaultListItems" :key="index" name="group-1" :value="id" v-model="listValue" @change="onChange">
84
+ <cv-structured-list-data v-for="(itemData, dataIndex) in data" :key="dataIndex" :no-wrap="args.noWrap">{{ itemData }}</cv-structured-list-data>
85
+ </cv-structured-list-item>
86
+ </template>
87
+ </cv-structured-list>
88
+
89
+ <div style="margin-top:1rem; background-color: #888888; padding:1rem" v-if="args.withVModel">
90
+ <div style="font-size: 150%">Sample interaction</div>
91
+ <template
92
+ v-for="({id}, vmodelIndex) in DefaultListItems"
93
+ :key="vmodelIndex"
94
+ >
95
+ <input name="listValue" :id="id" type="radio" @change="(ev) => {listValue = ev.target.id}" :checked="id === listValue" />
96
+ <label :for="id" style="margin-right: 16px;">{{id}}:</label>
97
+ </template>
98
+
99
+ <div style="margin-top: 16px;">Checked: <span style="font-weight: bold;">{{ listValue }}</span></div>
100
+ </div>
101
+ </div>
102
+ `;
103
+
104
+ const Template = args => {
105
+ return {
106
+ components: {
107
+ CvStructuredList,
108
+ CvStructuredListHeading,
109
+ CvStructuredListData,
110
+ CvStructuredListItem,
111
+ },
112
+ setup: () => ({
113
+ args,
114
+ listValue: ref(DefaultListItems[0].id),
115
+ DefaultListItems,
116
+ onChange: action('change'),
117
+ }),
118
+ template,
119
+ };
120
+ };
121
+
122
+ export const Default = Template.bind({});
123
+ Default.args = {
124
+ withVModel: false,
125
+ };
126
+ Default.parameters = storyParametersObject(
127
+ Default.parameters,
128
+ template,
129
+ Default.args
130
+ );
131
+
132
+ export const VModel = Template.bind({});
133
+ VModel.args = {
134
+ selectable: true,
135
+ withVModel: true,
136
+ };
137
+ VModel.parameters = storyParametersObject(
138
+ VModel.parameters,
139
+ template,
140
+ VModel.args
141
+ );
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ `${carbonPrefix}--structured-list`,
5
+ {
6
+ [`${carbonPrefix}--structured-list--selection`]: selectable,
7
+ [`${carbonPrefix}--structured-list--condensed`]: condensed,
8
+ },
9
+ ]"
10
+ :data-structured-list="selectable"
11
+ >
12
+ <div :class="`${carbonPrefix}--structured-list-thead`">
13
+ <div
14
+ :class="`${carbonPrefix}--structured-list-row ${carbonPrefix}--structured-list-row--header-row`"
15
+ >
16
+ <slot name="headings"></slot>
17
+ <div
18
+ v-if="selectable"
19
+ :class="`${carbonPrefix}--structured-list-th`"
20
+ ></div>
21
+ </div>
22
+ </div>
23
+ <div :class="`${carbonPrefix}--structured-list-tbody`">
24
+ <slot name="items"></slot>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script setup>
30
+ import { defineEmits, provide } from 'vue';
31
+ import { carbonPrefix } from '../../global/settings';
32
+
33
+ const props = defineProps({
34
+ selectable: Boolean,
35
+ condensed: Boolean,
36
+ });
37
+
38
+ const emit = defineEmits(['change']);
39
+
40
+ provide('change', val => {
41
+ emit('change', val);
42
+ });
43
+ provide('selectable', props.selectable);
44
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ `cv-structured-list-data ${carbonPrefix}--structured-list-td`,
5
+ {
6
+ [`${carbonPrefix}--structured-list-content--nowrap`]: noWrap,
7
+ },
8
+ ]"
9
+ >
10
+ <slot></slot>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup>
15
+ import { carbonPrefix } from '../../global/settings';
16
+ defineProps({
17
+ noWrap: Boolean,
18
+ });
19
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <div
3
+ :class="`cv-structured-list-heading ${carbonPrefix}--structured-list-th`"
4
+ >
5
+ <slot></slot>
6
+ </div>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { carbonPrefix } from '../../global/settings';
11
+ </script>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <component
3
+ :is="tagType"
4
+ v-bind="$attrs"
5
+ class="cv-structured-list-item"
6
+ :value="value"
7
+ :modelValue="modelValue"
8
+ >
9
+ <slot></slot>
10
+ </component>
11
+ </template>
12
+
13
+ <script setup>
14
+ import { computed, inject, provide } from 'vue';
15
+ import CvStructuredListItemStandard from './CvStructuredListItemStandard.vue';
16
+ import CvStructuredListItemSelectable from './CvStructuredListItemSelectable.vue';
17
+
18
+ defineOptions({
19
+ inheritAttrs: false,
20
+ });
21
+
22
+ defineProps({
23
+ modelValue: {
24
+ type: String,
25
+ default: undefined,
26
+ },
27
+ value: {
28
+ type: String,
29
+ default: undefined,
30
+ },
31
+ });
32
+
33
+ const selectable = inject('selectable');
34
+ const change = inject('change');
35
+ const emit = defineEmits(['change']);
36
+
37
+ provide('onRadioItemChange', clickedItemCvId => {
38
+ emit('change', clickedItemCvId);
39
+ change(clickedItemCvId); //emit to parent
40
+ });
41
+
42
+ const tagType = computed(() => {
43
+ return selectable
44
+ ? CvStructuredListItemSelectable
45
+ : CvStructuredListItemStandard;
46
+ });
47
+ </script>