@code-coaching/vuetiful 0.14.2 → 0.15.1
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 +0 -3
- package/dist/style.css +2 -2
- package/dist/styles/all.css +172 -95
- package/dist/types/components/atoms/VAvatar.vue.d.ts +69 -0
- package/dist/types/{utils/dark-mode/dark-mode.vue.d.ts → components/atoms/VLightSwitch.vue.d.ts} +1 -1
- package/dist/types/components/atoms/index.d.ts +4 -1
- package/dist/types/services/highlight.service.test.d.ts +1 -0
- package/dist/types/services/index.d.ts +3 -1
- package/dist/types/utils/index.d.ts +1 -4
- package/dist/vuetiful.es.mjs +3298 -3244
- package/dist/vuetiful.umd.js +14 -15
- package/package.json +1 -1
- package/src/components/atoms/VAvatar.test.ts +105 -0
- package/src/components/atoms/VAvatar.vue +51 -0
- package/src/{utils/code-block → components/atoms}/VCodeBlock.vue +1 -1
- package/src/{utils/dark-mode/dark-mode.vue → components/atoms/VLightSwitch.vue} +1 -2
- package/src/components/atoms/index.ts +6 -0
- package/src/{utils/dark-mode → services}/dark-mode.service.test.ts +11 -11
- package/src/{utils/dark-mode → services}/dark-mode.service.ts +1 -1
- package/src/services/index.ts +3 -1
- package/src/utils/index.ts +1 -4
- package/src/utils/theme/theme-switcher.vue +10 -15
- /package/dist/types/{utils/code-block/highlight.service.test.d.ts → components/atoms/VAvatar.test.d.ts} +0 -0
- /package/dist/types/{utils/code-block → components/atoms}/VCodeBlock.vue.d.ts +0 -0
- /package/dist/types/{utils/dark-mode → services}/dark-mode.service.d.ts +0 -0
- /package/dist/types/{utils/dark-mode → services}/dark-mode.service.test.d.ts +0 -0
- /package/dist/types/{utils/code-block → services}/highlight.service.d.ts +0 -0
- /package/src/{utils/code-block → services}/highlight.service.test.ts +0 -0
- /package/src/{utils/code-block → services}/highlight.service.ts +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { VAvatar } from ".";
|
|
4
|
+
|
|
5
|
+
test("VAvatar", () => {
|
|
6
|
+
expect(VAvatar).toBeTruthy();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
describe("VAvatar props", () => {
|
|
10
|
+
test("VAvatar defaults", () => {
|
|
11
|
+
const wrapper = mount(VAvatar);
|
|
12
|
+
|
|
13
|
+
expect(wrapper.classes()).toContain("avatar");
|
|
14
|
+
expect(wrapper.classes()).toContain("w-16");
|
|
15
|
+
expect(wrapper.classes()).toContain("rounded-token");
|
|
16
|
+
|
|
17
|
+
const avatarText = wrapper.find(".avatar-text");
|
|
18
|
+
expect(avatarText.exists()).toBe(true);
|
|
19
|
+
expect(avatarText.text()).toBe("");
|
|
20
|
+
expect(avatarText.classes()).toContain("dark:fill-on-surface-token");
|
|
21
|
+
expect(avatarText.classes()).toContain("fill-base-token");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("VAvatar initials", () => {
|
|
25
|
+
const wrapper = mount(VAvatar, {
|
|
26
|
+
props: {
|
|
27
|
+
initials: "JD",
|
|
28
|
+
class: "variant-filled",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
expect(wrapper.classes()).toContain("avatar");
|
|
33
|
+
expect(wrapper.classes()).toContain("w-16");
|
|
34
|
+
expect(wrapper.classes()).toContain("rounded-token");
|
|
35
|
+
|
|
36
|
+
const avatarText = wrapper.find(".avatar-text");
|
|
37
|
+
expect(avatarText.exists()).toBe(true);
|
|
38
|
+
expect(avatarText.text()).toBe("JD");
|
|
39
|
+
expect(avatarText.classes()).toContain("dark:fill-base-token");
|
|
40
|
+
expect(avatarText.classes()).toContain("fill-on-surface-token");
|
|
41
|
+
|
|
42
|
+
const avatarImage = wrapper.find(".avatar-image");
|
|
43
|
+
expect(avatarImage.exists()).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("VAvatar initials fill", () => {
|
|
47
|
+
const wrapper = mount(VAvatar, {
|
|
48
|
+
props: {
|
|
49
|
+
initials: "JD",
|
|
50
|
+
fill: "custom-fill-class",
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
expect(wrapper.classes()).toContain("avatar");
|
|
55
|
+
expect(wrapper.classes()).toContain("w-16");
|
|
56
|
+
expect(wrapper.classes()).toContain("rounded-token");
|
|
57
|
+
|
|
58
|
+
const avatarText = wrapper.find(".avatar-text");
|
|
59
|
+
expect(avatarText.exists()).toBe(true);
|
|
60
|
+
expect(avatarText.text()).toBe("JD");
|
|
61
|
+
expect(avatarText.classes()).toContain("custom-fill-class");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("VAvatar image", () => {
|
|
65
|
+
const wrapper = mount(VAvatar, {
|
|
66
|
+
props: {
|
|
67
|
+
src: "https://via.placeholder.com/150",
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(wrapper.classes()).toContain("avatar");
|
|
72
|
+
expect(wrapper.classes()).toContain("w-16");
|
|
73
|
+
expect(wrapper.classes()).toContain("rounded-token");
|
|
74
|
+
|
|
75
|
+
const avatarText = wrapper.find(".avatar-text");
|
|
76
|
+
expect(avatarText.exists()).toBe(false);
|
|
77
|
+
|
|
78
|
+
const avatarImage = wrapper.find(".avatar-image");
|
|
79
|
+
expect(avatarImage.exists()).toBe(true);
|
|
80
|
+
expect(avatarImage.attributes("src")).toBe("https://via.placeholder.com/150");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("VAvatar image fallback", async () => {
|
|
84
|
+
const wrapper = mount(VAvatar, {
|
|
85
|
+
props: {
|
|
86
|
+
src: "https://via.placeholder.com/150",
|
|
87
|
+
fallback: "/image/john-duck.png",
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(wrapper.classes()).toContain("avatar");
|
|
92
|
+
expect(wrapper.classes()).toContain("w-16");
|
|
93
|
+
expect(wrapper.classes()).toContain("rounded-token");
|
|
94
|
+
|
|
95
|
+
const avatarText = wrapper.find(".avatar-text");
|
|
96
|
+
expect(avatarText.exists()).toBe(false);
|
|
97
|
+
|
|
98
|
+
const avatarImage = wrapper.find(".avatar-image");
|
|
99
|
+
avatarImage.trigger("error");
|
|
100
|
+
await wrapper.vm.$nextTick();
|
|
101
|
+
|
|
102
|
+
expect(avatarImage.exists()).toBe(true);
|
|
103
|
+
expect(avatarImage.attributes("src")).toBe("/image/john-duck.png");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { CssClasses } from "@/index";
|
|
3
|
+
import { computed, ref, useAttrs } from "vue";
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
// Initials
|
|
7
|
+
initials: { type: String, default: "" },
|
|
8
|
+
fill: { type: String as () => CssClasses, default: "" },
|
|
9
|
+
|
|
10
|
+
// Image
|
|
11
|
+
src: { type: String, default: "" },
|
|
12
|
+
alt: { type: String, default: "" },
|
|
13
|
+
fallback: { type: String, default: "" },
|
|
14
|
+
|
|
15
|
+
width: { type: String as () => CssClasses, default: "w-16" },
|
|
16
|
+
rounded: { type: String as () => CssClasses, default: "rounded-token" },
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const imgSrc = ref(props.src);
|
|
20
|
+
const fillInitials = computed(() => {
|
|
21
|
+
if (props.fill) return props.fill;
|
|
22
|
+
|
|
23
|
+
const attrs = useAttrs();
|
|
24
|
+
const classString = attrs.class as string | undefined;
|
|
25
|
+
|
|
26
|
+
if (classString?.includes("variant-filled")) {
|
|
27
|
+
return "fill-on-surface-token dark:fill-base-token";
|
|
28
|
+
}
|
|
29
|
+
return "dark:fill-on-surface-token fill-base-token";
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
<template>
|
|
33
|
+
<figure
|
|
34
|
+
:class="`avatar isolate flex aspect-square items-center justify-center overflow-hidden font-semibold ${rounded} ${width}`"
|
|
35
|
+
>
|
|
36
|
+
<img class="avatar-image" v-if="src" :src="imgSrc" :alt="alt" @error="() => (imgSrc = fallback)" />
|
|
37
|
+
<svg v-else class="avatar-initials h-full w-full" viewBox="0 0 512 512">
|
|
38
|
+
<text
|
|
39
|
+
x="50%"
|
|
40
|
+
y="50%"
|
|
41
|
+
dominant-baseline="central"
|
|
42
|
+
text-anchor="middle"
|
|
43
|
+
font-weight="bold"
|
|
44
|
+
:font-size="150"
|
|
45
|
+
:class="`avatar-text ${fillInitials}`"
|
|
46
|
+
>
|
|
47
|
+
{{ String(initials).substring(0, 2).toUpperCase() }}
|
|
48
|
+
</text>
|
|
49
|
+
</svg>
|
|
50
|
+
</figure>
|
|
51
|
+
</template>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { CssClasses, vClipboard } from "@/index";
|
|
3
|
+
import { useHighlight } from "@/services/highlight.service";
|
|
3
4
|
import "highlight.js/styles/github-dark.css";
|
|
4
5
|
import { ref } from "vue";
|
|
5
|
-
import { useHighlight } from "./highlight.service";
|
|
6
6
|
|
|
7
7
|
const { highlight } = useHighlight();
|
|
8
8
|
|
|
@@ -24,9 +24,8 @@
|
|
|
24
24
|
</template>
|
|
25
25
|
|
|
26
26
|
<script lang="ts">
|
|
27
|
-
import
|
|
27
|
+
import { CssClasses, useDarkMode } from "@/index";
|
|
28
28
|
import { computed, ComputedRef, defineComponent, onMounted } from "vue";
|
|
29
|
-
import { useDarkMode } from "./dark-mode.service";
|
|
30
29
|
|
|
31
30
|
export default defineComponent({
|
|
32
31
|
props: {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import VAvatar from "./VAvatar.vue";
|
|
1
2
|
import VBadge from "./VBadge.vue";
|
|
2
3
|
import VButton from "./VButton.vue";
|
|
3
4
|
import VChip from "./VChip.vue";
|
|
5
|
+
import VCodeBlock from "./VCodeBlock.vue";
|
|
6
|
+
import VLightSwitch from "./VLightSwitch.vue";
|
|
4
7
|
|
|
5
8
|
import VRadioDescription from "./VRadio/VRadioDescription.vue";
|
|
6
9
|
import VRadioGroup from "./VRadio/VRadioGroup.vue";
|
|
@@ -13,9 +16,12 @@ import VSwitchGroup from "./VSwitch/VSwitchGroup.vue";
|
|
|
13
16
|
import VSwitchLabel from "./VSwitch/VSwitchLabel.vue";
|
|
14
17
|
|
|
15
18
|
export {
|
|
19
|
+
VAvatar,
|
|
16
20
|
VButton,
|
|
17
21
|
VBadge,
|
|
18
22
|
VChip,
|
|
23
|
+
VCodeBlock,
|
|
24
|
+
VLightSwitch,
|
|
19
25
|
VRadioGroup,
|
|
20
26
|
VRadioItem,
|
|
21
27
|
VRadioLabel,
|
|
@@ -13,7 +13,7 @@ describe("useDarkMode", () => {
|
|
|
13
13
|
describe("getModeUserPrefers", () => {
|
|
14
14
|
describe("given not in browser", () => {
|
|
15
15
|
it("should return default modeUserPrefers", async () => {
|
|
16
|
-
const platform = await import("../platform/platform.service");
|
|
16
|
+
const platform = await import("../utils/platform/platform.service");
|
|
17
17
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: false });
|
|
18
18
|
|
|
19
19
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -25,7 +25,7 @@ describe("useDarkMode", () => {
|
|
|
25
25
|
describe("given in browser", () => {
|
|
26
26
|
describe("given no modeUserPrefers in localStorage", () => {
|
|
27
27
|
it("should return default modeUserPrefers", async () => {
|
|
28
|
-
const platform = await import("../platform/platform.service");
|
|
28
|
+
const platform = await import("../utils/platform/platform.service");
|
|
29
29
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
30
30
|
|
|
31
31
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -39,7 +39,7 @@ describe("useDarkMode", () => {
|
|
|
39
39
|
});
|
|
40
40
|
describe("given modeUserPrefers in localStorage", () => {
|
|
41
41
|
it("should return the value", async () => {
|
|
42
|
-
const platform = await import("../platform/platform.service");
|
|
42
|
+
const platform = await import("../utils/platform/platform.service");
|
|
43
43
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
44
44
|
|
|
45
45
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -57,7 +57,7 @@ describe("useDarkMode", () => {
|
|
|
57
57
|
describe("getModeOsPrefers", () => {
|
|
58
58
|
describe("given not in browser", () => {
|
|
59
59
|
it("should return default modeOsPrefers", async () => {
|
|
60
|
-
const platform = await import("../platform/platform.service");
|
|
60
|
+
const platform = await import("../utils/platform/platform.service");
|
|
61
61
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: false });
|
|
62
62
|
|
|
63
63
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -69,7 +69,7 @@ describe("useDarkMode", () => {
|
|
|
69
69
|
describe("given in browser", () => {
|
|
70
70
|
describe("given prefers-color-scheme: light", () => {
|
|
71
71
|
it("should return true", async () => {
|
|
72
|
-
const platform = await import("../platform/platform.service");
|
|
72
|
+
const platform = await import("../utils/platform/platform.service");
|
|
73
73
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
74
74
|
const localStorageSpy = vi.spyOn(window.localStorage, "setItem");
|
|
75
75
|
|
|
@@ -83,7 +83,7 @@ describe("useDarkMode", () => {
|
|
|
83
83
|
});
|
|
84
84
|
describe("given prefers-color-scheme: dark", () => {
|
|
85
85
|
it("should return false", async () => {
|
|
86
|
-
const platform = await import("../platform/platform.service");
|
|
86
|
+
const platform = await import("../utils/platform/platform.service");
|
|
87
87
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
88
88
|
const localStorageSpy = vi.spyOn(window.localStorage, "setItem");
|
|
89
89
|
|
|
@@ -101,7 +101,7 @@ describe("useDarkMode", () => {
|
|
|
101
101
|
describe("getModeAutoPrefers", () => {
|
|
102
102
|
describe("given not in browser", () => {
|
|
103
103
|
it("should return default modeAutoPrefers", async () => {
|
|
104
|
-
const platform = await import("../platform/platform.service");
|
|
104
|
+
const platform = await import("../utils/platform/platform.service");
|
|
105
105
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: false });
|
|
106
106
|
|
|
107
107
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -113,7 +113,7 @@ describe("useDarkMode", () => {
|
|
|
113
113
|
describe("given in browser", () => {
|
|
114
114
|
describe("given no modeUserPrefers in localStorage", () => {
|
|
115
115
|
it("should return default modeAutoPrefers", async () => {
|
|
116
|
-
const platform = await import("../platform/platform.service");
|
|
116
|
+
const platform = await import("../utils/platform/platform.service");
|
|
117
117
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
118
118
|
|
|
119
119
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -127,7 +127,7 @@ describe("useDarkMode", () => {
|
|
|
127
127
|
});
|
|
128
128
|
describe("given modeUserPrefers in localStorage", () => {
|
|
129
129
|
it("should return the value", async () => {
|
|
130
|
-
const platform = await import("../platform/platform.service");
|
|
130
|
+
const platform = await import("../utils/platform/platform.service");
|
|
131
131
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
132
132
|
|
|
133
133
|
const { useDarkMode } = await import("./dark-mode.service");
|
|
@@ -145,7 +145,7 @@ describe("useDarkMode", () => {
|
|
|
145
145
|
describe("setModeUserPrefers", () => {
|
|
146
146
|
describe("given not in browser", () => {
|
|
147
147
|
it("should set modeUserPrefers", async () => {
|
|
148
|
-
const platform = await import("../platform/platform.service");
|
|
148
|
+
const platform = await import("../utils/platform/platform.service");
|
|
149
149
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: false });
|
|
150
150
|
vi.spyOn(window.localStorage, "setItem");
|
|
151
151
|
|
|
@@ -160,7 +160,7 @@ describe("useDarkMode", () => {
|
|
|
160
160
|
|
|
161
161
|
describe("given in browser", () => {
|
|
162
162
|
it("should set modeUserPrefers and localStorage", async () => {
|
|
163
|
-
const platform = await import("../platform/platform.service");
|
|
163
|
+
const platform = await import("../utils/platform/platform.service");
|
|
164
164
|
vi.spyOn(platform, "usePlatform").mockReturnValueOnce({ isBrowser: true });
|
|
165
165
|
|
|
166
166
|
const { useDarkMode } = await import("./dark-mode.service");
|
package/src/services/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { useRail } from "./rail.service";
|
|
2
2
|
import { useDrawer } from "./drawer.service";
|
|
3
|
+
import { useHighlight } from "./highlight.service";
|
|
4
|
+
import { useDarkMode } from "./dark-mode.service";
|
|
3
5
|
|
|
4
|
-
export { useRail, useDrawer };
|
|
6
|
+
export { useRail, useDrawer, useHighlight, useDarkMode };
|
package/src/utils/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import VCodeBlock from "./code-block/VCodeBlock.vue";
|
|
2
|
-
import { useDarkMode } from "./dark-mode/dark-mode.service";
|
|
3
|
-
import DarkModeSwitch from "./dark-mode/dark-mode.vue";
|
|
4
1
|
import ThemeSwitcher from "./theme/theme-switcher.vue";
|
|
5
2
|
import { useTheme } from "./theme/theme.service";
|
|
6
3
|
|
|
7
|
-
export {
|
|
4
|
+
export { ThemeSwitcher, useTheme };
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
Theme
|
|
5
5
|
</VButton>
|
|
6
6
|
|
|
7
|
-
<div
|
|
7
|
+
<div
|
|
8
|
+
v-if="showPopup"
|
|
9
|
+
class="cc-theme-switcher__popup absolute z-10 mt-1 p-4 shadow-xl"
|
|
10
|
+
:class="classes"
|
|
11
|
+
>
|
|
8
12
|
<div class="space-y-4">
|
|
9
13
|
<section class="flex items-center justify-between">
|
|
10
14
|
<h6>Mode</h6>
|
|
11
|
-
<
|
|
15
|
+
<v-light-switch />
|
|
12
16
|
</section>
|
|
13
17
|
<nav class="list-nav -m-4 overflow-y-auto p-4" :class="listClasses">
|
|
14
18
|
<ul class="flex flex-col gap-4">
|
|
@@ -33,12 +37,12 @@
|
|
|
33
37
|
</template>
|
|
34
38
|
|
|
35
39
|
<script lang="ts">
|
|
36
|
-
import { CssClasses,
|
|
40
|
+
import { CssClasses, useDarkMode, useTheme, VButton, VLightSwitch } from "@/index";
|
|
37
41
|
import { computed, defineComponent, onMounted, ref } from "vue";
|
|
38
42
|
|
|
39
43
|
export default defineComponent({
|
|
40
44
|
components: {
|
|
41
|
-
|
|
45
|
+
VLightSwitch,
|
|
42
46
|
VButton,
|
|
43
47
|
},
|
|
44
48
|
props: {
|
|
@@ -83,7 +87,7 @@ export default defineComponent({
|
|
|
83
87
|
default: "w-24",
|
|
84
88
|
},
|
|
85
89
|
},
|
|
86
|
-
setup(props
|
|
90
|
+
setup(props) {
|
|
87
91
|
const { initializeTheme, loadTheme, themes, chosenTheme } = useTheme();
|
|
88
92
|
const { currentMode, MODE } = useDarkMode();
|
|
89
93
|
|
|
@@ -116,8 +120,7 @@ export default defineComponent({
|
|
|
116
120
|
${text.value}
|
|
117
121
|
${props.width}
|
|
118
122
|
${props.ring}
|
|
119
|
-
${props.roundedContainer}
|
|
120
|
-
${attrs.class ?? ""}`;
|
|
123
|
+
${props.roundedContainer}`;
|
|
121
124
|
});
|
|
122
125
|
|
|
123
126
|
const listClasses = computed(() => {
|
|
@@ -145,11 +148,3 @@ export default defineComponent({
|
|
|
145
148
|
},
|
|
146
149
|
});
|
|
147
150
|
</script>
|
|
148
|
-
|
|
149
|
-
<style scoped>
|
|
150
|
-
.cc-theme-switcher__popup {
|
|
151
|
-
position: absolute;
|
|
152
|
-
z-index: 1;
|
|
153
|
-
margin-top: 0.25rem;
|
|
154
|
-
}
|
|
155
|
-
</style>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|