created filter menu
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Vercel Preview Deployment / Deploy-Preview (push) Successful in 2m22s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Vercel Preview Deployment / Deploy-Preview (push) Successful in 2m22s
				
			This commit is contained in:
		
							parent
							
								
									d7ebcb8558
								
							
						
					
					
						commit
						a3586f3059
					
				
							
								
								
									
										138
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										138
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -8,6 +8,8 @@
 | 
			
		||||
      "name": "wine-shop",
 | 
			
		||||
      "version": "0.1.0",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@radix-ui/react-dropdown-menu": "^2.0.6",
 | 
			
		||||
        "@radix-ui/react-navigation-menu": "^1.1.4",
 | 
			
		||||
        "@radix-ui/react-select": "^2.0.0",
 | 
			
		||||
        "@radix-ui/react-slot": "^1.0.2",
 | 
			
		||||
        "@radix-ui/react-toast": "^1.1.5",
 | 
			
		||||
@ -1911,6 +1913,35 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-dropdown-menu": {
 | 
			
		||||
      "version": "2.0.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz",
 | 
			
		||||
      "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@babel/runtime": "^7.13.10",
 | 
			
		||||
        "@radix-ui/primitive": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-compose-refs": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-context": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-id": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-menu": "2.0.6",
 | 
			
		||||
        "@radix-ui/react-primitive": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-use-controllable-state": "1.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@types/react": "*",
 | 
			
		||||
        "@types/react-dom": "*",
 | 
			
		||||
        "react": "^16.8 || ^17.0 || ^18.0",
 | 
			
		||||
        "react-dom": "^16.8 || ^17.0 || ^18.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "@types/react": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "@types/react-dom": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-focus-guards": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
 | 
			
		||||
