@vcita/design-system 1.3.2 → 1.3.4

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 (56) hide show
  1. package/config/locales/ds.en.yml +4 -0
  2. package/dist/@vcita/design-system.esm.js +1882 -1140
  3. package/dist/@vcita/design-system.min.js +2 -2
  4. package/dist/@vcita/design-system.ssr.js +1688 -965
  5. package/init/DesignSystem.js +3 -1
  6. package/init/initI18n.js +24 -16
  7. package/package.json +2 -1
  8. package/src/components/VcActionList/VcActionList.spec.js +16 -7
  9. package/src/components/VcActionList/VcActionList.stories.js +16 -3
  10. package/src/components/VcActionList/VcActionList.vue +35 -11
  11. package/src/components/VcBottomActions/VcBottomActions.vue +2 -1
  12. package/src/components/VcBottomSheet/VcBottomSheet.stories.js +6 -13
  13. package/src/components/VcBottomSheet/VcBottomSheet.vue +2 -3
  14. package/src/components/VcButton/VcButton.vue +1 -1
  15. package/src/components/VcCheckbox/VcCheckbox.vue +8 -1
  16. package/src/components/VcColorPicker/VcColorPicker.spec.js +206 -0
  17. package/src/components/VcColorPicker/VcColorPicker.stories.js +107 -0
  18. package/src/components/VcColorPicker/VcColorPicker.vue +270 -0
  19. package/src/components/VcFilterPanel/VcFilterPanel.spec.js +15 -0
  20. package/src/components/VcFilterPanel/VcFilterPanel.stories.js +9 -1
  21. package/src/components/VcFilterPanel/VcFilterPanel.vue +24 -3
  22. package/src/components/VcGalleryItem/VcGalleryItem.stories.js +2 -0
  23. package/src/components/VcGroupedItems/VcGroupedItems.spec.js +148 -0
  24. package/src/components/VcGroupedItems/VcGroupedItems.stories.js +135 -0
  25. package/src/components/VcGroupedItems/VcGroupedItems.vue +155 -0
  26. package/src/components/VcLink/VcLink.spec.js +3 -3
  27. package/src/components/VcLink/VcLink.stories.js +2 -6
  28. package/src/components/VcLink/VcLink.vue +1 -18
  29. package/src/components/VcMenu/VcDropdown.spec.js +120 -0
  30. package/src/components/VcMenu/VcDropdown.stories.js +272 -0
  31. package/src/components/VcMenu/VcDropdown.vue +93 -0
  32. package/src/components/VcMenu/VcMenu.spec.js +61 -10
  33. package/src/components/VcMenu/VcMenu.stories.js +38 -33
  34. package/src/components/VcMenu/VcMenu.vue +19 -3
  35. package/src/components/VcPopover/VcPopover.stories.js +2 -2
  36. package/src/components/VcRadioGroup/VcRadioGroup.spec.js +28 -0
  37. package/src/components/VcRadioGroup/VcRadioGroup.stories.js +3 -1
  38. package/src/components/VcRadioGroup/VcRadioGroup.vue +6 -1
  39. package/src/components/VcSearchPicker/VcSearchPicker.stories.js +3 -4
  40. package/src/components/VcSelectField/VcSelectField.vue +6 -0
  41. package/src/components/VcSideNav/VcSideNav.spec.js +1 -1
  42. package/src/components/VcSideNav/VcSideNav.vue +21 -104
  43. package/src/components/VcTextField/VcTextField.spec.js +13 -0
  44. package/src/components/VcTextField/VcTextField.stories.js +2 -1
  45. package/src/components/VcTextField/VcTextField.vue +11 -0
  46. package/src/components/VcTooltip/VcTooltip.stories.js +3 -1
  47. package/src/components/VcTooltip/VcTooltip.vue +6 -1
  48. package/src/components/index.js +4 -0
  49. package/src/components/list/VcBaseListItem/VcBaseListItem.stories.js +22 -13
  50. package/src/components/list/VcBaseListItem/VcBaseListItem.vue +4 -1
  51. package/src/components/list/VcList/VcList.stories.js +245 -240
  52. package/src/components/list/VcList/VcList.vue +11 -4
  53. package/src/components/page/layouts/centeredPage/CenteredPageLayout.stories.js +17 -16
  54. package/styles/variables.scss +1 -0
  55. package/styles/vuetify-variables.scss +9 -1
  56. package/CHANGELOG.md +0 -342
