BlocksSheets
Basic Sheet
A basic mobile navigation menu.
Preview
Loading...
Installation
Install the following dependencies:
npm install lucide-reactInstall the following registry dependencies:
npx shadcn@latest add @ndk/hooks-use-open @ndk/hooks-use-pathname button sheet @ndk/components-social-iconsCopy and paste the following code into your project:
"use client";
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
SheetTrigger,
} from "@/components/ui/sheet";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { usePathName } from "@/hooks/use-pathname";
import { useOpen } from "@/hooks/use-open";
import {
GithubIcon,
LinkedinIcon,
XTwitterIcon,
} from "@/components/_ui/social-icons";
import { socialLinks as slinks } from "@/app/_assets/constants";
import { Building2, Component, ShoppingBag, ToolCase } from "lucide-react";
export const NavLinks = [
{
name: "Services",
url: "#",
icon: <ToolCase size={16} />,
},
{
name: "Features",
url: "#",
icon: <Component size={16} />,
},
{
name: "Blocks",
url: "/blocks",
icon: <Building2 size={16} />,
},
{
name: "Marketplace",
url: "#",
icon: <ShoppingBag size={16} />,
},
];
const SocialIcons = () => {
return (
<div className="_icon-list my-5 flex items-center justify-center gap-3">
<GithubIcon url={slinks.github} className="text-neutral-500" />
<XTwitterIcon url={slinks.twitter} className="text-neutral-500" />
<LinkedinIcon url={slinks.linkedin} className="text-neutral-500" />
</div>
);
};
export function BasicSheet({
side = "left",
mobileOnly = true,
}: {
side?: "left" | "top" | "right" | "bottom" | undefined;
mobileOnly?: boolean;
}) {
const isActive = usePathName();
const { handleClick, open, setOpen } = useOpen();
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild>
<Button
className={`group size-8 ${mobileOnly ? "md:hidden" : ""}`}
variant="ghost"
size="icon"
>
<svg
className="pointer-events-none"
width={16}
height={16}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 12L20 12"
className="origin-center -translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-x-0 group-aria-expanded:translate-y-0 group-aria-expanded:rotate-315"
/>
<path
d="M4 12H20"
className="origin-center transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.8)] group-aria-expanded:rotate-45"
/>
<path
d="M4 12H20"
className="origin-center translate-y-[7px] transition-all duration-300 ease-[cubic-bezier(.5,.85,.25,1.1)] group-aria-expanded:translate-y-0 group-aria-expanded:rotate-135"
/>
</svg>
</Button>
</SheetTrigger>
<SheetContent
side={side}
className={`_sheet-content _ui bg-background text-foreground p-5 pt-3 pl-5 ${mobileOnly ? "md:hidden" : ""}`}
>
<SheetHeader aria-hidden className="">
<SheetTitle className="text-xl">Basic Sheet</SheetTitle>
<SheetDescription>A simple shadcn/ui sheet.</SheetDescription>
</SheetHeader>
<div className="sheet-content mx-auto mb-auto flex w-[90%] max-w-[450px] flex-col gap-3 text-[13px]">
<hr className="_line absolute left-0 mt-8 h-1 w-full" />
<nav className="_sheet-links mt-15">
<ul onClick={handleClick} className="space-y-3">
{NavLinks.map((link) => (
<li key={link.name.toString().slice(0, 5)}>
<Link
href={link.url}
id="navLink"
className={`sheet-link hover:bg-primary/50 dark:hover:bg-primary/15 flex items-center gap-1 rounded-md p-2 px-3 hover:text-white ${
isActive(link.url)
? "bg-primary dark:bg-primary/20 font-[600] text-white"
: ""
}`}
>
<span className="mr-2">{link.icon}</span>
{link.name}
</Link>
</li>
))}
</ul>
</nav>
<div className="_social-icons mt-15 flex flex-col">
<hr className="mt-3" />
<SocialIcons />
</div>
</div>
</SheetContent>
</Sheet>
);
}Update the import paths to match your project setup.
Props
Prop
Type