@code-coaching/vuetiful 0.1.4 → 0.3.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/dist/style.css +2 -2
- package/dist/styles/all.css +323 -52
- package/dist/types/components/atoms/VButton.test.d.ts +1 -0
- package/dist/types/components/atoms/VButton.vue.d.ts +6 -72
- package/dist/types/components/index.d.ts +2 -1
- package/dist/types/components/index.test.d.ts +1 -0
- package/dist/types/components/molecules/VRail.vue.d.ts +51 -0
- package/dist/types/components/molecules/VRailTile.vue.d.ts +55 -0
- package/dist/types/components/molecules/VShell.vue.d.ts +78 -0
- package/dist/types/components/molecules/index.d.ts +4 -0
- package/dist/types/directives/clipboard.test.d.ts +1 -0
- package/dist/types/directives/index.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.test.d.ts +1 -0
- package/dist/types/services/index.d.ts +2 -0
- package/dist/types/services/rail.service.d.ts +4 -0
- package/dist/types/utils/code-block/code-block.vue.d.ts +2 -2
- package/dist/types/utils/code-block/highlight.service.test.d.ts +1 -0
- package/dist/types/utils/dark-mode/dark-mode.service.test.d.ts +1 -0
- package/dist/types/utils/dark-mode/dark-mode.vue.d.ts +3 -3
- package/dist/types/utils/index.d.ts +3 -3
- package/dist/types/utils/index.test.d.ts +1 -0
- package/dist/types/utils/platform/platform.service.test.d.ts +1 -0
- package/dist/types/utils/theme/callback.test.d.ts +1 -0
- package/dist/types/utils/theme/remove.test.d.ts +1 -0
- package/dist/types/utils/theme/theme-switcher.vue.d.ts +3 -3
- package/dist/types/utils/theme/{theme.d.ts → theme.service.d.ts} +2 -1
- package/dist/types/utils/theme/theme.service.test.d.ts +1 -0
- package/dist/vuetiful.es.mjs +658 -499
- package/dist/vuetiful.umd.js +13 -20
- package/package.json +8 -2
- package/src/components/atoms/VButton.test.ts +27 -0
- package/src/components/atoms/VButton.vue +19 -73
- package/src/components/index.test.ts +10 -0
- package/src/components/index.ts +2 -1
- package/src/components/molecules/VRail.vue +46 -0
- package/src/components/molecules/VRailTile.vue +75 -0
- package/src/components/molecules/VShell.vue +71 -0
- package/src/components/molecules/index.ts +5 -0
- package/src/directives/clipboard.test.ts +26 -0
- package/src/directives/index.ts +2 -4
- package/src/index.test.ts +26 -0
- package/src/index.ts +1 -1
- package/src/services/index.ts +3 -0
- package/src/services/rail.service.ts +11 -0
- package/src/styles/all.css +9 -6
- package/src/styles/transitions/fade.css +14 -0
- package/src/styles/transitions/slide.css +83 -0
- package/src/styles/transitions.css +2 -0
- package/src/utils/code-block/code-block.vue +1 -1
- package/src/utils/code-block/highlight.service.test.ts +24 -0
- package/src/utils/dark-mode/dark-mode.service.test.ts +234 -0
- package/src/utils/dark-mode/{dark-mode.ts → dark-mode.service.ts} +5 -4
- package/src/utils/dark-mode/dark-mode.vue +1 -1
- package/src/utils/index.test.ts +11 -0
- package/src/utils/index.ts +3 -4
- package/src/utils/platform/platform.service.test.ts +19 -0
- package/src/utils/theme/callback.test.ts +24 -0
- package/src/utils/theme/remove.test.ts +25 -0
- package/src/utils/theme/theme.service.test.ts +160 -0
- package/src/utils/theme/{theme.ts → theme.service.ts} +6 -7
- package/dist/types/constants/MyConstants.d.ts +0 -1
- package/dist/types/constants/index.d.ts +0 -2
- package/src/constants/MyConstants.ts +0 -1
- package/src/constants/index.ts +0 -5
- /package/dist/types/utils/code-block/{highlight.d.ts → highlight.service.d.ts} +0 -0
- /package/dist/types/utils/dark-mode/{dark-mode.d.ts → dark-mode.service.d.ts} +0 -0
- /package/dist/types/utils/platform/{platform.d.ts → platform.service.d.ts} +0 -0
- /package/src/utils/code-block/{highlight.ts → highlight.service.ts} +0 -0
- /package/src/utils/platform/{platform.ts → platform.service.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-coaching/vuetiful",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "onchange 'src/**/*.vue' 'src/**/*.ts' 'src/**/*.css' -- npm run build",
|
|
6
6
|
"prebuild": "node 'scripts/intellisense.js'",
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"build:style": "npx tailwindcss -i ./src/styles/all.css -o ./dist/styles/all.css",
|
|
9
9
|
"docs:dev": "cd docs && npm run dev",
|
|
10
10
|
"docs:build": "cd docs && npm run build",
|
|
11
|
-
"docs:serve": "cd docs && npm run serve"
|
|
11
|
+
"docs:serve": "cd docs && npm run serve",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"coverage": "vitest run --coverage"
|
|
12
14
|
},
|
|
13
15
|
"peerDependencies": {
|
|
14
16
|
"vue": "^3.2.25"
|
|
@@ -19,7 +21,10 @@
|
|
|
19
21
|
"devDependencies": {
|
|
20
22
|
"@types/node": "^17.0.14",
|
|
21
23
|
"@vitejs/plugin-vue": "^2.0.0",
|
|
24
|
+
"@vitest/coverage-c8": "^0.29.8",
|
|
25
|
+
"@vue/test-utils": "^2.3.2",
|
|
22
26
|
"autoprefixer": "^10.4.14",
|
|
27
|
+
"jsdom": "^21.1.1",
|
|
23
28
|
"onchange": "^7.1.0",
|
|
24
29
|
"postcss": "^8.4.21",
|
|
25
30
|
"prettier": "^2.8.4",
|
|
@@ -28,6 +33,7 @@
|
|
|
28
33
|
"tailwindcss": "^3.2.7",
|
|
29
34
|
"typescript": "^4.4.4",
|
|
30
35
|
"vite": "^2.7.2",
|
|
36
|
+
"vitest": "^0.29.8",
|
|
31
37
|
"vue": "^3.2.25",
|
|
32
38
|
"vue-tsc": "^0.29.8"
|
|
33
39
|
},
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mount } from "@vue/test-utils";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { VButton } from ".";
|
|
4
|
+
|
|
5
|
+
test("VButton using prop", async () => {
|
|
6
|
+
expect(VButton).toBeTruthy();
|
|
7
|
+
|
|
8
|
+
const vButtonElement = mount(VButton, {
|
|
9
|
+
props: {
|
|
10
|
+
msg: "John Duck",
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
expect(vButtonElement.text()).toContain("John Duck");
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("VButton using slot", async () => {
|
|
18
|
+
expect(VButton).toBeTruthy();
|
|
19
|
+
|
|
20
|
+
const vButtonElement = mount(VButton, {
|
|
21
|
+
slots: {
|
|
22
|
+
default: "John Duck",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(vButtonElement.text()).toContain("John Duck");
|
|
27
|
+
});
|
|
@@ -1,78 +1,24 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
<template v-if="msg">{{ msg }}</template>
|
|
4
|
-
<slot />
|
|
5
|
-
</button>
|
|
6
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useAttrs } from "vue";
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export default defineComponent({
|
|
13
|
-
props: {
|
|
14
|
-
bgLight: {
|
|
15
|
-
type: String as () => CssClasses,
|
|
16
|
-
default: "bg-primary-50",
|
|
17
|
-
},
|
|
18
|
-
bgDark: {
|
|
19
|
-
type: String as () => CssClasses,
|
|
20
|
-
default: "bg-primary-900",
|
|
21
|
-
},
|
|
22
|
-
textOnLight: {
|
|
23
|
-
type: String as () => CssClasses,
|
|
24
|
-
default: "text-primary-900",
|
|
25
|
-
},
|
|
26
|
-
textOnDark: {
|
|
27
|
-
type: String as () => CssClasses,
|
|
28
|
-
default: "text-primary-50",
|
|
29
|
-
},
|
|
30
|
-
width: {
|
|
31
|
-
type: String as () => CssClasses,
|
|
32
|
-
default: "w-fit",
|
|
33
|
-
},
|
|
34
|
-
height: {
|
|
35
|
-
type: String as () => CssClasses,
|
|
36
|
-
default: "h-fit",
|
|
37
|
-
},
|
|
38
|
-
ring: {
|
|
39
|
-
type: String as () => CssClasses,
|
|
40
|
-
default: "ring-[1px] ring-primary-500/30",
|
|
41
|
-
},
|
|
42
|
-
rounded: {
|
|
43
|
-
type: String as () => CssClasses,
|
|
44
|
-
default: "rounded-token",
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
msg: {
|
|
48
|
-
type: String,
|
|
49
|
-
},
|
|
4
|
+
defineProps({
|
|
5
|
+
tag: {
|
|
6
|
+
type: String as () => string,
|
|
7
|
+
default: "button",
|
|
50
8
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const cTransition = `transition-all duration-[200ms]`;
|
|
54
|
-
|
|
55
|
-
const background = computed(() => {
|
|
56
|
-
return currentMode.value === MODE.LIGHT ? props.bgLight : props.bgDark;
|
|
57
|
-
});
|
|
58
|
-
const text = computed(() => {
|
|
59
|
-
return currentMode.value === MODE.LIGHT ? props.textOnLight : props.textOnDark;
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const classes = computed(() => {
|
|
63
|
-
return `${cTransition}
|
|
64
|
-
${background.value}
|
|
65
|
-
${text.value}
|
|
66
|
-
${props.width}
|
|
67
|
-
${props.height}
|
|
68
|
-
${props.ring}
|
|
69
|
-
${props.rounded}
|
|
70
|
-
${attrs.class ?? ""}`;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
classes,
|
|
75
|
-
};
|
|
9
|
+
msg: {
|
|
10
|
+
type: String,
|
|
76
11
|
},
|
|
77
12
|
});
|
|
13
|
+
const attrs = useAttrs();
|
|
78
14
|
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<component
|
|
18
|
+
:is="tag"
|
|
19
|
+
:class="`vuetiful-button btn border-token hover:cursor-pointer ${attrs.class ?? ''}`"
|
|
20
|
+
>
|
|
21
|
+
<template v-if="msg">{{ msg }}</template>
|
|
22
|
+
<slot />
|
|
23
|
+
</component>
|
|
24
|
+
</template>
|
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { CssClasses } from "@/index";
|
|
3
|
+
import { defineProps, provide, useAttrs } from "vue";
|
|
4
|
+
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
active: {
|
|
7
|
+
type: String as () => CssClasses,
|
|
8
|
+
default: "bg-secondary-active-token",
|
|
9
|
+
},
|
|
10
|
+
hover: {
|
|
11
|
+
type: String as () => CssClasses,
|
|
12
|
+
default: "hover:bg-secondary-hover-token",
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
regionLead: {
|
|
16
|
+
type: String as () => CssClasses,
|
|
17
|
+
default: "",
|
|
18
|
+
},
|
|
19
|
+
regionDefault: {
|
|
20
|
+
type: String as () => CssClasses,
|
|
21
|
+
default: "",
|
|
22
|
+
},
|
|
23
|
+
regionTrail: {
|
|
24
|
+
type: String as () => CssClasses,
|
|
25
|
+
default: "",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const attrs = useAttrs();
|
|
30
|
+
|
|
31
|
+
provide("active", props.active);
|
|
32
|
+
provide("hover", props.hover);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<div
|
|
37
|
+
class="v-rail"
|
|
38
|
+
:class="`grid h-full w-[70px] grid-rows-[auto_1fr_auto] gap-0 overflow-y-auto sm:w-20 ${
|
|
39
|
+
attrs.class || ''
|
|
40
|
+
}`"
|
|
41
|
+
>
|
|
42
|
+
<div class="v-bar-lead" :class="regionLead"><slot name="lead" /></div>
|
|
43
|
+
<div class="v-bar-default" :class="regionDefault"><slot /></div>
|
|
44
|
+
<div class="v-bar-trail" :class="regionTrail"><slot name="trail" /></div>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { CssClasses } from "@/index";
|
|
3
|
+
import { useRail } from "@/services";
|
|
4
|
+
import { inject, useAttrs } from "vue";
|
|
5
|
+
|
|
6
|
+
const emit = defineEmits<{
|
|
7
|
+
(event: "click"): void;
|
|
8
|
+
}>();
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
value: {
|
|
12
|
+
type: String,
|
|
13
|
+
default: "",
|
|
14
|
+
},
|
|
15
|
+
tag: {
|
|
16
|
+
type: String as () => string,
|
|
17
|
+
default: "button",
|
|
18
|
+
},
|
|
19
|
+
label: {
|
|
20
|
+
type: String as () => string,
|
|
21
|
+
default: "",
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
regionIcon: {
|
|
25
|
+
type: String as () => CssClasses,
|
|
26
|
+
default: "",
|
|
27
|
+
},
|
|
28
|
+
regionLabel: {
|
|
29
|
+
type: String as () => CssClasses,
|
|
30
|
+
default: "",
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const attrs = useAttrs();
|
|
35
|
+
|
|
36
|
+
const { selectedRailTile } = useRail();
|
|
37
|
+
const active = inject("active");
|
|
38
|
+
const hover = inject("hover");
|
|
39
|
+
|
|
40
|
+
const onClickHandler = (event: MouseEvent) => {
|
|
41
|
+
if (!props.value) return;
|
|
42
|
+
selectedRailTile.value = props.value;
|
|
43
|
+
emit("click");
|
|
44
|
+
};
|
|
45
|
+
const onKeyHandler = (event: KeyboardEvent) => {
|
|
46
|
+
if (!props.value) return;
|
|
47
|
+
if (!["Enter", "Space"].includes(event.key)) return;
|
|
48
|
+
selectedRailTile.value = props.value;
|
|
49
|
+
emit("click");
|
|
50
|
+
};
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<div
|
|
55
|
+
@click="onClickHandler"
|
|
56
|
+
@keydown="onKeyHandler"
|
|
57
|
+
>
|
|
58
|
+
<component
|
|
59
|
+
:is="tag"
|
|
60
|
+
v-bind="attrs"
|
|
61
|
+
:class="`app-rail-tile unstyled grid aspect-square w-full cursor-pointer place-content-center place-items-center space-y-1.5 ${hover} ${
|
|
62
|
+
selectedRailTile === value ? `${active}` : ''
|
|
63
|
+
} ${attrs.class || ''}`"
|
|
64
|
+
>
|
|
65
|
+
<template v-if="$slots.default">
|
|
66
|
+
<div :class="`app-rail-tile-icon ${regionIcon}`"><slot /></div>
|
|
67
|
+
</template>
|
|
68
|
+
<template v-if="label">
|
|
69
|
+
<div :class="`app-rail-tile-label text-center text-xs font-bold ${regionLabel}`">
|
|
70
|
+
{{ label }}
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
73
|
+
</component>
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* @slot fixedHeader - Insert fixed header content, such as Skeleton's App Bar component.
|
|
4
|
+
* @slot sidebarLeft - Hidden when empty. Allows you to set fixed left sidebar content.
|
|
5
|
+
* @slot sidebarRight - Hidden when empty. Allows you to set fixed right sidebar content.
|
|
6
|
+
* @slot pageHeader - Insert content that resides above your page content. Great for global alerts.
|
|
7
|
+
* @slot pageFooter - Insert content that resides below your page content. Recommended for most layouts.
|
|
8
|
+
* @slot fixedFooter - Insert fixed footer content. Not recommended for most layouts.
|
|
9
|
+
*/
|
|
10
|
+
import { useAttrs } from "vue";
|
|
11
|
+
export type CssClasses = string;
|
|
12
|
+
defineProps({
|
|
13
|
+
regionPage: { type: String as () => CssClasses, default: "" },
|
|
14
|
+
slotFixedHeader: { type: String as () => CssClasses, default: "z-10" },
|
|
15
|
+
slotSidebarLeft: { type: String as () => CssClasses, default: "w-auto" },
|
|
16
|
+
slotSidebarRight: { type: String as () => CssClasses, default: "w-auto" },
|
|
17
|
+
slotPageHeader: { type: String as () => CssClasses, default: "" },
|
|
18
|
+
slotPageContent: { type: String as () => CssClasses, default: "" },
|
|
19
|
+
slotPageFooter: { type: String as () => CssClasses, default: "" },
|
|
20
|
+
slotFixedFooter: { type: String as () => CssClasses, default: "" },
|
|
21
|
+
});
|
|
22
|
+
const attrs = useAttrs();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<div :class="`vuetiful-shell flex h-full w-full flex-col overflow-hidden ${attrs.class ?? ''}`">
|
|
27
|
+
<header v-if="$slots.fixedHeader" :class="`vuetiful-fixed-header ${slotFixedHeader}`">
|
|
28
|
+
<slot name="fixedHeader" />
|
|
29
|
+
</header>
|
|
30
|
+
|
|
31
|
+
<div class="vuetiful-shell-content flex h-full w-full flex-auto overflow-hidden">
|
|
32
|
+
<aside
|
|
33
|
+
v-if="$slots.sidebarLeft"
|
|
34
|
+
:class="`vuetiful-sidebar-left overflow-y-auto overflow-x-hidden ${slotSidebarLeft}`"
|
|
35
|
+
>
|
|
36
|
+
<slot name="sidebarLeft" />
|
|
37
|
+
</aside>
|
|
38
|
+
|
|
39
|
+
<div :class="`vuetiful-page flex flex-1 flex-col overflow-x-hidden ${regionPage ?? ''}`">
|
|
40
|
+
<header
|
|
41
|
+
v-if="$slots.pageHeader"
|
|
42
|
+
:class="`vuetiful-page-header flex-none ${slotPageHeader}`"
|
|
43
|
+
>
|
|
44
|
+
<slot name="pageHeader">(slot:header)</slot>
|
|
45
|
+
</header>
|
|
46
|
+
|
|
47
|
+
<main :class="`vuetiful-page-content flex-auto ${slotPageContent}`">
|
|
48
|
+
<slot />
|
|
49
|
+
</main>
|
|
50
|
+
|
|
51
|
+
<footer
|
|
52
|
+
v-if="$slots.pageFooter"
|
|
53
|
+
:class="`vuetiful-page-footer flex-none ${slotPageFooter}`"
|
|
54
|
+
>
|
|
55
|
+
<slot name="pageFooter">(slot:footer)</slot>
|
|
56
|
+
</footer>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<aside
|
|
60
|
+
v-if="$slots.sidebarRight"
|
|
61
|
+
:class="`vuetiful-sidebar-right flex-none overflow-y-auto overflow-x-hidden ${slotSidebarRight}`"
|
|
62
|
+
>
|
|
63
|
+
<slot name="sidebarRight" />
|
|
64
|
+
</aside>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<footer v-if="$slots.fixedFooter" :class="`vuetiful-fixed-footer ${slotFixedFooter}`">
|
|
68
|
+
<slot name="fixedFooter" />
|
|
69
|
+
</footer>
|
|
70
|
+
</div>
|
|
71
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { DirectiveBinding } from "vue";
|
|
3
|
+
import { vClipboard } from ".";
|
|
4
|
+
|
|
5
|
+
const navigatorMock = {
|
|
6
|
+
clipboard: {
|
|
7
|
+
writeText: vi.fn(),
|
|
8
|
+
} as any,
|
|
9
|
+
} as any;
|
|
10
|
+
|
|
11
|
+
describe("clipboard", () => {
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
vi.resetAllMocks();
|
|
14
|
+
});
|
|
15
|
+
describe("given the v-clipboard directive is used", () => {
|
|
16
|
+
it("should copy text to the clipboard on click", () => {
|
|
17
|
+
window.navigator = navigatorMock;
|
|
18
|
+
|
|
19
|
+
const el = document.createElement("div");
|
|
20
|
+
vClipboard(el, { value: "John Duck" } as DirectiveBinding);
|
|
21
|
+
el.click();
|
|
22
|
+
|
|
23
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith("John Duck");
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
package/src/directives/index.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import * as components from "./components";
|
|
3
|
+
import plugin, * as index from "./index";
|
|
4
|
+
|
|
5
|
+
describe("src", () => {
|
|
6
|
+
Object.entries(index).forEach(([key, value]) => {
|
|
7
|
+
it(`${key} is defined`, () => {
|
|
8
|
+
expect(value).toBeDefined();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("given install is called", () => {
|
|
13
|
+
it("should register all components", () => {
|
|
14
|
+
const app = {
|
|
15
|
+
component: vi.fn(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
plugin.install(app);
|
|
19
|
+
|
|
20
|
+
for (const key in components) {
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
expect(app.component).toHaveBeenCalledWith(key, components[key]);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -13,9 +13,9 @@ import "./styles/tailwind.css";
|
|
|
13
13
|
export default { install };
|
|
14
14
|
|
|
15
15
|
export * from "./components";
|
|
16
|
-
export * from "./constants";
|
|
17
16
|
export * from "./utils";
|
|
18
17
|
export * from "./directives";
|
|
18
|
+
export * from "./services";
|
|
19
19
|
|
|
20
20
|
// This type alias is to identify CSS classes within component props, which enables Tailwind IntelliSense
|
|
21
21
|
export type CssClasses = string;
|
package/src/styles/all.css
CHANGED
|
@@ -3,19 +3,22 @@
|
|
|
3
3
|
/* NOTE: The order shown below is required */
|
|
4
4
|
|
|
5
5
|
/* Tailwind Directives */
|
|
6
|
-
@import
|
|
6
|
+
@import "tailwind.css";
|
|
7
7
|
|
|
8
8
|
/* Global Styles */
|
|
9
|
-
@import
|
|
9
|
+
@import "core.css";
|
|
10
10
|
|
|
11
11
|
/* Typographical Settings */
|
|
12
|
-
@import
|
|
12
|
+
@import "typography.css";
|
|
13
13
|
|
|
14
14
|
/* Imports all Tailwind Elements */
|
|
15
|
-
@import
|
|
15
|
+
@import "elements.css";
|
|
16
16
|
|
|
17
17
|
/* Imports all Variant Styles */
|
|
18
|
-
@import
|
|
18
|
+
@import "variants.css";
|
|
19
|
+
|
|
20
|
+
/* Imports all Transitions */
|
|
21
|
+
@import "transitions.css";
|
|
19
22
|
|
|
20
23
|
/* Imports all Component Styles */
|
|
21
|
-
@import
|
|
24
|
+
@import "../../dist/style.css";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.fade-150-enter-active,
|
|
2
|
+
.fade-150-leave-active {
|
|
3
|
+
transition: opacity 150ms;
|
|
4
|
+
}
|
|
5
|
+
.fade-300-enter-active,
|
|
6
|
+
.fade-300-leave-active {
|
|
7
|
+
transition: opacity 300ms;
|
|
8
|
+
}
|
|
9
|
+
.fade-150-enter-from,
|
|
10
|
+
.fade-150-leave-to,
|
|
11
|
+
.fade-300-enter-from,
|
|
12
|
+
.fade-300-leave-to {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
.slide-left-150-enter-active {
|
|
2
|
+
animation: slide-left 150ms;
|
|
3
|
+
}
|
|
4
|
+
.slide-left-150-leave-active {
|
|
5
|
+
animation: slide-left 150ms reverse;
|
|
6
|
+
}
|
|
7
|
+
.slide-left-300-enter-active {
|
|
8
|
+
animation: slide-left 300ms;
|
|
9
|
+
}
|
|
10
|
+
.slide-left-300-leave-active {
|
|
11
|
+
animation: slide-left 300ms reverse;
|
|
12
|
+
}
|
|
13
|
+
@keyframes slide-left {
|
|
14
|
+
0% {
|
|
15
|
+
transform: translateX(-100%);
|
|
16
|
+
}
|
|
17
|
+
100% {
|
|
18
|
+
transform: translateX(0);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.slide-top-150-enter-active {
|
|
23
|
+
animation: slide-top 150ms;
|
|
24
|
+
}
|
|
25
|
+
.slide-top-150-leave-active {
|
|
26
|
+
animation: slide-top 150ms reverse;
|
|
27
|
+
}
|
|
28
|
+
.slide-top-300-enter-active {
|
|
29
|
+
animation: slide-top 300ms;
|
|
30
|
+
}
|
|
31
|
+
.slide-top-300-leave-active {
|
|
32
|
+
animation: slide-top 300ms reverse;
|
|
33
|
+
}
|
|
34
|
+
@keyframes slide-top {
|
|
35
|
+
0% {
|
|
36
|
+
transform: translateY(-100%);
|
|
37
|
+
}
|
|
38
|
+
100% {
|
|
39
|
+
transform: translateY(0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.slide-right-150-enter-active {
|
|
44
|
+
animation: slide-right 150ms;
|
|
45
|
+
}
|
|
46
|
+
.slide-right-150-leave-active {
|
|
47
|
+
animation: slide-right 150ms reverse;
|
|
48
|
+
}
|
|
49
|
+
.slide-right-300-enter-active {
|
|
50
|
+
animation: slide-right 300ms;
|
|
51
|
+
}
|
|
52
|
+
.slide-right-300-leave-active {
|
|
53
|
+
animation: slide-right 300ms reverse;
|
|
54
|
+
}
|
|
55
|
+
@keyframes slide-right {
|
|
56
|
+
0% {
|
|
57
|
+
transform: translateX(100%);
|
|
58
|
+
}
|
|
59
|
+
100% {
|
|
60
|
+
transform: translateX(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.slide-bottom-150-enter-active {
|
|
65
|
+
animation: slide-bottom 150ms;
|
|
66
|
+
}
|
|
67
|
+
.slide-bottom-150-leave-active {
|
|
68
|
+
animation: slide-bottom 150ms reverse;
|
|
69
|
+
}
|
|
70
|
+
.slide-bottom-300-enter-active {
|
|
71
|
+
animation: slide-bottom 300ms;
|
|
72
|
+
}
|
|
73
|
+
.slide-bottom-300-leave-active {
|
|
74
|
+
animation: slide-bottom 300ms reverse;
|
|
75
|
+
}
|
|
76
|
+
@keyframes slide-bottom {
|
|
77
|
+
0% {
|
|
78
|
+
transform: translateY(100%);
|
|
79
|
+
}
|
|
80
|
+
100% {
|
|
81
|
+
transform: translateY(0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { CssClasses, vClipboard } from "@/index";
|
|
3
3
|
import "highlight.js/styles/github-dark.css";
|
|
4
4
|
import { computed, ref, useAttrs } from "vue";
|
|
5
|
-
import { useHighlight } from "./highlight";
|
|
5
|
+
import { useHighlight } from "./highlight.service";
|
|
6
6
|
|
|
7
7
|
const { highlight } = useHighlight();
|
|
8
8
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { useHighlight } from "./highlight.service";
|
|
3
|
+
|
|
4
|
+
const { highlight } = useHighlight();
|
|
5
|
+
|
|
6
|
+
describe("useHighlight", () => {
|
|
7
|
+
describe("highlight", () => {
|
|
8
|
+
describe("given a known language is passed", () => {
|
|
9
|
+
it("should trim and highlight the code", () => {
|
|
10
|
+
expect(highlight(" const name = 'John Duck' ", "javascript")).toEqual(
|
|
11
|
+
'<span class="hljs-keyword">const</span> name = <span class="hljs-string">'John Duck'</span>'
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("given an unknown language is passed", () => {
|
|
17
|
+
it("should trim and auto highlight the code", () => {
|
|
18
|
+
expect(highlight(" const name = 'John Duck' ", "unknown")).toEqual(
|
|
19
|
+
'<span class="hljs-keyword">const</span> <span class="hljs-keyword">name</span> = <span class="hljs-string">'John Duck'</span>'
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
});
|