@@ -0,0 +1,270 @@
1
+ <template>
2
+ <div class="VcColorPicker d-flex flex-column"
3
+ ref="pickerInput" :data-qa="dataQa"
4
+ v-click-outside="closePicker">
5
+ <div class="VcColorPicker__input d-flex align-center">
6
+ <VcSelectField
7
+ :data-qa="`${dataQa}_select`"
8
+ :disabled="disabled"
9
+ class="VcColorPicker__input__dropdown"
10
+ :class="{'error--text' : getError}"
11
+ @click.native.stop.prevent="showPicker = true"
12
+ :readonly="!disabled">
13
+ <template v-slot:prepend>
14
+ <div class="color-preview" :style="{backgroundColor: color}"></div>
15
+ </template>
16
+ </VcSelectField>
17
+ <VcTextField
18
+ :data-qa="`${dataQa}_input`"
19
+ :class="{'error--text' : getError}"
20
+ :label="$dst('ds.color_picker.label')"
21
+ :disabled="disabled"
22
+ @blur="validateInput"
23
+ @input="onInputUpdate"
24
+ v-model="inputColor"></VcTextField>
25
+ </div>
26
+ <div class="VcColorPicker__messages mt-1"
27
+ :class="{'error-message' : getError}"
28
+ v-if="!showPicker">
29
+ <span v-if="hint && !getError" :data-qa="`${dataQa}-hint`">{{ hint }}</span>
30
+ <span v-if="getError" :data-qa="`${dataQa}-error`">{{ getError }}</span>
31
+ </div>
32
+ <div class="VcColorPicker__picker mt-2 pa-2" v-if="showPicker && !isMobile">
33
+ <v-color-picker
34
+ :hide-mode-switch="hexMode"
35
+ mode="hexa"
36
+ :value="color"
37
+ show-swatches
38
+ flat
39
+ :width="getPickerWidth"
40
+ :data-qa="`${dataQa}_picker`"
41
+ :swatches="swatches"
42
+ @update:color="onPickerUpdate">
43
+ </v-color-picker>
44
+ </div>
45
+ <v-bottom-sheet
46
+ v-if="isMobile"
47
+ v-model="showPicker">
48
+ <v-color-picker
49
+ :data-qa="`${dataQa}_picker`"
50
+ v-if="showPicker"
51
+ :hide-mode-switch="hexMode"
52
+ class="VcColorPicker__picker"
53
+ mode="hexa"
54
+ :value="color"
55
+ show-swatches
56
+ flat
57
+ :width="getPickerWidth"
58
+ @update:color="onPickerUpdate"
59
+ :swatches="swatches">
60
+ </v-color-picker>
61
+ </v-bottom-sheet>
62
+ </div>
63
+ </template>
64
+
65
+ <script>
66
+ const regexHex = /^#[0-9A-F]{6}$/i;
67
+ const regexHexa = /^#[0-9A-F]{8}$/i;
68
+ const swatchesConst = [["#EF4444", '#F97316'], ['#FACC15', '#4ADE80'], ['#2DD4BF', '#3B82F6'], ['#6467F2', '#EC4899'], ['#F43F5E', '#D946EF'], ['#8B5CF6', '#0EA5E9'], ['#10B981', '#84CC16']];
69
+
70
+ // import ClickOutside from 'vue-click-outside';
71
+ import VcTextField from "@/components/VcTextField/VcTextField.vue";
72
+ import VcSelectField from '@/components/VcSelectField/VcSelectField.vue';
73
+
74
+ export default {
75
+ name: "VcColorPicker",
76
+ // directives: {
77
+ // ClickOutside
78
+ // },
79
+ components: {VcTextField, VcSelectField},
80
+ props: {
81
+ dataQa: {
82
+ type: String,
83
+ default: 'VcColorPicker'
84
+ },
85
+ disabled: {
86
+ type: Boolean,
87
+ default: false
88
+ },
89
+ hint: {
90
+ type: String,
91
+ default: ""
92
+ },
93
+ color: {
94
+ type: String,
95
+ default: "",
96
+ validator: prop => !prop || (regexHex.test(prop)) || (regexHexa.test(prop)),
97
+ },
98
+ /**
99
+ * Similar to Vuetify rules prop - array of functions that return true or the message error as a string
100
+ * See an example in the storybook
101
+ */
102
+ rules: {
103
+ type: Array,
104
+ validator: prop => prop.every(rule => typeof rule === "function"),
105
+ },
106
+ hexMode: {
107
+ type: Boolean,
108
+ default: false
109
+ }
110
+ },
111
+ model: {
112
+ prop: 'color',
113
+ event: 'change'
114
+ },
115
+ data(vm) {
116
+ return {
117
+ showPicker: false,
118
+ inputColor: this.getHexMode(vm.color?.toUpperCase()),
119
+ swatches: swatchesConst,
120
+ }
121
+ },
122
+ methods: {
123
+ isValidHexColor(val) {
124
+ return (regexHex.test(val)) || (regexHexa.test(val));
125
+ },
126
+ closePicker() {
127
+ if (this.isMobile) return; // Don't close the picker after it's clicked
128
+ this.showPicker = false;
129
+ },
130
+ onPickerUpdate(color) {
131
+ this.inputColor = color.hexa.toUpperCase();
132
+ this.$emit('change', this.inputColor);
133
+ },
134
+ validateInput() {
135
+ this.inputColor = (this.isValidHexColor(this.inputColor) ? this.inputColor : this.color).toUpperCase();
136
+ },
137
+ onInputUpdate(color) {
138
+ if (this.isValidHexColor(color)) this.$emit('change', color.toUpperCase())
139
+ },
140
+ getHexMode(color) {
141
+ if (this.hexMode && color?.toString().match(/#[a-zA-Z0-9]{8}/)) {
142
+ return color.substr(0, 7).toUpperCase();
143
+ }
144
+ return color;
145
+ },
146
+ },
147
+ computed: {
148
+ getPickerWidth() {
149
+ if (this.isMobile) return window.innerWidth;
150
+ else return (this.$refs?.pickerInput?.offsetWidth);
151
+ },
152
+ isMobile() {
153
+ return (!this.$vuetify.breakpoint.mdAndUp);
154
+ },
155
+ getError() {
156
+ if (!this.rules) return false;
157
+ let errorMessages = this.rules.map((rule) => {
158
+ const resolve = rule.call(this, this.inputColor)
159
+ if (typeof (resolve) === 'string') return resolve;
160
+ }).filter(item => !!item);
161
+ return errorMessages[0];
162
+ }
163
+ },
164
+ watch: {
165
+ color(value) {
166
+ this.inputColor = this.getHexMode(value);
167
+ }
168
+ }
169
+ }
170
+ </script>
171
+
172
+ <style lang="scss">
173
+ .v-dialog:has(.v-color-picker__color) {
174
+ .v-color-picker__color {
175
+ &:has(span.v-icon) {
176
+ border: 2px solid #FFFFFF;
177
+ box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.25);
178
+
179
+ span.v-icon {
180
+ display: none;
181
+ }
182
+ }
183
+ }
184
+ }
185
+ </style>
186
+ <style lang="scss" scoped>
187
+ .VcColorPicker {
188
+ direction: ltr !important;
189
+
190
+ &__input {
191
+ &__dropdown {
192
+ width: var(--size-value18);
193
+ max-width: var(--size-value18);
194
+
195
+ .color-preview {
196
+ width: var(--size-value6);
197
+ height: var(--size-value6);
198
+ border-radius: var(--border-radius-circle);
199
+ }
200
+ }
201
+ }
202
+
203
+ &__picker {
204
+ box-shadow: var(--shadow-6);
205
+ }
206
+
207
+ &__messages {
208
+ font-weight: var(--font-weight-medium);
209
+ font-size: var(--font-size-xx-small);
210
+ line-height: var(--size-value4);
211
+ color: var(--gray-darken-3);
212
+
213
+ &.error-message {
214
+ color: var(--red);
215
+ }
216
+ }
217
+
218
+ ::v-deep {
219
+ .VcSelectField {
220
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
221
+
222
+ fieldset {
223
+ margin-top: 1px;
224
+ }
225
+ }
226
+
227
+ .VcTextInput.v-text-field .v-input__slot {
228
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
229
+ }
230
+
231
+ .v-color-picker__canvas {
232
+ border-radius: var(--border-radius);
233
+ }
234
+
235
+ .v-dialog__content {
236
+ background-color: red;
237
+ }
238
+
239
+ .v-color-picker__color {
240
+ &:has(span.v-icon) {
241
+ border: 2px solid #FFFFFF;
242
+ box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.25);
243
+
244
+ span.v-icon {
245
+ display: none;
246
+ }
247
+ }
248
+ }
249
+
250
+ .v-color-picker__input {
251
+ font-size: var(--font-size-x-small);
252
+ font-weight: var(--font-weight-medium2);
253
+ }
254
+
255
+ .v-color-picker__swatches > div {
256
+ padding: unset;
257
+ justify-content: space-between;
258
+ }
259
+
260
+ .v-color-picker__controls {
261
+ padding: var(--size-value4) var(--size-value2) var(--size-value6);
262
+ }
263
+
264
+ .v-color-picker__edit {
265
+ padding-bottom: var(--size-value4);
266
+ border-bottom: var(--border-frame);
267
+ }
268
+ }
269
+ }
270
+ </style>
@@ -77,4 +77,19 @@ describe("VcFilterPanel.vue", () => {
77
77
  const slotContent = getByText('content');
78
78
  expect(slotContent).toBeInTheDocument();
79
79
  });
