@code-coaching/vuetiful 0.2.0 → 0.4.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 +1 -1
- package/dist/styles/all.css +266 -3
- package/dist/types/components/index.d.ts +2 -2
- package/dist/types/components/molecules/VDrawer.vue.d.ts +60 -0
- package/dist/types/components/molecules/index.d.ts +2 -1
- package/dist/types/directives/index.d.ts +1 -1
- package/dist/types/services/drawer.service.d.ts +24 -0
- package/dist/types/services/index.d.ts +2 -1
- package/dist/vuetiful.es.mjs +133 -13
- package/dist/vuetiful.umd.js +11 -11
- package/package.json +1 -1
- package/src/components/index.ts +2 -2
- package/src/components/molecules/VDrawer.vue +97 -0
- package/src/components/molecules/VRailTile.vue +2 -5
- package/src/components/molecules/index.ts +2 -1
- package/src/directives/index.ts +2 -4
- package/src/services/drawer.service.ts +43 -0
- package/src/services/index.ts +2 -1
- 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/package.json
CHANGED
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { CssClasses } from "@/index";
|
|
3
|
+
import { useDrawer } from "@/services";
|
|
4
|
+
import { Ref, computed, onMounted, ref, toRefs, useAttrs } from "vue";
|
|
5
|
+
|
|
6
|
+
const { drawer, close } = useDrawer();
|
|
7
|
+
const attrs = useAttrs();
|
|
8
|
+
|
|
9
|
+
// #region Props
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
position: {
|
|
12
|
+
type: String as () => "left" | "top" | "right" | "bottom",
|
|
13
|
+
default: "left",
|
|
14
|
+
},
|
|
15
|
+
duration: {
|
|
16
|
+
type: Number as () => 150 | 300,
|
|
17
|
+
default: 300,
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// Regions
|
|
21
|
+
regionBackdrop: {
|
|
22
|
+
type: String as () => CssClasses,
|
|
23
|
+
default: "",
|
|
24
|
+
},
|
|
25
|
+
regionDrawer: {
|
|
26
|
+
type: String as () => CssClasses,
|
|
27
|
+
default: "",
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// a11y
|
|
31
|
+
labelledby: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: "",
|
|
34
|
+
},
|
|
35
|
+
describedby: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: "",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// prettier-ignore
|
|
42
|
+
const { position, duration, regionBackdrop, regionDrawer, labelledby, describedby } = toRefs(props);
|
|
43
|
+
// prettier-ignore
|
|
44
|
+
const presets = {
|
|
45
|
+
top: { alignment: 'top-0', width: 'w-full', height: 'h-[50%]', rounded: 'rounded-bl-container-token rounded-br-container-token' },
|
|
46
|
+
bottom: { alignment: 'bottom-0', width: 'w-full', height: ' h-[50%]', rounded: 'rounded-tl-container-token rounded-tr-container-token' },
|
|
47
|
+
left: { alignment: 'lef-0', width: 'w-[90%]', height: 'h-full', rounded: 'rounded-tr-container-token rounded-br-container-token' },
|
|
48
|
+
right: { alignment: 'right-0', width: 'w-[90%]', height: 'h-full', rounded: 'rounded-tl-container-token rounded-bl-container-token' }
|
|
49
|
+
};
|
|
50
|
+
const preset = computed(() => presets[position.value]);
|
|
51
|
+
// #endregion
|
|
52
|
+
|
|
53
|
+
// #region template refs
|
|
54
|
+
const elemBackdrop: Ref<HTMLElement> = ref() as Ref<HTMLElement>;
|
|
55
|
+
const elemDrawer: Ref<HTMLElement> = ref() as Ref<HTMLElement>;
|
|
56
|
+
// #endregion
|
|
57
|
+
|
|
58
|
+
// #region Event Handlers
|
|
59
|
+
const onBackdropInteraction = (event: Event) => {
|
|
60
|
+
if (event.target === elemBackdrop.value) close();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const onKeydownWindow = (event: KeyboardEvent) => {
|
|
64
|
+
if (event.code === "Escape") close();
|
|
65
|
+
};
|
|
66
|
+
onMounted(() => {
|
|
67
|
+
window.addEventListener("keydown", onKeydownWindow);
|
|
68
|
+
});
|
|
69
|
+
// #endregion
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<template>
|
|
73
|
+
<transition :name="`slide-${position}-${duration}`">
|
|
74
|
+
<div
|
|
75
|
+
v-if="drawer.open"
|
|
76
|
+
ref="elemDrawer"
|
|
77
|
+
:class="`drawer absolute overflow-y-auto shadow-xl transition-transform bg-surface-100-800-token ${preset.width} ${preset.height} ${preset.rounded} ${preset.alignment} z-50 ${regionDrawer}`"
|
|
78
|
+
role="dialog"
|
|
79
|
+
aria-modal="true"
|
|
80
|
+
:aria-labelledby="labelledby"
|
|
81
|
+
:aria-describedby="describedby"
|
|
82
|
+
>
|
|
83
|
+
<slot />
|
|
84
|
+
</div>
|
|
85
|
+
</transition>
|
|
86
|
+
<transition :name="`fade-${duration}`">
|
|
87
|
+
<div
|
|
88
|
+
v-if="drawer.open"
|
|
89
|
+
ref="elemBackdrop"
|
|
90
|
+
:class="`drawer-backdrop backdrop-blur-xs fixed top-0 left-0 right-0 bottom-0 flex bg-surface-backdrop-token ${regionBackdrop} z-40 ${
|
|
91
|
+
attrs.class ?? ''
|
|
92
|
+
}`"
|
|
93
|
+
@mousedown="onBackdropInteraction"
|
|
94
|
+
@touchstart="onBackdropInteraction"
|
|
95
|
+
></div>
|
|
96
|
+
</transition>
|
|
97
|
+
</template>
|
|
@@ -37,7 +37,7 @@ const { selectedRailTile } = useRail();
|
|
|
37
37
|
const active = inject("active");
|
|
38
38
|
const hover = inject("hover");
|
|
39
39
|
|
|
40
|
-
const onClickHandler = (
|
|
40
|
+
const onClickHandler = () => {
|
|
41
41
|
if (!props.value) return;
|
|
42
42
|
selectedRailTile.value = props.value;
|
|
43
43
|
emit("click");
|
|
@@ -51,10 +51,7 @@ const onKeyHandler = (event: KeyboardEvent) => {
|
|
|
51
51
|
</script>
|
|
52
52
|
|
|
53
53
|
<template>
|
|
54
|
-
<div
|
|
55
|
-
@click="onClickHandler"
|
|
56
|
-
@keydown="onKeyHandler"
|
|
57
|
-
>
|
|
54
|
+
<div @click="onClickHandler" @keydown="onKeyHandler">
|
|
58
55
|
<component
|
|
59
56
|
:is="tag"
|
|
60
57
|
v-bind="attrs"
|
package/src/directives/index.ts
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { reactive, readonly } from 'vue';
|
|
2
|
+
|
|
3
|
+
export interface DrawerSettings {
|
|
4
|
+
id?: string;
|
|
5
|
+
open?: boolean;
|
|
6
|
+
|
|
7
|
+
position?: 'left' | 'top' | 'right' | 'bottom';
|
|
8
|
+
duration?: 150 | 300;
|
|
9
|
+
|
|
10
|
+
regionBackdrop?: string;
|
|
11
|
+
regionDrawer?: string;
|
|
12
|
+
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const drawer = reactive<DrawerSettings>({
|
|
17
|
+
id: 'default',
|
|
18
|
+
open: false,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const useDrawer = () => {
|
|
22
|
+
const open = (settings?: DrawerSettings) => {
|
|
23
|
+
drawer.open = true;
|
|
24
|
+
if (settings) {
|
|
25
|
+
Object.keys(settings).forEach((key: string) => {
|
|
26
|
+
drawer[key] = settings[key];
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const close = () => (drawer.open = false);
|
|
32
|
+
|
|
33
|
+
const toggle = () => (drawer.open = !drawer.open);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
drawer: readonly(drawer),
|
|
37
|
+
open,
|
|
38
|
+
close,
|
|
39
|
+
toggle,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { useDrawer };
|
package/src/services/index.ts
CHANGED
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
|
+
}
|