@ -1971,6 +2002,82 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-menu": {
 | 
			
		||||
      "version": "2.0.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz",
 | 
			
		||||
      "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@babel/runtime": "^7.13.10",
 | 
			
		||||
        "@radix-ui/primitive": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-collection": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-compose-refs": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-context": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-direction": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-dismissable-layer": "1.0.5",
 | 
			
		||||
        "@radix-ui/react-focus-guards": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-focus-scope": "1.0.4",
 | 
			
		||||
        "@radix-ui/react-id": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-popper": "1.1.3",
 | 
			
		||||
        "@radix-ui/react-portal": "1.0.4",
 | 
			
		||||
        "@radix-ui/react-presence": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-primitive": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-roving-focus": "1.0.4",
 | 
			
		||||
        "@radix-ui/react-slot": "1.0.2",
 | 
			
		||||
        "@radix-ui/react-use-callback-ref": "1.0.1",
 | 
			
		||||
        "aria-hidden": "^1.1.1",
 | 
			
		||||
        "react-remove-scroll": "2.5.5"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@types/react": "*",
 | 
			
		||||
        "@types/react-dom": "*",
 | 
			
		||||
        "react": "^16.8 || ^17.0 || ^18.0",
 | 
			
		||||
        "react-dom": "^16.8 || ^17.0 || ^18.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "@types/react": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "@types/react-dom": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-navigation-menu": {
 | 
			
		||||
      "version": "1.1.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz",
 | 
			
		||||
      "integrity": "sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@babel/runtime": "^7.13.10",
 | 
			
		||||
        "@radix-ui/primitive": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-collection": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-compose-refs": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-context": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-direction": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-dismissable-layer": "1.0.5",
 | 
			
		||||
        "@radix-ui/react-id": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-presence": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-primitive": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-use-callback-ref": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-use-controllable-state": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-use-layout-effect": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-use-previous": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-visually-hidden": "1.0.3"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@types/react": "*",
 | 
			
		||||
        "@types/react-dom": "*",
 | 
			
		||||
        "react": "^16.8 || ^17.0 || ^18.0",
 | 
			
		||||
        "react-dom": "^16.8 || ^17.0 || ^18.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "@types/react": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "@types/react-dom": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-popper": {
 | 
			
		||||
      "version": "1.1.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
 | 
			
		||||
@ -2073,6 +2180,37 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-roving-focus": {
 | 
			
		||||
      "version": "1.0.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
 | 
			
		||||
      "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@babel/runtime": "^7.13.10",
 | 
			
		||||
        "@radix-ui/primitive": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-collection": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-compose-refs": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-context": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-direction": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-id": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-primitive": "1.0.3",
 | 
			
		||||
        "@radix-ui/react-use-callback-ref": "1.0.1",
 | 
			
		||||
        "@radix-ui/react-use-controllable-state": "1.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@types/react": "*",
 | 
			
		||||
        "@types/react-dom": "*",
 | 
			
		||||
        "react": "^16.8 || ^17.0 || ^18.0",
 | 
			
		||||
        "react-dom": "^16.8 || ^17.0 || ^18.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "@types/react": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "@types/react-dom": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@radix-ui/react-select": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.0.0.tgz",
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,8 @@
 | 
			
		||||
    "start": "next start"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@radix-ui/react-dropdown-menu": "^2.0.6",
 | 
			
		||||
    "@radix-ui/react-navigation-menu": "^1.1.4",
 | 
			
		||||
    "@radix-ui/react-select": "^2.0.0",
 | 
			
		||||
    "@radix-ui/react-slot": "^1.0.2",
 | 
			
		||||
    "@radix-ui/react-toast": "^1.1.5",
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,8 @@
 | 
			
		||||
import FormCard from "./FormCard";
 | 
			
		||||
import FormCard from "./_components/FormCard";
 | 
			
		||||
 | 
			
		||||
export default function App() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="container flex w-full flex-col justify-center">
 | 
			
		||||
      <h1>Yes hello</h1>
 | 
			
		||||
      <FormCard />
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
@ -44,7 +44,7 @@ export default function CreateWine() {
 | 
			
		||||
    loadProducers();
 | 
			
		||||
  }, []);
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="container flex w-full flex-col">
 | 
			
		||||
    <div className="flex w-full flex-col">
 | 
			
		||||
      <form action={formAction} className="flex flex-col gap-2">
 | 
			
		||||
        <Input
 | 
			
		||||
          placeholder="Enter wine name"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								src/app/_components/FilterMenu.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/app/_components/FilterMenu.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
import {
 | 
			
		||||
  DropdownMenu,
 | 
			
		||||
  DropdownMenuContent,
 | 
			
		||||
  DropdownMenuItem,
 | 
			
		||||
  DropdownMenuLabel,
 | 
			
		||||
  DropdownMenuSeparator,
 | 
			
		||||
  DropdownMenuTrigger,
 | 
			
		||||
} from "~/components/ui/dropdown-menu";
 | 
			
		||||
import { Input } from "~/components/ui/input";
 | 
			
		||||
 | 
			
		||||
export default function Filtermenu() {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="container flex justify-center gap-4 py-4">
 | 
			
		||||
      {/* TODO:
 | 
			
		||||
        Checkboxes instead of menuitems. Check boxes are added as badges under the search bar */}
 | 
			
		||||
      <DropdownMenu>
 | 
			
		||||
        <DropdownMenuTrigger>Type</DropdownMenuTrigger>
 | 
			
		||||
        <DropdownMenuContent>
 | 
			
		||||
          <DropdownMenuItem>Sparkling</DropdownMenuItem>
 | 
			
		||||
          <DropdownMenuItem>White</DropdownMenuItem>
 | 
			
		||||
          <DropdownMenuItem>Red</DropdownMenuItem>
 | 
			
		||||
          <DropdownMenuItem>Sweet</DropdownMenuItem>
 | 
			
		||||
          <DropdownMenuItem>Fortified</DropdownMenuItem>
 | 
			
		||||
        </DropdownMenuContent>
 | 
			
		||||
      </DropdownMenu>
 | 
			
		||||
      {/* Producer filter */}
 | 
			
		||||
      <DropdownMenu>
 | 
			
		||||
        <DropdownMenuTrigger>Producer</DropdownMenuTrigger>
 | 
			
		||||
        <DropdownMenuContent>
 | 
			
		||||
          {/* For each producer have DropdownMenuItem. */}
 | 
			
		||||
          <Input name="searchString" placeholder="search for producer" />
 | 
			
		||||
          <DropdownMenuSeparator />
 | 
			
		||||
          <DropdownMenuItem>Store Henning</DropdownMenuItem>
 | 
			
		||||
        </DropdownMenuContent>
 | 
			
		||||
      </DropdownMenu>
 | 
			
		||||
      {/* Country filter */}
 | 
			
		||||
      <DropdownMenu>
 | 
			
		||||
        <DropdownMenuTrigger>Country</DropdownMenuTrigger>
 | 
			
		||||
        <DropdownMenuContent>
 | 
			
		||||
          {/* For each Country have DropdownMenuItem. */}
 | 
			
		||||
          <DropdownMenuItem>France</DropdownMenuItem>
 | 
			
		||||
        </DropdownMenuContent>
 | 
			
		||||
      </DropdownMenu>
 | 
			
		||||
      {/* Region filter */}
 | 
			
		||||
      <DropdownMenu>
 | 
			
		||||
        <DropdownMenuTrigger>Region</DropdownMenuTrigger>
 | 
			
		||||
        <DropdownMenuContent>
 | 
			
		||||
          {/* For each Region have DropdownMenuItem. Check for country filter */}
 | 
			
		||||
          <Input name="searchString" placeholder="search for region" />
 | 
			
		||||
          <DropdownMenuSeparator />
 | 
			
		||||
          <DropdownMenuItem>Bourgogne</DropdownMenuItem>
 | 
			
		||||
        </DropdownMenuContent>
 | 
			
		||||
      </DropdownMenu>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@ -2,6 +2,8 @@ import "~/styles/globals.css";
 | 
			
		||||
 | 
			
		||||
import { Inter as FontSans } from "next/font/google";
 | 
			
		||||
import { cn } from "~/lib/utils";
 | 
			
		||||
import TopNav from "./_components/FilterMenu";
 | 
			
		||||
import Filtermenu from "./_components/FilterMenu";
 | 
			
		||||
 | 
			
		||||
const fontSans = FontSans({
 | 
			
		||||
  subsets: ["latin"],
 | 
			
		||||
@ -23,10 +25,11 @@ export default function RootLayout({
 | 
			
		||||
    <html lang="en">
 | 
			
		||||
      <body
 | 
			
		||||
        className={cn(
 | 
			
		||||
          "bg-background min-h-screen font-sans antialiased",
 | 
			
		||||
          "min-h-screen bg-background font-sans antialiased",
 | 
			
		||||
          fontSans.variable,
 | 
			
		||||
        )}
 | 
			
		||||
      >
 | 
			
		||||
        <Filtermenu />
 | 
			
		||||
        {children}
 | 
			
		||||
      </body>
 | 
			
		||||
    </html>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import App from "./_components/App";
 | 
			
		||||
import App from "./App";
 | 
			
		||||
 | 
			
		||||
export default async function HomePage() {
 | 
			
		||||
  return (
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										200
									
								
								src/components/ui/dropdown-menu.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								src/components/ui/dropdown-menu.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,200 @@
 | 
			
		||||
"use client"
 | 
			
		||||
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
 | 
			
		||||
import { Check, ChevronRight, Circle } from "lucide-react"
 | 
			
		||||
 | 
			
		||||
import { cn } from "~/lib/utils"
 | 
			
		||||
 | 
			
		||||
const DropdownMenu = DropdownMenuPrimitive.Root
 | 
			
		||||
 | 
			
		||||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
 | 
			
		||||
 | 
			
		||||
const DropdownMenuGroup = DropdownMenuPrimitive.Group
 | 
			
		||||
 | 
			
		||||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSub = DropdownMenuPrimitive.Sub
 | 
			
		||||
 | 
			
		||||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSubTrigger = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
 | 
			
		||||
    inset?: boolean
 | 
			
		||||
  }
 | 
			
		||||
>(({ className, inset, children, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.SubTrigger
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
 | 
			
		||||
      inset && "pl-8",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    {children}
 | 
			
		||||
    <ChevronRight className="ml-auto h-4 w-4" />
 | 
			
		||||
  </DropdownMenuPrimitive.SubTrigger>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSubTrigger.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.SubTrigger.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSubContent = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.SubContent
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSubContent.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.SubContent.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuContent = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.Content>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
 | 
			
		||||
>(({ className, sideOffset = 4, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Portal>
 | 
			
		||||
    <DropdownMenuPrimitive.Content
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      sideOffset={sideOffset}
 | 
			
		||||
      className={cn(
 | 
			
		||||
        "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 | 
			
		||||
        className
 | 
			
		||||
      )}
 | 
			
		||||
      {...props}
 | 
			
		||||
    />
 | 
			
		||||
  </DropdownMenuPrimitive.Portal>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuItem = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.Item>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
 | 
			
		||||
    inset?: boolean
 | 
			
		||||
  }
 | 
			
		||||
>(({ className, inset, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Item
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      inset && "pl-8",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuCheckboxItem = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
 | 
			
		||||
>(({ className, children, checked, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.CheckboxItem
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    checked={checked}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
 | 
			
		||||
      <DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
        <Check className="h-4 w-4" />
 | 
			
		||||
      </DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
    </span>
 | 
			
		||||
    {children}
 | 
			
		||||
  </DropdownMenuPrimitive.CheckboxItem>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuCheckboxItem.displayName =
 | 
			
		||||
  DropdownMenuPrimitive.CheckboxItem.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuRadioItem = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
 | 
			
		||||
>(({ className, children, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.RadioItem
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
 | 
			
		||||
      <DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
        <Circle className="h-2 w-2 fill-current" />
 | 
			
		||||
      </DropdownMenuPrimitive.ItemIndicator>
 | 
			
		||||
    </span>
 | 
			
		||||
    {children}
 | 
			
		||||
  </DropdownMenuPrimitive.RadioItem>
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuLabel = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.Label>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
 | 
			
		||||
    inset?: boolean
 | 
			
		||||
  }
 | 
			
		||||
>(({ className, inset, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Label
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "px-2 py-1.5 text-sm font-semibold",
 | 
			
		||||
      inset && "pl-8",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuSeparator = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <DropdownMenuPrimitive.Separator
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn("-mx-1 my-1 h-px bg-muted", className)}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
 | 
			
		||||
 | 
			
		||||
const DropdownMenuShortcut = ({
 | 
			
		||||
  className,
 | 
			
		||||
  ...props
 | 
			
		||||
}: React.HTMLAttributes<HTMLSpanElement>) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <span
 | 
			
		||||
      className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
 | 
			
		||||
      {...props}
 | 
			
		||||
    />
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  DropdownMenu,
 | 
			
		||||
  DropdownMenuTrigger,
 | 
			
		||||
  DropdownMenuContent,
 | 
			
		||||
  DropdownMenuItem,
 | 
			
		||||
  DropdownMenuCheckboxItem,
 | 
			
		||||
  DropdownMenuRadioItem,
 | 
			
		||||
  DropdownMenuLabel,
 | 
			
		||||
  DropdownMenuSeparator,
 | 
			
		||||
  DropdownMenuShortcut,
 | 
			
		||||
  DropdownMenuGroup,
 | 
			
		||||
  DropdownMenuPortal,
 | 
			
		||||
  DropdownMenuSub,
 | 
			
		||||
  DropdownMenuSubContent,
 | 
			
		||||
  DropdownMenuSubTrigger,
 | 
			
		||||
  DropdownMenuRadioGroup,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										128
									
								
								src/components/ui/navigation-menu.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/components/ui/navigation-menu.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,128 @@
 | 
			
		||||
import * as React from "react"
 | 
			
		||||
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
 | 
			
		||||
import { cva } from "class-variance-authority"
 | 
			
		||||
import { ChevronDown } from "lucide-react"
 | 
			
		||||
 | 
			
		||||
import { cn } from "~/lib/utils"
 | 
			
		||||
 | 
			
		||||
const NavigationMenu = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.Root>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
 | 
			
		||||
>(({ className, children, ...props }, ref) => (
 | 
			
		||||
  <NavigationMenuPrimitive.Root
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "relative z-10 flex max-w-max flex-1 items-center justify-center",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    {children}
 | 
			
		||||
    <NavigationMenuViewport />
 | 
			
		||||
  </NavigationMenuPrimitive.Root>
 | 
			
		||||
))
 | 
			
		||||
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
 | 
			
		||||
 | 
			
		||||
const NavigationMenuList = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.List>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <NavigationMenuPrimitive.List
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "group flex flex-1 list-none items-center justify-center space-x-1",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
 | 
			
		||||
 | 
			
		||||
const NavigationMenuItem = NavigationMenuPrimitive.Item
 | 
			
		||||
 | 
			
		||||
const navigationMenuTriggerStyle = cva(
 | 
			
		||||
  "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const NavigationMenuTrigger = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
 | 
			
		||||
>(({ className, children, ...props }, ref) => (
 | 
			
		||||
  <NavigationMenuPrimitive.Trigger
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(navigationMenuTriggerStyle(), "group", className)}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    {children}{" "}
 | 
			
		||||
    <ChevronDown
 | 
			
		||||
      className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
 | 
			
		||||
      aria-hidden="true"
 | 
			
		||||
    />
 | 
			
		||||
  </NavigationMenuPrimitive.Trigger>
 | 
			
		||||
))
 | 
			
		||||
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
 | 
			
		||||
 | 
			
		||||
const NavigationMenuContent = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.Content>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <NavigationMenuPrimitive.Content
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  />
 | 
			
		||||
))
 | 
			
		||||
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
 | 
			
		||||
 | 
			
		||||
const NavigationMenuLink = NavigationMenuPrimitive.Link
 | 
			
		||||
 | 
			
		||||
const NavigationMenuViewport = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <div className={cn("absolute left-0 top-full flex justify-center")}>
 | 
			
		||||
    <NavigationMenuPrimitive.Viewport
 | 
			
		||||
      className={cn(
 | 
			
		||||
        "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
 | 
			
		||||
        className
 | 
			
		||||
      )}
 | 
			
		||||
      ref={ref}
 | 
			
		||||
      {...props}
 | 
			
		||||
    />
 | 
			
		||||
  </div>
 | 
			
		||||
))
 | 
			
		||||
NavigationMenuViewport.displayName =
 | 
			
		||||
  NavigationMenuPrimitive.Viewport.displayName
 | 
			
		||||
 | 
			
		||||
const NavigationMenuIndicator = React.forwardRef<
 | 
			
		||||
  React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
 | 
			
		||||
  React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
 | 
			
		||||
>(({ className, ...props }, ref) => (
 | 
			
		||||
  <NavigationMenuPrimitive.Indicator
 | 
			
		||||
    ref={ref}
 | 
			
		||||
    className={cn(
 | 
			
		||||
      "top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
 | 
			
		||||
      className
 | 
			
		||||
    )}
 | 
			
		||||
    {...props}
 | 
			
		||||
  >
 | 
			
		||||
    <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
 | 
			
		||||
  </NavigationMenuPrimitive.Indicator>
 | 
			
		||||
))
 | 
			
		||||
NavigationMenuIndicator.displayName =
 | 
			
		||||
  NavigationMenuPrimitive.Indicator.displayName
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  navigationMenuTriggerStyle,
 | 
			
		||||
  NavigationMenu,
 | 
			
		||||
  NavigationMenuList,
 | 
			
		||||
  NavigationMenuItem,
 | 
			
		||||
  NavigationMenuContent,
 | 
			
		||||
  NavigationMenuTrigger,
 | 
			
		||||
  NavigationMenuLink,
 | 
			
		||||
  NavigationMenuIndicator,
 | 
			
		||||
  NavigationMenuViewport,
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user