@code-coaching/vuetiful 0.22.0 → 0.23.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 +1 -1
- package/dist/style.css +2 -2
- package/dist/types/components/VBootstrap.vue.d.ts +15 -0
- package/dist/types/components/atoms/VAvatar.vue.d.ts +37 -10
- package/dist/types/components/atoms/VBadge.vue.d.ts +22 -1
- package/dist/types/components/atoms/VButton.vue.d.ts +27 -0
- package/dist/types/components/atoms/VChip.vue.d.ts +22 -1
- package/dist/types/components/atoms/VRadio/VRadioGroup.vue.d.ts +10 -1
- package/dist/types/components/atoms/VRadio/VRadioItem.vue.d.ts +2 -2
- package/dist/types/components/atoms/VSwitch/VSwitch.vue.d.ts +24 -15
- package/dist/types/components/atoms/index.d.ts +1 -2
- package/dist/types/components/molecules/VAccordion/VAccordion.vue.d.ts +15 -6
- package/dist/types/components/molecules/VAccordion/VAccordionItem.vue.d.ts +11 -1
- package/dist/types/components/molecules/VAlert.vue.d.ts +39 -3
- package/dist/types/components/molecules/VCard/VCard.vue.d.ts +5 -5
- package/dist/types/components/molecules/VCard/VCardBody.vue.d.ts +13 -1
- package/dist/types/components/molecules/VCard/VCardFooter.vue.d.ts +22 -1
- package/dist/types/components/molecules/VCard/VCardHeader.vue.d.ts +22 -1
- package/dist/types/components/{atoms → molecules}/VCodeBlock.vue.d.ts +36 -9
- package/dist/types/components/molecules/VListbox/VListbox.vue.d.ts +51 -14
- package/dist/types/components/molecules/VListbox/VListboxItem.vue.d.ts +13 -3
- package/dist/types/components/molecules/VListbox/VListboxItems.vue.d.ts +9 -0
- package/dist/types/components/molecules/VTabs/VTab.vue.d.ts +9 -0
- package/dist/types/components/molecules/VTabs/VTabs.vue.d.ts +18 -0
- package/dist/types/components/molecules/index.d.ts +4 -3
- package/dist/types/props/index.d.ts +1 -0
- package/dist/types/props/props.d.ts +14 -0
- package/dist/types/services/index.d.ts +5 -3
- package/dist/types/services/settings.service.d.ts +132 -0
- package/dist/types/services/settings.service.test.d.ts +1 -0
- package/dist/types/types/index.d.ts +53 -0
- package/dist/vuetiful.es.mjs +920 -557
- package/dist/vuetiful.umd.js +23 -10
- package/package.json +1 -1
- package/src/components/VBootstrap.vue +62 -0
- package/src/components/atoms/VAvatar.test.ts +98 -28
- package/src/components/atoms/VAvatar.vue +46 -13
- package/src/components/atoms/VBadge.test.ts +10 -0
- package/src/components/atoms/VBadge.vue +13 -1
- package/src/components/atoms/VButton.test.ts +58 -0
- package/src/components/atoms/VButton.vue +31 -2
- package/src/components/atoms/VChip.test.ts +26 -11
- package/src/components/atoms/VChip.vue +13 -1
- package/src/components/atoms/VRadio/VRadioDescription.vue +1 -1
- package/src/components/atoms/VRadio/VRadioGroup.test.ts +7 -7
- package/src/components/atoms/VRadio/VRadioGroup.vue +16 -5
- package/src/components/atoms/VRadio/VRadioItem.vue +12 -8
- package/src/components/atoms/VRadio/VRadioLabel.vue +1 -1
- package/src/components/atoms/VSwitch/VSwitch.test.ts +20 -18
- package/src/components/atoms/VSwitch/VSwitch.vue +29 -17
- package/src/components/atoms/VSwitch/VSwitchDescription.vue +1 -1
- package/src/components/atoms/VSwitch/VSwitchGroup.vue +2 -2
- package/src/components/atoms/VSwitch/VSwitchLabel.vue +1 -1
- package/src/components/atoms/index.ts +0 -2
- package/src/components/molecules/VAccordion/VAccordion.test.ts +11 -0
- package/src/components/molecules/VAccordion/VAccordion.vue +16 -7
- package/src/components/molecules/VAccordion/VAccordionItem.test.ts +65 -16
- package/src/components/molecules/VAccordion/VAccordionItem.vue +53 -32
- package/src/components/molecules/VAlert.test.ts +11 -1
- package/src/components/molecules/VAlert.vue +33 -7
- package/src/components/molecules/VCard/VCard.test.ts +1 -1
- package/src/components/molecules/VCard/VCard.vue +12 -7
- package/src/components/molecules/VCard/VCardBody.test.ts +18 -0
- package/src/components/molecules/VCard/VCardBody.vue +16 -1
- package/src/components/molecules/VCard/VCardFooter.test.ts +18 -0
- package/src/components/molecules/VCard/VCardFooter.vue +21 -3
- package/src/components/molecules/VCard/VCardHeader.test.ts +18 -0
- package/src/components/molecules/VCard/VCardHeader.vue +26 -5
- package/src/components/molecules/VCodeBlock.test.ts +133 -0
- package/src/components/molecules/VCodeBlock.vue +120 -0
- package/src/components/molecules/VListbox/VListbox.test.ts +42 -15
- package/src/components/molecules/VListbox/VListbox.vue +44 -15
- package/src/components/molecules/VListbox/VListboxButton.test.ts +15 -6
- package/src/components/molecules/VListbox/VListboxButton.vue +10 -1
- package/src/components/molecules/VListbox/VListboxItem.test.ts +2 -2
- package/src/components/molecules/VListbox/VListboxItem.vue +18 -7
- package/src/components/molecules/VListbox/VListboxItems.test.ts +2 -2
- package/src/components/molecules/VListbox/VListboxItems.vue +18 -5
- package/src/components/molecules/VListbox/VListboxLabel.test.ts +1 -2
- package/src/components/molecules/VListbox/VListboxLabel.vue +1 -1
- package/src/components/molecules/VPreview.vue +9 -5
- package/src/components/molecules/{VRail.test.ts → VRail/VRail.test.ts} +1 -1
- package/src/components/molecules/{VRail.vue → VRail/VRail.vue} +6 -6
- package/src/components/molecules/VRail/VRailTile.test.ts +99 -0
- package/src/components/molecules/{VRailTile.vue → VRail/VRailTile.vue} +4 -6
- package/src/components/molecules/VTabs/VTab.test.ts +7 -3
- package/src/components/molecules/VTabs/VTab.vue +20 -5
- package/src/components/molecules/VTabs/VTabPanel.vue +2 -2
- package/src/components/molecules/VTabs/VTabs.test.ts +4 -2
- package/src/components/molecules/VTabs/VTabs.vue +32 -8
- package/src/components/molecules/index.ts +5 -2
- package/src/props/index.ts +1 -0
- package/src/props/props.ts +62 -0
- package/src/services/index.ts +5 -3
- package/src/services/settings.service.test.ts +17 -0
- package/src/services/settings.service.ts +136 -0
- package/src/types/index.ts +58 -0
- package/src/components/atoms/VCodeBlock.test.ts +0 -14
- package/src/components/atoms/VCodeBlock.vue +0 -92
- package/src/components/molecules/VRailTile.test.ts +0 -14
- /package/dist/types/components/{atoms → molecules}/VCodeBlock.test.d.ts +0 -0
- /package/dist/types/components/molecules/{VRail.test.d.ts → VRail/VRail.test.d.ts} +0 -0
- /package/dist/types/components/molecules/{VRail.vue.d.ts → VRail/VRail.vue.d.ts} +0 -0
- /package/dist/types/components/molecules/{VRailTile.test.d.ts → VRail/VRailTile.test.d.ts} +0 -0
- /package/dist/types/components/molecules/{VRailTile.vue.d.ts → VRail/VRailTile.vue.d.ts} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useSettings } from "@/index";
|
|
2
3
|
import { RadioGroup } from "@headlessui/vue";
|
|
3
4
|
import { provide, ref, watch } from "vue";
|
|
4
5
|
|
|
@@ -37,6 +38,11 @@ const props = defineProps({
|
|
|
37
38
|
default: "text-surface-900 dark:text-surface-50",
|
|
38
39
|
},
|
|
39
40
|
|
|
41
|
+
classItem: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: "",
|
|
44
|
+
},
|
|
45
|
+
|
|
40
46
|
unstyled: {
|
|
41
47
|
type: Boolean,
|
|
42
48
|
default: false,
|
|
@@ -59,20 +65,25 @@ watch(
|
|
|
59
65
|
|
|
60
66
|
provide("active", props.active);
|
|
61
67
|
provide("hover", props.hover);
|
|
68
|
+
provide("classItem", props.classItem);
|
|
69
|
+
|
|
70
|
+
const { settings } = useSettings();
|
|
71
|
+
const isUnstyled =
|
|
72
|
+
settings.global.unstyled || settings.components.radioGroup.unstyled || props.unstyled;
|
|
62
73
|
</script>
|
|
63
74
|
l
|
|
64
75
|
<template>
|
|
65
|
-
<!-- There is some odd behavior with test
|
|
76
|
+
<!-- There is some odd behavior with test coverage, v-model must be the last property in this component -->
|
|
66
77
|
<radio-group
|
|
67
78
|
data-test="radio-group"
|
|
68
79
|
:as="as"
|
|
69
80
|
:disabled="disabled"
|
|
70
81
|
:by="by"
|
|
71
|
-
:class="
|
|
72
|
-
|
|
82
|
+
:class="`vuetiful-radio-group inline-flex ${
|
|
83
|
+
isUnstyled
|
|
73
84
|
? ''
|
|
74
|
-
: `
|
|
75
|
-
}`"
|
|
85
|
+
: `gap-1 p-1 border-token border-surface-400-500-token rounded-container-token`
|
|
86
|
+
} ${background} ${text}`"
|
|
76
87
|
v-model="parentModelValue"
|
|
77
88
|
>
|
|
78
89
|
<slot></slot>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useSettings } from "@/index";
|
|
2
3
|
import { RadioGroupOption } from "@headlessui/vue";
|
|
3
4
|
import { inject } from "vue";
|
|
4
5
|
|
|
5
|
-
defineProps({
|
|
6
|
+
const props = defineProps({
|
|
6
7
|
value: {
|
|
7
8
|
type: [String, Number, Boolean, Object],
|
|
8
9
|
required: true,
|
|
@@ -15,19 +16,22 @@ defineProps({
|
|
|
15
16
|
|
|
16
17
|
const active = inject("active") as string;
|
|
17
18
|
const hover = inject("hover") as string;
|
|
19
|
+
const classItem = inject("classItem") as string;
|
|
20
|
+
|
|
21
|
+
const { settings } = useSettings();
|
|
22
|
+
const isUnstyled =
|
|
23
|
+
settings.global.unstyled || settings.components.radioItem.unstyled || props.unstyled;
|
|
18
24
|
</script>
|
|
19
25
|
|
|
20
26
|
<template>
|
|
21
27
|
<RadioGroupOption v-slot="{ checked, disabled }" :value="value">
|
|
22
28
|
<div
|
|
23
29
|
data-test="radio-item"
|
|
24
|
-
:class="`radio-item ${
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}`
|
|
30
|
-
}`"
|
|
30
|
+
:class="`vuetiful-radio-item ${
|
|
31
|
+
isUnstyled ? '' : `px-4 py-1 text-center text-base rounded-token`
|
|
32
|
+
} ${checked ? active : hover} ${
|
|
33
|
+
disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'
|
|
34
|
+
} ${classItem}`"
|
|
31
35
|
>
|
|
32
36
|
<slot />
|
|
33
37
|
</div>
|
|
@@ -10,10 +10,11 @@ describe("VSwitch props", () => {
|
|
|
10
10
|
modelValue: false,
|
|
11
11
|
disabled: false,
|
|
12
12
|
size: "md",
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
classTrack: "variant-filled",
|
|
14
|
+
classThumb: "bg-surface-100-800-token",
|
|
15
15
|
as: "button",
|
|
16
16
|
name: "",
|
|
17
|
+
unstyled: false,
|
|
17
18
|
});
|
|
18
19
|
});
|
|
19
20
|
|
|
@@ -24,7 +25,7 @@ describe("VSwitch props", () => {
|
|
|
24
25
|
},
|
|
25
26
|
});
|
|
26
27
|
|
|
27
|
-
const track = wrapper.find("
|
|
28
|
+
const track = wrapper.find("[data-test='switch-track']");
|
|
28
29
|
expect(track.attributes("class")).toContain("w-8 h-4");
|
|
29
30
|
});
|
|
30
31
|
|
|
@@ -35,7 +36,7 @@ describe("VSwitch props", () => {
|
|
|
35
36
|
},
|
|
36
37
|
});
|
|
37
38
|
|
|
38
|
-
const track = wrapper.find("
|
|
39
|
+
const track = wrapper.find("[data-test='switch-track']");
|
|
39
40
|
expect(track.attributes("class")).toContain("w-12 h-6");
|
|
40
41
|
});
|
|
41
42
|
|
|
@@ -46,7 +47,7 @@ describe("VSwitch props", () => {
|
|
|
46
47
|
},
|
|
47
48
|
});
|
|
48
49
|
|
|
49
|
-
const track = wrapper.find("
|
|
50
|
+
const track = wrapper.find("[data-test='switch-track']");
|
|
50
51
|
expect(track.attributes("class")).toContain("w-16 h-8");
|
|
51
52
|
});
|
|
52
53
|
|
|
@@ -57,7 +58,7 @@ describe("VSwitch props", () => {
|
|
|
57
58
|
},
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
const track = wrapper.find("
|
|
61
|
+
const track = wrapper.find("[data-test='switch-track']");
|
|
61
62
|
expect(track.attributes("class")).toContain("w-20 h-10");
|
|
62
63
|
});
|
|
63
64
|
|
|
@@ -68,20 +69,9 @@ describe("VSwitch props", () => {
|
|
|
68
69
|
},
|
|
69
70
|
});
|
|
70
71
|
|
|
71
|
-
const track = wrapper.find("
|
|
72
|
+
const track = wrapper.find("[data-test='switch-track']");
|
|
72
73
|
expect(track.attributes("class")).toContain("w-24 h-12");
|
|
73
74
|
});
|
|
74
|
-
|
|
75
|
-
test("size custom", () => {
|
|
76
|
-
const wrapper = mount(VSwitch, {
|
|
77
|
-
props: {
|
|
78
|
-
size: "custom",
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
const track = wrapper.find(".slide-toggle-track");
|
|
83
|
-
expect(track.attributes("class")).toContain("custom");
|
|
84
|
-
});
|
|
85
75
|
});
|
|
86
76
|
|
|
87
77
|
describe("VSwitch events", () => {
|
|
@@ -96,3 +86,15 @@ describe("VSwitch events", () => {
|
|
|
96
86
|
expect(wrapper.emitted()).toHaveProperty("update:modelValue");
|
|
97
87
|
});
|
|
98
88
|
});
|
|
89
|
+
|
|
90
|
+
describe("VSwitch default slot", () => {
|
|
91
|
+
test("default slot", () => {
|
|
92
|
+
const wrapper = mount(VSwitch, {
|
|
93
|
+
slots: {
|
|
94
|
+
default: "John Duck",
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
expect(wrapper.text()).toContain("John Duck");
|
|
99
|
+
});
|
|
100
|
+
})
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useSettings } from "@/index";
|
|
3
|
+
import { sizeProp, unstyledProp } from "@/props";
|
|
2
4
|
import { Switch } from "@headlessui/vue";
|
|
3
5
|
import { computed, ref, watch } from "vue";
|
|
4
6
|
|
|
@@ -12,16 +14,12 @@ const props = defineProps({
|
|
|
12
14
|
type: Boolean,
|
|
13
15
|
default: false,
|
|
14
16
|
},
|
|
15
|
-
size: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: "md",
|
|
18
|
-
},
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
classTrack: {
|
|
21
19
|
type: String,
|
|
22
20
|
default: "variant-filled",
|
|
23
21
|
},
|
|
24
|
-
|
|
22
|
+
classThumb: {
|
|
25
23
|
type: String,
|
|
26
24
|
default: "bg-surface-100-800-token",
|
|
27
25
|
},
|
|
@@ -34,6 +32,9 @@ const props = defineProps({
|
|
|
34
32
|
type: String,
|
|
35
33
|
default: "",
|
|
36
34
|
},
|
|
35
|
+
|
|
36
|
+
size: sizeProp,
|
|
37
|
+
unstyled: unstyledProp,
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
const parentModelValue = ref(props.modelValue);
|
|
@@ -62,17 +63,22 @@ const trackSize = computed(() => {
|
|
|
62
63
|
return "w-20 h-10";
|
|
63
64
|
case "xl":
|
|
64
65
|
return "w-24 h-12";
|
|
65
|
-
default:
|
|
66
|
-
return props.size;
|
|
67
66
|
}
|
|
68
67
|
});
|
|
68
|
+
|
|
69
|
+
const { settings } = useSettings();
|
|
70
|
+
const isUnstyled =
|
|
71
|
+
settings.global.unstyled || settings.components.switch.unstyled || props.unstyled;
|
|
69
72
|
</script>
|
|
70
73
|
|
|
71
74
|
<template>
|
|
72
|
-
<!-- There is some odd behavior with test
|
|
75
|
+
<!-- There is some odd behavior with test coverage, v-model must be the last property in this component -->
|
|
73
76
|
<Switch
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
data-test="switch"
|
|
78
|
+
:class="`vuetiful-slide-toggle ${
|
|
79
|
+
isUnstyled
|
|
80
|
+
? ''
|
|
81
|
+
: `rounded-container-token ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}`
|
|
76
82
|
}`"
|
|
77
83
|
:name="name"
|
|
78
84
|
:as="as"
|
|
@@ -80,17 +86,23 @@ const trackSize = computed(() => {
|
|
|
80
86
|
v-model="parentModelValue"
|
|
81
87
|
>
|
|
82
88
|
<div
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
data-test="switch-track"
|
|
90
|
+
:class="`vuetiful-slide-toggle-track flex ${
|
|
91
|
+
isUnstyled ? '' : `transition-all duration-[150ms] border-token rounded-token`
|
|
92
|
+
}
|
|
93
|
+
${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
|
|
94
|
+
${trackSize} ${classTrack}`"
|
|
86
95
|
>
|
|
87
96
|
<template v-if="$slots.default">
|
|
88
97
|
<span class="sr-only"><slot /></span>
|
|
89
98
|
</template>
|
|
90
99
|
<div
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
data-test="switch-thumb"
|
|
101
|
+
:class="`vuetiful-slide-toggle-thumb w-[50%] scale-[0.8] ${
|
|
102
|
+
isUnstyled ? '' : `bg-opactiy-90 shadow transition-all duration-[150ms] rounded-token `
|
|
103
|
+
}
|
|
104
|
+
${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
|
|
105
|
+
${checked ? 'translate-x-full' : `${isUnstyled ? '' : 'opacity-90'}`} ${classThumb}`"
|
|
94
106
|
></div>
|
|
95
107
|
</div>
|
|
96
108
|
</Switch>
|
|
@@ -4,13 +4,13 @@ import { SwitchGroup } from "@headlessui/vue";
|
|
|
4
4
|
defineProps({
|
|
5
5
|
as: {
|
|
6
6
|
type: String,
|
|
7
|
-
default: "
|
|
7
|
+
default: "div",
|
|
8
8
|
},
|
|
9
9
|
});
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
13
|
-
<SwitchGroup :as="as">
|
|
13
|
+
<SwitchGroup class="vuetiful-switch-group" :as="as">
|
|
14
14
|
<slot />
|
|
15
15
|
</SwitchGroup>
|
|
16
16
|
</template>
|
|
@@ -2,7 +2,6 @@ import VAvatar from "./VAvatar.vue";
|
|
|
2
2
|
import VBadge from "./VBadge.vue";
|
|
3
3
|
import VButton from "./VButton.vue";
|
|
4
4
|
import VChip from "./VChip.vue";
|
|
5
|
-
import VCodeBlock from "./VCodeBlock.vue";
|
|
6
5
|
import VLightSwitch from "./VLightSwitch.vue";
|
|
7
6
|
|
|
8
7
|
import VRadioDescription from "./VRadio/VRadioDescription.vue";
|
|
@@ -20,7 +19,6 @@ export {
|
|
|
20
19
|
VButton,
|
|
21
20
|
VBadge,
|
|
22
21
|
VChip,
|
|
23
|
-
VCodeBlock,
|
|
24
22
|
VLightSwitch,
|
|
25
23
|
VRadioGroup,
|
|
26
24
|
VRadioItem,
|
|
@@ -19,4 +19,15 @@ describe("VAccordion", () => {
|
|
|
19
19
|
"gap-1",
|
|
20
20
|
]);
|
|
21
21
|
});
|
|
22
|
+
|
|
23
|
+
test("unstyled", async () => {
|
|
24
|
+
const wrapper = mount({
|
|
25
|
+
template: /*html*/ `<v-accordion unstyled></v-accordion>`,
|
|
26
|
+
components: {
|
|
27
|
+
"v-accordion": VAccordion,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(wrapper.classes()).toEqual(["vuetiful-accordion"]);
|
|
32
|
+
})
|
|
22
33
|
});
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useSettings } from '@/services';
|
|
3
|
+
import { provide, useSSRContext } from 'vue';
|
|
3
4
|
|
|
4
5
|
const props = defineProps({
|
|
5
|
-
|
|
6
|
+
classQuestion: {
|
|
6
7
|
type: String,
|
|
7
|
-
default: 'hover:variant-soft',
|
|
8
|
+
default: 'bg-surface-200-700-token hover:variant-soft',
|
|
8
9
|
},
|
|
9
|
-
|
|
10
|
+
classAnswer: {
|
|
10
11
|
type: String,
|
|
11
12
|
default: 'bg-surface-200-700-token',
|
|
12
13
|
},
|
|
14
|
+
|
|
15
|
+
unstyled: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
default: false,
|
|
18
|
+
},
|
|
13
19
|
});
|
|
14
20
|
|
|
15
|
-
provide('
|
|
16
|
-
provide('
|
|
21
|
+
provide('classQuestion', props.classQuestion);
|
|
22
|
+
provide('classAnswer', props.classAnswer);
|
|
23
|
+
|
|
24
|
+
const { settings } = useSettings()
|
|
25
|
+
const isUnstyled = settings.global.unstyled || settings.components.accordion.unstyled || props.unstyled
|
|
17
26
|
</script>
|
|
18
27
|
|
|
19
28
|
<template>
|
|
20
|
-
<div class="vuetiful-accordion flex w-full flex-col gap-1">
|
|
29
|
+
<div :class="`vuetiful-accordion ${isUnstyled ? '' : 'flex w-full flex-col gap-1'}`">
|
|
21
30
|
<slot></slot>
|
|
22
31
|
</div>
|
|
23
32
|
</template>
|
|
@@ -22,11 +22,48 @@ describe("VAccordionItem", () => {
|
|
|
22
22
|
|
|
23
23
|
const accordionItemButton = accordionItem.find(".vuetiful-accordion-item-button");
|
|
24
24
|
expect(accordionItemButton.classes()).toEqual([
|
|
25
|
+
"items-center",
|
|
26
|
+
"justify-between",
|
|
27
|
+
"p-4",
|
|
28
|
+
"py-2",
|
|
29
|
+
"rounded-container-token",
|
|
30
|
+
"hover:cursor-pointer",
|
|
25
31
|
"bg-surface-200-700-token",
|
|
26
32
|
"hover:variant-soft",
|
|
27
33
|
"vuetiful-accordion-item-button",
|
|
34
|
+
"flex",
|
|
35
|
+
"w-full",
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const accordionItemTitle = accordionItem.find(".vuetiful-accordion-title");
|
|
39
|
+
expect(accordionItemTitle.text()).toEqual(accordionItem.props().title);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("unstyled", async () => {
|
|
44
|
+
const wrapper = mount({
|
|
45
|
+
template: /*html*/ `
|
|
46
|
+
<v-accordion>
|
|
47
|
+
<v-accordion-item title="Vuetiful" unstyled>John Duck</v-accordion-item>
|
|
48
|
+
<v-accordion-item title="Is" unstyled>Janine Duck</v-accordion-item>
|
|
49
|
+
</v-accordion>`,
|
|
50
|
+
components: {
|
|
51
|
+
"v-accordion": VAccordion,
|
|
52
|
+
"v-accordion-item": VAccordionItem,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const accordionItems = wrapper.findAllComponents(VAccordionItem);
|
|
57
|
+
accordionItems.forEach((accordionItem) => {
|
|
58
|
+
expect(accordionItem.classes()).toEqual(["vuetiful-accordion-item"]);
|
|
59
|
+
|
|
60
|
+
const accordionItemButton = accordionItem.find(".vuetiful-accordion-item-button");
|
|
61
|
+
expect(accordionItemButton.classes()).toEqual([
|
|
62
|
+
"bg-surface-200-700-token",
|
|
63
|
+
"hover:variant-soft",
|
|
64
|
+
"vuetiful-accordion-item-button",
|
|
65
|
+
"flex",
|
|
28
66
|
"w-full",
|
|
29
|
-
"rounded-container-token",
|
|
30
67
|
]);
|
|
31
68
|
|
|
32
69
|
const accordionItemTitle = accordionItem.find(".vuetiful-accordion-title");
|
|
@@ -54,32 +91,44 @@ describe("VAccordionItem", () => {
|
|
|
54
91
|
await accordionItemButtonOne.trigger("click");
|
|
55
92
|
|
|
56
93
|
expect(accordionItemButtonOne.classes()).toEqual([
|
|
57
|
-
"bg-surface-200-700-token",
|
|
58
|
-
"hover:variant-soft",
|
|
59
94
|
"!rounded-bl-none",
|
|
60
95
|
"!rounded-br-none",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
96
|
+
"items-center",
|
|
97
|
+
"justify-between",
|
|
98
|
+
"p-4",
|
|
99
|
+
"py-2",
|
|
63
100
|
"rounded-container-token",
|
|
64
|
-
|
|
65
|
-
expect(accordionItemButtonTwo.classes()).toEqual([
|
|
101
|
+
"hover:cursor-pointer",
|
|
66
102
|
"bg-surface-200-700-token",
|
|
67
103
|
"hover:variant-soft",
|
|
68
104
|
"vuetiful-accordion-item-button",
|
|
105
|
+
"flex",
|
|
69
106
|
"w-full",
|
|
70
|
-
"rounded-container-token",
|
|
71
107
|
]);
|
|
72
|
-
|
|
108
|
+
expect(accordionItemButtonTwo.classes()).toEqual([
|
|
109
|
+
'items-center',
|
|
110
|
+
'justify-between',
|
|
111
|
+
'p-4',
|
|
112
|
+
'py-2',
|
|
113
|
+
'rounded-container-token',
|
|
114
|
+
'hover:cursor-pointer',
|
|
115
|
+
'bg-surface-200-700-token',
|
|
116
|
+
'hover:variant-soft',
|
|
117
|
+
'vuetiful-accordion-item-button',
|
|
118
|
+
'flex',
|
|
119
|
+
'w-full'
|
|
120
|
+
]);
|
|
121
|
+
|
|
73
122
|
const accordionItemPanelOne = accordionItems[0].find(".vuetiful-accordion-item-panel");
|
|
74
123
|
|
|
75
124
|
expect(accordionItemPanelOne.classes()).toEqual([
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
125
|
+
'vuetiful-accordion-item-panel',
|
|
126
|
+
'!rounded-tl-none',
|
|
127
|
+
'!rounded-tr-none',
|
|
128
|
+
'p-4',
|
|
129
|
+
'py-2',
|
|
130
|
+
'rounded-container-token',
|
|
131
|
+
'bg-surface-200-700-token'
|
|
83
132
|
]);
|
|
84
133
|
});
|
|
85
134
|
});
|
|
@@ -1,52 +1,73 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useSettings } from "@/services";
|
|
2
3
|
import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/vue";
|
|
3
4
|
import { inject } from "vue";
|
|
4
5
|
|
|
5
|
-
defineProps({
|
|
6
|
+
const props = defineProps({
|
|
6
7
|
title: {
|
|
7
8
|
type: String,
|
|
8
9
|
required: true,
|
|
9
10
|
},
|
|
11
|
+
|
|
12
|
+
unstyled: {
|
|
13
|
+
type: Boolean,
|
|
14
|
+
default: false,
|
|
15
|
+
},
|
|
10
16
|
});
|
|
11
17
|
|
|
12
|
-
const
|
|
13
|
-
const
|
|
18
|
+
const classQuestion = inject("classQuestion");
|
|
19
|
+
const classAnswer = inject("classAnswer");
|
|
20
|
+
|
|
21
|
+
const { settings } = useSettings();
|
|
22
|
+
const isUnstyled =
|
|
23
|
+
settings.global.unstyled || settings.components.accordionItem.unstyled || props.unstyled;
|
|
14
24
|
</script>
|
|
15
25
|
|
|
16
26
|
<template>
|
|
17
27
|
<Disclosure class="vuetiful-accordion-item" as="div" v-slot="{ open }">
|
|
18
28
|
<DisclosureButton
|
|
19
|
-
:class="`${
|
|
20
|
-
|
|
29
|
+
:class="`${isUnstyled ? '' : `${open ? '!rounded-bl-none !rounded-br-none' : ''}`}
|
|
30
|
+
${
|
|
31
|
+
isUnstyled
|
|
32
|
+
? ''
|
|
33
|
+
: 'items-center justify-between p-4 py-2 rounded-container-token hover:cursor-pointer'
|
|
34
|
+
}
|
|
35
|
+
${classQuestion}`"
|
|
36
|
+
class="vuetiful-accordion-item-button flex w-full"
|
|
21
37
|
>
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
<span class="vuetiful-accordion-title">{{ title }}</span>
|
|
39
|
+
<slot v-if="!open" name="open-item">
|
|
40
|
+
<!-- https://fontawesome.com/icons/plus?f=classic&s=solid -->
|
|
41
|
+
<svg
|
|
42
|
+
class="vuetiful-accordion-item-icon-plus icon"
|
|
43
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
44
|
+
viewBox="0 0 448 512"
|
|
45
|
+
>
|
|
46
|
+
<!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
|
47
|
+
<path
|
|
48
|
+
d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"
|
|
49
|
+
/>
|
|
50
|
+
</svg>
|
|
51
|
+
</slot>
|
|
52
|
+
<slot v-if="open" name="close-item">
|
|
53
|
+
<!-- https://fontawesome.com/icons/minus?f=classic&s=solid -->
|
|
54
|
+
<svg
|
|
55
|
+
class="vuetiful-accordion-item-icon-minus icon"
|
|
56
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
57
|
+
viewBox="0 0 448 512"
|
|
58
|
+
>
|
|
59
|
+
<!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
|
60
|
+
<path
|
|
61
|
+
d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"
|
|
62
|
+
/>
|
|
63
|
+
</svg>
|
|
64
|
+
</slot>
|
|
46
65
|
</DisclosureButton>
|
|
47
66
|
<DisclosurePanel
|
|
48
|
-
class="vuetiful-accordion-item-panel
|
|
49
|
-
:class="`${open ? `${
|
|
67
|
+
class="vuetiful-accordion-item-panel"
|
|
68
|
+
:class="`${open ? `${isUnstyled ? '' : '!rounded-tl-none !rounded-tr-none'}` : ''} ${
|
|
69
|
+
isUnstyled ? '' : 'p-4 py-2 rounded-container-token'
|
|
70
|
+
} ${classAnswer}`"
|
|
50
71
|
>
|
|
51
72
|
<slot></slot>
|
|
52
73
|
</DisclosurePanel>
|
|
@@ -55,6 +76,6 @@ const background = inject("background");
|
|
|
55
76
|
|
|
56
77
|
<style scoped>
|
|
57
78
|
.icon {
|
|
58
|
-
@apply my-1 h-4 w-4 fill-current;
|
|
79
|
+
@apply my-1 h-4 min-h-[1rem] w-4 min-w-[1rem] fill-current;
|
|
59
80
|
}
|
|
60
81
|
</style>
|
|
@@ -18,7 +18,7 @@ describe("VAlert", () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
const defaultAlert = wrapper.find("[data-test=default]");
|
|
21
|
-
expect(defaultAlert.classes()).toContain("variant-filled-primary");
|
|
21
|
+
expect(defaultAlert.classes()).not.toContain("variant-filled-primary");
|
|
22
22
|
|
|
23
23
|
const infoAlert = wrapper.find("[data-test=info]");
|
|
24
24
|
expect(infoAlert.classes()).toContain("variant-filled");
|
|
@@ -30,6 +30,16 @@ describe("VAlert", () => {
|
|
|
30
30
|
expect(warningAlert.classes()).toContain("variant-filled-warning");
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
+
test("unstyled", () => {
|
|
34
|
+
const wrapper = mount(VAlert, {
|
|
35
|
+
props: {
|
|
36
|
+
unstyled: true,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(wrapper.classes()).toEqual(["vuetiful-alert", "flex"]);
|
|
41
|
+
});
|
|
42
|
+
|
|
33
43
|
describe("given close icon is clicked", () => {
|
|
34
44
|
test("should emit close", async () => {
|
|
35
45
|
const wrapper = mount(VAlert, { props: { showClose: true } });
|