Skip to content

Commit

Permalink
feat: menu
Browse files Browse the repository at this point in the history
  • Loading branch information
yongenaelf committed Jul 22, 2024
1 parent 1bf3702 commit f97e0ad
Show file tree
Hide file tree
Showing 8 changed files with 423 additions and 10 deletions.
10 changes: 5 additions & 5 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
Expand All @@ -22,8 +22,8 @@
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
--ring: 221.2 83.2% 53.3%;
--radius: 1rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
Expand All @@ -38,7 +38,7 @@
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
Expand All @@ -50,7 +50,7 @@
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
--ring: 224.3 76.3% 48%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
Expand Down
13 changes: 8 additions & 5 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { Poppins } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
import { MenubarComponent } from "@/components/menu";
import { PropsWithChildren } from "react";
import TopMenu from "@/components/top-menu";

const inter = Inter({ subsets: ["latin"] });
const font = Poppins({
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
subsets: ["latin"],
});

export const metadata: Metadata = {
title: "Create Next App",
Expand All @@ -15,14 +18,14 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: PropsWithChildren) {
return (
<html lang="en">
<body className={inter.className}>
<body className={font.className}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<MenubarComponent />
<TopMenu />
{children}
</ThemeProvider>
</body>
Expand Down
106 changes: 106 additions & 0 deletions components/top-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"use client";

import Link from "next/link";
import { Sheet, SheetTrigger, SheetContent } from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { MenuIcon, MoonIcon, SunIcon, SunMoonIcon } from "lucide-react";
import { useTheme } from "next-themes";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

export default function TopMenu() {
const { theme, setTheme } = useTheme();

return (
<header className="sticky top-0 z-50 w-full bg-background shadow-sm transition-colors dark:bg-background-dark">
<div className="container mx-auto flex h-16 items-center justify-between px-4 md:px-6">
<Link href="/" className="text-lg font-semibold">
AElf Playground
</Link>
<nav className="hidden space-x-4 md:flex">
<Link
href="/"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
>
Home
</Link>
<Link
href="/workspace-open"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
>
Workspaces
</Link>
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
Settings
</Link>
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
Contact
</Link>
</nav>
<div className="flex items-center space-x-4">
<ToggleGroup type="single" value={theme} onValueChange={setTheme}>
<ToggleGroupItem value="system" aria-label="Toggle system">
<SunMoonIcon className="h-5 w-5 transition-colors" />
</ToggleGroupItem>
<ToggleGroupItem value="light" aria-label="Toggle light">
<SunIcon className="h-5 w-5 transition-colors" />
</ToggleGroupItem>
<ToggleGroupItem value="dark" aria-label="Toggle dark">
<MoonIcon className="h-5 w-5 transition-colors" />
</ToggleGroupItem>
</ToggleGroup>
<Sheet>
<SheetTrigger asChild>
<Button variant="outline" size="icon" className="md:hidden">
<MenuIcon className="h-6 w-6" />
<span className="sr-only">Toggle navigation menu</span>
</Button>
</SheetTrigger>
<SheetContent
side="right"
className="w-full max-w-xs bg-background dark:bg-background-dark"
>
<div className="flex flex-col gap-4 p-4">
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
Home
</Link>
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
About
</Link>
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
Services
</Link>
<Link
href="#"
className="text-sm font-medium transition-colors hover:text-primary dark:hover:text-primary-dark"
prefetch={false}
>
Contact
</Link>
</div>
</SheetContent>
</Sheet>
</div>
</div>
</header>
);
}
140 changes: 140 additions & 0 deletions components/ui/sheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
"use client"

import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"

import { cn } from "@/lib/utils"

const Sheet = SheetPrimitive.Root

const SheetTrigger = SheetPrimitive.Trigger

const SheetClose = SheetPrimitive.Close

const SheetPortal = SheetPrimitive.Portal

const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName

const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)

interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}

const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
{children}
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName

const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"

const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"

const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName

const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName

export {
Sheet,
SheetPortal,
SheetOverlay,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}
61 changes: 61 additions & 0 deletions components/ui/toggle-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client"

import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"

const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
})

const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn("flex items-center justify-center gap-1", className)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
))

ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName

const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext)

return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
})

ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName

export { ToggleGroup, ToggleGroupItem }
Loading

0 comments on commit f97e0ad

Please sign in to comment.