Skip to content

Commit f9d0797

Browse files
committed
test: add hover tests
1 parent 27aa7da commit f9d0797

File tree

3 files changed

+323
-107
lines changed

3 files changed

+323
-107
lines changed

packages/motion/README.md

Lines changed: 0 additions & 106 deletions
This file was deleted.

packages/motion/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../README.md
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
<script setup lang="ts">
2+
import { onMounted, ref } from 'vue'
3+
import { type MotionProps, motion, useDomRef } from 'motion-v'
4+
5+
const isOpen = ref(false)
6+
const containerRef = useDomRef()
7+
const dimensions = ref({ width: 0, height: 0 })
8+
9+
onMounted(() => {
10+
if (containerRef.value) {
11+
dimensions.value.width = containerRef.value.offsetWidth
12+
dimensions.value.height = containerRef.value.offsetHeight
13+
}
14+
})
15+
16+
function toggle() {
17+
isOpen.value = !isOpen.value
18+
}
19+
20+
const navVariants: MotionProps['variants'] = {
21+
open: {
22+
transition: { staggerChildren: 0.07, delayChildren: 0.2 },
23+
},
24+
closed: {
25+
transition: { staggerChildren: 0.05, staggerDirection: -1 },
26+
},
27+
}
28+
29+
const itemVariants = {
30+
open: {
31+
y: 0,
32+
opacity: 1,
33+
transition: {
34+
y: { stiffness: 1000, velocity: -100 },
35+
},
36+
},
37+
closed: {
38+
y: 50,
39+
opacity: 0,
40+
transition: {
41+
y: { stiffness: 1000 },
42+
},
43+
},
44+
}
45+
46+
const sidebarVariants: MotionProps['variants'] = {
47+
open: (height: any = 1000) => ({
48+
clipPath: `circle(${height * 2 + 200}px at 40px 40px)`,
49+
transition: {
50+
type: 'spring',
51+
stiffness: 20,
52+
restDelta: 2,
53+
},
54+
}),
55+
closed: {
56+
clipPath: 'circle(30px at 40px 40px)',
57+
transition: {
58+
delay: 0.2,
59+
type: 'spring',
60+
stiffness: 400,
61+
damping: 40,
62+
},
63+
},
64+
}
65+
66+
const colors = ['#FF008C', '#D309E1', '#9C1AFF', '#7700FF', '#4400FF']
67+
</script>
68+
69+
<template>
70+
<div>
71+
<div class="container">
72+
<motion.nav
73+
ref="containerRef"
74+
:initial="false"
75+
:animate="isOpen ? 'open' : 'closed'"
76+
:custom="dimensions.height"
77+
class="nav"
78+
>
79+
<motion.div
80+
class="background"
81+
:variants="sidebarVariants"
82+
/>
83+
84+
<!-- Navigation -->
85+
<motion.ul
86+
class="list"
87+
:variants="navVariants"
88+
>
89+
<motion.li
90+
v-for="i in 5"
91+
:key="i - 1"
92+
class="list-item"
93+
:variants="itemVariants"
94+
:while-press="{ scale: 0.95 }"
95+
:while-hover="{ scale: 1.1 }"
96+
>
97+
<div
98+
class="icon-placeholder"
99+
:style="{ border: `2px solid ${colors[i - 1]}` }"
100+
/>
101+
<div
102+
class="text-placeholder"
103+
:style="{ border: `2px solid ${colors[i - 1]}` }"
104+
/>
105+
</motion.li>
106+
</motion.ul>
107+
108+
<!-- Menu Toggle -->
109+
<button
110+
class="toggle-container"
111+
@click="toggle"
112+
>
113+
<svg
114+
width="23"
115+
height="23"
116+
viewBox="0 0 23 23"
117+
>
118+
<motion.path
119+
fill="transparent"
120+
stroke-width="3"
121+
stroke="hsl(0, 0%, 18%)"
122+
stroke-linecap="round"
123+
:variants="{
124+
closed: { d: 'M 2 2.5 L 20 2.5' },
125+
open: { d: 'M 3 16.5 L 17 2.5' },
126+
}"
127+
/>
128+
<motion.path
129+
fill="transparent"
130+
stroke-width="3"
131+
stroke="hsl(0, 0%, 18%)"
132+
stroke-linecap="round"
133+
d="M 2 9.423 L 20 9.423"
134+
:variants="{
135+
closed: { opacity: 1 },
136+
open: { opacity: 0 },
137+
}"
138+
:transition="{ duration: 0.1 }"
139+
/>
140+
<motion.path
141+
fill="transparent"
142+
stroke-width="3"
143+
stroke="hsl(0, 0%, 18%)"
144+
stroke-linecap="round"
145+
:variants="{
146+
closed: { d: 'M 2 16.346 L 20 16.346' },
147+
open: { d: 'M 3 2.5 L 17 16.346' },
148+
}"
149+
/>
150+
</svg>
151+
</button>
152+
</motion.nav>
153+
</div>
154+
</div>
155+
</template>
156+
157+
<style scoped>
158+
.container {
159+
position: relative;
160+
display: flex;
161+
justify-content: flex-start;
162+
align-items: stretch;
163+
flex: 1;
164+
width: 500px;
165+
max-width: 100%;
166+
height: 400px;
167+
background-color: var(--accent);
168+
border-radius: 20px;
169+
overflow: hidden;
170+
}
171+
172+
.nav {
173+
width: 300px;
174+
}
175+
176+
.background {
177+
background-color: #f5f5f5;
178+
position: absolute;
179+
top: 0;
180+
left: 0;
181+
bottom: 0;
182+
width: 300px;
183+
}
184+
185+
.toggle-container {
186+
outline: none;
187+
border: none;
188+
-webkit-user-select: none;
189+
-moz-user-select: none;
190+
cursor: pointer;
191+
position: absolute;
192+
top: 18px;
193+
left: 15px;
194+
width: 50px;
195+
height: 50px;
196+
border-radius: 50%;
197+
background: transparent;
198+
}
199+
200+
.list {
201+
list-style: none;
202+
padding: 25px;
203+
margin: 0;
204+
position: absolute;
205+
top: 80px;
206+
width: 230px;
207+
}
208+
209+
.list-item {
210+
display: flex;
211+
align-items: center;
212+
justify-content: flex-start;
213+
padding: 0;
214+
margin: 0;
215+
list-style: none;
216+
margin-bottom: 20px;
217+
cursor: pointer;
218+
}
219+
220+
.icon-placeholder {
221+
width: 40px;
222+
height: 40px;
223+
border-radius: 50%;
224+
flex: 40px 0;
225+
margin-right: 20px;
226+
}
227+
228+
.text-placeholder {
229+
border-radius: 5px;
230+
width: 200px;
231+
height: 20px;
232+
flex: 1;
233+
}
234+
</style>

0 commit comments

Comments
 (0)