Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import { CommandMenuProvider } from "@/components/command-menu-context";
import { TooltipProvider } from "@/components/ui/tooltip";
import { LINKS } from "@/constants";
import { Analytics } from "@vercel/analytics/react";
import { StickyBanner } from "@/components/ui/sticky-banner";
import { GithubStarsProvider } from "@/components/github-stars-context";
import ExternalLinkIcon from "@/icons/external-link-icon";
import Link from "next/link";
import UmamiAnalytics from "@/components/UmamiAnalytics";

const geistSans = Geist({
Expand Down Expand Up @@ -68,24 +65,7 @@ export default function RootLayout({
<CommandMenuProvider>
<TooltipProvider>
<CommandMenu />
<StickyBanner
className="bg-primary text-primary-foreground h-auto min-h-8 py-2"
hideOnScroll
>
<Link
href="https://evilcharts.com/?ref=itshover.com"
target="_blank"
className="flex items-center justify-center gap-2 text-center text-sm font-medium hover:underline"
>
<span>
A Beautiful & Animated Chart UI Website built on top of
recharts.
</span>
<ExternalLinkIcon className="h-4 w-4 shrink-0" />
</Link>
</StickyBanner>
<Navbar />

{children}
<Footer />
</TooltipProvider>
Expand Down
19 changes: 14 additions & 5 deletions icons/accessibility-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef, useImperativeHandle } from "react";
import { forwardRef, useImperativeHandle, useRef } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

Expand All @@ -8,12 +8,18 @@ const AccessibilityIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
ref,
) => {
const [scope, animate] = useAnimate();
const animationControls = useRef<Array<ReturnType<typeof animate>>>([]);

const start = async () => {
animate(
".wheel",
{ rotate: [0, 360] },
{ duration: 1, ease: "easeInOut", repeat: Infinity },
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animationControls.current.push(
animate(
".wheel",
{ rotate: [0, 360] },
{ duration: 1, ease: "easeInOut", repeat: Infinity },
),
);
animate(
".person",
Expand All @@ -23,6 +29,9 @@ const AccessibilityIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
};

const stop = () => {
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animate(".wheel", { rotate: 0 }, { duration: 0.3 });
animate(".person", { y: 0 }, { duration: 0.2 });
};
Expand Down
53 changes: 32 additions & 21 deletions icons/alarm-clock-plus-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef, useImperativeHandle } from "react";
import { forwardRef, useImperativeHandle, useRef } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

Expand All @@ -8,30 +8,38 @@ const AlarmClockPlusIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
ref,
) => {
const [scope, animate] = useAnimate();
const animationControls = useRef<Array<ReturnType<typeof animate>>>([]);

const start = async () => {
animate(
".clock",
{
y: -1.5,
x: [-1, 1, -1, 1, -1, 0],
},
{
y: { duration: 0.2, type: "spring", stiffness: 200, damping: 25 },
x: { duration: 0.3, repeat: Infinity, ease: "linear" },
},
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animationControls.current.push(
animate(
".clock",
{
y: -1.5,
x: [-1, 1, -1, 1, -1, 0],
},
{
y: { duration: 0.2, type: "spring", stiffness: 200, damping: 25 },
x: { duration: 0.3, repeat: Infinity, ease: "linear" },
},
),
);

animate(
".bells",
{
y: -2.5,
x: [-2, 2, -2, 2, -2, 0],
},
{
y: { duration: 0.2, type: "spring", stiffness: 200, damping: 25 },
x: { duration: 0.3, repeat: Infinity, ease: "linear" },
},
animationControls.current.push(
animate(
".bells",
{
y: -2.5,
x: [-2, 2, -2, 2, -2, 0],
},
{
y: { duration: 0.2, type: "spring", stiffness: 200, damping: 25 },
x: { duration: 0.3, repeat: Infinity, ease: "linear" },
},
),
);

await animate(
Expand All @@ -42,6 +50,9 @@ const AlarmClockPlusIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
};

const stop = () => {
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animate(".clock", { y: 0, x: 0 }, { duration: 0.2 });
animate(".bells", { y: 0, x: 0 }, { duration: 0.2 });
};
Expand Down
19 changes: 14 additions & 5 deletions icons/ambulance-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef, useImperativeHandle } from "react";
import { forwardRef, useImperativeHandle, useRef } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

Expand All @@ -8,12 +8,18 @@ const AmbulanceIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
ref,
) => {
const [scope, animate] = useAnimate();
const animationControls = useRef<Array<ReturnType<typeof animate>>>([]);

const start = async () => {
animate(
".ambulance",
{ x: [0, 1, 0, -1] },
{ duration: 0.6, ease: "easeInOut", repeat: Infinity },
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animationControls.current.push(
animate(
".ambulance",
{ x: [0, 1, 0, -1] },
{ duration: 0.6, ease: "easeInOut", repeat: Infinity },
),
);
animate(
".plus",
Expand All @@ -23,6 +29,9 @@ const AmbulanceIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
};

const stop = () => {
animationControls.current.forEach((control) => control.stop());
animationControls.current = [];

animate(".ambulance", { x: 0 }, { duration: 0.2, ease: "easeInOut" });
animate(".plus", { scale: 1 }, { duration: 0.2, ease: "easeInOut" });
};
Expand Down
88 changes: 88 additions & 0 deletions icons/brand-aws-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { forwardRef, useImperativeHandle } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

const BrandAwsIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
(
{ size = 24, color = "currentColor", strokeWidth = 2, className = "" },
ref,
) => {
const [scope, animate] = useAnimate();

const start = async () => {
await animate(
".smile",
{
pathOffset: 1,
opacity: [0, 1],
pathLength: 1,
},
{
duration: 0.1,
ease: "easeInOut",
},
);

await animate(
".smile",
{ pathOffset: 0 },
{ duration: 0.45, ease: "easeInOut" },
);

await animate(
".arrowhead",
{ scale: [0.8, 1.15, 1], opacity: [0, 1] },
{ duration: 0.4, ease: "easeOut" },
);
};

const stop = () => {};

useImperativeHandle(ref, () => ({
startAnimation: start,
stopAnimation: stop,
}));

return (
<motion.svg
ref={scope}
onHoverStart={start}
onHoverEnd={stop}
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke={color}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
className={`cursor-pointer select-none ${className}`}
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />

{/* Smile + Arrow */}
<motion.g className="smile-group">
<motion.path
className="smile"
d="M17 18.5a15.198 15.198 0 0 1 -7.37 1.44a14.62 14.62 0 0 1 -6.63 -2.94"
/>
<motion.path
className="arrowhead"
d="M19.5 21c.907 -1.411 1.451 -3.323 1.5 -5c-1.197 -.773 -2.577 -.935 -4 -1"
/>
</motion.g>

<motion.g className="text">
<path d="M3 11v-4.5a1.5 1.5 0 0 1 3 0v4.5" />
<path d="M3 9h3" />
<path d="M9 5l1.2 6l1.8 -4l1.8 4l1.2 -6" />
<path d="M18 10.25c0 .414 .336 .75 .75 .75h1.25a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1a1 1 0 0 1 -1 -1v-1a1 1 0 0 1 1 -1h1.25a.75 .75 0 0 1 .75 .75" />
</motion.g>
</motion.svg>
);
},
);

BrandAwsIcon.displayName = "BrandAwsIcon";
export default BrandAwsIcon;
8 changes: 4 additions & 4 deletions icons/cursor-ide-icon.tsx → icons/brand-cursor-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useCallback } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

const CursorIdeIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
const BrandCursorIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
({ size = 24, color = "currentColor", className = "" }, ref) => {
const [scope, animate] = useAnimate();

Expand Down Expand Up @@ -42,7 +42,7 @@ const CursorIdeIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
style={{ flex: "none", lineHeight: 1 }}
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className={className}
className={`cursor-ide-icon cursor-pointer ${className}`}
stroke={color}
>
<title>Cursor</title>
Expand All @@ -52,5 +52,5 @@ const CursorIdeIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
},
);

CursorIdeIcon.displayName = "CursorIdeIcon";
export default CursorIdeIcon;
BrandCursorIcon.displayName = "BrandCursorIcon";
export default BrandCursorIcon;
8 changes: 4 additions & 4 deletions icons/gemini-icon.tsx → icons/brand-gemini-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useCallback } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

const GeminiIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
const BrandGeminiIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
({ size = 24, color = "currentColor", className = "" }, ref) => {
const [scope, animate] = useAnimate();

Expand Down Expand Up @@ -47,7 +47,7 @@ const GeminiIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
height={size}
width={size}
xmlns="http://www.w3.org/2000/svg"
className={className}
className={`gemini-icon cursor-pointer ${className}`}
role="img"
aria-label="Gemini"
style={{
Expand All @@ -69,5 +69,5 @@ const GeminiIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
},
);

GeminiIcon.displayName = "GeminiIcon";
export default GeminiIcon;
BrandGeminiIcon.displayName = "BrandGeminiIcon";
export default BrandGeminiIcon;
12 changes: 6 additions & 6 deletions icons/grok-icon.tsx → icons/brand-grok-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useCallback } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

const GrokIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
const BrandGrokIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
({ size = 24, color = "currentColor", className = "" }, ref) => {
const [scope, animate] = useAnimate();

Expand Down Expand Up @@ -34,13 +34,13 @@ const GrokIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(

animate(
".grok-upper",
{ x: 0, y: 0, opacity: 0.5 },
{ x: 0, y: 0, opacity: 1 },
{ duration: 0.25, ease: "easeInOut" },
);

animate(
".grok-lower",
{ x: 0, y: 0, opacity: 0.5 },
{ x: 0, y: 0, opacity: 1 },
{ duration: 0.25, ease: "easeInOut" },
);
}, [animate, scope]);
Expand All @@ -59,7 +59,7 @@ const GrokIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
viewBox="0 0 24 24"
width={size}
height={size}
className={className}
className={`grok-icon cursor-pointer ${className}`}
style={{ flex: "none", lineHeight: 1 }}
>
<title>Grok</title>
Expand All @@ -80,5 +80,5 @@ const GrokIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
},
);

GrokIcon.displayName = "GrokIcon";
export default GrokIcon;
BrandGrokIcon.displayName = "BrandGrokIcon";
export default BrandGrokIcon;
8 changes: 4 additions & 4 deletions icons/notion-icon.tsx → icons/brand-notion-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useCallback } from "react";
import type { AnimatedIconHandle, AnimatedIconProps } from "./types";
import { motion, useAnimate } from "motion/react";

const NotionIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
const BrandNotionIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
({ size = 24, color = "currentColor", className = "" }, ref) => {
const [scope, animate] = useAnimate();

Expand Down Expand Up @@ -47,7 +47,7 @@ const NotionIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
style={{ flex: "none", lineHeight: 1 }}
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className={className}
className={`notion-icon cursor-pointer ${className}`}
>
<title>Notion</title>

Expand All @@ -67,5 +67,5 @@ const NotionIcon = forwardRef<AnimatedIconHandle, AnimatedIconProps>(
},
);

NotionIcon.displayName = "NotionIcon";
export default NotionIcon;
BrandNotionIcon.displayName = "BrandNotionIcon";
export default BrandNotionIcon;
Loading