From 5b7ccf0b671e2999b62befc729a3e517a0433728 Mon Sep 17 00:00:00 2001 From: Bertrand Yuan Date: Mon, 15 Dec 2025 23:48:10 +0800 Subject: initial commit -- the front-end prototype The initial code is base on Anirudh's work. More to see at: https://github.com/techwithanirudh/shadcn-blog Therefore, the code in this commit is under MIT license. --- src/components/sections/header/menu.tsx | 120 ++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/components/sections/header/menu.tsx (limited to 'src/components/sections/header/menu.tsx') diff --git a/src/components/sections/header/menu.tsx b/src/components/sections/header/menu.tsx new file mode 100644 index 0000000..57ddf12 --- /dev/null +++ b/src/components/sections/header/menu.tsx @@ -0,0 +1,120 @@ +'use client'; + +import { cva } from 'class-variance-authority'; +import Link from 'fumadocs-core/link'; +import { cn } from 'fumadocs-ui/components/api'; +import { buttonVariants } from 'fumadocs-ui/components/ui/button'; +import { + NavigationMenuContent, + NavigationMenuItem, + NavigationMenuLink, + NavigationMenuTrigger, +} from 'fumadocs-ui/components/ui/navigation-menu'; +import { BaseLinkItem, type LinkItemType } from 'fumadocs-ui/layouts/links'; +import type { ComponentPropsWithoutRef } from 'react'; + +const menuItemVariants = cva('', { + variants: { + variant: { + main: 'inline-flex items-center gap-2 py-1.5 transition-colors hover:text-fd-popover-foreground/50 data-[active=true]:font-medium data-[active=true]:text-fd-primary [&_svg]:size-4', + icon: buttonVariants({ + size: 'icon', + color: 'ghost', + }), + button: buttonVariants({ + color: 'secondary', + className: 'gap-1.5 [&_svg]:size-4', + }), + }, + }, + defaultVariants: { + variant: 'main', + }, +}); + +export const MenuLinkItem = ({ + item, + ...props +}: { + item: LinkItemType; + className?: string; +}) => { + if (item.type === 'custom') + return
{item.children}
; + + if (item.type === 'menu') { + const header = ( + <> + {item.icon} + {item.text} + + ); + + return ( +
+

+ {item.url ? ( + + {header} + + ) : ( + header + )} +

+ {item.items.map((child, i) => ( + + ))} +
+ ); + } + + return ( + + + {item.icon} + {item.type === 'icon' ? undefined : item.text} + + + ); +}; + +export const Menu = NavigationMenuItem; + +export const MenuTrigger = ({ + ...props +}: ComponentPropsWithoutRef & {}) => { + return ( + + {props.children} + + ); +}; + +export const MenuContent = ( + props: ComponentPropsWithoutRef, +) => { + return ( + + {props.children} + + ); +}; -- cgit v1.2.3