🙆

【NextJs14】NextJs14 と 便利なライブラリ【#10Shadcn-ui MenuItems 】

2023/12/21に公開

【#10Shadcn-ui MenuItems 】

YouTube: https://youtu.be/TSBIsjt6_0k

https://youtu.be/TSBIsjt6_0k

今回はメニューのアイテムをコンポーネントに変更します。

動画の編集ミスで「MainSidebarItemProps」を
適用する部分がカットされていますので、
こちらの追加を忘れないようにご注意ください。

app/(main)/_components/main-sidebar.tsx
import { Separator } from "@/components/ui/separator";
import { Database, Home, Image, ShieldCheck, User } from "lucide-react";
import { MainSidebarItem } from "./main-sidebar-item";

export type MenuItem = {
  id: string;
  href: string;
  pathname: string;
  label: string;
  icon: React.ReactNode;
};

const menuItems = [
  {
    id: "0",
    href: "/home",
    pathname: "/home",
    label: "Home",
    icon: <Home className="h-5 w-5 mr-3 group-hover:text-white" />,
  },
  {
    id: "1",
    href: "/account",
    pathname: "/account",
    label: "Account",
    icon: <User className="h-5 w-5 mr-3 group-hover:text-white" />,
  },
  {
    id: "2",
    href: "/images",
    pathname: "/images",
    label: "Images",
    icon: <Image className="h-5 w-5 mr-3 group-hover:text-white" />,
  },
  {
    id: "3",
    href: "/data",
    pathname: "/data",
    label: "Data",
    icon: <Database className="h-5 w-5 mr-3 group-hover:text-white" />,
  },
  {
    id: "4",
    href: "/protected",
    pathname: "/protected",
    label: "Protected",
    icon: <ShieldCheck className="h-5 w-5 mr-3 group-hover:text-white" />,
  },
];

export const MainSidebar = () => {
  return (
    <div className="w-full flex py-4 px-4 flex-col items-center">
      <div className="w-full">
        <h3 className="text-lg">Menu</h3>
      </div>
      <Separator className="bg-slate-400 mt-2" />
      <div className="w-full py-4">
        <ul>
          {menuItems.map((item) => (
            <MainSidebarItem key={item.id} item={item} />
          ))}
        </ul>
      </div>
    </div>
  );
};
app/(main)/_components/main-sidebar-item.tsx
"use client";

import { usePathname } from "next/navigation";
import Link from "next/link";
import { MenuItem } from "./main-sidebar";
import { cn } from "@/lib/utils";

interface MainSidebarItemProps {
  item: MenuItem;
}

export const MainSidebarItem = ({ item }: MainSidebarItemProps) => {
  const pathname = usePathname();

  return (
    <li
      className={cn(
        "group rounded-sm p-2 transition",
        item.pathname === pathname
          ? "bg-slate-700 text-white"
          : "text-neutral-600 dark:text-neutral-400 hover:bg-slate-700"
      )}
    >
      <Link href={item.href} className="flex items-center">
        {item.icon}
        <span className="group-hover:text-white">{item.label}</span>
      </Link>
    </li>
  );
};

Discussion