vueless 1.3.6-beta.1 → 1.3.6-beta.11
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/components.d.ts +2 -0
- package/components.ts +2 -0
- package/constants.d.ts +2 -0
- package/constants.js +2 -0
- package/package.json +2 -2
- package/types.ts +2 -0
- package/ui.button/UButton.vue +1 -1
- package/ui.button/storybook/stories.ts +2 -2
- package/ui.container-card/storybook/stories.ts +2 -2
- package/ui.container-drawer/UDrawer.vue +3 -3
- package/ui.container-drawer/storybook/stories.ts +2 -2
- package/ui.container-grid/UGrid.vue +39 -0
- package/ui.container-grid/config.ts +123 -0
- package/ui.container-grid/constants.ts +5 -0
- package/ui.container-grid/storybook/docs.mdx +17 -0
- package/ui.container-grid/storybook/stories.ts +246 -0
- package/ui.container-grid/tests/UGrid.test.ts +297 -0
- package/ui.container-grid/types.ts +91 -0
- package/ui.container-modal/storybook/stories.ts +2 -2
- package/ui.container-modal-confirm/storybook/stories.ts +2 -2
- package/ui.container-page/storybook/stories.ts +3 -3
- package/ui.form-calendar/tests/UCalendar.test.ts +113 -0
- package/ui.form-date-picker-range/UDatePickerRangeInputs.vue +5 -1
- package/ui.form-date-picker-range/tests/UDatePickerRange.test.ts +114 -0
- package/ui.form-date-picker-range/types.ts +1 -0
- package/ui.form-listbox/config.ts +1 -1
- package/ui.image-avatar/UAvatar.vue +55 -28
- package/ui.image-avatar/config.ts +18 -1
- package/ui.image-avatar/storybook/docs.mdx +16 -1
- package/ui.image-avatar/storybook/stories.ts +17 -3
- package/ui.image-avatar/tests/UAvatar.test.ts +35 -7
- package/ui.image-avatar/types.ts +13 -0
- package/ui.image-avatar-group/UAvatarGroup.vue +87 -0
- package/ui.image-avatar-group/config.ts +11 -0
- package/ui.image-avatar-group/constants.ts +5 -0
- package/ui.image-avatar-group/storybook/docs.mdx +16 -0
- package/ui.image-avatar-group/storybook/stories.ts +147 -0
- package/ui.image-avatar-group/tests/UAvatarGroup.test.ts +141 -0
- package/ui.image-avatar-group/types.ts +51 -0
- package/ui.navigation-pagination/storybook/stories.ts +2 -2
- package/ui.navigation-tab/tests/UTab.test.ts +2 -3
- package/ui.navigation-tabs/UTabs.vue +44 -1
- package/ui.navigation-tabs/storybook/stories.ts +33 -0
- package/ui.navigation-tabs/tests/UTabs.test.ts +88 -0
- package/ui.text-block/config.ts +1 -0
- package/ui.text-block/storybook/stories.ts +2 -2
- package/ui.text-notify/UNotify.vue +31 -8
- package/ui.text-notify/config.ts +1 -1
- package/ui.text-notify/tests/UNotify.test.ts +22 -7
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
|
|
4
|
+
import UGrid from "../UGrid.vue";
|
|
5
|
+
|
|
6
|
+
import type { Props } from "../types";
|
|
7
|
+
|
|
8
|
+
describe("UGrid.vue", () => {
|
|
9
|
+
describe("Props", () => {
|
|
10
|
+
it("Cols – applies the correct cols class", () => {
|
|
11
|
+
const colsClasses = {
|
|
12
|
+
"1": "grid-cols-1",
|
|
13
|
+
"2": "grid-cols-2",
|
|
14
|
+
"3": "grid-cols-3",
|
|
15
|
+
"4": "grid-cols-4",
|
|
16
|
+
"5": "grid-cols-5",
|
|
17
|
+
"6": "grid-cols-6",
|
|
18
|
+
"7": "grid-cols-7",
|
|
19
|
+
"8": "grid-cols-8",
|
|
20
|
+
"9": "grid-cols-9",
|
|
21
|
+
"10": "grid-cols-10",
|
|
22
|
+
"11": "grid-cols-11",
|
|
23
|
+
"12": "grid-cols-12",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
Object.entries(colsClasses).forEach(([cols, classes]) => {
|
|
27
|
+
const component = mount(UGrid, {
|
|
28
|
+
props: {
|
|
29
|
+
cols: cols as Props["cols"],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(component.attributes("class")).toContain(classes);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("Rows – applies the correct rows class", () => {
|
|
38
|
+
const rowsClasses = {
|
|
39
|
+
"1": "grid-rows-1",
|
|
40
|
+
"2": "grid-rows-2",
|
|
41
|
+
"3": "grid-rows-3",
|
|
42
|
+
"4": "grid-rows-4",
|
|
43
|
+
"5": "grid-rows-5",
|
|
44
|
+
"6": "grid-rows-6",
|
|
45
|
+
"7": "grid-rows-7",
|
|
46
|
+
"8": "grid-rows-8",
|
|
47
|
+
"9": "grid-rows-9",
|
|
48
|
+
"10": "grid-rows-10",
|
|
49
|
+
"11": "grid-rows-11",
|
|
50
|
+
"12": "grid-rows-12",
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Object.entries(rowsClasses).forEach(([rows, classes]) => {
|
|
54
|
+
const component = mount(UGrid, {
|
|
55
|
+
props: {
|
|
56
|
+
rows: rows as Props["rows"],
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
expect(component.attributes("class")).toContain(classes);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("Gap – applies the correct gap class", () => {
|
|
65
|
+
const gapClasses = {
|
|
66
|
+
none: "gap-0",
|
|
67
|
+
"2xs": "gap-1",
|
|
68
|
+
xs: "gap-2",
|
|
69
|
+
sm: "gap-3",
|
|
70
|
+
md: "gap-4",
|
|
71
|
+
lg: "gap-5",
|
|
72
|
+
xl: "gap-6",
|
|
73
|
+
"2xl": "gap-8",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
Object.entries(gapClasses).forEach(([gap, classes]) => {
|
|
77
|
+
const component = mount(UGrid, {
|
|
78
|
+
props: {
|
|
79
|
+
gap: gap as Props["gap"],
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(component.attributes("class")).toContain(classes);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("Row Gap – applies the correct row gap class", () => {
|
|
88
|
+
const rowGapClasses = {
|
|
89
|
+
none: "gap-y-0",
|
|
90
|
+
"2xs": "gap-y-1",
|
|
91
|
+
xs: "gap-y-2",
|
|
92
|
+
sm: "gap-y-3",
|
|
93
|
+
md: "gap-y-4",
|
|
94
|
+
lg: "gap-y-5",
|
|
95
|
+
xl: "gap-y-6",
|
|
96
|
+
"2xl": "gap-y-8",
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
Object.entries(rowGapClasses).forEach(([rowGap, classes]) => {
|
|
100
|
+
const component = mount(UGrid, {
|
|
101
|
+
props: {
|
|
102
|
+
rowGap: rowGap as Props["rowGap"],
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(component.attributes("class")).toContain(classes);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("Col Gap – applies the correct col gap class", () => {
|
|
111
|
+
const colGapClasses = {
|
|
112
|
+
none: "gap-x-0",
|
|
113
|
+
"2xs": "gap-x-1",
|
|
114
|
+
xs: "gap-x-2",
|
|
115
|
+
sm: "gap-x-3",
|
|
116
|
+
md: "gap-x-4",
|
|
117
|
+
lg: "gap-x-5",
|
|
118
|
+
xl: "gap-x-6",
|
|
119
|
+
"2xl": "gap-x-8",
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
Object.entries(colGapClasses).forEach(([colGap, classes]) => {
|
|
123
|
+
const component = mount(UGrid, {
|
|
124
|
+
props: {
|
|
125
|
+
colGap: colGap as Props["colGap"],
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(component.attributes("class")).toContain(classes);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("Align – applies the correct align class", () => {
|
|
134
|
+
const alignClasses = {
|
|
135
|
+
start: "items-start",
|
|
136
|
+
end: "items-end",
|
|
137
|
+
center: "items-center",
|
|
138
|
+
stretch: "items-stretch",
|
|
139
|
+
baseline: "items-baseline",
|
|
140
|
+
normal: "items-normal",
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
Object.entries(alignClasses).forEach(([align, classes]) => {
|
|
144
|
+
const component = mount(UGrid, {
|
|
145
|
+
props: {
|
|
146
|
+
align: align as Props["align"],
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(component.attributes("class")).toContain(classes);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("Content – applies the correct content class", () => {
|
|
155
|
+
const contentClasses = {
|
|
156
|
+
start: "content-start",
|
|
157
|
+
end: "content-end",
|
|
158
|
+
center: "content-center",
|
|
159
|
+
around: "content-around",
|
|
160
|
+
evenly: "content-evenly",
|
|
161
|
+
between: "content-between",
|
|
162
|
+
normal: "content-normal",
|
|
163
|
+
stretch: "content-stretch",
|
|
164
|
+
baseline: "content-baseline",
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
Object.entries(contentClasses).forEach(([content, classes]) => {
|
|
168
|
+
const component = mount(UGrid, {
|
|
169
|
+
props: {
|
|
170
|
+
content: content as Props["content"],
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(component.attributes("class")).toContain(classes);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("Justify – applies the correct justify class", () => {
|
|
179
|
+
const justifyClasses = {
|
|
180
|
+
start: "justify-items-start",
|
|
181
|
+
end: "justify-items-end",
|
|
182
|
+
"end-safe": "justify-items-end-safe",
|
|
183
|
+
center: "justify-items-center",
|
|
184
|
+
"center-safe": "justify-items-center-safe",
|
|
185
|
+
stretch: "justify-items-stretch",
|
|
186
|
+
normal: "justify-items-normal",
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
Object.entries(justifyClasses).forEach(([justify, classes]) => {
|
|
190
|
+
const component = mount(UGrid, {
|
|
191
|
+
props: {
|
|
192
|
+
justify: justify as Props["justify"],
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
expect(component.attributes("class")).toContain(classes);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("Place Content – applies the correct place content class", () => {
|
|
201
|
+
const placeContentClasses = {
|
|
202
|
+
start: "place-content-start",
|
|
203
|
+
end: "place-content-end",
|
|
204
|
+
"end-safe": "place-content-end-safe",
|
|
205
|
+
center: "place-content-center",
|
|
206
|
+
"center-safe": "place-content-center-safe",
|
|
207
|
+
around: "place-content-around",
|
|
208
|
+
evenly: "place-content-evenly",
|
|
209
|
+
between: "place-content-between",
|
|
210
|
+
stretch: "place-content-stretch",
|
|
211
|
+
baseline: "place-content-baseline",
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
Object.entries(placeContentClasses).forEach(([placeContent, classes]) => {
|
|
215
|
+
const component = mount(UGrid, {
|
|
216
|
+
props: {
|
|
217
|
+
placeContent: placeContent as Props["placeContent"],
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(component.attributes("class")).toContain(classes);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("Place Items – applies the correct place items class", () => {
|
|
226
|
+
const placeItemsClasses = {
|
|
227
|
+
start: "place-items-start",
|
|
228
|
+
end: "place-items-end",
|
|
229
|
+
"end-safe": "place-items-end-safe",
|
|
230
|
+
center: "place-items-center",
|
|
231
|
+
"center-safe": "place-items-center-safe",
|
|
232
|
+
stretch: "place-items-stretch",
|
|
233
|
+
baseline: "place-items-baseline",
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
Object.entries(placeItemsClasses).forEach(([placeItems, classes]) => {
|
|
237
|
+
const component = mount(UGrid, {
|
|
238
|
+
props: {
|
|
239
|
+
placeItems: placeItems as Props["placeItems"],
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
expect(component.attributes("class")).toContain(classes);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("Tag – renders the correct HTML tag", () => {
|
|
248
|
+
const tags = ["div", "section", "article", "main", "aside", "nav", "span"];
|
|
249
|
+
|
|
250
|
+
tags.forEach((tag) => {
|
|
251
|
+
const component = mount(UGrid, {
|
|
252
|
+
props: {
|
|
253
|
+
tag,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
expect(component.element.tagName.toLowerCase()).toBe(tag);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it("Data Test – applies the correct data-test attribute", () => {
|
|
262
|
+
const dataTest = "grid-test";
|
|
263
|
+
|
|
264
|
+
const component = mount(UGrid, {
|
|
265
|
+
props: {
|
|
266
|
+
dataTest,
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
expect(component.attributes("data-test")).toBe(dataTest);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
describe("Slots", () => {
|
|
275
|
+
it("Default – renders content from default slot", () => {
|
|
276
|
+
const slotContent = "Custom Content";
|
|
277
|
+
|
|
278
|
+
const component = mount(UGrid, {
|
|
279
|
+
slots: {
|
|
280
|
+
default: slotContent,
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
expect(component.text()).toContain(slotContent);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe("Exposed refs", () => {
|
|
289
|
+
it("wrapperRef – exposes wrapperRef", () => {
|
|
290
|
+
const component = mount(UGrid);
|
|
291
|
+
|
|
292
|
+
expect(component.vm.wrapperRef).toBeDefined();
|
|
293
|
+
// wrapperRef is a reference to the wrapper div element, not a boolean
|
|
294
|
+
expect(component.vm.wrapperRef instanceof HTMLElement).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import defaultConfig from "./config";
|
|
2
|
+
|
|
3
|
+
import type { ComponentConfig } from "../types";
|
|
4
|
+
|
|
5
|
+
export type Config = typeof defaultConfig;
|
|
6
|
+
|
|
7
|
+
export interface Props {
|
|
8
|
+
/**
|
|
9
|
+
* Number of columns.
|
|
10
|
+
*/
|
|
11
|
+
cols?: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Number of rows.
|
|
15
|
+
*/
|
|
16
|
+
rows?: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Gap between items.
|
|
20
|
+
*/
|
|
21
|
+
gap?: "none" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Vertical gap override.
|
|
25
|
+
*/
|
|
26
|
+
rowGap?: "none" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Horizontal gap override.
|
|
30
|
+
*/
|
|
31
|
+
colGap?: "none" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Vertical alignment (align-items).
|
|
35
|
+
*/
|
|
36
|
+
align?: "start" | "end" | "center" | "stretch" | "baseline" | "normal";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Items vertical align for multi-row grid containers (align-content).
|
|
40
|
+
*/
|
|
41
|
+
content?:
|
|
42
|
+
| "start"
|
|
43
|
+
| "end"
|
|
44
|
+
| "center"
|
|
45
|
+
| "around"
|
|
46
|
+
| "evenly"
|
|
47
|
+
| "between"
|
|
48
|
+
| "normal"
|
|
49
|
+
| "stretch"
|
|
50
|
+
| "baseline";
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Control how grid items are aligned along their inline axis (justify-items).
|
|
54
|
+
*/
|
|
55
|
+
justify?: "start" | "end" | "end-safe" | "center" | "center-safe" | "stretch" | "normal";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Control how content is justified and aligned within the grid (place-content).
|
|
59
|
+
*/
|
|
60
|
+
placeContent?:
|
|
61
|
+
| "start"
|
|
62
|
+
| "end"
|
|
63
|
+
| "end-safe"
|
|
64
|
+
| "center"
|
|
65
|
+
| "center-safe"
|
|
66
|
+
| "around"
|
|
67
|
+
| "evenly"
|
|
68
|
+
| "between"
|
|
69
|
+
| "stretch"
|
|
70
|
+
| "baseline";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Control how items are justified and aligned within the grid (place-items).
|
|
74
|
+
*/
|
|
75
|
+
placeItems?: "start" | "end" | "end-safe" | "center" | "center-safe" | "stretch" | "baseline";
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Allows changing HTML tag.
|
|
79
|
+
*/
|
|
80
|
+
tag?: string;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Component config object.
|
|
84
|
+
*/
|
|
85
|
+
config?: ComponentConfig<Config>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Data-test attribute for automated testing.
|
|
89
|
+
*/
|
|
90
|
+
dataTest?: string | null;
|
|
91
|
+
}
|
|
@@ -280,8 +280,8 @@ WithoutDivider.parameters = {
|
|
|
280
280
|
export const Sizes = EnumTemplate.bind({});
|
|
281
281
|
Sizes.args = { enum: "size", modelValues: {} };
|
|
282
282
|
|
|
283
|
-
export const
|
|
284
|
-
|
|
283
|
+
export const Variants = EnumTemplate.bind({});
|
|
284
|
+
Variants.args = { enum: "variant", modelValues: {} };
|
|
285
285
|
|
|
286
286
|
export const BackLink: StoryFn<UModalArgs> = (args: UModalArgs) => ({
|
|
287
287
|
components: { UModal, UButton, UCheckbox, UCol, URow, UDivider, UInput, UInputPassword },
|
|
@@ -221,8 +221,8 @@ DisableConfirmButton.args = { confirmDisabled: true };
|
|
|
221
221
|
export const Sizes = EnumTemplate.bind({});
|
|
222
222
|
Sizes.args = { enum: "size", modelValues: {} };
|
|
223
223
|
|
|
224
|
-
export const
|
|
225
|
-
|
|
224
|
+
export const Variants = EnumTemplate.bind({});
|
|
225
|
+
Variants.args = { enum: "variant", modelValues: {} };
|
|
226
226
|
|
|
227
227
|
export const Colors: StoryFn<UModalConfirmArgs> = (args: UModalConfirmArgs, { argTypes }) => ({
|
|
228
228
|
components: { UModalConfirm, UButton, URow },
|
|
@@ -212,9 +212,9 @@ Sizes.parameters = {
|
|
|
212
212
|
},
|
|
213
213
|
};
|
|
214
214
|
|
|
215
|
-
export const
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
export const Variants = EnumTemplate.bind({});
|
|
216
|
+
Variants.args = { enum: "variant", description: "{enumValue}" };
|
|
217
|
+
Variants.parameters = {
|
|
218
218
|
docs: {
|
|
219
219
|
description: {
|
|
220
220
|
story: "Page variant.",
|
|
@@ -131,6 +131,31 @@ describe("UCalendar.vue", () => {
|
|
|
131
131
|
expect(rangeUpdate.to).not.toBeNull();
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
+
it("Range – allows selecting the same day for from and to", async () => {
|
|
135
|
+
const component = mount(UCalendar, {
|
|
136
|
+
props: {
|
|
137
|
+
range: true,
|
|
138
|
+
modelValue: { from: null, to: null },
|
|
139
|
+
dateFormat: "Y-m-d",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const dayView = component.findComponent(DayView);
|
|
144
|
+
const days = dayView.findAll('[vl-key="day"]');
|
|
145
|
+
|
|
146
|
+
await days[5].trigger("click");
|
|
147
|
+
await days[5].trigger("click");
|
|
148
|
+
|
|
149
|
+
expect(component.emitted("update:modelValue")).toBeTruthy();
|
|
150
|
+
expect(component.emitted("update:modelValue")).toHaveLength(2);
|
|
151
|
+
|
|
152
|
+
const rangeUpdate = component.emitted("update:modelValue")![1][0] as RangeDate;
|
|
153
|
+
|
|
154
|
+
expect(rangeUpdate.from).not.toBeNull();
|
|
155
|
+
expect(rangeUpdate.to).not.toBeNull();
|
|
156
|
+
expect(rangeUpdate.from).toBe(rangeUpdate.to);
|
|
157
|
+
});
|
|
158
|
+
|
|
134
159
|
it("Timepicker – shows timepicker when enabled", () => {
|
|
135
160
|
const component = mount(UCalendar, {
|
|
136
161
|
props: {
|
|
@@ -518,6 +543,94 @@ describe("UCalendar.vue", () => {
|
|
|
518
543
|
|
|
519
544
|
expect(component.emitted("userDateChange")).toBeTruthy();
|
|
520
545
|
});
|
|
546
|
+
|
|
547
|
+
it("ChangeRange – emits when first date is selected in range mode", async () => {
|
|
548
|
+
const component = mount(UCalendar, {
|
|
549
|
+
props: {
|
|
550
|
+
range: true,
|
|
551
|
+
modelValue: { from: null, to: null },
|
|
552
|
+
dateFormat: "Y-m-d",
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
const dayView = component.findComponent(DayView);
|
|
557
|
+
const days = dayView.findAll('[vl-key="day"]');
|
|
558
|
+
|
|
559
|
+
await days[0].trigger("click");
|
|
560
|
+
|
|
561
|
+
expect(component.emitted("change-range")).toBeTruthy();
|
|
562
|
+
expect(component.emitted("change-range")![0][0]).toHaveProperty("from");
|
|
563
|
+
expect(component.emitted("change-range")![0][0]).toHaveProperty("to");
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it("ChangeRange – emits when both dates are selected in range mode", async () => {
|
|
567
|
+
const component = mount(UCalendar, {
|
|
568
|
+
props: {
|
|
569
|
+
range: true,
|
|
570
|
+
modelValue: { from: null, to: null },
|
|
571
|
+
dateFormat: "Y-m-d",
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
const dayView = component.findComponent(DayView);
|
|
576
|
+
const days = dayView.findAll('[vl-key="day"]');
|
|
577
|
+
|
|
578
|
+
await days[0].trigger("click");
|
|
579
|
+
await days[3].trigger("click");
|
|
580
|
+
|
|
581
|
+
const changeRangeEvents = component.emitted("change-range");
|
|
582
|
+
|
|
583
|
+
expect(changeRangeEvents).toBeTruthy();
|
|
584
|
+
expect(changeRangeEvents!.length).toBeGreaterThan(0);
|
|
585
|
+
|
|
586
|
+
const lastEvent = changeRangeEvents![changeRangeEvents!.length - 1][0] as RangeDate;
|
|
587
|
+
|
|
588
|
+
expect(lastEvent.from).not.toBeNull();
|
|
589
|
+
expect(lastEvent.to).not.toBeNull();
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
it("ChangeRange – emits when same date is selected twice in range mode", async () => {
|
|
593
|
+
const component = mount(UCalendar, {
|
|
594
|
+
props: {
|
|
595
|
+
range: true,
|
|
596
|
+
modelValue: { from: null, to: null },
|
|
597
|
+
dateFormat: "Y-m-d",
|
|
598
|
+
},
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
const dayView = component.findComponent(DayView);
|
|
602
|
+
const days = dayView.findAll('[vl-key="day"]');
|
|
603
|
+
|
|
604
|
+
await days[5].trigger("click");
|
|
605
|
+
await days[5].trigger("click");
|
|
606
|
+
|
|
607
|
+
const changeRangeEvents = component.emitted("change-range");
|
|
608
|
+
|
|
609
|
+
expect(changeRangeEvents).toBeTruthy();
|
|
610
|
+
|
|
611
|
+
const lastEvent = changeRangeEvents![changeRangeEvents!.length - 1][0] as RangeDate;
|
|
612
|
+
|
|
613
|
+
expect(lastEvent.from).not.toBeNull();
|
|
614
|
+
expect(lastEvent.to).not.toBeNull();
|
|
615
|
+
expect(lastEvent.from).toBe(lastEvent.to);
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
it("ChangeRange – does not emit when range mode is disabled", async () => {
|
|
619
|
+
const component = mount(UCalendar, {
|
|
620
|
+
props: {
|
|
621
|
+
range: false,
|
|
622
|
+
modelValue: null,
|
|
623
|
+
dateFormat: "Y-m-d",
|
|
624
|
+
},
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
const dayView = component.findComponent(DayView);
|
|
628
|
+
const day = dayView.find('[vl-key="day"]');
|
|
629
|
+
|
|
630
|
+
await day.trigger("click");
|
|
631
|
+
|
|
632
|
+
expect(component.emitted("change-range")).toBeFalsy();
|
|
633
|
+
});
|
|
521
634
|
});
|
|
522
635
|
|
|
523
636
|
describe("Exposed Properties", () => {
|
|
@@ -16,7 +16,9 @@ type UInputRef = InstanceType<typeof UInput>;
|
|
|
16
16
|
|
|
17
17
|
defineOptions({ internal: true });
|
|
18
18
|
|
|
19
|
-
const props = defineProps<UDatePickerRangeInputsProps>()
|
|
19
|
+
const props = withDefaults(defineProps<UDatePickerRangeInputsProps>(), {
|
|
20
|
+
dataTest: null,
|
|
21
|
+
});
|
|
20
22
|
|
|
21
23
|
const rangeInputStartRef = useTemplateRef<UInputRef>("range-input-start");
|
|
22
24
|
const rangeInputEndRef = useTemplateRef<UInputRef>("range-input-end");
|
|
@@ -140,6 +142,7 @@ defineExpose({
|
|
|
140
142
|
v-bind="attrs.rangeInputFirstAttrs.value"
|
|
141
143
|
:name="rangeInputName"
|
|
142
144
|
no-autocomplete
|
|
145
|
+
:data-test="`${dataTest}-from`"
|
|
143
146
|
@blur="updateDateValue(rangeStart, InputRangeType.Start)"
|
|
144
147
|
@keydown.enter="updateDateValue(rangeStart, InputRangeType.Start)"
|
|
145
148
|
@input="validateInput($event, InputRangeType.Start)"
|
|
@@ -153,6 +156,7 @@ defineExpose({
|
|
|
153
156
|
v-bind="attrs.rangeInputLastAttrs.value"
|
|
154
157
|
:name="rangeInputName"
|
|
155
158
|
no-autocomplete
|
|
159
|
+
:data-test="`${dataTest}-to`"
|
|
156
160
|
@blur="updateDateValue(rangeEnd, InputRangeType.End)"
|
|
157
161
|
@keydown.enter="updateDateValue(rangeEnd, InputRangeType.End)"
|
|
158
162
|
@input="validateInput($event, InputRangeType.End)"
|