80
+ it("does not render header with the right prop", async () => {
81
+ const {queryByText, updateProps} = renderWithVuetify(VcFilterPanel, {
82
+ props: {
83
+ title: 'filter panel',
84
+ shouldDisplayHeader: true,
85
+ },
86
+ })
87
+ let title = queryByText('filter panel');
88
+ expect(title).toBeInTheDocument();
89
+ await updateProps({
90
+ shouldDisplayHeader: false,
91
+ })
92
+ title = queryByText('filter panel');
93
+ expect(title).not.toBeInTheDocument();
94
+ });
80
95
  });
@@ -9,6 +9,8 @@ const Template = (args, {argTypes}) => ({
9
9
  <VcFilterPanel :title="title"
10
10
  :is-loading="isLoading"
11
11
  :show-close-button="showCloseButton"
12
+ :type="type"
13
+ :shouldDisplayHeader="shouldDisplayHeader"
12
14
  :data-qa="dataQa"
13
15
  @close="onClose"/>
14
16
  </div>`,
@@ -21,7 +23,9 @@ Playground.args = {
21
23
  title: 'Filter',
22
24
  isLoading: false,
23
25
  showCloseButton: true,
24
- dataQa: 'VcFilterPanel'
26
+ dataQa: 'VcFilterPanel',
27
+ type: 'primary',
28
+ shouldDisplayHeader: true,
25
29
  }
26
30
 
27
31
  export default {
@@ -30,6 +34,10 @@ export default {
30
34
  component: VcFilterPanelCmp,
31
35
  argTypes: {
32
36
  onClose: {action: 'close', table: {disable: true}},
37
+ type: {
38
+ options: ['primary', 'secondary'],
39
+ control: {type: 'radio'}
40
+ },
33
41
  },
34
42
  parameters: {
35
43
  design: {
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <VcLayout column align-content-space-between class="VcFilterPanel" :data-qa="dataQa">
2
+ <VcLayout column align-content-space-between class="VcFilterPanel" :class="`vc-${flavor}`" :data-qa="dataQa">
3
3
  <VcLayout class="VcFilterPanel-container" column>
4
- <VcLayout class="VcFilterPanel-label-container">
4
+ <VcLayout class="VcFilterPanel-label-container" v-if="shouldDisplayHeader">
5
5
  <div class="filter">
6
6
  <span class="filter-label">{{ title }}</span>
7
7
  <slot name="header"/>
@@ -44,6 +44,15 @@ export default {
44
44
  type: Boolean,
45
45
  default: false,
46
46
  },
47
+ flavor: {
48
+ type: String,
49
+ default: 'primary',
50
+ validator: prop => ['primary', 'secondary'].includes(prop),
51
+ },
52
+ shouldDisplayHeader: {
53
+ type: Boolean,
54
+ default: true,
55
+ },
47
56
  dataQa: {
48
57
  type: String,
49
58
  default: 'VcFilterPanel'
@@ -101,6 +110,18 @@ export default {
101
110
  }
102
111
  }
103
112
 
113
+ &.vc-secondary {
114
+ .filter {
115
+ border-bottom: none;
116
+ background-color: var(--modal-bg-color);
117
+
118
+ .filter-label {
119
+ font-weight: 700;
120
+ font-size: 18px;
121
+ }
122
+ }
123
+ }
124
+
104
125
  .VcFilterPanel-content-wrapper {
105
126
  flex-grow: 1;
106
127
  }
@@ -125,7 +146,7 @@ export default {
125
146
  margin-right: var(--size-value0);
126
147
 
127
148
  svg {
128
- fill:var(--gray-darken-2);
149
+ fill: var(--gray-darken-2);
129
150
  width: var(--size-value4);
130
151
  height: var(--size-value4);
131
152
  }
@@ -9,6 +9,8 @@ const baseProps = {
9
9
  selected: false,
10
10
  disabled: false,
11
11
  dataQa: 'VcGalleryItem',
12
+ actionsSlotContent: null,
13
+ labelSlotContent: null,
12
14
  }
13
15
 
14
16
  const Template = (args, {argTypes}) => ({
@@ -0,0 +1,148 @@
1
+ import '@testing-library/jest-dom';
2
+ import VcGroupedItems from "./VcGroupedItems.vue";
3
+ import Vue from 'vue';
4
+ import Vuetify from 'vuetify';
5
+ import {render} from "@testing-library/vue";
6
+ import init from "../../../testing-library.config";
7
+ import userEvent from "@testing-library/user-event";
8
+
9
+ init();
10
+
11
+ Vue.use(Vuetify);
12
+
13
+ const basicProps = {
14
+ itemGroups: [
15
+ {
16
+ label: 'GROUP 1',
17
+ id: 1,
18
+ items: [
19
+ {id: '1', label: 'Menu Item 1'},
20
+ {id: '2', label: 'Menu Item 2'},
21
+ {id: '3', label: 'Menu Item 3'},
22
+ {id: '4', label: 'Menu Item 4'},
23
+ {id: '5', label: 'Menu Item 5', disabled: true},
24
+ ]
25
+ },
26
+ {
27
+ label: 'GROUP 2',
28
+ id: 2,
29
+ items: [
30
+ {id: '6', label: 'Menu Item 6'},
31
+ {id: '7', label: 'Menu Item 7'},
32
+ {id: '8', label: 'Menu Item 8'},
33
+ {id: '9', label: 'Menu Item 9'},
34
+ {id: '10', label: 'Menu Item 10'},
35
+ ]
36
+ },
37
+ ],
38
+ showDividers: false,
39
+ flavor: 'flat',
40
+ dataQa: 'VcGroupedItems',
41
+ }
42
+
43
+ describe("VcGroupedItems.vue", () => {
44
+
45
+ const renderWithVuetify = (component, options, callback, isMobile = false) => {
46
+ const root = document.createElement('div')
47
+ root.setAttribute('data-app', 'true')
48
+
49
+ const vuetify = new Vuetify()
50
+ if (isMobile) {
51
+ const breakpoint = {
52
+ init: jest.fn(),
53
+ framework: {},
54
+ smAndDown: true,
55
+ }
56
+
57
+ vuetify.framework.breakpoint = breakpoint;
58
+ }
59
+
60
+ return render(
61
+ component,
62
+ {
63
+ container: document.body.appendChild(root),
64
+ // for Vuetify components that use the vuetify instance property
65
+ vuetify,
66
+ ...options,
67
+ mocks: {
68
+ $t: value => value,
69
+ $dst: value => value, // <- for the design system
70
+ },
71
+ },
72
+ callback,
73
+ )
74
+ }
75
+
76
+ it("mounts and shows groups and items", () => {
77
+ // Queries: https://testing-library.com/docs/queries/about#types-of-queries
78
+ const {container, getByTestId, getByText} = renderWithVuetify(VcGroupedItems, {
79
+ props: {
80
+ ...basicProps,
81
+ }
82
+ });
83
+
84
+ // Expect options: https://github.com/testing-library/jest-dom
85
+ expect(container).toHaveAttribute('data-app', 'true');
86
+
87
+ // Make sure the component has the data-qa attribute
88
+ const component = getByTestId('VcGroupedItems');
89
+ expect(component).toBeInTheDocument();
90
+
91
+ const group1 = getByText('GROUP 1');
92
+ expect(group1).toBeInTheDocument();
93
+
94
+ const group2 = getByText('GROUP 2');
95
+ expect(group2).toBeInTheDocument();
96
+
97
+ for (let i = 1; i < 11; i++) {
98
+ const item = getByText(`Menu Item ${i}`);
99
+ expect(item).toBeInTheDocument();
100
+ }
101
+ });
102
+
103
+ it("shows dividers", async () => {
104
+ const {getByRole, updateProps, getAllByRole} = renderWithVuetify(VcGroupedItems, {
105
+ props: {
106
+ ...basicProps,
107
+ showDividers: true,
108
+ }
109
+ });
110
+
111
+ const divider = getByRole('separator');
112
+ expect(divider).toBeInTheDocument();
113
+
114
+ const thirdGroup = {
115
+ label: 'GROUP 3',
116
+ id: 3,
117
+ items: [
118
+ {id: '11', label: 'Menu Item 11'},
119
+ {id: '12', label: 'Menu Item 12'},
120
+ {id: '13', label: 'Menu Item 13'},
121
+ {id: '14', label: 'Menu Item 14'},
122
+ {id: '15', label: 'Menu Item 15'},
123
+ ]
124
+ };
125
+
126
+ await updateProps({itemGroups: [...basicProps.itemGroups, thirdGroup]});
127
+
128
+ const dividers = getAllByRole('separator');
129
+ expect(dividers.length).toBe(2);
130
+ });
131
+
132
+ it("emits selection events", async () => {
133
+ const {getByText, emitted} = renderWithVuetify(VcGroupedItems, {
134
+ props: {
135
+ ...basicProps,
136
+ }
137
+ });
138
+
139
+ await userEvent.click(getByText('Menu Item 1'));
140
+ expect(emitted().change.length).toBe(1);
141
+ expect(emitted().change[0][0]).toBe('1');
142
+
143
+ await userEvent.click(getByText('Menu Item 5'));
144
+ expect(emitted().change.length).toBe(2);
145
+ expect(emitted().change[1][0]).toBe('5');
146
+ });
147
+
148
+ });
@@ -0,0 +1,135 @@
1
+ import VcGroupedItemsCmp from './VcGroupedItems';
2
+ import VcBaseDocs from '@/stories/VcBaseDocs.mdx'
3
+ import VcBadge from "@/components/VcBadge/VcBadge";
4
+ import VcIcon from "@/components/VcIcon/VcIcon";
5
+
6
+ const basicProps = {
7
+ itemGroups: [
8
+ {
9
+ label: 'GROUP 1',
10
+ id: 1,
11
+ items: [
12
+ {id: '1', label: 'Menu Item'},
13
+ {id: '2', label: 'Menu Item'},
14
+ {id: '3', label: 'Menu Item'},
15
+ {id: '4', label: 'Menu Item'},
16
+ {id: '5', label: 'Menu Item', disabled: true},
17
+ ]
18
+ },
19
+ {
20
+ label: 'GROUP 2',
21
+ id: 2,
22
+ items: [
23
+ {id: '6', label: 'Menu Item'},
24
+ {id: '7', label: 'Menu Item'},
25
+ {id: '8', label: 'Menu Item'},
26
+ {id: '9', label: 'Menu Item'},
27
+ {id: '10', label: 'Menu Item'},
28
+ ]
29
+ },
30
+ ],
31
+ showDividers: false,
32
+ flavor: 'flat',
33
+ dataQa: 'VcGroupedItems',
34
+ }
35
+
36
+ const Template = (args, {argTypes}) => ({
37
+ components: {VcGroupedItems: VcGroupedItemsCmp},
38
+ props: Object.keys(argTypes),
39
+ data: () => ({
40
+ selectedIdx: undefined,
41
+ }),
42
+ template: `
43
+ <div>
44
+ <VcGroupedItems :item-groups="itemGroups" :selected="selectedIdx" :show-dividers="showDividers" :flavor="flavor"
45
+ :dataQa="dataQa"
46
+ @change="onChange"/>
47
+ </div>`,
48
+ })
49
+
50
+ export const Playground = Template.bind({});
51
+
52
+ // Set default values
53
+ Playground.args = {
54
+ ...basicProps,
55
+ }
56
+
57
+ export const ElevatedFlavor = Template.bind({});
58
+
59
+ // Set default values
60
+ ElevatedFlavor.args = {
61
+ ...basicProps,
62
+ flavor: 'elevated',
63
+ }
64
+
65
+ export const FlatFlavor = Template.bind({});
66
+
67
+ // Set default values
68
+ FlatFlavor.args = {
69
+ ...basicProps,
70
+ flavor: 'elevated',
71
+ }
72
+
73
+ export const WithDividers = Template.bind({});
74
+
75
+ // Set default values
76
+ WithDividers.args = {
77
+ ...basicProps,
78
+ showDividers: true,
79
+ }
80
+
81
+ const TemplateWithSlots = (args, {argTypes}) => ({
82
+ components: {VcGroupedItems: VcGroupedItemsCmp, VcBadge, VcIcon},
83
+ props: Object.keys(argTypes),
84
+ data: () => ({
85
+ selectedIdx: undefined,
86
+ }),
87
+ template: `
88
+ <div>
89
+ <VcGroupedItems :item-groups="itemGroups" :selected="selectedIdx" :show-dividers="showDividers" :flavor="flavor"
90
+ :dataQa="dataQa">
91
+ <template #group-1-header>
92
+ <div class="d-flex align-center">
93
+ <span>Group Title</span>
94
+ <VcBadge class="ps-2" badgeText="new" :offsetX="-2" :offsetY="0"></VcBadge>
95
+ </div>
96
+ </template>
97
+ <template #item-4>
98
+ <div class="d-flex align-center flex-grow-1 justify-space-between px-6">
99
+ <span>Slot Label</span>
100
+ <div class="d-flex align-center">
101
+ <vc-icon size="16" color="black" class="mx-3">$magnify_glass</vc-icon>
102
+ <vc-icon size="16" color="black" class="mx-3">$plus</vc-icon>
103
+ </div>
104
+ </div>
105
+ </template>
106
+ </VcGroupedItems>
107
+ </div>`,
108
+ })
109
+
110
+ export const UsingGroupAndItemSlots = TemplateWithSlots.bind({});
111
+
112
+ UsingGroupAndItemSlots.args = {
113
+ ...basicProps,
114
+ }
115
+
116
+ export default {
117
+ title: 'containers / VcGroupedItems', // This will control the story sidebar position
118
+ id: 'VcGroupedItems', // This will be the permanent link to this component
119
+ component: VcGroupedItemsCmp,
120
+ argTypes: {
121
+ onChange: {action: 'change', table: {disable: true}},
122
+ },
123
+ parameters: {
124
+ design: {
125
+ type: 'figma',
126
+ url: 'https://www.figma.com/file/xIOY6fBoA1wpy1tHv3i5js/vcita---ui-library?node-id=251%3A908',
127
+ },
128
+ status: {
129
+ type: 'beta', // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate'
130
+ },
131
+ docs: {
132
+ page: VcBaseDocs,
133
+ },
134
+ },
135
+ };