a tool for shared writing and social publishing
at main 2.8 kB view raw
1"use client"; 2import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; 3import { theme } from "tailwind.config"; 4import { NestedCardThemeProvider } from "./ThemeManager/ThemeProvider"; 5import { PopoverArrow } from "./Icons/PopoverArrow"; 6import { PopoverOpenContext } from "./Popover/PopoverContext"; 7import { useState } from "react"; 8 9export const Menu = (props: { 10 open?: boolean; 11 trigger: React.ReactNode; 12 children: React.ReactNode; 13 align?: "start" | "end" | "center" | undefined; 14 alignOffset?: number; 15 side?: "top" | "bottom" | "right" | "left" | undefined; 16 background?: string; 17 border?: string; 18 className?: string; 19 onOpenChange?: (o: boolean) => void; 20 asChild?: boolean; 21}) => { 22 let [open, setOpen] = useState(props.open || false); 23 24 return ( 25 <DropdownMenu.Root 26 onOpenChange={(o) => { 27 setOpen(o); 28 props.onOpenChange?.(o); 29 }} 30 open={props.open} 31 > 32 <PopoverOpenContext value={open}> 33 <DropdownMenu.Trigger asChild={props.asChild}> 34 {props.trigger} 35 </DropdownMenu.Trigger> 36 <DropdownMenu.Portal> 37 <NestedCardThemeProvider> 38 <DropdownMenu.Content 39 side={props.side ? props.side : "bottom"} 40 align={props.align ? props.align : "center"} 41 alignOffset={props.alignOffset ? props.alignOffset : undefined} 42 sideOffset={4} 43 collisionPadding={16} 44 className={` 45 dropdownMenu z-20 p-1 46 flex flex-col gap-0.5 47 bg-bg-page 48 border border-border rounded-md shadow-md 49 ${props.className}`} 50 > 51 {props.children} 52 <DropdownMenu.Arrow 53 asChild 54 width={16} 55 height={8} 56 viewBox="0 0 16 8" 57 > 58 <PopoverArrow 59 arrowFill={ 60 props.background 61 ? props.background 62 : theme.colors["bg-page"] 63 } 64 arrowStroke={ 65 props.border ? props.border : theme.colors["border"] 66 } 67 /> 68 </DropdownMenu.Arrow> 69 </DropdownMenu.Content> 70 </NestedCardThemeProvider> 71 </DropdownMenu.Portal> 72 </PopoverOpenContext> 73 </DropdownMenu.Root> 74 ); 75}; 76 77export const MenuItem = (props: { 78 children?: React.ReactNode; 79 className?: string; 80 onSelect: (e: Event) => void; 81 id?: string; 82}) => { 83 return ( 84 <DropdownMenu.Item 85 id={props.id} 86 onSelect={(event) => { 87 props.onSelect(event); 88 }} 89 className={` 90 menuItem 91 ${props.className} 92 `} 93 > 94 {props.children} 95 </DropdownMenu.Item> 96 ); 97};