feat: reactive nav buttons

This commit is contained in:
Henry
2023-11-22 20:34:10 +00:00
parent 80e5eb3a26
commit 3d4df5f7e5
6 changed files with 74 additions and 23 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -31,6 +31,7 @@
"react-beautiful-dnd": "^13.1.1",
"react-dom": "18.2.0",
"react-icons": "^4.11.0",
"react-lottie-player": "^1.5.5",
"superjson": "^1.13.1",
"zod": "^3.22.4"
},

File diff suppressed because one or more lines are too long

View File

@@ -1,33 +1,16 @@
import Link from "next/link";
import Image from "next/image";
import { redirect } from "next/navigation";
import { getServerAuthSession } from "~/server/auth";
import boardsIcon from "~/app/assets/boards.json";
import ReactiveButton from "~/app/components/ReactiveButton";
const navigation = [
{ name: "Boards", href: "/boards", icon: null, current: true },
{ name: "Boards", href: "/boards", icon: boardsIcon, current: true },
];
function classNames(...classes: string[]): string {
return classes.filter(Boolean).join(" ");
}
const NavButton: React.FC<{
href: string;
current: boolean;
name: string;
}> = ({ href, current, name }) => (
<Link
href={href}
className={classNames(
current ? "bg-dark-200 text-white" : "bg-dark-200 text-white",
"group flex items-center gap-x-3 rounded-md p-1.5 text-sm font-normal leading-6 text-dark-1000",
)}
>
{name}
</Link>
);
export default async function Layout(props: { children: React.ReactNode }) {
const session = await getServerAuthSession();
@@ -49,10 +32,11 @@ export default async function Layout(props: { children: React.ReactNode }) {
<ul role="list" className="-mx-2 my-6 space-y-1">
{navigation.map((item) => (
<li key={item.name}>
<NavButton
<ReactiveButton
href={item.href}
current={item.current}
name={item.name}
json={item.icon}
/>
</li>
))}

View File

@@ -0,0 +1,24 @@
"use client";
import Lottie from "react-lottie-player";
type IconProps = {
isPlaying: boolean;
index: number;
json: object;
};
const Icon: React.FC<IconProps> = ({ isPlaying, index, json }) => {
return (
<Lottie
key={index}
animationData={json}
play={isPlaying}
loop={false}
style={{ width: 20, height: 20, fill: "white" }}
rendererSettings={{ preserveAspectRatio: "xMidYMid slice" }}
/>
);
};
export default Icon;

View File

@@ -0,0 +1,41 @@
"use client";
import { useState } from "react";
import Link from "next/link";
import LottieIcon from "~/app/components/LottieIcon";
function classNames(...classes: string[]): string {
return classes.filter(Boolean).join(" ");
}
const Button: React.FC<{
href: string;
current: boolean;
name: string;
json: object;
}> = ({ href, current, name, json }) => {
const [isHovered, setIsHovered] = useState(false);
const [index, setIndex] = useState(0);
const handleMouseEnter = () => {
setIsHovered(true);
setIndex((index) => index + 1);
};
return (
<Link
href={href}
onMouseEnter={handleMouseEnter}
className={classNames(
current ? "bg-dark-200 text-white" : "bg-dark-200 text-white",
"group flex items-center gap-x-3 rounded-md p-1.5 text-sm font-normal leading-6 text-dark-1000",
)}
>
<LottieIcon index={index} json={json} isPlaying={isHovered} />
{name}
</Link>
);
};
export default Button;