import classNames from 'classnames'; import type { ComponentProps, ReactNode } from 'react'; import { useLayoutEffect } from 'react'; import { useContext } from 'react'; import { useRef } from 'react'; import { VegaLogo } from '../vega-logo'; import * as NavigationMenu from '@radix-ui/react-navigation-menu'; import { VegaIcon, VegaIconNames } from '../icon'; import { Drawer } from '../drawer'; import { NavLink } from 'react-router-dom'; import type { NavigationElementProps, NavigationProps, } from './navigation-utils'; import { setSizeVariantClasses } from './navigation-utils'; import { NavigationBreakpoint, NavigationContext } from './navigation-utils'; import { NavigationDrawerTrigger, NavigationDrawerContext, useNavigationDrawer, NavigationDrawerContent, } from './navigation-drawer'; const Logo = ({ appName, homeLink, }: Pick) => { const { theme } = useContext(NavigationContext); return (
{homeLink ? ( ) : ( )} {appName && ( {appName} )}
); }; const determineIfHidden = ({ hide, hideInDrawer }: NavigationElementProps) => [ { '[.nav-size-full_.navbar_&]:hidden': Array.isArray(hide) && hide?.includes(NavigationBreakpoint.Full), '[.nav-size-narrow_.navbar_&]:hidden': Array.isArray(hide) && hide?.includes(NavigationBreakpoint.Narrow), '[.nav-size-small_.navbar_&]:hidden': Array.isArray(hide) && hide?.includes(NavigationBreakpoint.Small), '[.drawer-content_&]:hidden': hideInDrawer, }, ]; const Spacer = () => ; export const NavigationItem = ({ children, className, hide, hideInDrawer, ...props }: ComponentProps & NavigationElementProps) => { const insideDrawer = useContext(NavigationDrawerContext); return ( {children} ); }; export const NavigationList = ({ children, className, hide, hideInDrawer, ...props }: ComponentProps & NavigationElementProps) => { const insideDrawer = useContext(NavigationDrawerContext); if (!insideDrawer && hide === true) { return null; } return ( {children} ); }; export const NavigationTrigger = ({ children, className, isActive = false, hide, hideInDrawer, ...props }: ComponentProps & { isActive?: boolean; } & NavigationElementProps) => { const { theme } = useContext(NavigationContext); const insideDrawer = useContext(NavigationDrawerContext); return ( e.preventDefault()} // disables hover onPointerLeave={(e) => e.preventDefault()} // disables hover disabled={insideDrawer} {...props} > {children} ); }; export const NavigationContent = ({ children, className, ...props }: ComponentProps) => { const { theme } = useContext(NavigationContext); const insideDrawer = useContext(NavigationDrawerContext); const content = ( e.preventDefault()} // disables hover asChild {...props} >
{children}
); const list = (
{children}
); return insideDrawer ? list : content; }; export const NavigationLink = ({ children, to, ...props }: ComponentProps) => { const { theme } = useContext(NavigationContext); const setDrawerOpen = useNavigationDrawer((state) => state.setDrawerOpen); return ( { setDrawerOpen(false); }} > {({ isActive }) => ( <> {children as ReactNode} )} ); }; export const Navigation = ({ appName, homeLink = '/', children, actions, theme = 'system', breakpoints = [478, 1000], onResize, }: NavigationProps) => { const navigationRef = useRef(null); const actionsRef = useRef(null); useLayoutEffect(() => { if (!navigationRef.current) return; const target = navigationRef.current; const currentWidth = Math.min( target.getBoundingClientRect().width, window.innerWidth ); setSizeVariantClasses(breakpoints, currentWidth, target); onResize?.(currentWidth, target); const handler = () => { const currentWidth = Math.min( target.getBoundingClientRect().width, window.innerWidth ); setSizeVariantClasses(breakpoints, currentWidth, target); onResize?.(currentWidth, target); }; window.addEventListener('resize', handler); return () => { window.removeEventListener('resize', handler); }; }, [breakpoints, onResize]); const { drawerOpen, setDrawerOpen } = useNavigationDrawer((state) => ({ drawerOpen: state.drawerOpen, setDrawerOpen: state.setDrawerOpen, })); return (
{children}
{(actions || children) && (
{actions} setDrawerOpen(isOpen)} trigger={} container={actionsRef.current} > {children}
)}
); };