💭
【NextJs14】NextJs14 と 便利なライブラリ【#9Shadcn-ui Sheet 】
【#9Shadcn-ui Sheet 】
YouTube: https://youtu.be/SbPJHmmMk08
今回は「Sheet」コンポーネントを使用して、
サイドバーを実装します。
npx shadcn-ui@latest add sheet
npx shadcn-ui@latest add separator
app/(main)/protected/page.tsx
import { currentUser, UserProfile } from "@clerk/nextjs";
import { dark } from "@clerk/themes";
import Image from "next/image";
const ProtectedPage = async () => {
const user = await currentUser();
return (
<div className="flex flex-col p-10">
<ul className="flex flex-col p-6">
<li>
User Name: {user?.lastName} {user?.firstName}
</li>
<li>User Email: {user?.emailAddresses?.[0].emailAddress}</li>
<li className="flex gap-x-2">
User Image:{" "}
<Image src={user?.imageUrl!} width={30} height={30} alt="User" />
</li>
</ul>
<UserProfile
appearance={{
baseTheme: dark,
elements: {
card: {
// boxShadow: "none",
},
},
}}
/>
</div>
);
};
export default ProtectedPage;
app/(main)/layout.tsx
import React from "react";
import { MainNavbar } from "./_components/main-navbar";
import { MainSidebar } from "./_components/main-sidebar";
const MainLayout = ({ children }: { children: React.ReactNode }) => {
return (
<>
<MainNavbar />
<main className="flex w-full relative overflow-hidden overflow-y-auto">
<div className="w-[200px] shrink-0 hidden lg:block">
<MainSidebar />
</div>
{children}
</main>
</>
);
};
export default MainLayout;
app/(main)/_components/main-sidebar.tsx
import { Separator } from "@/components/ui/separator";
import { Database, Home, Image, User } from "lucide-react";
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>
<li className="flex items-center group text-neutral-600 dark:text-neutral-400 hover:bg-slate-700 rounded-sm p-2 cursor-pointer">
<Home className="h-5 w-5 mr-3 group-hover:text-white" />
<span className="group-hover:text-white">Home</span>
</li>
<li className="flex items-center group text-neutral-600 dark:text-neutral-400 hover:bg-slate-700 rounded-sm p-2 cursor-pointer">
<User className="h-5 w-5 mr-3 group-hover:text-white" />
<span className="group-hover:text-white">Account</span>
</li>
<li className="flex items-center group text-neutral-600 dark:text-neutral-400 hover:bg-slate-700 rounded-sm p-2 cursor-pointer">
<Image className="h-5 w-5 mr-3 group-hover:text-white" />
<span className="group-hover:text-white">Images</span>
</li>
<li className="flex items-center group text-neutral-600 dark:text-neutral-400 hover:bg-slate-700 rounded-sm p-2 cursor-pointer">
<Database className="h-5 w-5 mr-3 group-hover:text-white" />
<span className="group-hover:text-white">Data</span>
</li>
</ul>
</div>
</div>
);
};
app/(main)/_components/main-sidebar.tsx
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
import { MainSidebar } from "./main-sidebar";
import { Menu } from "lucide-react";
export const MainMobileSidebar = () => {
return (
<Sheet>
<SheetTrigger>
<Menu />
</SheetTrigger>
<SheetContent side="left" className="w-[240px] dark:bg-slate-900">
<div>Main Page</div>
<MainSidebar />
</SheetContent>
</Sheet>
);
};
app/(main)/_components/main-navbar.tsx
import { ModeToggle } from "@/components/mode-toggle-button";
import { UserButton } from "@clerk/nextjs";
import { MainMobileSidebar } from "./main-mobile-sidebar";
export const MainNavbar = () => {
return (
<nav className="w-full h-auto px-4 py-3 flex items-center justify-between bg-slate-200 dark:bg-slate-900">
<div className="hidden lg:block">Main Page</div>
<div className="block lg:hidden">
<MainMobileSidebar />
</div>
<div className="flex items-center justify-center gap-x-2">
<ModeToggle />
<UserButton afterSignOutUrl="/" />
</div>
</nav>
);
};
Discussion
いつも記事を参考にさせていただいています。
nextjs周りのclerkやshadcn-uiを利用した解説にとても感謝しております。
一つ問題が解決できず、質問させていただきます。
shadcn-uiのsheetに関してです。
desktop環境で常にsidebarが表示されている時は問題無いのですが、
mobile環境で、main-mobile-sidebarを表示させ、任意のリンクでurlを遷移させても、
main-mobile-sidebar自体は表示されたままとなる問題が発生しています。
通常urlが変われば、一旦sidebarは非表示としたいところですが、実現方法がわかりません。
Shadcn-ui sheetのページ
や、Radixのページ のページを参考に、<SheetClose asChild>の内側にbuttonやButtonを設置することでsheetをhideすることが、
可能なことは確認できましたが、そうすると記事内で多用されているnext/linkを使うことができず、
行き詰ってしまいました。
解決方法があれば、ご教授お願い致します。
追記:その後、<SheetClose asChild>内に<Link>(next/link)タグではなく、普通の<a>タグを置くことでsheetをhideすることを確認しました。釈然としませんが、先に進みたいと思います。
ありがとうございました。