@vcita/design-system 0.6.15 → 0.6.17-beta.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.
- package/CHANGELOG.MD +9 -0
- package/config/locales/ds.en.yml +1 -0
- package/dist/@vcita/design-system.esm.js +654 -607
- package/dist/@vcita/design-system.min.js +1 -1
- package/dist/@vcita/design-system.ssr.js +660 -611
- package/package.json +1 -1
- package/src/components/VcSearchBar/VcSearchBar.vue +6 -3
- package/src/components/VcTooltip/VcTooltip.vue +0 -2
- package/src/components/listBox/VcChecklistItem/VcChecklistItem.vue +12 -8
- package/src/components/listBox/VcListbox/VcListbox.spec.js +65 -4
- package/src/components/listBox/VcListbox/VcListbox.stories.js +13 -4
- package/src/components/listBox/VcListbox/VcListbox.vue +95 -18
- package/src/components/wizard/VcWizard/VcWizard.vue +1 -1
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import VcIcon from '@/components/VcIcon/VcIcon.vue'
|
|
20
20
|
import VcTextField from "@/components/VcTextField/VcTextField.vue";
|
|
21
|
+
|
|
21
22
|
const throttle = require("lodash.throttle")
|
|
22
23
|
|
|
23
24
|
export default {
|
|
@@ -75,14 +76,16 @@ export default {
|
|
|
75
76
|
</script>
|
|
76
77
|
|
|
77
78
|
<style lang="scss" scoped>
|
|
78
|
-
.vc-search-bar {
|
|
79
|
+
.vc-search-bar.VcTextInput {
|
|
79
80
|
padding: var(--size-value0);
|
|
80
81
|
margin: var(--size-value0);
|
|
81
82
|
|
|
82
83
|
&.border-top-radius {
|
|
83
84
|
::v-deep {
|
|
84
|
-
.v-
|
|
85
|
-
|
|
85
|
+
.v-input__control {
|
|
86
|
+
.v-input__slot {
|
|
87
|
+
border-radius: var(--border-radius) var(--border-radius) var(--size-value0) var(--size-value0);
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<VcTooltip :content="tooltipContent"
|
|
3
|
-
dark
|
|
4
3
|
:disabled="!tooltipContent || !disabled"
|
|
5
|
-
class="VcChecklistItem-wrapper"
|
|
4
|
+
class="VcChecklistItem-wrapper"
|
|
5
|
+
dark>
|
|
6
6
|
<template>
|
|
7
|
-
<VcLayout class="
|
|
8
|
-
|
|
9
|
-
<VcCheckbox :
|
|
10
|
-
:
|
|
7
|
+
<VcLayout :class="{'disabled': disabled}" :data-qa="dataQa"
|
|
8
|
+
class="VcChecklistItem">
|
|
9
|
+
<VcCheckbox :avatar="getAvatar"
|
|
10
|
+
:checked="checked"
|
|
11
|
+
:data-qa="`${dataQa}-checkbox`"
|
|
12
|
+
:disabled="disabled"
|
|
11
13
|
:label="label"
|
|
12
14
|
:show-avatar-border="false"
|
|
13
|
-
:disabled="disabled"
|
|
14
|
-
:data-qa="`${dataQa}-checkbox`"
|
|
15
15
|
@change="onChange">
|
|
16
16
|
|
|
17
17
|
</VcCheckbox>
|
|
@@ -83,6 +83,10 @@ export default {
|
|
|
83
83
|
.VcChecklistItem-wrapper {
|
|
84
84
|
width: 100%;
|
|
85
85
|
|
|
86
|
+
&[hide=true] {
|
|
87
|
+
display: none;
|
|
88
|
+
}
|
|
89
|
+
|
|
86
90
|
.VcChecklistItem {
|
|
87
91
|
&.disabled {
|
|
88
92
|
background-color: var(--gray-lighten-3);
|
|
@@ -4,6 +4,7 @@ import Vuetify from 'vuetify'
|
|
|
4
4
|
import {render} from "@testing-library/vue";
|
|
5
5
|
import init from "../../../../testing-library.config";
|
|
6
6
|
import {fireEvent} from "@testing-library/dom";
|
|
7
|
+
import userEvent from "@testing-library/user-event";
|
|
7
8
|
|
|
8
9
|
init();
|
|
9
10
|
|
|
@@ -14,13 +15,15 @@ const props = {
|
|
|
14
15
|
label: 'Peter Parker',
|
|
15
16
|
avatar: {
|
|
16
17
|
path: require('@/stories/assets/pics/spider-man.png'),
|
|
17
|
-
}
|
|
18
|
+
},
|
|
19
|
+
identifier: 0
|
|
18
20
|
},
|
|
19
21
|
{
|
|
20
22
|
label: 'Tony Stark',
|
|
21
23
|
avatar: {
|
|
22
24
|
path: require('@/stories/assets/pics/ironman.png'),
|
|
23
|
-
}
|
|
25
|
+
},
|
|
26
|
+
identifier: 1
|
|
24
27
|
},
|
|
25
28
|
{
|
|
26
29
|
label: 'Bruce Banner',
|
|
@@ -28,13 +31,15 @@ const props = {
|
|
|
28
31
|
path: require('@/stories/assets/pics/hulk.png'),
|
|
29
32
|
},
|
|
30
33
|
disabled: true,
|
|
31
|
-
tooltipContent: 'Hulk is too STRONG'
|
|
34
|
+
tooltipContent: 'Hulk is too STRONG',
|
|
35
|
+
identifier: 2
|
|
32
36
|
},
|
|
33
37
|
{
|
|
34
38
|
label: 'Clint Barton',
|
|
35
39
|
avatar: {
|
|
36
40
|
colorId: 13,
|
|
37
41
|
},
|
|
42
|
+
identifier: 3
|
|
38
43
|
},
|
|
39
44
|
],
|
|
40
45
|
}
|
|
@@ -123,4 +128,60 @@ describe("VcListbox.vue", () => {
|
|
|
123
128
|
expect(emitted().addNew.length).toBe(1);
|
|
124
129
|
expect(getByText('add new Item')).toBeInTheDocument();
|
|
125
130
|
});
|
|
126
|
-
|
|
131
|
+
|
|
132
|
+
it("With search bar", async () => {
|
|
133
|
+
const {container, getByText, getByTestId} = renderWithVuetify(VcListbox, {
|
|
134
|
+
props: {
|
|
135
|
+
...props,
|
|
136
|
+
addSearch: true,
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
const searchBar = getByTestId('vc-list-box-search')
|
|
140
|
+
expect(searchBar).toBeVisible()
|
|
141
|
+
|
|
142
|
+
props.items.forEach((item) => expect(getByText(item.label)).toBeVisible())
|
|
143
|
+
|
|
144
|
+
await userEvent.type(searchBar, 'peter')
|
|
145
|
+
|
|
146
|
+
const checklistItemWrappers = container.getElementsByClassName('VcChecklistItem-wrapper')
|
|
147
|
+
|
|
148
|
+
expect(checklistItemWrappers[0]).not.toHaveAttribute('hide', 'true')
|
|
149
|
+
|
|
150
|
+
for (let i = 1; i < props.items.length; i++) {
|
|
151
|
+
expect(checklistItemWrappers[i]).toHaveAttribute('hide', 'true')
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("Empty result from the search bar", async () => {
|
|
156
|
+
const {getByText, getByTestId, queryByText} = renderWithVuetify(VcListbox, {
|
|
157
|
+
props: {
|
|
158
|
+
...props,
|
|
159
|
+
addSearch: true
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
props.items.forEach((item) => expect(getByText(item.label)).toBeVisible())
|
|
164
|
+
|
|
165
|
+
const searchBar = getByTestId('vc-list-box-search')
|
|
166
|
+
await userEvent.paste(searchBar, 'clark kent')
|
|
167
|
+
|
|
168
|
+
for (let i = 0; i < props.items.length; i++) {
|
|
169
|
+
expect(queryByText(props.items[i].label)).not.toBeInTheDocument()
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("Empty result from the search bar with unique empty list massage", async () => {
|
|
174
|
+
const {getByTestId} = renderWithVuetify(VcListbox, {
|
|
175
|
+
props: {
|
|
176
|
+
...props,
|
|
177
|
+
addSearch: true,
|
|
178
|
+
emptyListMsg: 'No Avengers found'
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const searchBar = getByTestId('vc-list-box-search')
|
|
183
|
+
await userEvent.paste(searchBar, 'clark kent')
|
|
184
|
+
const emptyCase = getByTestId('vc-list-box-empty')
|
|
185
|
+
expect(emptyCase).toHaveTextContent('No Avengers found')
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -9,6 +9,8 @@ const Template = (args, {argTypes}) => ({
|
|
|
9
9
|
:title="title"
|
|
10
10
|
:add-another="addAnother"
|
|
11
11
|
:add-another-label="addAnotherLabel"
|
|
12
|
+
:add-search="addSearch"
|
|
13
|
+
:empty-list-msg="emptyListMsg"
|
|
12
14
|
:data-qa="dataQa"
|
|
13
15
|
@change="onChange"
|
|
14
16
|
@addNew="onAddNew">
|
|
@@ -21,28 +23,33 @@ export const Playground = Template.bind({});
|
|
|
21
23
|
// Set default values
|
|
22
24
|
Playground.args = {
|
|
23
25
|
title: 'Avengers crew',
|
|
26
|
+
addSearch: false,
|
|
24
27
|
addAnother: false,
|
|
25
28
|
addAnotherLabel: 'Add new Avenger',
|
|
29
|
+
emptyListMsg: 'No Avengers found',
|
|
26
30
|
dataQa: "vc-listbox",
|
|
27
31
|
items: [
|
|
28
32
|
{
|
|
29
33
|
label: 'Peter Parker',
|
|
30
34
|
avatar: {
|
|
31
35
|
path: require('@/stories/assets/pics/spider-man.png'),
|
|
32
|
-
}
|
|
36
|
+
},
|
|
37
|
+
identifier: 0
|
|
33
38
|
},
|
|
34
39
|
{
|
|
35
40
|
label: 'Tony Stark',
|
|
36
41
|
avatar: {
|
|
37
42
|
path: require('@/stories/assets/pics/ironman.png'),
|
|
38
43
|
},
|
|
39
|
-
checked: true
|
|
44
|
+
checked: true,
|
|
45
|
+
identifier: 1
|
|
40
46
|
},
|
|
41
47
|
{
|
|
42
48
|
label: 'Natasha Romanoff',
|
|
43
49
|
avatar: {
|
|
44
50
|
path: require('@/stories/assets/pics/black-widow.jpeg'),
|
|
45
|
-
}
|
|
51
|
+
},
|
|
52
|
+
identifier: 2
|
|
46
53
|
},
|
|
47
54
|
{
|
|
48
55
|
label: 'Bruce Banner',
|
|
@@ -50,13 +57,15 @@ Playground.args = {
|
|
|
50
57
|
path: require('@/stories/assets/pics/hulk.png'),
|
|
51
58
|
},
|
|
52
59
|
disabled: true,
|
|
53
|
-
tooltipContent: 'Hulk is too STRONG'
|
|
60
|
+
tooltipContent: 'Hulk is too STRONG',
|
|
61
|
+
identifier: 3
|
|
54
62
|
},
|
|
55
63
|
{
|
|
56
64
|
label: 'Clint Barton',
|
|
57
65
|
avatar: {
|
|
58
66
|
colorId: 13,
|
|
59
67
|
},
|
|
68
|
+
identifier: 4
|
|
60
69
|
},
|
|
61
70
|
],
|
|
62
71
|
onChange: action('changed'),
|
|
@@ -1,34 +1,48 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<div v-if="title"
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
:data-qa="`${dataQa}-title`"
|
|
5
|
+
class="vc-list-title">
|
|
6
6
|
{{ title }}
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
<v-list class="
|
|
10
|
-
:data-qa="dataQa"
|
|
9
|
+
<v-list :class="{'with-search' : addSearch, 'with-add-another' : addAnother}"
|
|
10
|
+
:data-qa="dataQa"
|
|
11
|
+
class="VcListbox">
|
|
12
|
+
<VcSearchBar v-if="addSearch"
|
|
13
|
+
:data-qa="`${dataQa}-search`"
|
|
14
|
+
border-top-radius
|
|
15
|
+
@search="onSearch">
|
|
16
|
+
</VcSearchBar>
|
|
11
17
|
<div class="vc-overflow">
|
|
12
18
|
<v-list-item-group
|
|
19
|
+
v-if="listExist"
|
|
13
20
|
:value="confirmedArray"
|
|
14
21
|
multiple
|
|
15
22
|
@change="onSelection">
|
|
16
|
-
<VcTooltip v-for="
|
|
17
|
-
:key="
|
|
18
|
-
dark
|
|
23
|
+
<VcTooltip v-for="item in filteredItems"
|
|
24
|
+
:key="item.identifier"
|
|
19
25
|
:content="item.tooltipContent"
|
|
26
|
+
:data-qa="`${dataQa}-${setDataQa(item.label)}-tooltip`"
|
|
20
27
|
:disabled="!item.tooltipContent || !item.disabled"
|
|
21
|
-
|
|
22
|
-
<v-list-item
|
|
23
|
-
:tabindex="
|
|
28
|
+
dark>
|
|
29
|
+
<v-list-item :disabled="item.disabled"
|
|
30
|
+
:tabindex="`${item.label}-${item.identifier}`"
|
|
24
31
|
:value="item"
|
|
25
|
-
|
|
26
|
-
<VcChecklistItem
|
|
27
|
-
|
|
32
|
+
class="vc-list-item">
|
|
33
|
+
<VcChecklistItem v-bind="item"
|
|
34
|
+
:data-qa="`${dataQa}-${setDataQa(item.label)}`">
|
|
28
35
|
</VcChecklistItem>
|
|
29
36
|
</v-list-item>
|
|
30
37
|
</VcTooltip>
|
|
31
38
|
</v-list-item-group>
|
|
39
|
+
<VcLayout v-else
|
|
40
|
+
:data-qa="`${dataQa}-empty`"
|
|
41
|
+
align-center
|
|
42
|
+
class="VcListbox__empty"
|
|
43
|
+
justify-center>
|
|
44
|
+
{{ noItemsMsg }}
|
|
45
|
+
</VcLayout>
|
|
32
46
|
</div>
|
|
33
47
|
|
|
34
48
|
<div v-if="addAnother"
|
|
@@ -49,20 +63,26 @@
|
|
|
49
63
|
import VcChecklistItem from "@/components/listBox/VcChecklistItem/VcChecklistItem.vue";
|
|
50
64
|
import VcIcon from "@/components/VcIcon/VcIcon.vue";
|
|
51
65
|
import VcTooltip from "@/components/VcTooltip/VcTooltip.vue";
|
|
66
|
+
import VcSearchBar from "@/components/VcSearchBar/VcSearchBar.vue";
|
|
67
|
+
import VcLayout from "@/components/VcLayout/VcLayout.vue";
|
|
52
68
|
|
|
53
69
|
export default {
|
|
54
70
|
name: "VcListbox",
|
|
55
|
-
components: {VcChecklistItem, VcIcon, VcTooltip},
|
|
71
|
+
components: {VcLayout, VcSearchBar, VcChecklistItem, VcIcon, VcTooltip},
|
|
56
72
|
props: {
|
|
57
73
|
items: {
|
|
58
74
|
type: Array,
|
|
59
75
|
required: true,
|
|
60
|
-
validator: items => items.every(item => item.label),
|
|
76
|
+
validator: items => items.every(item => item.label && item.identifier || item.identifier === 0),
|
|
61
77
|
},
|
|
62
78
|
addAnother: {
|
|
63
79
|
type: Boolean,
|
|
64
80
|
default: false
|
|
65
81
|
},
|
|
82
|
+
addSearch: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: false
|
|
85
|
+
},
|
|
66
86
|
addAnotherLabel: {
|
|
67
87
|
type: String,
|
|
68
88
|
default: ""
|
|
@@ -71,17 +91,38 @@ export default {
|
|
|
71
91
|
type: String,
|
|
72
92
|
default: ''
|
|
73
93
|
},
|
|
94
|
+
emptyListMsg: {
|
|
95
|
+
type: String
|
|
96
|
+
},
|
|
74
97
|
dataQa: {
|
|
75
98
|
type: String,
|
|
76
99
|
default: 'VcListbox'
|
|
77
100
|
}
|
|
78
101
|
},
|
|
102
|
+
data: () => ({
|
|
103
|
+
search: ''
|
|
104
|
+
}
|
|
105
|
+
),
|
|
79
106
|
computed: {
|
|
80
107
|
getAddAnotherLabel() {
|
|
81
108
|
return this.addAnotherLabel || this.$dst('ds.listbox.add')
|
|
82
109
|
},
|
|
83
110
|
confirmedArray() {
|
|
84
|
-
return this.
|
|
111
|
+
return this.filteredItems.filter(item => item.checked)
|
|
112
|
+
},
|
|
113
|
+
filteredItems() {
|
|
114
|
+
return this.items.map((item) => (
|
|
115
|
+
{
|
|
116
|
+
...item,
|
|
117
|
+
hide: !item.label.toLowerCase().includes(this.search),
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
},
|
|
121
|
+
listExist() {
|
|
122
|
+
return this.filteredItems.some((item) => !item.hide)
|
|
123
|
+
},
|
|
124
|
+
noItemsMsg() {
|
|
125
|
+
return this.emptyListMsg || this.$dst('ds.listbox.empty_list')
|
|
85
126
|
}
|
|
86
127
|
},
|
|
87
128
|
methods: {
|
|
@@ -89,8 +130,11 @@ export default {
|
|
|
89
130
|
const newSelections = selections.map((selected) => ({...selected, checked: true}))
|
|
90
131
|
this.$emit('change', newSelections)
|
|
91
132
|
},
|
|
133
|
+
onSearch(search) {
|
|
134
|
+
this.search = search
|
|
135
|
+
},
|
|
92
136
|
setDataQa(label) {
|
|
93
|
-
return label.replace(/ /g,'-')
|
|
137
|
+
return label.replace(/ /g, '-')
|
|
94
138
|
}
|
|
95
139
|
}
|
|
96
140
|
};
|
|
@@ -115,13 +159,38 @@ export default {
|
|
|
115
159
|
border-radius: var(--border-radius);
|
|
116
160
|
box-shadow: none !important;
|
|
117
161
|
|
|
162
|
+
&.with-search {
|
|
163
|
+
border: none;
|
|
164
|
+
|
|
165
|
+
.vc-overflow {
|
|
166
|
+
border-inline: var(--border-frame);
|
|
167
|
+
border-block-end: var(--border-frame);
|
|
168
|
+
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&.with-add-another {
|
|
172
|
+
.vc-overflow {
|
|
173
|
+
border-inline: var(--border-frame);
|
|
174
|
+
border-block-end: unset;
|
|
175
|
+
border-radius: unset;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.last-item {
|
|
179
|
+
border-inline: var(--border-frame);
|
|
180
|
+
border-block-end: var(--border-frame);
|
|
181
|
+
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
118
186
|
.vc-overflow {
|
|
119
187
|
overflow: auto;
|
|
120
|
-
|
|
188
|
+
height: 160px;
|
|
121
189
|
|
|
122
190
|
.vc-list-item {
|
|
123
191
|
padding: var(--size-value0);
|
|
124
192
|
min-height: unset;
|
|
193
|
+
|
|
125
194
|
&:before {
|
|
126
195
|
opacity: 0;
|
|
127
196
|
}
|
|
@@ -135,6 +204,7 @@ export default {
|
|
|
135
204
|
.last-item {
|
|
136
205
|
cursor: pointer;
|
|
137
206
|
min-height: var(--size-value10);
|
|
207
|
+
padding-block: var(--size-value1) var(--size-value2);
|
|
138
208
|
|
|
139
209
|
&:hover {
|
|
140
210
|
background-color: var(--gray-lighten-3);
|
|
@@ -163,5 +233,12 @@ export default {
|
|
|
163
233
|
}
|
|
164
234
|
}
|
|
165
235
|
}
|
|
236
|
+
|
|
237
|
+
&__empty {
|
|
238
|
+
height: 100%;
|
|
239
|
+
font-weight: var(--font-weight-medium2);
|
|
240
|
+
font-size: var(--font-size-xx-small);
|
|
241
|
+
color: var(--gray-darken-4);
|
|
242
|
+
}
|
|
166
243
|
}
|
|
167
244
|
</style>
|