feat: reactive nav buttons
This commit is contained in:
@@ -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"
|
||||
},
|
||||
|
||||
1
src/app/assets/boards.json
Normal file
1
src/app/assets/boards.json
Normal file
File diff suppressed because one or more lines are too long
@@ -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>
|
||||
))}
|
||||
|
||||
24
src/app/components/LottieIcon.tsx
Normal file
24
src/app/components/LottieIcon.tsx
Normal 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;
|
||||
41
src/app/components/ReactiveButton.tsx
Normal file
41
src/app/components/ReactiveButton.tsx
Normal 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;
|
||||
Reference in New Issue
Block a user