@code-coaching/vuetiful 0.13.1 → 0.14.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/README.md +55 -2
- package/dist/style.css +10 -0
- package/dist/styles/all.css +6458 -0
- package/dist/types/components/atoms/VBadge.test.d.ts +1 -0
- package/dist/types/components/atoms/VChip.test.d.ts +1 -0
- package/dist/types/components/atoms/VSwitch/VSwitch.test.d.ts +1 -0
- package/dist/types/components/atoms/VSwitch/VSwitch.vue.d.ts +70 -0
- package/dist/types/components/atoms/VSwitch/VSwitchDescription.test.d.ts +1 -0
- package/dist/types/components/atoms/VSwitch/VSwitchDescription.vue.d.ts +14 -0
- package/dist/types/components/atoms/VSwitch/VSwitchGroup.test.d.ts +1 -0
- package/dist/types/components/atoms/VSwitch/VSwitchGroup.vue.d.ts +14 -0
- package/dist/types/components/atoms/VSwitch/VSwitchLabel.test.d.ts +1 -0
- package/dist/types/components/atoms/VSwitch/VSwitchLabel.vue.d.ts +23 -0
- package/dist/types/components/atoms/index.d.ts +5 -1
- package/dist/vuetiful.es.mjs +48082 -0
- package/dist/vuetiful.umd.js +21 -0
- package/package.json +1 -1
- package/src/components/atoms/VBadge.test.ts +18 -0
- package/src/components/atoms/VButton.test.ts +32 -32
- package/src/components/atoms/VChip.test.ts +18 -0
- package/src/components/atoms/VSwitch/VSwitch.test.ts +121 -0
- package/src/components/atoms/VSwitch/VSwitch.vue +97 -0
- package/src/components/atoms/VSwitch/VSwitchDescription.test.ts +56 -0
- package/src/components/atoms/VSwitch/VSwitchDescription.vue +16 -0
- package/src/components/atoms/VSwitch/VSwitchGroup.test.ts +26 -0
- package/src/components/atoms/VSwitch/VSwitchGroup.vue +16 -0
- package/src/components/atoms/VSwitch/VSwitchLabel.test.ts +89 -0
- package/src/components/atoms/VSwitch/VSwitchLabel.vue +20 -0
- package/src/components/atoms/index.ts +18 -1
- package/src/components/molecules/VRail.vue +1 -1
- package/src/utils/theme/remove.test.ts +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { VBadge } from ".";
|
|
4
|
+
|
|
5
|
+
test("VBadge", () => {
|
|
6
|
+
expect(VBadge).toBeTruthy();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("VBadge using slot", () => {
|
|
10
|
+
const wrapper = mount(VBadge, {
|
|
11
|
+
slots: {
|
|
12
|
+
default: "John Duck",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
17
|
+
expect(wrapper.classes()).toContain("badge");
|
|
18
|
+
});
|
|
@@ -7,36 +7,36 @@ test("VButton", () => {
|
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
test("VButton using slot", () => {
|
|
10
|
-
const
|
|
10
|
+
const wrapper = mount(VButton, {
|
|
11
11
|
slots: {
|
|
12
12
|
default: "John Duck",
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
expect(
|
|
16
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
describe("VButton props", () => {
|
|
20
20
|
describe("given icon is true", () => {
|
|
21
21
|
test("should have btn-icon class, not have btn class", () => {
|
|
22
|
-
const
|
|
22
|
+
const wrapper = mount(VButton, {
|
|
23
23
|
props: {
|
|
24
24
|
icon: true,
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
|
-
expect(
|
|
28
|
-
expect(
|
|
27
|
+
expect(wrapper.classes()).toContain("btn-icon");
|
|
28
|
+
expect(wrapper.classes()).not.toContain("btn");
|
|
29
29
|
});
|
|
30
30
|
});
|
|
31
31
|
describe("given icon is false", () => {
|
|
32
32
|
test("should have btn class, not have btn-icon class", () => {
|
|
33
|
-
const
|
|
33
|
+
const wrapper = mount(VButton, {
|
|
34
34
|
props: {
|
|
35
35
|
icon: false,
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
38
|
+
expect(wrapper.classes()).not.toContain("btn-icon");
|
|
39
|
+
expect(wrapper.classes()).toContain("btn");
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
});
|
|
@@ -44,13 +44,13 @@ describe("VButton props", () => {
|
|
|
44
44
|
describe("VButton events", () => {
|
|
45
45
|
describe("given click event", () => {
|
|
46
46
|
test("should preventDefault and emit click event", async () => {
|
|
47
|
-
const
|
|
47
|
+
const wrapper = mount(VButton);
|
|
48
48
|
const clickEvent = { preventDefault: () => {} };
|
|
49
49
|
const preventDefaultSpy = vi.spyOn(clickEvent, "preventDefault");
|
|
50
|
-
|
|
51
|
-
await
|
|
50
|
+
wrapper.trigger("click", clickEvent);
|
|
51
|
+
await wrapper.vm.$nextTick();
|
|
52
52
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
|
53
|
-
expect(
|
|
53
|
+
expect(wrapper.emitted("click")).toBeTruthy();
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
});
|
|
@@ -58,50 +58,50 @@ describe("VButton events", () => {
|
|
|
58
58
|
describe("VButton a11y", () => {
|
|
59
59
|
describe("a11y role", () => {
|
|
60
60
|
test("should have role button", () => {
|
|
61
|
-
const
|
|
62
|
-
expect(
|
|
61
|
+
const wrapper = mount(VButton);
|
|
62
|
+
expect(wrapper.attributes("role")).toBe("button");
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
65
|
describe("a11y tabindex", () => {
|
|
66
66
|
test("should have tabindex 0", () => {
|
|
67
|
-
const
|
|
68
|
-
expect(
|
|
67
|
+
const wrapper = mount(VButton);
|
|
68
|
+
expect(wrapper.attributes("tabindex")).toBe("0");
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
describe("given keydown event", () => {
|
|
72
72
|
describe("given key is Enter", () => {
|
|
73
73
|
test("should preventDefault and emit click event", async () => {
|
|
74
|
-
const
|
|
74
|
+
const wrapper = mount(VButton);
|
|
75
75
|
const keydownEvent = { key: "Enter", preventDefault: () => {} };
|
|
76
76
|
const preventDefaultSpy = vi.spyOn(keydownEvent, "preventDefault");
|
|
77
|
-
|
|
78
|
-
await
|
|
77
|
+
wrapper.trigger("keydown", keydownEvent);
|
|
78
|
+
await wrapper.vm.$nextTick();
|
|
79
79
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
|
80
|
-
expect(
|
|
80
|
+
expect(wrapper.emitted("click")).toBeTruthy();
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
describe("given key is Space", () => {
|
|
85
85
|
test("should preventDefault and not emit click event", async () => {
|
|
86
|
-
const
|
|
86
|
+
const wrapper = mount(VButton);
|
|
87
87
|
const keydownEvent = { key: " ", preventDefault: () => {} };
|
|
88
88
|
const preventDefaultSpy = vi.spyOn(keydownEvent, "preventDefault");
|
|
89
|
-
|
|
90
|
-
await
|
|
89
|
+
wrapper.trigger("keydown", keydownEvent);
|
|
90
|
+
await wrapper.vm.$nextTick();
|
|
91
91
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
|
92
|
-
expect(
|
|
92
|
+
expect(wrapper.emitted("click")).toBeFalsy();
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
describe("given key is not Enter or Space", () => {
|
|
97
97
|
test("should not preventDefault and not emit click event", async () => {
|
|
98
|
-
const
|
|
98
|
+
const wrapper = mount(VButton);
|
|
99
99
|
const keydownEvent = { key: "a", preventDefault: () => {} };
|
|
100
100
|
const preventDefaultSpy = vi.spyOn(keydownEvent, "preventDefault");
|
|
101
|
-
|
|
102
|
-
await
|
|
101
|
+
wrapper.trigger("keydown", keydownEvent);
|
|
102
|
+
await wrapper.vm.$nextTick();
|
|
103
103
|
expect(preventDefaultSpy).not.toHaveBeenCalled();
|
|
104
|
-
expect(
|
|
104
|
+
expect(wrapper.emitted("click")).toBeFalsy();
|
|
105
105
|
});
|
|
106
106
|
});
|
|
107
107
|
});
|
|
@@ -109,13 +109,13 @@ describe("VButton a11y", () => {
|
|
|
109
109
|
describe("given keyup event", () => {
|
|
110
110
|
describe("given key is Space", () => {
|
|
111
111
|
test("should preventDefault and emit click event", async () => {
|
|
112
|
-
const
|
|
112
|
+
const wrapper = mount(VButton);
|
|
113
113
|
const keyupEvent = { key: " ", preventDefault: () => {} };
|
|
114
114
|
const preventDefaultSpy = vi.spyOn(keyupEvent, "preventDefault");
|
|
115
|
-
|
|
116
|
-
await
|
|
115
|
+
wrapper.trigger("keyup", keyupEvent);
|
|
116
|
+
await wrapper.vm.$nextTick();
|
|
117
117
|
expect(preventDefaultSpy).toHaveBeenCalled();
|
|
118
|
-
expect(
|
|
118
|
+
expect(wrapper.emitted("click")).toBeTruthy();
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { VChip } from ".";
|
|
4
|
+
|
|
5
|
+
test("VChip", () => {
|
|
6
|
+
expect(VChip).toBeTruthy();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("VChip using slot", () => {
|
|
10
|
+
const wrapper = mount(VChip, {
|
|
11
|
+
slots: {
|
|
12
|
+
default: "John Duck",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
17
|
+
expect(wrapper.classes()).toContain("chip");
|
|
18
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import VSwitch from "./VSwitch.vue";
|
|
4
|
+
import { ref } from "vue";
|
|
5
|
+
|
|
6
|
+
describe("VSwitch slots", () => {
|
|
7
|
+
test("should not add screen reader text by default", () => {
|
|
8
|
+
const wrapper = mount(VSwitch);
|
|
9
|
+
|
|
10
|
+
const srOnly = wrapper.find(".sr-only");
|
|
11
|
+
expect(srOnly.exists()).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
test("should add screen reader text if default slot is present", () => {
|
|
14
|
+
const wrapper = mount(VSwitch, {
|
|
15
|
+
slots: {
|
|
16
|
+
default: "John Duck",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const srOnly = wrapper.find(".sr-only");
|
|
21
|
+
expect(srOnly.text()).toContain("John Duck");
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("VSwitch props", () => {
|
|
26
|
+
test("defaults", () => {
|
|
27
|
+
const wrapper = mount(VSwitch);
|
|
28
|
+
|
|
29
|
+
expect(wrapper.props()).toEqual({
|
|
30
|
+
modelValue: false,
|
|
31
|
+
disabled: false,
|
|
32
|
+
size: "md",
|
|
33
|
+
switchClass: "variant-filled",
|
|
34
|
+
thumbClass: "bg-surface-100-800-token",
|
|
35
|
+
as: "button",
|
|
36
|
+
name: "",
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("size xs", () => {
|
|
41
|
+
const wrapper = mount(VSwitch, {
|
|
42
|
+
props: {
|
|
43
|
+
size: "xs",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
48
|
+
expect(track.attributes("class")).toContain("w-8 h-4");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("size sm", () => {
|
|
52
|
+
const wrapper = mount(VSwitch, {
|
|
53
|
+
props: {
|
|
54
|
+
size: "sm",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
59
|
+
expect(track.attributes("class")).toContain("w-12 h-6");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("size md", () => {
|
|
63
|
+
const wrapper = mount(VSwitch, {
|
|
64
|
+
props: {
|
|
65
|
+
size: "md",
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
70
|
+
expect(track.attributes("class")).toContain("w-16 h-8");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("size lg", () => {
|
|
74
|
+
const wrapper = mount(VSwitch, {
|
|
75
|
+
props: {
|
|
76
|
+
size: "lg",
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
81
|
+
expect(track.attributes("class")).toContain("w-20 h-10");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("size xl", () => {
|
|
85
|
+
const wrapper = mount(VSwitch, {
|
|
86
|
+
props: {
|
|
87
|
+
size: "xl",
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
92
|
+
expect(track.attributes("class")).toContain("w-24 h-12");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("size custom", () => {
|
|
96
|
+
const wrapper = mount(VSwitch, {
|
|
97
|
+
props: {
|
|
98
|
+
size: "custom",
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const track = wrapper.find(".slide-toggle-track");
|
|
103
|
+
expect(track.attributes("class")).toContain("custom");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe("VSwitch events", () => {
|
|
111
|
+
test("update:modelValue", async () => {
|
|
112
|
+
const wrapper = mount(VSwitch, {
|
|
113
|
+
props: {
|
|
114
|
+
modelValue: false,
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
await wrapper.setProps({ modelValue: true});
|
|
119
|
+
expect(wrapper.emitted()).toHaveProperty("update:modelValue");
|
|
120
|
+
})
|
|
121
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Switch } from "@headlessui/vue";
|
|
3
|
+
import { computed, ref, watch } from "vue";
|
|
4
|
+
|
|
5
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
modelValue: {
|
|
8
|
+
type: Boolean,
|
|
9
|
+
default: false,
|
|
10
|
+
},
|
|
11
|
+
disabled: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
default: false,
|
|
14
|
+
},
|
|
15
|
+
size: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: "md",
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
switchClass: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: "variant-filled",
|
|
23
|
+
},
|
|
24
|
+
thumbClass: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: "bg-surface-100-800-token",
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
as: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: "button",
|
|
32
|
+
},
|
|
33
|
+
name: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: "",
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const parentModelValue = ref(props.modelValue);
|
|
40
|
+
watch(
|
|
41
|
+
() => props.modelValue,
|
|
42
|
+
(newValue) => {
|
|
43
|
+
parentModelValue.value = newValue;
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
watch(
|
|
47
|
+
() => parentModelValue.value,
|
|
48
|
+
(newValue) => {
|
|
49
|
+
emit("update:modelValue", newValue);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const trackSize = computed(() => {
|
|
54
|
+
switch (props.size) {
|
|
55
|
+
case "xs":
|
|
56
|
+
return "w-8 h-4";
|
|
57
|
+
case "sm":
|
|
58
|
+
return "w-12 h-6";
|
|
59
|
+
case "md":
|
|
60
|
+
return "w-16 h-8";
|
|
61
|
+
case "lg":
|
|
62
|
+
return "w-20 h-10";
|
|
63
|
+
case "xl":
|
|
64
|
+
return "w-24 h-12";
|
|
65
|
+
default:
|
|
66
|
+
return props.size;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<template>
|
|
72
|
+
<!-- There is some odd behavior with test coverge, v-model must be the last property in this component -->
|
|
73
|
+
<Switch
|
|
74
|
+
:class="`slide-toggle rounded-container-token ${
|
|
75
|
+
disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
|
|
76
|
+
}`"
|
|
77
|
+
:name="name"
|
|
78
|
+
:as="as"
|
|
79
|
+
v-slot="{ checked }"
|
|
80
|
+
v-model="parentModelValue"
|
|
81
|
+
>
|
|
82
|
+
<button
|
|
83
|
+
:class="`slide-toggle-track flex transition-all duration-[150ms] border-token rounded-token ${trackSize} ${
|
|
84
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer'
|
|
85
|
+
} ${switchClass}`"
|
|
86
|
+
>
|
|
87
|
+
<template v-if="$slots.default">
|
|
88
|
+
<span class="sr-only"><slot /></span>
|
|
89
|
+
</template>
|
|
90
|
+
<div
|
|
91
|
+
:class="`slide-toggle-thumb h-full w-[50%] scale-[0.8] shadow transition-all duration-[150ms] rounded-token ${
|
|
92
|
+
checked ? 'translate-x-full' : 'opacity-90'
|
|
93
|
+
} ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'} ${thumbClass} bg-opacity-90`"
|
|
94
|
+
></div>
|
|
95
|
+
</button>
|
|
96
|
+
</Switch>
|
|
97
|
+
</template>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import VSwitchGroup from "./VSwitchGroup.vue";
|
|
4
|
+
import VSwitchDescription from "./VSwitchDescription.vue";
|
|
5
|
+
|
|
6
|
+
test("VSwitchDescription using slot", () => {
|
|
7
|
+
const wrapper = mount({
|
|
8
|
+
template: `
|
|
9
|
+
<v-switch-group>
|
|
10
|
+
<v-switch-label>John Duck</v-switch-label>
|
|
11
|
+
</v-switch-group>
|
|
12
|
+
`,
|
|
13
|
+
components: {
|
|
14
|
+
"v-switch-label": VSwitchDescription,
|
|
15
|
+
"v-switch-group": VSwitchGroup,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe("VSwitchDescription props", () => {
|
|
23
|
+
test("default 'as' prop", () => {
|
|
24
|
+
const wrapper = mount({
|
|
25
|
+
template: `
|
|
26
|
+
<v-switch-group>
|
|
27
|
+
<v-switch-label data-test="label">John Duck</v-switch-label>
|
|
28
|
+
</v-switch-group>
|
|
29
|
+
`,
|
|
30
|
+
components: {
|
|
31
|
+
"v-switch-label": VSwitchDescription,
|
|
32
|
+
"v-switch-group": VSwitchGroup,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const label = wrapper.find("[data-test='label']");
|
|
37
|
+
expect(label.element).toBeInstanceOf(HTMLParagraphElement);
|
|
38
|
+
});
|
|
39
|
+
test("custom 'as' prop", () => {
|
|
40
|
+
const wrapper = mount({
|
|
41
|
+
template: `
|
|
42
|
+
<v-switch-group>
|
|
43
|
+
<v-switch-label as="div" data-test="label">John Duck</v-switch-label>
|
|
44
|
+
</v-switch-group>
|
|
45
|
+
`,
|
|
46
|
+
components: {
|
|
47
|
+
"v-switch-label": VSwitchDescription,
|
|
48
|
+
"v-switch-group": VSwitchGroup,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const label = wrapper.find("[data-test='label']");
|
|
53
|
+
expect(label.element).toBeInstanceOf(HTMLDivElement);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { SwitchDescription } from '@headlessui/vue';
|
|
3
|
+
|
|
4
|
+
defineProps({
|
|
5
|
+
as: {
|
|
6
|
+
type: String,
|
|
7
|
+
default: 'p',
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<SwitchDescription :as="as">
|
|
14
|
+
<slot />
|
|
15
|
+
</SwitchDescription>
|
|
16
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import VSwitchGroup from "./VSwitchGroup.vue";
|
|
4
|
+
|
|
5
|
+
test("VSwitchGroup using slot", () => {
|
|
6
|
+
const wrapper = mount(VSwitchGroup as any, {
|
|
7
|
+
slots: {
|
|
8
|
+
default: "John Duck",
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe("VSwitchGroup props", () => {
|
|
16
|
+
test("custom 'as' prop", () => {
|
|
17
|
+
const wrapper = mount(VSwitchGroup as any, {
|
|
18
|
+
props: {
|
|
19
|
+
as: "div",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const divEl = wrapper.find("div");
|
|
24
|
+
expect(divEl).not.toBeUndefined();
|
|
25
|
+
})
|
|
26
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { SwitchGroup } from '@headlessui/vue';
|
|
3
|
+
|
|
4
|
+
defineProps({
|
|
5
|
+
as: {
|
|
6
|
+
type: String,
|
|
7
|
+
default: 'template',
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<SwitchGroup :as="as">
|
|
14
|
+
<slot />
|
|
15
|
+
</SwitchGroup>
|
|
16
|
+
</template>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import VSwitchGroup from "./VSwitchGroup.vue";
|
|
4
|
+
import VSwitchLabel from "./VSwitchLabel.vue";
|
|
5
|
+
|
|
6
|
+
test("VSwitchLabel using slot", () => {
|
|
7
|
+
const wrapper = mount({
|
|
8
|
+
template: `
|
|
9
|
+
<v-switch-group>
|
|
10
|
+
<v-switch-label>John Duck</v-switch-label>
|
|
11
|
+
</v-switch-group>
|
|
12
|
+
`,
|
|
13
|
+
components: {
|
|
14
|
+
"v-switch-label": VSwitchLabel,
|
|
15
|
+
"v-switch-group": VSwitchGroup,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe("VSwitchLabel props", () => {
|
|
23
|
+
test("default 'as' prop", () => {
|
|
24
|
+
const wrapper = mount({
|
|
25
|
+
template: `
|
|
26
|
+
<v-switch-group>
|
|
27
|
+
<v-switch-label data-test="label">John Duck</v-switch-label>
|
|
28
|
+
</v-switch-group>
|
|
29
|
+
`,
|
|
30
|
+
components: {
|
|
31
|
+
"v-switch-label": VSwitchLabel,
|
|
32
|
+
"v-switch-group": VSwitchGroup,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const label = wrapper.find("[data-test='label']");
|
|
37
|
+
expect(label.element).toBeInstanceOf(HTMLParagraphElement);
|
|
38
|
+
});
|
|
39
|
+
test("custom 'as' prop", () => {
|
|
40
|
+
const wrapper = mount({
|
|
41
|
+
template: `
|
|
42
|
+
<v-switch-group>
|
|
43
|
+
<v-switch-label as="div" data-test="label">John Duck</v-switch-label>
|
|
44
|
+
</v-switch-group>
|
|
45
|
+
`,
|
|
46
|
+
components: {
|
|
47
|
+
"v-switch-label": VSwitchLabel,
|
|
48
|
+
"v-switch-group": VSwitchGroup,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const label = wrapper.find("[data-test='label']");
|
|
53
|
+
expect(label.element).toBeInstanceOf(HTMLDivElement);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("default 'passive' prop'", () => {
|
|
57
|
+
const wrapper = mount({
|
|
58
|
+
template: `
|
|
59
|
+
<v-switch-group>
|
|
60
|
+
<v-switch-label>John Duck</v-switch-label>
|
|
61
|
+
</v-switch-group>
|
|
62
|
+
`,
|
|
63
|
+
components: {
|
|
64
|
+
"v-switch-label": VSwitchLabel,
|
|
65
|
+
"v-switch-group": VSwitchGroup,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const label = wrapper.findComponent(VSwitchLabel);
|
|
70
|
+
expect(label.props('passive')).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("custom 'passive' prop'", () => {
|
|
74
|
+
const wrapper = mount({
|
|
75
|
+
template: `
|
|
76
|
+
<v-switch-group>
|
|
77
|
+
<v-switch-label passive>John Duck</v-switch-label>
|
|
78
|
+
</v-switch-group>
|
|
79
|
+
`,
|
|
80
|
+
components: {
|
|
81
|
+
"v-switch-label": VSwitchLabel,
|
|
82
|
+
"v-switch-group": VSwitchGroup,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const label = wrapper.findComponent(VSwitchLabel);
|
|
87
|
+
expect(label.props('passive')).toBe(true);
|
|
88
|
+
})
|
|
89
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { SwitchLabel } from '@headlessui/vue';
|
|
3
|
+
|
|
4
|
+
defineProps({
|
|
5
|
+
as: {
|
|
6
|
+
type: String,
|
|
7
|
+
default: 'p',
|
|
8
|
+
},
|
|
9
|
+
passive: {
|
|
10
|
+
type: Boolean,
|
|
11
|
+
default: false,
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<SwitchLabel :as="as" :passive="passive">
|
|
18
|
+
<slot />
|
|
19
|
+
</SwitchLabel>
|
|
20
|
+
</template>
|
|
@@ -7,4 +7,21 @@ import VRadioGroup from "./VRadio/VRadioGroup.vue";
|
|
|
7
7
|
import VRadioItem from "./VRadio/VRadioItem.vue";
|
|
8
8
|
import VRadioLabel from "./VRadio/VRadioLabel.vue";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
import VSwitch from "./VSwitch/VSwitch.vue";
|
|
11
|
+
import VSwitchDescription from "./VSwitch/VSwitchDescription.vue";
|
|
12
|
+
import VSwitchGroup from "./VSwitch/VSwitchGroup.vue";
|
|
13
|
+
import VSwitchLabel from "./VSwitch/VSwitchLabel.vue";
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
VButton,
|
|
17
|
+
VBadge,
|
|
18
|
+
VChip,
|
|
19
|
+
VRadioGroup,
|
|
20
|
+
VRadioItem,
|
|
21
|
+
VRadioLabel,
|
|
22
|
+
VRadioDescription,
|
|
23
|
+
VSwitchGroup,
|
|
24
|
+
VSwitchLabel,
|
|
25
|
+
VSwitchDescription,
|
|
26
|
+
VSwitch,
|
|
27
|
+
};
|
|
@@ -6,7 +6,7 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
describe("given there is no existing theme style tag", () => {
|
|
9
|
-
it
|
|
9
|
+
it("should create a new theme style tag", async () => {
|
|
10
10
|
const { useTheme } = await import("./theme.service");
|
|
11
11
|
const { loadTheme } = useTheme();
|
|
12
12
|
|