cloudflare/kumo

Public

mirrored fromhttps://github.com/cloudflare/kumoAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
d86c9318c15924a4d4fab2205271148f8f184454

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/kumo-docs-astro/src/components/KumoMenuIcon.tsx

284lines · modecode

1import { useState } from "react";
2import { cn } from "@cloudflare/kumo";
3
4interface KumoMenuIconProps {
5 className?: string;
6}
7
8export function KumoMenuIcon({ className }: KumoMenuIconProps) {
9 const [isHovered, setIsHovered] = useState(false);
10
11 return (
12 <div
13 className={cn(
14 "h-[19.8px] w-[20px] cursor-pointer overflow-visible",
15 className,
16 )}
17 onMouseEnter={() => setIsHovered(true)}
18 onMouseLeave={() => setIsHovered(false)}
19 >
20 <svg
21 viewBox="0 0 108 107"
22 fill="none"
23 xmlns="http://www.w3.org/2000/svg"
24 className="h-full w-full"
25 >
26 <defs>
27 <clipPath id="contentClip">
28 <rect x="0" y="25" width="108" height="82" />
29 </clipPath>
30 </defs>
31
32 {/* Vertical connector - NOT clipped */}
33 <path
34 className={cn(
35 "origin-center-top transition-all duration-800",
36 isHovered
37 ? "translate-y-[22px] scale-y-0 opacity-0"
38 : "translate-y-0 scale-y-100 opacity-100",
39 )}
40 style={{
41 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
42 transitionDelay: "0.03s",
43 }}
44 d="M48.8398 2.75977H57.5998V52.9198H48.8398V2.75977Z"
45 fill="currentColor"
46 />
47
48 {/* Character parts that will animate away (clipped below y=25) */}
49 <g clipPath="url(#contentClip)">
50 <path
51 className={cn(
52 "origin-center-top transition-all duration-800",
53 isHovered
54 ? "-translate-y-[33px] scale-y-[0.01]"
55 : "translate-y-0 scale-y-100",
56 )}
57 style={{
58 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
59 transitionDelay: "0.05s",
60 }}
61 d="M13.7998 57.96H93.2398V65.04H13.7998V57.96Z"
62 fill="currentColor"
63 />
64 <path
65 className={cn(
66 "origin-center-top transition-all duration-800",
67 isHovered
68 ? "-translate-y-[49px] scale-y-[0.01]"
69 : "translate-y-0 scale-y-100",
70 )}
71 style={{
72 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
73 transitionDelay: "0.1s",
74 }}
75 d="M0 73.5601H107.28V80.7601H0V73.5601Z"
76 fill="currentColor"
77 />
78 <path
79 className={cn(
80 "origin-center-top transition-all duration-800",
81 isHovered
82 ? "-translate-y-[51px] scale-y-[0.01]"
83 : "translate-y-0 scale-y-100",
84 )}
85 style={{
86 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
87 transitionDelay: "0.15s",
88 }}
89 d="M33.0002 75.2402L43.5602 77.1602C41.0802 81.0802 38.3202 85.1202 35.2802 89.2802C32.3202 93.3602 29.5202 96.8802 26.8802 99.8402L19.2002 97.5602C20.8802 95.5602 22.5602 93.2402 24.2402 90.6002C26.0002 87.9602 27.6402 85.3202 29.1602 82.6802C30.6802 79.9602 31.9602 77.4802 33.0002 75.2402Z"
90 fill="currentColor"
91 />
92 <path
93 className={cn(
94 "origin-center-top transition-all duration-800",
95 isHovered
96 ? "-translate-y-[70px] scale-y-[0.01]"
97 : "translate-y-0 scale-y-100",
98 )}
99 style={{
100 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
101 transitionDelay: "0.2s",
102 }}
103 d="M6.6001 94.92C13.3201 94.76 21.2001 94.6 30.2401 94.44C39.3601 94.28 49.0401 94.08 59.2801 93.84C69.6001 93.52 79.8801 93.24 90.1201 93L89.7601 100.2C79.8401 100.52 69.8401 100.88 59.7601 101.28C49.6801 101.68 40.1601 102 31.2001 102.24C22.2401 102.48 14.3201 102.72 7.4401 102.96L6.6001 94.92Z"
104 fill="currentColor"
105 />
106 <path
107 className={cn(
108 "origin-center-top transition-all duration-800",
109 isHovered
110 ? "translate-y-[25px] scale-y-[0.01]"
111 : "translate-y-0 scale-y-100",
112 )}
113 style={{
114 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
115 transitionDelay: "0s",
116 }}
117 d="M9.35986 0H97.7999V7.2H9.35986V0Z"
118 fill="currentColor"
119 />
120 <path
121 className={cn(
122 "origin-center-top transition-all duration-800",
123 isHovered
124 ? "-translate-y-[5px] scale-y-[0.01]"
125 : "translate-y-0 scale-y-100",
126 )}
127 style={{
128 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
129 transitionDelay: "0.05s",
130 }}
131 d="M17.1602 30.2402H42.6002V36.4802H17.1602V30.2402Z"
132 fill="currentColor"
133 />
134 <path
135 className={cn(
136 "origin-center-top transition-all duration-800",
137 isHovered
138 ? "-translate-y-[19px] scale-y-[0.01]"
139 : "translate-y-0 scale-y-100",
140 )}
141 style={{
142 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
143 transitionDelay: "0.1s",
144 }}
145 d="M14.6401 44.04H42.4801V50.28H14.6401V44.04Z"
146 fill="currentColor"
147 />
148 <path
149 className={cn(
150 "origin-center-top transition-all duration-800",
151 isHovered
152 ? "-translate-y-[19px] scale-y-[0.01]"
153 : "translate-y-0 scale-y-100",
154 )}
155 style={{
156 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
157 transitionDelay: "0.1s",
158 }}
159 d="M63.96 44.04H93V50.28H63.96V44.04Z"
160 fill="currentColor"
161 />
162 <path
163 className={cn(
164 "origin-center-top transition-all duration-800",
165 isHovered
166 ? "-translate-y-[5px] scale-y-[0.01]"
167 : "translate-y-0 scale-y-100",
168 )}
169 style={{
170 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
171 transitionDelay: "0.05s",
172 }}
173 d="M63.96 30.2402H89.76V36.4802H63.96V30.2402Z"
174 fill="currentColor"
175 />
176 <path
177 className={cn(
178 "origin-center-top transition-all duration-800",
179 isHovered
180 ? "translate-y-[9px] scale-y-[0.01]"
181 : "translate-y-0 scale-y-100",
182 )}
183 style={{
184 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
185 transitionDelay: "0.02s",
186 }}
187 d="M2.75977 15.8398H104.64V41.7598H96.2398V22.9198H10.9198V41.7598H2.75977V15.8398Z"
188 fill="currentColor"
189 />
190 <path
191 className={cn(
192 "origin-center-top transition-all duration-800",
193 isHovered
194 ? "translate-y-[9px] scale-y-[0.01]"
195 : "translate-y-0 scale-y-100",
196 )}
197 style={{
198 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
199 transitionDelay: "0.02s",
200 }}
201 d="M104.64 15.8398H2.75977V22.9198H10.9198H96.2398H104.64V15.8398Z"
202 fill="currentColor"
203 />
204 <path
205 className={cn(
206 "origin-center-top transition-all duration-800",
207 isHovered
208 ? "-translate-y-[60px] scale-y-[0.01]"
209 : "translate-y-0 scale-y-100",
210 )}
211 style={{
212 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
213 transitionDelay: "0.25s",
214 }}
215 d="M66.3599 84.6001L73.9199 80.6401C77.1999 82.6401 80.5999 84.9201 84.1199 87.4801C87.7199 90.0401 91.0799 92.6402 94.1999 95.2802C97.3199 97.8402 99.8799 100.2 101.88 102.36L93.8399 106.68C91.9999 104.52 89.5599 102.12 86.5199 99.4801C83.4799 96.9201 80.1999 94.3201 76.6799 91.6801C73.1599 89.0401 69.7199 86.6801 66.3599 84.6001Z"
216 fill="currentColor"
217 />
218 </g>
219
220 {/* Hamburger lines (on top, not clipped) */}
221 <rect
222 className={cn(
223 "origin-left-center transition-all duration-800",
224 isHovered
225 ? "h-[6px] translate-x-[0.36px] translate-y-[24.88px]"
226 : "h-[7px]",
227 )}
228 style={{
229 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
230 }}
231 x="9.64014"
232 y="0.120117"
233 width="88"
234 fill="currentColor"
235 />
236 <rect
237 className={cn(
238 "origin-left-center transition-all duration-800",
239 isHovered
240 ? "h-[6px] translate-x-[7.36px] translate-y-[30.88px] scale-x-[0.863]"
241 : "h-[9px]",
242 )}
243 style={{
244 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
245 }}
246 x="2.64014"
247 y="16.1201"
248 width="102"
249 fill="currentColor"
250 />
251 <rect
252 className={cn(
253 "origin-left-center transition-all duration-800",
254 isHovered
255 ? "h-[6px] -translate-x-[3.64px] -translate-y-[11.12px] scale-x-[1.114] opacity-0"
256 : "h-[6px] opacity-100",
257 )}
258 style={{
259 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
260 }}
261 x="13.6401"
262 y="58.1201"
263 width="79"
264 fill="currentColor"
265 />
266 <rect
267 className={cn(
268 "origin-left-center transition-all duration-800",
269 isHovered
270 ? "h-[6px] translate-x-[9.36px] -translate-y-[5.12px] scale-x-[0.83]"
271 : "h-[6px]",
272 )}
273 style={{
274 transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
275 }}
276 x="0.640137"
277 y="74.1201"
278 width="106"
279 fill="currentColor"
280 />
281 </svg>
282 </div>
283 );
284}
285