From 367af786fa145225a00741c2d1de5a4d0c33d7c3 Mon Sep 17 00:00:00 2001 From: sumi-0011 Date: Tue, 7 Jan 2025 17:54:03 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20sidebar=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- src/app.tsx | 27 +- src/components/SideBar/NavMain.tsx | 75 +++ src/components/SideBar/NavProjects.tsx | 43 ++ src/components/SideBar/Sidebar.tsx | 79 +++ src/components/layout/index.tsx | 53 +- src/components/ui/breadcrumb.tsx | 115 ++++ src/components/ui/collapsible.tsx | 11 + src/components/ui/dropdown-menu.tsx | 198 +++++++ src/components/ui/separator.tsx | 29 + src/components/ui/sidebar.tsx | 765 +++++++++++++++++++++++++ src/hooks/use-mobile.tsx | 19 + src/pages/gallery/index.tsx | 2 +- src/styles/globals.less | 25 +- tailwind.config.js | 36 +- yarn.lock | 139 ++++- 16 files changed, 1585 insertions(+), 36 deletions(-) create mode 100644 src/components/SideBar/NavMain.tsx create mode 100644 src/components/SideBar/NavProjects.tsx create mode 100644 src/components/SideBar/Sidebar.tsx create mode 100644 src/components/ui/breadcrumb.tsx create mode 100644 src/components/ui/collapsible.tsx create mode 100644 src/components/ui/dropdown-menu.tsx create mode 100644 src/components/ui/separator.tsx create mode 100644 src/components/ui/sidebar.tsx create mode 100644 src/hooks/use-mobile.tsx diff --git a/package.json b/package.json index 06f496e2..a681ffbb 100644 --- a/package.json +++ b/package.json @@ -17,16 +17,19 @@ "dependencies": { "@loadable/component": "^5.15.3", "@radix-ui/react-alert-dialog": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.4", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-menubar": "^1.1.2", "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.3", + "@radix-ui/react-tooltip": "^1.1.6", "@supabase/supabase-js": "^2.45.4", "@tanstack/react-query": "^4.29.3", "@toss/react": "^1.7.0", diff --git a/src/app.tsx b/src/app.tsx index cfc7b00c..128e1a51 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -8,6 +8,7 @@ import ReactGA from "react-ga4"; import Home from "./pages/home"; import GalleryPage from "./pages/gallery"; import ErrorPage from "./components/error-page"; +import { Layout } from "./components/layout"; export default function App() { const queryClient = useMemo(() => new QueryClient({}), []); @@ -25,13 +26,25 @@ export default function App() { -
- - } /> - } /> - } /> - -
+ + + + + } + /> + + + + } + /> + } /> +
+ Services + + {items.map((item) => ( + + + + + {item.icon && } + + {item.title} + + + + + + + {item.items?.map((subItem) => ( + + + + {subItem.title} + + + + ))} + + + + + ))} + + + ); +} diff --git a/src/components/SideBar/NavProjects.tsx b/src/components/SideBar/NavProjects.tsx new file mode 100644 index 00000000..002c7407 --- /dev/null +++ b/src/components/SideBar/NavProjects.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { type LucideIcon } from "lucide-react"; + +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "src/components/ui/sidebar"; + +export function NavProjects({ + projects, +}: { + projects: { + name: string; + url: string; + icon: LucideIcon; + }[]; +}) { + const { isMobile } = useSidebar(); + + return ( + + Others + + {projects.map((item) => ( + + + + + {item.name} + + + + ))} + + + ); +} diff --git a/src/components/SideBar/Sidebar.tsx b/src/components/SideBar/Sidebar.tsx new file mode 100644 index 00000000..5b5317d3 --- /dev/null +++ b/src/components/SideBar/Sidebar.tsx @@ -0,0 +1,79 @@ +"use client"; + +import * as React from "react"; + +import { GalleryVerticalEnd, ImageIcon, SmileIcon } from "lucide-react"; + +import { NavMain } from "./NavMain"; +import { NavProjects } from "./NavProjects"; +import { + Sidebar, + SidebarContent, + SidebarGroup, + SidebarRail, + SidebarTrigger, + useSidebar, +} from "src/components/ui/sidebar"; +import { cn } from "src/lib/utils"; + +// This is sample data. +const data = { + user: { + name: "shadcn", + email: "marcexample.com", + avatar: "/avatars/shadcn.jpg", + }, + teams: [ + { + name: "space", + logo: GalleryVerticalEnd, + }, + ], + navMain: [ + { + title: "Thumbnail Maker", + url: "https://thumbnail.ssumi.space/", + icon: ImageIcon, + isActive: true, + items: [ + { + title: "Home", + url: "/", + }, + { + title: "Gallery", + url: "/gallery", + }, + { + title: "Github", + url: "https://github.com/sumi-0011/Thumbnail-Maker", + }, + ], + }, + ], + projects: [ + { + name: "Maker Contact", + url: "https://various.ssumi.space/maker", + icon: SmileIcon, + }, + ], +}; + +export function AppSidebar({ ...props }: React.ComponentProps) { + const { open } = useSidebar(); + return ( + + + + + + + + + + + ); +} diff --git a/src/components/layout/index.tsx b/src/components/layout/index.tsx index 43f50290..b5db8014 100644 --- a/src/components/layout/index.tsx +++ b/src/components/layout/index.tsx @@ -1,14 +1,59 @@ import React from "react"; import { Header } from "../header"; import Contact from "../contact/Contact"; +import { Separator } from "@radix-ui/react-select"; +import { AppSidebar } from "../SideBar/Sidebar"; +import { SidebarProvider, SidebarInset, SidebarTrigger } from "../ui/sidebar"; +import { + Breadcrumb, + BreadcrumbList, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbSeparator, + BreadcrumbPage, +} from "src/components/ui/breadcrumb"; export const getNoneLayout = (page: React.ReactElement) => page; export const getDefaultLayout = (page: React.ReactElement) => { return ( -
- {page} - -
+ + + +
+
+ + + + + + + Building Your Application + + + + + Data Fetching + + + +
+
+ {page} +
+
); }; + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + +
+ {children} +
+
+
+ ); +} diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx new file mode 100644 index 00000000..32a08bbb --- /dev/null +++ b/src/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "src/lib/utils" + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode + } +>(({ ...props }, ref) =>