Skip to content

Instantly share code, notes, and snippets.

@sturmenta
Last active October 14, 2024 20:30
Show Gist options
  • Save sturmenta/2dc2006ee17a8529fc63535b82626721 to your computer and use it in GitHub Desktop.
Save sturmenta/2dc2006ee17a8529fc63535b82626721 to your computer and use it in GitHub Desktop.
Sidebar for mobile and desktop using shadcn-ui
"use client"
import { WithSidebar } from "@/components/with-sidebar"
export const Dashboard = () => {
return (
<WithSidebar
sidebarContent={SidebarContent}
mobileDashboardHeader={CustomHeader}>
<div className="p-10">
<p>dashboard</p>
</div>
</WithSidebar>
)
}
const CustomHeader = () => {
return (
<div className="flex px-4">
<span className="text-2xl font-extrabold">Floop</span>
</div>
)
}
const SidebarContent = () => {
return (
<div>
<CustomHeader />
<div className="mt-6">
{["Inicio", "Preguntas"].map((item, index) => (
<a
key={index}
href="#"
className="block rounded px-4 py-2.5 transition duration-200 hover:bg-cyan-900">
{item}
</a>
))}
</div>
</div>
)
}
import { MenuIcon } from "lucide-react"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
export const WithMobileSidebar = ({
children,
sidebarContent: SidebarContent,
mobileDashboardHeader: MobileDashboardHeader
}: {
children: React.ReactNode
sidebarContent: () => JSX.Element
mobileDashboardHeader?: () => JSX.Element
}) => {
return (
<>
<Sheet>
<div className="mt-5 flex md:hidden">
<div className="flex flex-1">
{MobileDashboardHeader && <MobileDashboardHeader />}
</div>
<SheetTrigger>
<MenuIcon size={24} />
</SheetTrigger>
</div>
<SheetContent side="left">
<SidebarContent />
</SheetContent>
</Sheet>
{children}
</>
)
}
// ─────────────────────────────────────────────────────────────────────────────
const WithDesktopSidebar = ({
children,
sidebarContent: SidebarContent
}: {
children: React.ReactNode
sidebarContent: () => JSX.Element
}) => {
return (
// style used from here -> https://github.com/shadcn-ui/ui/blob/1cf5fad881b1da8f96923b7ad81d22d0aa3574b9/apps/www/app/docs/layout.tsx#L12
<div className="container h-screen flex-1 items-start md:grid md:grid-cols-[220px_minmax(0,1fr)] md:gap-6 lg:grid-cols-[240px_minmax(0,1fr)] lg:gap-10">
<aside className="fixed top-14 z-30 -ml-2 hidden h-screen w-full shrink-0 border-r md:sticky md:block">
<div className="h-full py-6 pl-8 pr-6 lg:py-8">
<SidebarContent />
</div>
</aside>
{children}
</div>
)
}
// ─────────────────────────────────────────────────────────────────────────────
export const WithSidebar = ({
children,
...props
}: {
children: React.ReactNode
sidebarContent: () => JSX.Element
mobileDashboardHeader?: () => JSX.Element
}) => {
return (
<WithDesktopSidebar {...props}>
<WithMobileSidebar {...props}>{children}</WithMobileSidebar>
</WithDesktopSidebar>
)
}
@sturmenta
Copy link
Author

video preview:

Screen.Recording.2023-11-28.at.17.09.05.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment