@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.
- package/config/locales/ds.en.yml +4 -0
- package/dist/@vcita/design-system.esm.js +1882 -1140
- package/dist/@vcita/design-system.min.js +2 -2
- package/dist/@vcita/design-system.ssr.js +1688 -965
- package/init/DesignSystem.js +3 -1
- package/init/initI18n.js +24 -16
- package/package.json +2 -1
- package/src/components/VcActionList/VcActionList.spec.js +16 -7
- package/src/components/VcActionList/VcActionList.stories.js +16 -3
- package/src/components/VcActionList/VcActionList.vue +35 -11
- package/src/components/VcBottomActions/VcBottomActions.vue +2 -1
- package/src/components/VcBottomSheet/VcBottomSheet.stories.js +6 -13
- package/src/components/VcBottomSheet/VcBottomSheet.vue +2 -3
- package/src/components/VcButton/VcButton.vue +1 -1
- package/src/components/VcCheckbox/VcCheckbox.vue +8 -1
- package/src/components/VcColorPicker/VcColorPicker.spec.js +206 -0
- package/src/components/VcColorPicker/VcColorPicker.stories.js +107 -0
- package/src/components/VcColorPicker/VcColorPicker.vue +270 -0
- package/src/components/VcFilterPanel/VcFilterPanel.spec.js +15 -0
- package/src/components/VcFilterPanel/VcFilterPanel.stories.js +9 -1
- package/src/components/VcFilterPanel/VcFilterPanel.vue +24 -3
- package/src/components/VcGalleryItem/VcGalleryItem.stories.js +2 -0
- package/src/components/VcGroupedItems/VcGroupedItems.spec.js +148 -0
- package/src/components/VcGroupedItems/VcGroupedItems.stories.js +135 -0
- package/src/components/VcGroupedItems/VcGroupedItems.vue +155 -0
- package/src/components/VcLink/VcLink.spec.js +3 -3
- package/src/components/VcLink/VcLink.stories.js +2 -6
- package/src/components/VcLink/VcLink.vue +1 -18
- package/src/components/VcMenu/VcDropdown.spec.js +120 -0
- package/src/components/VcMenu/VcDropdown.stories.js +272 -0
- package/src/components/VcMenu/VcDropdown.vue +93 -0
- package/src/components/VcMenu/VcMenu.spec.js +61 -10
- package/src/components/VcMenu/VcMenu.stories.js +38 -33
- package/src/components/VcMenu/VcMenu.vue +19 -3
- package/src/components/VcPopover/VcPopover.stories.js +2 -2
- package/src/components/VcRadioGroup/VcRadioGroup.spec.js +28 -0
- package/src/components/VcRadioGroup/VcRadioGroup.stories.js +3 -1
- package/src/components/VcRadioGroup/VcRadioGroup.vue +6 -1
- package/src/components/VcSearchPicker/VcSearchPicker.stories.js +3 -4
- package/src/components/VcSelectField/VcSelectField.vue +6 -0
- package/src/components/VcSideNav/VcSideNav.spec.js +1 -1
- package/src/components/VcSideNav/VcSideNav.vue +21 -104
- package/src/components/VcTextField/VcTextField.spec.js +13 -0
- package/src/components/VcTextField/VcTextField.stories.js +2 -1
- package/src/components/VcTextField/VcTextField.vue +11 -0
- package/src/components/VcTooltip/VcTooltip.stories.js +3 -1
- package/src/components/VcTooltip/VcTooltip.vue +6 -1
- package/src/components/index.js +4 -0
- package/src/components/list/VcBaseListItem/VcBaseListItem.stories.js +22 -13
- package/src/components/list/VcBaseListItem/VcBaseListItem.vue +4 -1
- package/src/components/list/VcList/VcList.stories.js +245 -240
- package/src/components/list/VcList/VcList.vue +11 -4
- package/src/components/page/layouts/centeredPage/CenteredPageLayout.stories.js +17 -16
- package/styles/variables.scss +1 -0
- package/styles/vuetify-variables.scss +9 -1
- package/CHANGELOG.md +0 -342
package/init/DesignSystem.js
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
VTabsItems,
|
|
49
49
|
VTabItem,
|
|
50
50
|
VBreadcrumbs,
|
|
51
|
+
VColorPicker,
|
|
51
52
|
} from "vuetify/lib/components";
|
|
52
53
|
// import initI18n from "./initI18n";
|
|
53
54
|
import svgImages from "./svgImages";
|
|
@@ -100,6 +101,7 @@ Vue.use(Vuetify, {
|
|
|
100
101
|
VTabsItems,
|
|
101
102
|
VTabItem,
|
|
102
103
|
VBreadcrumbs,
|
|
104
|
+
VColorPicker,
|
|
103
105
|
}
|
|
104
106
|
});
|
|
105
107
|
|
|
@@ -125,7 +127,7 @@ const DesignSystem = ({theme = {}, options = {}, extIcons = {}} = {}, locale ='e
|
|
|
125
127
|
}
|
|
126
128
|
};
|
|
127
129
|
|
|
128
|
-
const vuetifyConfigOverride = {...vuetifyConfig, ...theme, ...icons };
|
|
130
|
+
const vuetifyConfigOverride = {...vuetifyConfig, ...theme, ...icons, rtl: window.direction === 'rtl' };
|
|
129
131
|
// initI18n(locale);
|
|
130
132
|
return new Vuetify(vuetifyConfigOverride);
|
|
131
133
|
}
|
package/init/initI18n.js
CHANGED
|
@@ -28,25 +28,33 @@ const initI18n = (locale = 'en') => {
|
|
|
28
28
|
Vue.prototype.$ds.setLocale(locale);
|
|
29
29
|
|
|
30
30
|
Vue.prototype.$dst = (key, params) => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
const fallbackLanguage = messages['en'];
|
|
32
|
+
const language = messages[Vue.prototype.$ds.locale] || fallbackLanguage;
|
|
33
|
+
|
|
34
|
+
const result = getKeyFromLanguage(language, key, params);
|
|
35
|
+
if (result === key) {
|
|
36
|
+
return getKeyFromLanguage(fallbackLanguage, key, params);
|
|
37
|
+
}
|
|
38
|
+
return result || key;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const getKeyFromLanguage = (language, key, params) => {
|
|
43
|
+
const path = key.split('.');
|
|
44
|
+
let result = language;
|
|
45
|
+
try {
|
|
46
|
+
for (let item of path) {
|
|
47
|
+
result = result[item];
|
|
43
48
|
}
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
for (let param in params) {
|
|
50
|
+
let regex = new RegExp(`{${param}}`, 'gi')
|
|
51
|
+
result = result.replace(regex, params[param])
|
|
46
52
|
}
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
} catch {
|
|
54
|
+
result = key;
|
|
49
55
|
}
|
|
56
|
+
|
|
57
|
+
return result;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
export default initI18n;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vcita/design-system",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "vcita design system",
|
|
5
5
|
"author": "vcita",
|
|
6
6
|
"scripts": {
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"eslint-plugin-jest": "^24.4.0",
|
|
70
70
|
"eslint-plugin-storybook": "^0.6.4",
|
|
71
71
|
"eslint-plugin-vue": "^6.2.2",
|
|
72
|
+
"jest-canvas-mock": "^2.4.0",
|
|
72
73
|
"minimist": "^1.2.5",
|
|
73
74
|
"rollup": "^2.36.1",
|
|
74
75
|
"rollup-plugin-babel": "^4.4.0",
|
|
@@ -27,19 +27,28 @@ describe("VcActionList.vue", () => {
|
|
|
27
27
|
|
|
28
28
|
const defaultProps = {
|
|
29
29
|
items: [
|
|
30
|
+
{
|
|
31
|
+
header: 'User actions',
|
|
32
|
+
},
|
|
30
33
|
{
|
|
31
34
|
title: 'Move to guest list',
|
|
32
35
|
event: 'moveToGustList',
|
|
33
|
-
icon: 'information'
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
+
icon: '$information'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: 'Remove from waitlist',
|
|
36
40
|
event: 'remove',
|
|
37
|
-
icon: 'warning_fill'
|
|
38
|
-
},
|
|
41
|
+
icon: '$warning_fill'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
header: 'navigate actions',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
39
47
|
title: 'Go to client page',
|
|
40
48
|
event: 'goToClientPage',
|
|
41
|
-
icon: 'vip'
|
|
42
|
-
}
|
|
49
|
+
icon: '$vip'
|
|
50
|
+
},
|
|
51
|
+
|
|
43
52
|
],
|
|
44
53
|
dataQa: 'action-list-test'
|
|
45
54
|
}
|
|
@@ -21,19 +21,32 @@ export const Playground = GeneralTemplate.bind({});
|
|
|
21
21
|
// Set default values
|
|
22
22
|
Playground.args = {
|
|
23
23
|
items: [
|
|
24
|
+
{
|
|
25
|
+
header: 'User actions',
|
|
26
|
+
},
|
|
24
27
|
{
|
|
25
28
|
title: 'Move to guest list',
|
|
26
29
|
event: 'moveToGustList',
|
|
27
30
|
icon: '$information'
|
|
28
|
-
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
29
33
|
title: 'Remove from waitlist',
|
|
30
34
|
event: 'remove',
|
|
31
35
|
icon: '$warning_fill'
|
|
32
|
-
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
header: 'navigate actions',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
33
41
|
title: 'Go to client page',
|
|
34
42
|
event: 'goToClientPage',
|
|
35
43
|
icon: '$vip'
|
|
36
|
-
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
header: 'no header',
|
|
47
|
+
HideHeader: true,
|
|
48
|
+
},
|
|
49
|
+
|
|
37
50
|
],
|
|
38
51
|
dataQa: 'playground-qa'
|
|
39
52
|
}
|
|
@@ -6,17 +6,28 @@
|
|
|
6
6
|
</template>
|
|
7
7
|
<v-list :data-qa="dataQa">
|
|
8
8
|
<vc-layout column class="items-wrapper">
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
<template
|
|
10
|
+
v-for="(item, index) in items"
|
|
11
|
+
>
|
|
12
|
+
<v-subheader
|
|
13
|
+
:class="{'hide-header': item.HideHeader}"
|
|
14
|
+
:key="`${item.header}-${index}`"
|
|
15
|
+
v-if="item.header">
|
|
16
|
+
{{ item.header }}
|
|
17
|
+
</v-subheader>
|
|
18
|
+
<v-list-item
|
|
19
|
+
v-else
|
|
20
|
+
class="sheet-item"
|
|
21
|
+
@click="$emit('action', item.event)">
|
|
22
|
+
<v-list-item-title class="option-title">
|
|
23
|
+
<vc-icon v-if="item.icon && !isNotAllItemsWithIcons" size="20" class="icon-item">
|
|
24
|
+
{{ item.icon }}
|
|
25
|
+
</vc-icon>
|
|
26
|
+
{{ item.title }}
|
|
27
|
+
</v-list-item-title>
|
|
28
|
+
</v-list-item>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
20
31
|
</vc-layout>
|
|
21
32
|
</v-list>
|
|
22
33
|
</v-menu>
|
|
@@ -62,6 +73,19 @@ export default {
|
|
|
62
73
|
padding: var(--size-value1) 0;
|
|
63
74
|
|
|
64
75
|
.items-wrapper {
|
|
76
|
+
.v-subheader {
|
|
77
|
+
font-weight: 600;
|
|
78
|
+
font-size: 10px;
|
|
79
|
+
line-height: 16px;
|
|
80
|
+
color: var(--gray-darken-3);
|
|
81
|
+
height: 36px;
|
|
82
|
+
&:not(:first-child) {
|
|
83
|
+
border-top: var(--border-frame);
|
|
84
|
+
}
|
|
85
|
+
&.hide-header {
|
|
86
|
+
border-top: none;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
65
89
|
.sheet-item {
|
|
66
90
|
min-height: var(--size-value10);
|
|
67
91
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import VcBottomSheetCmp from './VcBottomSheet';
|
|
2
|
-
import {VcIcon,
|
|
2
|
+
import {VcIcon, VcLayout} from "@/components/index";
|
|
3
3
|
import VcBaseDocs from "@/stories/VcBaseDocs.mdx";
|
|
4
4
|
|
|
5
5
|
const GeneralTemplate = (args, {argTypes}) => ({
|
|
6
|
-
components: {VcBottomSheet: VcBottomSheetCmp, VcIcon,
|
|
6
|
+
components: {VcBottomSheet: VcBottomSheetCmp, VcIcon, VcLayout},
|
|
7
7
|
props: Object.keys(argTypes),
|
|
8
8
|
data: () => ({
|
|
9
9
|
showSheet: false,
|
|
@@ -23,17 +23,10 @@ const GeneralTemplate = (args, {argTypes}) => ({
|
|
|
23
23
|
$three_dots
|
|
24
24
|
</VcIcon>
|
|
25
25
|
</template>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
button="Reload"
|
|
31
|
-
link-label="Link label"
|
|
32
|
-
link-url="www.google.com"
|
|
33
|
-
:image="image"
|
|
34
|
-
@click="onClick"
|
|
35
|
-
style="padding: 24px"/>
|
|
36
|
-
</template>
|
|
26
|
+
<VcLayout align-center justify-center
|
|
27
|
+
:style="{ minHeight: '300px', backgroundColor: 'var(--green-lighten-2)', padding: '12px'}">
|
|
28
|
+
Your content goes here
|
|
29
|
+
</VcLayout>
|
|
37
30
|
</VcBottomSheet>
|
|
38
31
|
</div>`,
|
|
39
32
|
watch: {
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
<template v-slot:activator="activatorObj">
|
|
8
8
|
<slot v-bind="activatorObj" name="activator"/>
|
|
9
9
|
</template>
|
|
10
|
-
<v-sheet :data-qa="`${dataQa}-sheet`"
|
|
11
|
-
class="vc-sheet">
|
|
10
|
+
<v-sheet :data-qa="`${dataQa}-sheet`" class="vc-sheet">
|
|
12
11
|
<slot/>
|
|
13
12
|
</v-sheet>
|
|
14
13
|
</v-bottom-sheet>
|
|
@@ -18,7 +17,6 @@
|
|
|
18
17
|
|
|
19
18
|
import VcLayout from "@/components/VcLayout/VcLayout.vue";
|
|
20
19
|
|
|
21
|
-
|
|
22
20
|
export default {
|
|
23
21
|
name: "VcBottomSheet",
|
|
24
22
|
components: {VcLayout},
|
|
@@ -53,6 +51,7 @@ export default {
|
|
|
53
51
|
border-radius: var(--modal-border-radius) var(--modal-border-radius) 0 0;
|
|
54
52
|
display: flex;
|
|
55
53
|
box-shadow: var(--modal-box-shadow);
|
|
54
|
+
overflow: auto;
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
</style>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:value="value"
|
|
15
15
|
:data-qa="dataQa">
|
|
16
16
|
<template #label>
|
|
17
|
-
<div class="d-flex align-center">
|
|
17
|
+
<div class="d-flex align-center ms-2">
|
|
18
18
|
<VcAvatar v-if="avatar && label" class="ms-1 me-3"
|
|
19
19
|
:image-path="avatar.path"
|
|
20
20
|
:name="avatar.name"
|
|
@@ -99,6 +99,7 @@ export default {
|
|
|
99
99
|
.v-input__slot .v-input--selection-controls__input {
|
|
100
100
|
width: var(--size-value4);
|
|
101
101
|
height: var(--size-value4);
|
|
102
|
+
margin-inline-end: 0;
|
|
102
103
|
|
|
103
104
|
.v-icon {
|
|
104
105
|
color: transparent;
|
|
@@ -107,6 +108,12 @@ export default {
|
|
|
107
108
|
border-radius: 2px;
|
|
108
109
|
font-size: var(--font-size-small);
|
|
109
110
|
font-weight: bold;
|
|
111
|
+
z-index: 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
input {
|
|
115
|
+
z-index: 0;
|
|
116
|
+
opacity: 1;
|
|
110
117
|
}
|
|
111
118
|
}
|
|
112
119
|
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import 'jest-canvas-mock';
|
|
3
|
+
import VcColorPicker from "@/components/VcColorPicker/VcColorPicker";
|
|
4
|
+
import Vue from 'vue';
|
|
5
|
+
import Vuetify from 'vuetify';
|
|
6
|
+
import {render, fireEvent} from "@testing-library/vue";
|
|
7
|
+
import init from "../../../testing-library.config";
|
|
8
|
+
import userEvent from "@testing-library/user-event";
|
|
9
|
+
|
|
10
|
+
init();
|
|
11
|
+
|
|
12
|
+
Vue.use(Vuetify);
|
|
13
|
+
|
|
14
|
+
describe("VcColorPicker.vue", () => {
|
|
15
|
+
const renderWithVuetify = (component, options, callback, isMobile = false) => {
|
|
16
|
+
const root = document.createElement('div')
|
|
17
|
+
root.setAttribute('data-app', 'true')
|
|
18
|
+
|
|
19
|
+
const vuetify = new Vuetify()
|
|
20
|
+
if (isMobile) {
|
|
21
|
+
const breakpoint = {
|
|
22
|
+
init: jest.fn(),
|
|
23
|
+
framework: {},
|
|
24
|
+
smAndDown: true,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
vuetify.framework.breakpoint = breakpoint;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return render(
|
|
31
|
+
component,
|
|
32
|
+
{
|
|
33
|
+
container: document.body.appendChild(root),
|
|
34
|
+
// for Vuetify components that use the vuetify instance property
|
|
35
|
+
vuetify,
|
|
36
|
+
...options,
|
|
37
|
+
mocks: {
|
|
38
|
+
$t: value => value,
|
|
39
|
+
$dst: () => 'Color', // <- for the design system
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
callback,
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
it("Component is loaded", async () => {
|
|
47
|
+
const {container, getByTestId} = renderWithVuetify(VcColorPicker, {props: {}})
|
|
48
|
+
expect(container).toHaveAttribute('data-app', "true")
|
|
49
|
+
const component = getByTestId('VcColorPicker');
|
|
50
|
+
expect(component).toBeInTheDocument()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("input elements are disabled as expected", async () => {
|
|
54
|
+
const {getByTestId} = renderWithVuetify(VcColorPicker, {props: {disabled: true}})
|
|
55
|
+
const inputElement = getByTestId('VcColorPicker_input');
|
|
56
|
+
expect(inputElement).toBeInTheDocument();
|
|
57
|
+
expect(inputElement).toBeDisabled();
|
|
58
|
+
|
|
59
|
+
const selectElement = getByTestId('VcColorPicker_select');
|
|
60
|
+
expect(selectElement).toBeInTheDocument();
|
|
61
|
+
expect(selectElement).toBeDisabled();
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it("Check hex mode", async () => {
|
|
65
|
+
let hexaColor = "#aabbccff";
|
|
66
|
+
let hexColor = hexaColor.substr(0, 7);
|
|
67
|
+
const {getByLabelText} = renderWithVuetify(VcColorPicker, {props: {hexMode: true, color: hexaColor}})
|
|
68
|
+
const expectedInputValue = getByLabelText("Color");
|
|
69
|
+
expect(expectedInputValue).toBeInTheDocument();
|
|
70
|
+
expect(expectedInputValue).toHaveValue(hexColor.toUpperCase());
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it("Change color", async () => {
|
|
74
|
+
const {getByTestId, getByLabelText, updateProps} = renderWithVuetify(VcColorPicker, {props: {color: "#aabbcc"}})
|
|
75
|
+
const selectElement = getByTestId("VcColorPicker_select");
|
|
76
|
+
expect(selectElement).toBeInTheDocument();
|
|
77
|
+
|
|
78
|
+
userEvent.click(selectElement);
|
|
79
|
+
|
|
80
|
+
const hexaColor = "#aabbccff";
|
|
81
|
+
const hexColor = hexaColor.substr(0, 7);
|
|
82
|
+
|
|
83
|
+
const expectedInputValue = getByLabelText("Color");
|
|
84
|
+
expect(expectedInputValue).toBeInTheDocument();
|
|
85
|
+
expect(expectedInputValue).toHaveValue(hexColor.toUpperCase());
|
|
86
|
+
|
|
87
|
+
const newColor = "#325E8BFF";
|
|
88
|
+
await updateProps({color: newColor});
|
|
89
|
+
expect(expectedInputValue).toHaveValue(newColor.toUpperCase());
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it ("Shows hint", async () => {
|
|
93
|
+
let hint = "please use hex format"
|
|
94
|
+
const {getByTestId, getByText} = renderWithVuetify(VcColorPicker, {props: {hint: hint}})
|
|
95
|
+
let hintElement = getByTestId("VcColorPicker-hint")
|
|
96
|
+
expect(hintElement).toBeInTheDocument();
|
|
97
|
+
|
|
98
|
+
hintElement = getByText(hint);
|
|
99
|
+
expect(hintElement).toBeInTheDocument();
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it("Rules with error", async () => {
|
|
103
|
+
const {
|
|
104
|
+
getByText,
|
|
105
|
+
getByTestId
|
|
106
|
+
} = renderWithVuetify(VcColorPicker, {props: {rules: [value => !!value || 'Required.']}})
|
|
107
|
+
const component = getByTestId('VcColorPicker');
|
|
108
|
+
expect(component).toBeInTheDocument()
|
|
109
|
+
|
|
110
|
+
const errorMsg = getByText("Required.");
|
|
111
|
+
expect(errorMsg).toBeInTheDocument();
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it("update to valid color", async () => {
|
|
115
|
+
const {getByLabelText, emitted} = renderWithVuetify(VcColorPicker, {});
|
|
116
|
+
|
|
117
|
+
const expectedInputValue = getByLabelText("Color");
|
|
118
|
+
expect(expectedInputValue).toBeInTheDocument();
|
|
119
|
+
expect(expectedInputValue).toHaveValue('');
|
|
120
|
+
|
|
121
|
+
await fireEvent.update(expectedInputValue, '#333333');
|
|
122
|
+
await fireEvent.blur(expectedInputValue);
|
|
123
|
+
|
|
124
|
+
expect(expectedInputValue).toHaveValue('#333333');
|
|
125
|
+
|
|
126
|
+
expect(emitted().change.length).toBe(1);
|
|
127
|
+
expect(emitted().change[0][0]).toBe('#333333');
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it("update to invalid color", async () => {
|
|
131
|
+
const {getByLabelText} = renderWithVuetify(VcColorPicker, {});
|
|
132
|
+
|
|
133
|
+
const expectedInputValue = getByLabelText("Color");
|
|
134
|
+
expect(expectedInputValue).toBeInTheDocument();
|
|
135
|
+
expect(expectedInputValue).toHaveValue('');
|
|
136
|
+
|
|
137
|
+
await fireEvent.update(expectedInputValue, '-');
|
|
138
|
+
await fireEvent.blur(expectedInputValue);
|
|
139
|
+
|
|
140
|
+
expect(expectedInputValue).toHaveValue('');
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it("open and close on click outside in desktop", async () => {
|
|
144
|
+
const {getByRole, queryByTestId, baseElement} = renderWithVuetify(VcColorPicker, {});
|
|
145
|
+
|
|
146
|
+
const button = getByRole("button");
|
|
147
|
+
expect(button).toBeInTheDocument();
|
|
148
|
+
|
|
149
|
+
let picker = queryByTestId('VcColorPicker_picker');
|
|
150
|
+
expect(picker).not.toBeInTheDocument();
|
|
151
|
+
|
|
152
|
+
// Open menu
|
|
153
|
+
await userEvent.click(button);
|
|
154
|
+
picker = queryByTestId('VcColorPicker_picker');
|
|
155
|
+
expect(picker).toBeInTheDocument();
|
|
156
|
+
|
|
157
|
+
// Close menu by click-outside
|
|
158
|
+
await userEvent.click(baseElement);
|
|
159
|
+
expect(picker).not.toBeInTheDocument();
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it("open and close on click outside in mobile", async () => {
|
|
163
|
+
const {getByRole, queryByTestId, baseElement} = renderWithVuetify(VcColorPicker, {}, undefined, true);
|
|
164
|
+
|
|
165
|
+
const button = getByRole("button");
|
|
166
|
+
expect(button).toBeInTheDocument();
|
|
167
|
+
|
|
168
|
+
// Open menu
|
|
169
|
+
await userEvent.click(button);
|
|
170
|
+
let picker = queryByTestId('VcColorPicker_picker');
|
|
171
|
+
expect(picker).toBeVisible();
|
|
172
|
+
|
|
173
|
+
await userEvent.click(baseElement);
|
|
174
|
+
// picker = queryByTestId('VcColorPicker_picker');
|
|
175
|
+
// expect(picker).not.toBeInTheDocument();
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it("click inside in mobile mode will not close the element", async () => {
|
|
179
|
+
const {getByRole, queryByTestId} = renderWithVuetify(VcColorPicker, {}, undefined, true);
|
|
180
|
+
|
|
181
|
+
const button = getByRole("button");
|
|
182
|
+
expect(button).toBeInTheDocument();
|
|
183
|
+
|
|
184
|
+
// Open menu
|
|
185
|
+
await userEvent.click(button);
|
|
186
|
+
let picker = queryByTestId('VcColorPicker_picker');
|
|
187
|
+
expect(picker).toBeVisible();
|
|
188
|
+
|
|
189
|
+
await userEvent.click(picker);
|
|
190
|
+
picker = queryByTestId('VcColorPicker_picker');
|
|
191
|
+
expect(picker).toBeVisible();
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it("return error with value not string", async () => {
|
|
195
|
+
const {getByTestId, queryByText} = renderWithVuetify(VcColorPicker,
|
|
196
|
+
{
|
|
197
|
+
props:
|
|
198
|
+
{rules: [() => 12]}
|
|
199
|
+
})
|
|
200
|
+
const component = getByTestId('VcColorPicker');
|
|
201
|
+
expect(component).toBeInTheDocument()
|
|
202
|
+
|
|
203
|
+
const errorMsg = queryByText("VcColorPicker-error");
|
|
204
|
+
expect(errorMsg).not.toBeInTheDocument();
|
|
205
|
+
})
|
|
206
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import VcColorPicker from './VcColorPicker';
|
|
2
|
+
import VcBaseDocs from '@/stories/VcBaseDocs.mdx';
|
|
3
|
+
|
|
4
|
+
const baseProps = {
|
|
5
|
+
dataQa: 'VcColorPicker',
|
|
6
|
+
disabled: false,
|
|
7
|
+
hint: "",
|
|
8
|
+
hexMode: false
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const Template = (args, {argTypes}) => ({
|
|
12
|
+
components: {VcColorPicker: VcColorPicker},
|
|
13
|
+
props: Object.keys(argTypes),
|
|
14
|
+
data: () => ({
|
|
15
|
+
color: '#aabbccff',
|
|
16
|
+
}),
|
|
17
|
+
template: `
|
|
18
|
+
<div>
|
|
19
|
+
<VcColorPicker
|
|
20
|
+
@change="onChange"
|
|
21
|
+
style="width: 256px"
|
|
22
|
+
:hex-mode="hexMode"
|
|
23
|
+
v-model="color"
|
|
24
|
+
:hint="hint"
|
|
25
|
+
:disabled="disabled"
|
|
26
|
+
:data-qa="dataQa"
|
|
27
|
+
:rules="rules"
|
|
28
|
+
/>
|
|
29
|
+
</div>`,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export const Playground = Template.bind({});
|
|
33
|
+
|
|
34
|
+
// Set default values
|
|
35
|
+
Playground.args = {
|
|
36
|
+
...baseProps,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const Disabled = Template.bind({});
|
|
40
|
+
|
|
41
|
+
// Set default values
|
|
42
|
+
Disabled.args = {
|
|
43
|
+
...baseProps,
|
|
44
|
+
disabled: true,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const HexMode = Template.bind({});
|
|
48
|
+
|
|
49
|
+
// Set default values
|
|
50
|
+
HexMode.args = {
|
|
51
|
+
...baseProps,
|
|
52
|
+
hexMode: true,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const ErrorTemplate = (args, {argTypes}) => ({
|
|
56
|
+
components: {VcColorPicker: VcColorPicker},
|
|
57
|
+
props: Object.keys(argTypes),
|
|
58
|
+
data: () => ({
|
|
59
|
+
color: '',
|
|
60
|
+
}),
|
|
61
|
+
template: `
|
|
62
|
+
<div>
|
|
63
|
+
Possible errors: <br>
|
|
64
|
+
1. Empty value <br>
|
|
65
|
+
2. Enter "#123456" in the value field
|
|
66
|
+
<VcColorPicker
|
|
67
|
+
:hex-mode="hexMode"
|
|
68
|
+
style="width: 256px"
|
|
69
|
+
v-model="color"
|
|
70
|
+
:hint="hint"
|
|
71
|
+
:disabled="disabled"
|
|
72
|
+
:data-qa="dataQa"
|
|
73
|
+
:rules="rules"
|
|
74
|
+
/>
|
|
75
|
+
</div>`,
|
|
76
|
+
})
|
|
77
|
+
export const WithError = ErrorTemplate.bind({});
|
|
78
|
+
|
|
79
|
+
// Set default values
|
|
80
|
+
WithError.args = {
|
|
81
|
+
...baseProps,
|
|
82
|
+
rules: [value => !!value || 'Required.',
|
|
83
|
+
value => value === "#123456" ? "Error example" : false,
|
|
84
|
+
],
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default {
|
|
88
|
+
title: 'controls / VcColorPicker', // This will control the story sidebar position
|
|
89
|
+
id: 'VcColorPicker', // This will be the permanent link to this component
|
|
90
|
+
component: VcColorPicker,
|
|
91
|
+
argTypes: {
|
|
92
|
+
onChange: {action: 'change', table: {disable: true}},
|
|
93
|
+
},
|
|
94
|
+
parameters: {
|
|
95
|
+
design: {
|
|
96
|
+
type: 'figma',
|
|
97
|
+
url: 'https://www.figma.com/file/xIOY6fBoA1wpy1tHv3i5js/vcita---ui-library?node-id=11590%3A245239',
|
|
98
|
+
},
|
|
99
|
+
status: {
|
|
100
|
+
type: 'stable', // 'beta' | 'stable' | 'deprecated' | 'releaseCandidate'
|
|
101
|
+
url: 'https://vuetifyjs.com/en/components/color-pickers/', // will make the tag a link
|
|
102
|
+
},
|
|
103
|
+
docs: {
|
|
104
|
+
page: VcBaseDocs,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|