@fragments-sdk/ui 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codeblock.cjs +25 -29
- package/dist/codeblock.cjs.map +1 -1
- package/dist/codeblock.js +25 -29
- package/dist/codeblock.js.map +1 -1
- package/dist/components/Chip/index.cjs +2 -1
- package/dist/components/Chip/index.cjs.map +1 -1
- package/dist/components/Chip/index.d.ts.map +1 -1
- package/dist/components/Chip/index.js +2 -1
- package/dist/components/Chip/index.js.map +1 -1
- package/dist/components/CodeBlock/index.d.ts.map +1 -1
- package/dist/components/Command/index.cjs +6 -0
- package/dist/components/Command/index.cjs.map +1 -1
- package/dist/components/Command/index.d.ts.map +1 -1
- package/dist/components/Command/index.js +6 -0
- package/dist/components/Command/index.js.map +1 -1
- package/dist/components/DataTable/index.cjs +26 -26
- package/dist/components/DataTable/index.cjs.map +1 -1
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/index.js +26 -26
- package/dist/components/DataTable/index.js.map +1 -1
- package/dist/components/Listbox/index.cjs +6 -0
- package/dist/components/Listbox/index.cjs.map +1 -1
- package/dist/components/Listbox/index.d.ts.map +1 -1
- package/dist/components/Listbox/index.js +6 -0
- package/dist/components/Listbox/index.js.map +1 -1
- package/dist/components/Loading/index.cjs +2 -12
- package/dist/components/Loading/index.cjs.map +1 -1
- package/dist/components/Loading/index.d.ts.map +1 -1
- package/dist/components/Loading/index.js +2 -12
- package/dist/components/Loading/index.js.map +1 -1
- package/dist/components/NavigationMenu/index.cjs +12 -1
- package/dist/components/NavigationMenu/index.cjs.map +1 -1
- package/dist/components/NavigationMenu/index.d.ts.map +1 -1
- package/dist/components/NavigationMenu/index.js +12 -1
- package/dist/components/NavigationMenu/index.js.map +1 -1
- package/dist/components/Skeleton/index.cjs +3 -3
- package/dist/components/Skeleton/index.cjs.map +1 -1
- package/dist/components/Skeleton/index.js +3 -3
- package/dist/components/Skeleton/index.js.map +1 -1
- package/dist/components/Stack/index.cjs +4 -3
- package/dist/components/Stack/index.cjs.map +1 -1
- package/dist/components/Stack/index.d.ts.map +1 -1
- package/dist/components/Stack/index.js +4 -3
- package/dist/components/Stack/index.js.map +1 -1
- package/dist/markdown.cjs +1 -1
- package/dist/markdown.cjs.map +1 -1
- package/dist/markdown.js +1 -1
- package/dist/markdown.js.map +1 -1
- package/fragments.json +1 -1
- package/package.json +1 -1
- package/src/components/Chip/index.tsx +3 -1
- package/src/components/CodeBlock/index.tsx +35 -41
- package/src/components/ColorPicker/ColorPicker.fragment.tsx +17 -15
- package/src/components/Command/index.tsx +1 -0
- package/src/components/DataTable/index.tsx +45 -45
- package/src/components/Listbox/index.tsx +1 -0
- package/src/components/Loading/index.tsx +6 -12
- package/src/components/Markdown/index.tsx +2 -2
- package/src/components/Menu/Menu.fragment.tsx +17 -15
- package/src/components/NavigationMenu/index.tsx +6 -1
- package/src/components/Skeleton/index.tsx +3 -3
- package/src/components/Slider/Slider.fragment.tsx +19 -17
- package/src/components/Stack/index.tsx +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/components/NavigationMenu/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { CaretDown, CaretRight, List, X } from '@phosphor-icons/react';\nimport { handleArrowNavigation, useFocusTrap } from '../../utils/a11y';\nimport { Collapsible } from '../Collapsible';\nimport { ScrollArea } from '../ScrollArea';\nimport {\n NavigationMenuContext,\n NavigationMenuItemContext,\n useNavigationMenuContext,\n useNavigationMenuItemContext,\n type NavigationMenuItemInfo,\n} from './NavigationMenuContext';\nimport { useNavigationMenu } from './useNavigationMenu';\nimport styles from './NavigationMenu.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface NavigationMenuProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode;\n /** Controlled open item value */\n value?: string;\n /** Default open item value */\n defaultValue?: string;\n /** Callback when open item changes */\n onValueChange?: (value: string) => void;\n /** Menu orientation */\n orientation?: 'horizontal' | 'vertical';\n /** Delay before opening on hover (ms) */\n delayDuration?: number;\n /** Duration to skip delays between triggers (ms) */\n skipDelayDuration?: number;\n}\n\nexport interface NavigationMenuListProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuItemProps {\n children: React.ReactNode;\n /** Unique item value (required for items with Trigger+Content) */\n value?: string;\n className?: string;\n}\n\nexport interface NavigationMenuTriggerProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuContentProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Simple mode: children as text content */\n children?: React.ReactNode;\n /** Structured mode: title text */\n title?: string;\n /** Structured mode: description text */\n description?: string;\n /** Structured mode: icon element */\n icon?: React.ReactNode;\n /** Whether this link is the current page */\n active?: boolean;\n /** Highlighted card style */\n featured?: boolean;\n /** Render as child element (polymorphic) */\n asChild?: boolean;\n}\n\nexport interface NavigationMenuIndicatorProps {\n className?: string;\n}\n\nexport interface NavigationMenuViewportProps {\n className?: string;\n}\n\nexport interface NavigationMenuMobileContentProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileBrandProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileSectionProps {\n children: React.ReactNode;\n /** Section heading label */\n label?: string;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mq = window.matchMedia('(max-width: 767px)');\n setIsMobile(mq.matches);\n\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isMobile;\n}\n\n// ============================================\n// Root\n// ============================================\n\nfunction NavigationMenuRoot({\n children,\n value: controlledValue,\n defaultValue,\n onValueChange,\n orientation = 'horizontal',\n delayDuration = 200,\n skipDelayDuration = 300,\n className,\n 'aria-label': ariaLabel = 'Main navigation',\n ...htmlProps\n}: NavigationMenuProps) {\n const rootId = React.useId();\n const isMobile = useIsMobile();\n\n const state = useNavigationMenu({\n value: controlledValue,\n defaultValue,\n onValueChange,\n delayDuration,\n skipDelayDuration,\n });\n\n const classes = [\n styles.root,\n orientation === 'vertical' && styles.rootVertical,\n className,\n ].filter(Boolean).join(' ');\n\n const contextValue = React.useMemo(\n () => ({\n ...state,\n orientation,\n isMobile,\n rootId,\n }),\n [state, orientation, isMobile, rootId]\n );\n\n return (\n <NavigationMenuContext.Provider value={contextValue}>\n <nav {...htmlProps} className={classes} aria-label={ariaLabel} data-orientation={orientation}>\n {children}\n {isMobile && <MobileHamburger />}\n {isMobile && state.mobileOpen && <MobileDrawer />}\n </nav>\n </NavigationMenuContext.Provider>\n );\n}\n\n// ============================================\n// List\n// ============================================\n\nfunction NavigationMenuList({ children, className }: NavigationMenuListProps) {\n const { orientation, triggerOrder, triggerRefs, value } = useNavigationMenuContext();\n\n const listRef = React.useRef<HTMLUListElement>(null);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const order = triggerOrder.current;\n const currentIdx = order.indexOf(value);\n\n const newIdx = handleArrowNavigation(e, order, currentIdx >= 0 ? currentIdx : 0, {\n orientation: orientation === 'horizontal' ? 'horizontal' : 'vertical',\n loop: true,\n });\n\n if (newIdx !== undefined) {\n const targetValue = order[newIdx];\n const trigger = triggerRefs.current.get(targetValue);\n trigger?.focus();\n }\n };\n\n const classes = [\n styles.list,\n orientation === 'vertical' && styles.listVertical,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <ul\n ref={listRef}\n className={classes}\n role=\"list\"\n data-orientation={orientation}\n onKeyDown={handleKeyDown}\n >\n {children}\n </ul>\n );\n}\n\n// ============================================\n// Item\n// ============================================\n\nlet itemCounter = 0;\n\nfunction NavigationMenuItem({ children, value: valueProp, className }: NavigationMenuItemProps) {\n const rootCtx = useNavigationMenuContext();\n const [autoValue] = React.useState(() => valueProp || `navmenu-item-${++itemCounter}`);\n const triggerId = `${rootCtx.rootId}-trigger-${autoValue}`;\n const contentId = `${rootCtx.rootId}-content-${autoValue}`;\n\n const itemCtx = React.useMemo(\n () => ({\n value: autoValue,\n triggerId,\n contentId,\n }),\n [autoValue, triggerId, contentId]\n );\n\n return (\n <NavigationMenuItemContext.Provider value={itemCtx}>\n <li className={className}>{children}</li>\n </NavigationMenuItemContext.Provider>\n );\n}\n\n// ============================================\n// Trigger\n// ============================================\n\nfunction NavigationMenuTrigger({ children, className }: NavigationMenuTriggerProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n\n // Register trigger\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n React.useEffect(() => {\n if (triggerRef.current) {\n ctx.triggerRefs.current.set(itemCtx.value, triggerRef.current);\n if (!ctx.triggerOrder.current.includes(itemCtx.value)) {\n ctx.triggerOrder.current.push(itemCtx.value);\n }\n }\n return () => {\n ctx.triggerRefs.current.delete(itemCtx.value);\n ctx.triggerOrder.current = ctx.triggerOrder.current.filter(v => v !== itemCtx.value);\n };\n // Only register/unregister on mount/unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value]);\n\n // Register item info for mobile drawer\n React.useEffect(() => {\n const label = typeof children === 'string' ? children : '';\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: label || existing?.triggerLabel || '',\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n const handleClick = () => {\n ctx.setValue(isOpen ? '' : itemCtx.value);\n };\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n\n // Skip delay if recently open\n if (ctx.isRecentlyOpenRef.current) {\n ctx.setValue(itemCtx.value);\n return;\n }\n\n ctx.openTimerRef.current = setTimeout(() => {\n ctx.setValue(itemCtx.value);\n }, ctx.delayDuration);\n };\n\n const handlePointerLeave = () => {\n if (ctx.openTimerRef.current) {\n clearTimeout(ctx.openTimerRef.current);\n ctx.openTimerRef.current = null;\n }\n\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n ctx.setValue(isOpen ? '' : itemCtx.value);\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n ctx.setValue('');\n triggerRef.current?.focus();\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n return (\n <button\n ref={triggerRef}\n type=\"button\"\n id={itemCtx.triggerId}\n className={classes}\n aria-expanded={isOpen}\n aria-controls={itemCtx.contentId}\n data-state={isOpen ? 'open' : 'closed'}\n onClick={handleClick}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n onKeyDown={handleKeyDown}\n >\n {children}\n <CaretDown size={12} className={styles.triggerChevron} aria-hidden />\n </button>\n );\n}\n\n// ============================================\n// Content\n// ============================================\n\nfunction NavigationMenuContent({ children, className }: NavigationMenuContentProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // Register content children into item info (for mobile drawer)\n React.useEffect(() => {\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: existing?.triggerLabel || '',\n contentChildren: children,\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n // Measure content for viewport animation\n React.useEffect(() => {\n if (!isOpen || !contentRef.current) return;\n\n const el = contentRef.current;\n const observer = new ResizeObserver(([entry]) => {\n if (entry) {\n ctx.setViewportSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n });\n observer.observe(el);\n\n // Initial measurement\n ctx.setViewportSize({\n width: el.scrollWidth,\n height: el.scrollHeight,\n });\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n // Determine motion direction\n const prevValue = ctx.previousValue.current;\n const triggerOrder = ctx.triggerOrder.current;\n const prevIdx = triggerOrder.indexOf(prevValue);\n const currentIdx = triggerOrder.indexOf(itemCtx.value);\n let motion: string | undefined;\n if (isOpen && prevValue && prevValue !== itemCtx.value) {\n motion = currentIdx > prevIdx ? 'from-end' : 'from-start';\n }\n\n // Update previousValue when this content becomes active\n React.useEffect(() => {\n if (isOpen) {\n ctx.previousValue.current = itemCtx.value;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, itemCtx.value]);\n\n if (!isOpen) return null;\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n };\n\n const handlePointerLeave = () => {\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const contentElement = (\n <div\n ref={contentRef}\n id={itemCtx.contentId}\n className={classes}\n role=\"region\"\n aria-labelledby={itemCtx.triggerId}\n data-motion={motion}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </div>\n );\n\n // Portal into viewport if it exists\n if (ctx.viewportRef.current) {\n return createPortal(contentElement, ctx.viewportRef.current);\n }\n\n return contentElement;\n}\n\n// ============================================\n// Link\n// ============================================\n\nfunction NavigationMenuLink({\n children,\n title,\n description,\n icon,\n active = false,\n featured = false,\n asChild = false,\n className,\n href,\n onClick,\n ...htmlProps\n}: NavigationMenuLinkProps) {\n const ctx = React.useContext(NavigationMenuContext);\n const isStructured = !!(title || description || icon);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n // Close mobile drawer on link click\n if (ctx?.isMobile && ctx.mobileOpen) {\n ctx.setMobileOpen(false);\n }\n // Close desktop menu\n if (ctx) {\n ctx.setValue('');\n }\n };\n\n // Structured mode (title + description + icon)\n if (isStructured) {\n const classes = [\n styles.link,\n styles.linkStructured,\n active && styles.linkActive,\n featured && styles.linkFeatured,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n children: (\n <>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </>\n ),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return (\n <a {...linkProps}>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </a>\n );\n }\n\n // Simple link mode\n const classes = [\n styles.link,\n active && styles.linkActive,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return <a {...linkProps}>{children}</a>;\n}\n\n// ============================================\n// Indicator\n// ============================================\n\nfunction NavigationMenuIndicator({ className }: NavigationMenuIndicatorProps) {\n const { value, triggerRefs } = useNavigationMenuContext();\n const [style, setStyle] = React.useState<React.CSSProperties>({ opacity: 0 });\n\n React.useEffect(() => {\n if (!value) {\n setStyle({ opacity: 0 });\n return;\n }\n const trigger = triggerRefs.current.get(value);\n if (trigger) {\n const parent = trigger.closest('ul');\n if (parent) {\n const parentRect = parent.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setStyle({\n left: triggerRect.left - parentRect.left,\n width: triggerRect.width,\n opacity: 1,\n });\n }\n }\n }, [value, triggerRefs]);\n\n const classes = [styles.indicator, className].filter(Boolean).join(' ');\n\n return <div className={classes} style={style} aria-hidden />;\n}\n\n// ============================================\n// Viewport\n// ============================================\n\nfunction NavigationMenuViewport({ className }: NavigationMenuViewportProps) {\n const ctx = useNavigationMenuContext();\n const { viewportSize, viewportRef, value, triggerRefs } = ctx;\n const isOpen = !!value;\n\n // Compute the active trigger's left offset relative to the nav root\n const [triggerLeft, setTriggerLeft] = React.useState(0);\n\n React.useEffect(() => {\n if (!isOpen || !value) return;\n const trigger = triggerRefs.current.get(value);\n if (!trigger || !viewportRef.current) return;\n\n const navRoot = viewportRef.current.parentElement;\n if (!navRoot) return;\n\n const navRect = navRoot.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setTriggerLeft(triggerRect.left - navRect.left);\n }, [isOpen, value, triggerRefs, viewportRef]);\n\n const cssVars = {\n '--fui-navmenu-viewport-width': isOpen ? `${viewportSize.width}px` : '0px',\n '--fui-navmenu-viewport-height': isOpen ? `${viewportSize.height}px` : '0px',\n '--fui-navmenu-viewport-left': `${triggerLeft}px`,\n } as React.CSSProperties;\n\n // Mark skip-delay state\n React.useEffect(() => {\n if (isOpen) {\n ctx.isRecentlyOpenRef.current = true;\n if (ctx.skipDelayTimerRef.current) {\n clearTimeout(ctx.skipDelayTimerRef.current);\n }\n } else {\n ctx.skipDelayTimerRef.current = setTimeout(() => {\n ctx.isRecentlyOpenRef.current = false;\n }, ctx.skipDelayDuration);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const classes = [styles.viewport, className].filter(Boolean).join(' ');\n\n return (\n <div\n ref={viewportRef}\n className={classes}\n style={cssVars}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"presentation\"\n />\n );\n}\n\n// ============================================\n// MobileContent (slot for extra mobile sections)\n// ============================================\n\nfunction NavigationMenuMobileContent({ children }: NavigationMenuMobileContentProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileContentChildren(children);\n return () => ctx.setMobileContentChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n // This component renders nothing visually on desktop or in the tree.\n // Its children are extracted into the mobile drawer via context.\n return null;\n}\n\n// ============================================\n// MobileBrand (slot for brand in mobile drawer header)\n// ============================================\n\nfunction NavigationMenuMobileBrand({ children }: NavigationMenuMobileBrandProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileBrandChildren(children);\n return () => ctx.setMobileBrandChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n return null;\n}\n\n// ============================================\n// MobileSection\n// ============================================\n\nfunction NavigationMenuMobileSection({ children, label }: NavigationMenuMobileSectionProps) {\n return (\n <div role=\"group\" aria-label={label}>\n {label && <div className={styles.drawerSectionLabel}>{label}</div>}\n <div className={styles.drawerNav}>{children}</div>\n </div>\n );\n}\n\n// ============================================\n// Mobile Hamburger Button\n// ============================================\n\nfunction MobileHamburger() {\n const { mobileOpen, setMobileOpen } = useNavigationMenuContext();\n\n return (\n <button\n type=\"button\"\n className={styles.hamburger}\n onClick={() => setMobileOpen(!mobileOpen)}\n aria-label=\"Toggle navigation\"\n aria-expanded={mobileOpen}\n >\n {mobileOpen ? <X size={24} aria-hidden /> : <List size={24} aria-hidden />}\n </button>\n );\n}\n\n// ============================================\n// Mobile Drawer\n// ============================================\n\nfunction MobileDrawer() {\n const ctx = useNavigationMenuContext();\n const drawerRef = React.useRef<HTMLDivElement>(null);\n\n useFocusTrap(drawerRef, true);\n\n // Lock body scroll\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle Escape\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n ctx.setMobileOpen(false);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [ctx]);\n\n // Build auto-converted nav items from item info registry\n const autoItems = React.useMemo(() => {\n const items: NavigationMenuItemInfo[] = [];\n for (const value of ctx.triggerOrder.current) {\n const info = ctx.itemInfoMap.current.get(value);\n if (info) items.push(info);\n }\n return items;\n }, [ctx.triggerOrder, ctx.itemInfoMap]);\n\n const handleLinkClick = () => {\n ctx.setMobileOpen(false);\n };\n\n const drawerContent = (\n <>\n <div\n className={styles.drawerBackdrop}\n onClick={() => ctx.setMobileOpen(false)}\n aria-hidden\n />\n <div\n ref={drawerRef}\n className={styles.drawer}\n role=\"dialog\"\n aria-modal\n aria-label=\"Navigation\"\n >\n <div className={styles.drawerHeader}>\n {ctx.mobileBrandChildren ?? <span />}\n <button\n type=\"button\"\n className={styles.drawerClose}\n onClick={() => ctx.setMobileOpen(false)}\n aria-label=\"Close navigation\"\n >\n <X size={20} aria-hidden />\n </button>\n </div>\n <ScrollArea orientation=\"vertical\" className={styles.drawerBody}>\n {/* When MobileContent is provided, it takes full control of the drawer nav.\n Otherwise, auto-convert registered Trigger+Content items. */}\n {ctx.mobileContentChildren ? (\n ctx.mobileContentChildren\n ) : (\n <div className={styles.drawerNav}>\n {autoItems.map((item) =>\n item.contentChildren ? (\n <MobileCollapsibleSection\n key={item.value}\n label={item.triggerLabel}\n onLinkClick={handleLinkClick}\n >\n {item.contentChildren}\n </MobileCollapsibleSection>\n ) : item.linkHref ? (\n <a\n key={item.value}\n className={styles.drawerLink}\n href={item.linkHref}\n onClick={handleLinkClick}\n >\n {item.triggerLabel}\n </a>\n ) : null\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n </>\n );\n\n if (typeof document === 'undefined') return null;\n return createPortal(drawerContent, document.body);\n}\n\n// ============================================\n// Mobile Collapsible Section (auto-converted)\n// ============================================\n\nfunction MobileCollapsibleSection({\n label,\n children,\n onLinkClick,\n}: {\n label: string;\n children: React.ReactNode;\n onLinkClick: () => void;\n}) {\n return (\n <Collapsible defaultOpen={false}>\n <Collapsible.Trigger className={styles.drawerCollapsibleTrigger}>\n {label}\n </Collapsible.Trigger>\n <Collapsible.Content>\n <div className={styles.drawerCollapsibleContent} onClick={onLinkClick}>\n {children}\n </div>\n </Collapsible.Content>\n </Collapsible>\n );\n}\n\n// ============================================\n// Export Compound Component\n// ============================================\n\nexport const NavigationMenu = Object.assign(NavigationMenuRoot, {\n List: NavigationMenuList,\n Item: NavigationMenuItem,\n Trigger: NavigationMenuTrigger,\n Content: NavigationMenuContent,\n Link: NavigationMenuLink,\n Indicator: NavigationMenuIndicator,\n Viewport: NavigationMenuViewport,\n MobileBrand: NavigationMenuMobileBrand,\n MobileContent: NavigationMenuMobileContent,\n MobileSection: NavigationMenuMobileSection,\n});\n\nexport {\n NavigationMenuRoot,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n NavigationMenuMobileBrand,\n NavigationMenuMobileContent,\n NavigationMenuMobileSection,\n};\n"],"names":["React","useNavigationMenu","styles","jsx","NavigationMenuContext","jsxs","useNavigationMenuContext","handleArrowNavigation","NavigationMenuItemContext","useNavigationMenuItemContext","CaretDown","createPortal","classes","linkProps","Fragment","X","List","useFocusTrap","ScrollArea","Collapsible"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/components/NavigationMenu/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { CaretDown, CaretRight, List, X } from '@phosphor-icons/react';\nimport { handleArrowNavigation, useFocusTrap } from '../../utils/a11y';\nimport { Collapsible } from '../Collapsible';\nimport { ScrollArea } from '../ScrollArea';\nimport {\n NavigationMenuContext,\n NavigationMenuItemContext,\n useNavigationMenuContext,\n useNavigationMenuItemContext,\n type NavigationMenuItemInfo,\n} from './NavigationMenuContext';\nimport { useNavigationMenu } from './useNavigationMenu';\nimport styles from './NavigationMenu.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface NavigationMenuProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode;\n /** Controlled open item value */\n value?: string;\n /** Default open item value */\n defaultValue?: string;\n /** Callback when open item changes */\n onValueChange?: (value: string) => void;\n /** Menu orientation */\n orientation?: 'horizontal' | 'vertical';\n /** Delay before opening on hover (ms) */\n delayDuration?: number;\n /** Duration to skip delays between triggers (ms) */\n skipDelayDuration?: number;\n}\n\nexport interface NavigationMenuListProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuItemProps {\n children: React.ReactNode;\n /** Unique item value (required for items with Trigger+Content) */\n value?: string;\n className?: string;\n}\n\nexport interface NavigationMenuTriggerProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuContentProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Simple mode: children as text content */\n children?: React.ReactNode;\n /** Structured mode: title text */\n title?: string;\n /** Structured mode: description text */\n description?: string;\n /** Structured mode: icon element */\n icon?: React.ReactNode;\n /** Whether this link is the current page */\n active?: boolean;\n /** Highlighted card style */\n featured?: boolean;\n /** Render as child element (polymorphic) */\n asChild?: boolean;\n}\n\nexport interface NavigationMenuIndicatorProps {\n className?: string;\n}\n\nexport interface NavigationMenuViewportProps {\n className?: string;\n}\n\nexport interface NavigationMenuMobileContentProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileBrandProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileSectionProps {\n children: React.ReactNode;\n /** Section heading label */\n label?: string;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mq = window.matchMedia('(max-width: 767px)');\n setIsMobile(mq.matches);\n\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isMobile;\n}\n\n// ============================================\n// Root\n// ============================================\n\nfunction NavigationMenuRoot({\n children,\n value: controlledValue,\n defaultValue,\n onValueChange,\n orientation = 'horizontal',\n delayDuration = 200,\n skipDelayDuration = 300,\n className,\n 'aria-label': ariaLabel = 'Main navigation',\n ...htmlProps\n}: NavigationMenuProps) {\n const rootId = React.useId();\n const isMobile = useIsMobile();\n\n const state = useNavigationMenu({\n value: controlledValue,\n defaultValue,\n onValueChange,\n delayDuration,\n skipDelayDuration,\n });\n\n const classes = [\n styles.root,\n orientation === 'vertical' && styles.rootVertical,\n className,\n ].filter(Boolean).join(' ');\n\n const contextValue = React.useMemo(\n () => ({\n ...state,\n orientation,\n isMobile,\n rootId,\n }),\n [state, orientation, isMobile, rootId]\n );\n\n return (\n <NavigationMenuContext.Provider value={contextValue}>\n <nav {...htmlProps} className={classes} aria-label={ariaLabel} data-orientation={orientation}>\n {children}\n {isMobile && <MobileHamburger />}\n {isMobile && state.mobileOpen && <MobileDrawer />}\n </nav>\n </NavigationMenuContext.Provider>\n );\n}\n\n// ============================================\n// List\n// ============================================\n\nfunction NavigationMenuList({ children, className }: NavigationMenuListProps) {\n const { orientation, triggerOrder, triggerRefs, value } = useNavigationMenuContext();\n\n const listRef = React.useRef<HTMLUListElement>(null);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const order = triggerOrder.current;\n const currentIdx = order.indexOf(value);\n\n const newIdx = handleArrowNavigation(e, order, currentIdx >= 0 ? currentIdx : 0, {\n orientation: orientation === 'horizontal' ? 'horizontal' : 'vertical',\n loop: true,\n });\n\n if (newIdx !== undefined) {\n const targetValue = order[newIdx];\n const trigger = triggerRefs.current.get(targetValue);\n trigger?.focus();\n }\n };\n\n const classes = [\n styles.list,\n orientation === 'vertical' && styles.listVertical,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <ul\n ref={listRef}\n className={classes}\n role=\"list\"\n data-orientation={orientation}\n onKeyDown={handleKeyDown}\n >\n {children}\n </ul>\n );\n}\n\n// ============================================\n// Item\n// ============================================\n\nlet itemCounter = 0;\n\nfunction NavigationMenuItem({ children, value: valueProp, className }: NavigationMenuItemProps) {\n const rootCtx = useNavigationMenuContext();\n const [autoValue] = React.useState(() => valueProp || `navmenu-item-${++itemCounter}`);\n const triggerId = `${rootCtx.rootId}-trigger-${autoValue}`;\n const contentId = `${rootCtx.rootId}-content-${autoValue}`;\n\n const itemCtx = React.useMemo(\n () => ({\n value: autoValue,\n triggerId,\n contentId,\n }),\n [autoValue, triggerId, contentId]\n );\n\n return (\n <NavigationMenuItemContext.Provider value={itemCtx}>\n <li className={className}>{children}</li>\n </NavigationMenuItemContext.Provider>\n );\n}\n\n// ============================================\n// Trigger\n// ============================================\n\nfunction NavigationMenuTrigger({ children, className }: NavigationMenuTriggerProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n\n // Register trigger\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n React.useEffect(() => {\n if (triggerRef.current) {\n ctx.triggerRefs.current.set(itemCtx.value, triggerRef.current);\n if (!ctx.triggerOrder.current.includes(itemCtx.value)) {\n ctx.triggerOrder.current.push(itemCtx.value);\n }\n }\n return () => {\n ctx.triggerRefs.current.delete(itemCtx.value);\n ctx.triggerOrder.current = ctx.triggerOrder.current.filter(v => v !== itemCtx.value);\n };\n // Only register/unregister on mount/unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value]);\n\n // Register item info for mobile drawer\n React.useEffect(() => {\n const label = typeof children === 'string' ? children : '';\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: label || existing?.triggerLabel || '',\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n const handleClick = () => {\n ctx.setValue(isOpen ? '' : itemCtx.value);\n };\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n\n // Skip delay if recently open\n if (ctx.isRecentlyOpenRef.current) {\n ctx.setValue(itemCtx.value);\n return;\n }\n\n ctx.openTimerRef.current = setTimeout(() => {\n ctx.setValue(itemCtx.value);\n }, ctx.delayDuration);\n };\n\n const handlePointerLeave = () => {\n if (ctx.openTimerRef.current) {\n clearTimeout(ctx.openTimerRef.current);\n ctx.openTimerRef.current = null;\n }\n\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n ctx.setValue(isOpen ? '' : itemCtx.value);\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n ctx.setValue('');\n triggerRef.current?.focus();\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n return (\n <button\n ref={triggerRef}\n type=\"button\"\n id={itemCtx.triggerId}\n className={classes}\n aria-expanded={isOpen}\n aria-controls={itemCtx.contentId}\n data-state={isOpen ? 'open' : 'closed'}\n onClick={handleClick}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n onKeyDown={handleKeyDown}\n >\n {children}\n <CaretDown size={12} className={styles.triggerChevron} aria-hidden />\n </button>\n );\n}\n\n// ============================================\n// Content\n// ============================================\n\nfunction NavigationMenuContent({ children, className }: NavigationMenuContentProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // Register content children into item info (for mobile drawer)\n React.useEffect(() => {\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: existing?.triggerLabel || '',\n contentChildren: children,\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n // Measure content for viewport animation\n React.useEffect(() => {\n if (!isOpen || !contentRef.current) return;\n\n const el = contentRef.current;\n const observer = new ResizeObserver(([entry]) => {\n if (entry) {\n ctx.setViewportSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n });\n observer.observe(el);\n\n // Initial measurement\n ctx.setViewportSize({\n width: el.scrollWidth,\n height: el.scrollHeight,\n });\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n // Determine motion direction\n const prevValue = ctx.previousValue.current;\n const triggerOrder = ctx.triggerOrder.current;\n const prevIdx = triggerOrder.indexOf(prevValue);\n const currentIdx = triggerOrder.indexOf(itemCtx.value);\n let motion: string | undefined;\n if (isOpen && prevValue && prevValue !== itemCtx.value) {\n motion = currentIdx > prevIdx ? 'from-end' : 'from-start';\n }\n\n // Update previousValue when this content becomes active\n React.useEffect(() => {\n if (isOpen) {\n ctx.previousValue.current = itemCtx.value;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, itemCtx.value]);\n\n if (!isOpen) return null;\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n };\n\n const handlePointerLeave = () => {\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const contentElement = (\n <div\n ref={contentRef}\n id={itemCtx.contentId}\n className={classes}\n role=\"region\"\n aria-labelledby={itemCtx.triggerId}\n data-motion={motion}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </div>\n );\n\n // Portal into viewport if it exists\n if (ctx.viewportRef.current) {\n return createPortal(contentElement, ctx.viewportRef.current);\n }\n\n return contentElement;\n}\n\n// ============================================\n// Link\n// ============================================\n\nfunction NavigationMenuLink({\n children,\n title,\n description,\n icon,\n active = false,\n featured = false,\n asChild = false,\n className,\n href,\n onClick,\n ...htmlProps\n}: NavigationMenuLinkProps) {\n const ctx = React.useContext(NavigationMenuContext);\n const isStructured = !!(title || description || icon);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n // Close mobile drawer on link click\n if (ctx?.isMobile && ctx.mobileOpen) {\n ctx.setMobileOpen(false);\n }\n // Close desktop menu\n if (ctx) {\n ctx.setValue('');\n }\n };\n\n // Structured mode (title + description + icon)\n if (isStructured) {\n const classes = [\n styles.link,\n styles.linkStructured,\n active && styles.linkActive,\n featured && styles.linkFeatured,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n children: (\n <>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </>\n ),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return (\n <a {...linkProps}>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </a>\n );\n }\n\n // Simple link mode\n const classes = [\n styles.link,\n active && styles.linkActive,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return <a {...linkProps}>{children}</a>;\n}\n\n// ============================================\n// Indicator\n// ============================================\n\nfunction NavigationMenuIndicator({ className }: NavigationMenuIndicatorProps) {\n const { value, triggerRefs } = useNavigationMenuContext();\n const [style, setStyle] = React.useState<React.CSSProperties>({ opacity: 0 });\n\n React.useEffect(() => {\n if (!value) {\n setStyle({ opacity: 0 });\n return;\n }\n const trigger = triggerRefs.current.get(value);\n if (trigger) {\n const parent = trigger.closest('ul');\n if (parent) {\n const parentRect = parent.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setStyle({\n left: triggerRect.left - parentRect.left,\n width: triggerRect.width,\n opacity: 1,\n });\n }\n }\n }, [value, triggerRefs]);\n\n const classes = [styles.indicator, className].filter(Boolean).join(' ');\n\n return <div className={classes} style={style} aria-hidden />;\n}\n\n// ============================================\n// Viewport\n// ============================================\n\nfunction NavigationMenuViewport({ className }: NavigationMenuViewportProps) {\n const ctx = useNavigationMenuContext();\n const { viewportSize, viewportRef, value, triggerRefs } = ctx;\n const isOpen = !!value;\n\n // Compute the active trigger's left offset relative to the nav root\n const [triggerLeft, setTriggerLeft] = React.useState(0);\n\n React.useEffect(() => {\n if (!isOpen || !value) return;\n const trigger = triggerRefs.current.get(value);\n if (!trigger || !viewportRef.current) return;\n\n const navRoot = viewportRef.current.parentElement;\n if (!navRoot) return;\n\n const navRect = navRoot.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setTriggerLeft(triggerRect.left - navRect.left);\n }, [isOpen, value, triggerRefs, viewportRef]);\n\n const cssVars = {\n '--fui-navmenu-viewport-width': isOpen ? `${viewportSize.width}px` : '0px',\n '--fui-navmenu-viewport-height': isOpen ? `${viewportSize.height}px` : '0px',\n '--fui-navmenu-viewport-left': `${triggerLeft}px`,\n } as React.CSSProperties;\n\n // Mark skip-delay state\n React.useEffect(() => {\n if (isOpen) {\n ctx.isRecentlyOpenRef.current = true;\n if (ctx.skipDelayTimerRef.current) {\n clearTimeout(ctx.skipDelayTimerRef.current);\n }\n } else {\n ctx.skipDelayTimerRef.current = setTimeout(() => {\n ctx.isRecentlyOpenRef.current = false;\n }, ctx.skipDelayDuration);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const classes = [styles.viewport, className].filter(Boolean).join(' ');\n\n return (\n <div\n ref={viewportRef}\n className={classes}\n style={cssVars}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"presentation\"\n />\n );\n}\n\n// ============================================\n// MobileContent (slot for extra mobile sections)\n// ============================================\n\nfunction NavigationMenuMobileContent({ children }: NavigationMenuMobileContentProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileContentChildren(children);\n return () => ctx.setMobileContentChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n // This component renders nothing visually on desktop or in the tree.\n // Its children are extracted into the mobile drawer via context.\n return null;\n}\n\n// ============================================\n// MobileBrand (slot for brand in mobile drawer header)\n// ============================================\n\nfunction NavigationMenuMobileBrand({ children }: NavigationMenuMobileBrandProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileBrandChildren(children);\n return () => ctx.setMobileBrandChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n return null;\n}\n\n// ============================================\n// MobileSection\n// ============================================\n\nfunction NavigationMenuMobileSection({ children, label }: NavigationMenuMobileSectionProps) {\n return (\n <div role=\"group\" aria-label={label}>\n {label && <div className={styles.drawerSectionLabel}>{label}</div>}\n <div className={styles.drawerNav}>{children}</div>\n </div>\n );\n}\n\n// ============================================\n// Mobile Hamburger Button\n// ============================================\n\nfunction MobileHamburger() {\n const { mobileOpen, setMobileOpen } = useNavigationMenuContext();\n\n return (\n <button\n type=\"button\"\n className={styles.hamburger}\n onClick={() => setMobileOpen(!mobileOpen)}\n aria-label=\"Toggle navigation\"\n aria-expanded={mobileOpen}\n >\n {mobileOpen ? <X size={24} aria-hidden /> : <List size={24} aria-hidden />}\n </button>\n );\n}\n\n// ============================================\n// Mobile Drawer\n// ============================================\n\nfunction MobileDrawer() {\n const ctx = useNavigationMenuContext();\n const drawerRef = React.useRef<HTMLDivElement>(null);\n\n useFocusTrap(drawerRef, true);\n\n // Lock body scroll\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle Escape\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n ctx.setMobileOpen(false);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [ctx]);\n\n // Build auto-converted nav items from item info registry\n const autoItems = React.useMemo(() => {\n const items: NavigationMenuItemInfo[] = [];\n for (const value of ctx.triggerOrder.current) {\n const info = ctx.itemInfoMap.current.get(value);\n if (info) items.push(info);\n }\n return items;\n }, [ctx.triggerOrder, ctx.itemInfoMap]);\n\n const handleLinkClick = () => {\n ctx.setMobileOpen(false);\n };\n\n const drawerContent = (\n <>\n <div\n className={styles.drawerBackdrop}\n onClick={() => ctx.setMobileOpen(false)}\n aria-hidden\n />\n <div\n ref={drawerRef}\n className={styles.drawer}\n role=\"dialog\"\n aria-modal\n aria-label=\"Navigation\"\n >\n <div className={styles.drawerHeader}>\n {ctx.mobileBrandChildren ?? <span />}\n <button\n type=\"button\"\n className={styles.drawerClose}\n onClick={() => ctx.setMobileOpen(false)}\n aria-label=\"Close navigation\"\n >\n <X size={20} aria-hidden />\n </button>\n </div>\n <ScrollArea orientation=\"vertical\" className={styles.drawerBody}>\n {/* When MobileContent is provided, it takes full control of the drawer nav.\n Otherwise, auto-convert registered Trigger+Content items. */}\n {ctx.mobileContentChildren ? (\n ctx.mobileContentChildren\n ) : (\n <div className={styles.drawerNav}>\n {autoItems.map((item) =>\n item.contentChildren ? (\n <MobileCollapsibleSection\n key={item.value}\n label={item.triggerLabel}\n onLinkClick={handleLinkClick}\n >\n {item.contentChildren}\n </MobileCollapsibleSection>\n ) : item.linkHref ? (\n <a\n key={item.value}\n className={styles.drawerLink}\n href={item.linkHref}\n onClick={handleLinkClick}\n >\n {item.triggerLabel}\n </a>\n ) : null\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n </>\n );\n\n if (typeof document === 'undefined') return null;\n return createPortal(drawerContent, document.body);\n}\n\n// ============================================\n// Mobile Collapsible Section (auto-converted)\n// ============================================\n\nfunction MobileCollapsibleSection({\n label,\n children,\n onLinkClick,\n}: {\n label: string;\n children: React.ReactNode;\n onLinkClick: () => void;\n}) {\n return (\n <Collapsible defaultOpen={false}>\n <Collapsible.Trigger className={styles.drawerCollapsibleTrigger}>\n {label}\n </Collapsible.Trigger>\n <Collapsible.Content>\n <div\n className={styles.drawerCollapsibleContent}\n onClick={onLinkClick}\n onKeyDown={(e) => { if (e.key === 'Enter') onLinkClick(); }}\n role=\"group\"\n >\n {children}\n </div>\n </Collapsible.Content>\n </Collapsible>\n );\n}\n\n// ============================================\n// Export Compound Component\n// ============================================\n\nexport const NavigationMenu = Object.assign(NavigationMenuRoot, {\n List: NavigationMenuList,\n Item: NavigationMenuItem,\n Trigger: NavigationMenuTrigger,\n Content: NavigationMenuContent,\n Link: NavigationMenuLink,\n Indicator: NavigationMenuIndicator,\n Viewport: NavigationMenuViewport,\n MobileBrand: NavigationMenuMobileBrand,\n MobileContent: NavigationMenuMobileContent,\n MobileSection: NavigationMenuMobileSection,\n});\n\nexport {\n NavigationMenuRoot,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n NavigationMenuMobileBrand,\n NavigationMenuMobileContent,\n NavigationMenuMobileSection,\n};\n"],"names":["React","useNavigationMenu","styles","jsx","NavigationMenuContext","jsxs","useNavigationMenuContext","handleArrowNavigation","NavigationMenuItemContext","useNavigationMenuItemContext","CaretDown","createPortal","classes","linkProps","Fragment","X","List","useFocusTrap","ScrollArea","Collapsible"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/NavigationMenu/index.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/NavigationMenu/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -552,7 +552,18 @@ function MobileCollapsibleSection({
|
|
|
552
552
|
}) {
|
|
553
553
|
return /* @__PURE__ */ jsxs(Collapsible, { defaultOpen: false, children: [
|
|
554
554
|
/* @__PURE__ */ jsx(Collapsible.Trigger, { className: styles.drawerCollapsibleTrigger, children: label }),
|
|
555
|
-
/* @__PURE__ */ jsx(Collapsible.Content, { children: /* @__PURE__ */ jsx(
|
|
555
|
+
/* @__PURE__ */ jsx(Collapsible.Content, { children: /* @__PURE__ */ jsx(
|
|
556
|
+
"div",
|
|
557
|
+
{
|
|
558
|
+
className: styles.drawerCollapsibleContent,
|
|
559
|
+
onClick: onLinkClick,
|
|
560
|
+
onKeyDown: (e) => {
|
|
561
|
+
if (e.key === "Enter") onLinkClick();
|
|
562
|
+
},
|
|
563
|
+
role: "group",
|
|
564
|
+
children
|
|
565
|
+
}
|
|
566
|
+
) })
|
|
556
567
|
] });
|
|
557
568
|
}
|
|
558
569
|
const NavigationMenu = Object.assign(NavigationMenuRoot, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/NavigationMenu/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { CaretDown, CaretRight, List, X } from '@phosphor-icons/react';\nimport { handleArrowNavigation, useFocusTrap } from '../../utils/a11y';\nimport { Collapsible } from '../Collapsible';\nimport { ScrollArea } from '../ScrollArea';\nimport {\n NavigationMenuContext,\n NavigationMenuItemContext,\n useNavigationMenuContext,\n useNavigationMenuItemContext,\n type NavigationMenuItemInfo,\n} from './NavigationMenuContext';\nimport { useNavigationMenu } from './useNavigationMenu';\nimport styles from './NavigationMenu.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface NavigationMenuProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode;\n /** Controlled open item value */\n value?: string;\n /** Default open item value */\n defaultValue?: string;\n /** Callback when open item changes */\n onValueChange?: (value: string) => void;\n /** Menu orientation */\n orientation?: 'horizontal' | 'vertical';\n /** Delay before opening on hover (ms) */\n delayDuration?: number;\n /** Duration to skip delays between triggers (ms) */\n skipDelayDuration?: number;\n}\n\nexport interface NavigationMenuListProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuItemProps {\n children: React.ReactNode;\n /** Unique item value (required for items with Trigger+Content) */\n value?: string;\n className?: string;\n}\n\nexport interface NavigationMenuTriggerProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuContentProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Simple mode: children as text content */\n children?: React.ReactNode;\n /** Structured mode: title text */\n title?: string;\n /** Structured mode: description text */\n description?: string;\n /** Structured mode: icon element */\n icon?: React.ReactNode;\n /** Whether this link is the current page */\n active?: boolean;\n /** Highlighted card style */\n featured?: boolean;\n /** Render as child element (polymorphic) */\n asChild?: boolean;\n}\n\nexport interface NavigationMenuIndicatorProps {\n className?: string;\n}\n\nexport interface NavigationMenuViewportProps {\n className?: string;\n}\n\nexport interface NavigationMenuMobileContentProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileBrandProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileSectionProps {\n children: React.ReactNode;\n /** Section heading label */\n label?: string;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mq = window.matchMedia('(max-width: 767px)');\n setIsMobile(mq.matches);\n\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isMobile;\n}\n\n// ============================================\n// Root\n// ============================================\n\nfunction NavigationMenuRoot({\n children,\n value: controlledValue,\n defaultValue,\n onValueChange,\n orientation = 'horizontal',\n delayDuration = 200,\n skipDelayDuration = 300,\n className,\n 'aria-label': ariaLabel = 'Main navigation',\n ...htmlProps\n}: NavigationMenuProps) {\n const rootId = React.useId();\n const isMobile = useIsMobile();\n\n const state = useNavigationMenu({\n value: controlledValue,\n defaultValue,\n onValueChange,\n delayDuration,\n skipDelayDuration,\n });\n\n const classes = [\n styles.root,\n orientation === 'vertical' && styles.rootVertical,\n className,\n ].filter(Boolean).join(' ');\n\n const contextValue = React.useMemo(\n () => ({\n ...state,\n orientation,\n isMobile,\n rootId,\n }),\n [state, orientation, isMobile, rootId]\n );\n\n return (\n <NavigationMenuContext.Provider value={contextValue}>\n <nav {...htmlProps} className={classes} aria-label={ariaLabel} data-orientation={orientation}>\n {children}\n {isMobile && <MobileHamburger />}\n {isMobile && state.mobileOpen && <MobileDrawer />}\n </nav>\n </NavigationMenuContext.Provider>\n );\n}\n\n// ============================================\n// List\n// ============================================\n\nfunction NavigationMenuList({ children, className }: NavigationMenuListProps) {\n const { orientation, triggerOrder, triggerRefs, value } = useNavigationMenuContext();\n\n const listRef = React.useRef<HTMLUListElement>(null);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const order = triggerOrder.current;\n const currentIdx = order.indexOf(value);\n\n const newIdx = handleArrowNavigation(e, order, currentIdx >= 0 ? currentIdx : 0, {\n orientation: orientation === 'horizontal' ? 'horizontal' : 'vertical',\n loop: true,\n });\n\n if (newIdx !== undefined) {\n const targetValue = order[newIdx];\n const trigger = triggerRefs.current.get(targetValue);\n trigger?.focus();\n }\n };\n\n const classes = [\n styles.list,\n orientation === 'vertical' && styles.listVertical,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <ul\n ref={listRef}\n className={classes}\n role=\"list\"\n data-orientation={orientation}\n onKeyDown={handleKeyDown}\n >\n {children}\n </ul>\n );\n}\n\n// ============================================\n// Item\n// ============================================\n\nlet itemCounter = 0;\n\nfunction NavigationMenuItem({ children, value: valueProp, className }: NavigationMenuItemProps) {\n const rootCtx = useNavigationMenuContext();\n const [autoValue] = React.useState(() => valueProp || `navmenu-item-${++itemCounter}`);\n const triggerId = `${rootCtx.rootId}-trigger-${autoValue}`;\n const contentId = `${rootCtx.rootId}-content-${autoValue}`;\n\n const itemCtx = React.useMemo(\n () => ({\n value: autoValue,\n triggerId,\n contentId,\n }),\n [autoValue, triggerId, contentId]\n );\n\n return (\n <NavigationMenuItemContext.Provider value={itemCtx}>\n <li className={className}>{children}</li>\n </NavigationMenuItemContext.Provider>\n );\n}\n\n// ============================================\n// Trigger\n// ============================================\n\nfunction NavigationMenuTrigger({ children, className }: NavigationMenuTriggerProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n\n // Register trigger\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n React.useEffect(() => {\n if (triggerRef.current) {\n ctx.triggerRefs.current.set(itemCtx.value, triggerRef.current);\n if (!ctx.triggerOrder.current.includes(itemCtx.value)) {\n ctx.triggerOrder.current.push(itemCtx.value);\n }\n }\n return () => {\n ctx.triggerRefs.current.delete(itemCtx.value);\n ctx.triggerOrder.current = ctx.triggerOrder.current.filter(v => v !== itemCtx.value);\n };\n // Only register/unregister on mount/unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value]);\n\n // Register item info for mobile drawer\n React.useEffect(() => {\n const label = typeof children === 'string' ? children : '';\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: label || existing?.triggerLabel || '',\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n const handleClick = () => {\n ctx.setValue(isOpen ? '' : itemCtx.value);\n };\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n\n // Skip delay if recently open\n if (ctx.isRecentlyOpenRef.current) {\n ctx.setValue(itemCtx.value);\n return;\n }\n\n ctx.openTimerRef.current = setTimeout(() => {\n ctx.setValue(itemCtx.value);\n }, ctx.delayDuration);\n };\n\n const handlePointerLeave = () => {\n if (ctx.openTimerRef.current) {\n clearTimeout(ctx.openTimerRef.current);\n ctx.openTimerRef.current = null;\n }\n\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n ctx.setValue(isOpen ? '' : itemCtx.value);\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n ctx.setValue('');\n triggerRef.current?.focus();\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n return (\n <button\n ref={triggerRef}\n type=\"button\"\n id={itemCtx.triggerId}\n className={classes}\n aria-expanded={isOpen}\n aria-controls={itemCtx.contentId}\n data-state={isOpen ? 'open' : 'closed'}\n onClick={handleClick}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n onKeyDown={handleKeyDown}\n >\n {children}\n <CaretDown size={12} className={styles.triggerChevron} aria-hidden />\n </button>\n );\n}\n\n// ============================================\n// Content\n// ============================================\n\nfunction NavigationMenuContent({ children, className }: NavigationMenuContentProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // Register content children into item info (for mobile drawer)\n React.useEffect(() => {\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: existing?.triggerLabel || '',\n contentChildren: children,\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n // Measure content for viewport animation\n React.useEffect(() => {\n if (!isOpen || !contentRef.current) return;\n\n const el = contentRef.current;\n const observer = new ResizeObserver(([entry]) => {\n if (entry) {\n ctx.setViewportSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n });\n observer.observe(el);\n\n // Initial measurement\n ctx.setViewportSize({\n width: el.scrollWidth,\n height: el.scrollHeight,\n });\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n // Determine motion direction\n const prevValue = ctx.previousValue.current;\n const triggerOrder = ctx.triggerOrder.current;\n const prevIdx = triggerOrder.indexOf(prevValue);\n const currentIdx = triggerOrder.indexOf(itemCtx.value);\n let motion: string | undefined;\n if (isOpen && prevValue && prevValue !== itemCtx.value) {\n motion = currentIdx > prevIdx ? 'from-end' : 'from-start';\n }\n\n // Update previousValue when this content becomes active\n React.useEffect(() => {\n if (isOpen) {\n ctx.previousValue.current = itemCtx.value;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, itemCtx.value]);\n\n if (!isOpen) return null;\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n };\n\n const handlePointerLeave = () => {\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const contentElement = (\n <div\n ref={contentRef}\n id={itemCtx.contentId}\n className={classes}\n role=\"region\"\n aria-labelledby={itemCtx.triggerId}\n data-motion={motion}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </div>\n );\n\n // Portal into viewport if it exists\n if (ctx.viewportRef.current) {\n return createPortal(contentElement, ctx.viewportRef.current);\n }\n\n return contentElement;\n}\n\n// ============================================\n// Link\n// ============================================\n\nfunction NavigationMenuLink({\n children,\n title,\n description,\n icon,\n active = false,\n featured = false,\n asChild = false,\n className,\n href,\n onClick,\n ...htmlProps\n}: NavigationMenuLinkProps) {\n const ctx = React.useContext(NavigationMenuContext);\n const isStructured = !!(title || description || icon);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n // Close mobile drawer on link click\n if (ctx?.isMobile && ctx.mobileOpen) {\n ctx.setMobileOpen(false);\n }\n // Close desktop menu\n if (ctx) {\n ctx.setValue('');\n }\n };\n\n // Structured mode (title + description + icon)\n if (isStructured) {\n const classes = [\n styles.link,\n styles.linkStructured,\n active && styles.linkActive,\n featured && styles.linkFeatured,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n children: (\n <>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </>\n ),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return (\n <a {...linkProps}>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </a>\n );\n }\n\n // Simple link mode\n const classes = [\n styles.link,\n active && styles.linkActive,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return <a {...linkProps}>{children}</a>;\n}\n\n// ============================================\n// Indicator\n// ============================================\n\nfunction NavigationMenuIndicator({ className }: NavigationMenuIndicatorProps) {\n const { value, triggerRefs } = useNavigationMenuContext();\n const [style, setStyle] = React.useState<React.CSSProperties>({ opacity: 0 });\n\n React.useEffect(() => {\n if (!value) {\n setStyle({ opacity: 0 });\n return;\n }\n const trigger = triggerRefs.current.get(value);\n if (trigger) {\n const parent = trigger.closest('ul');\n if (parent) {\n const parentRect = parent.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setStyle({\n left: triggerRect.left - parentRect.left,\n width: triggerRect.width,\n opacity: 1,\n });\n }\n }\n }, [value, triggerRefs]);\n\n const classes = [styles.indicator, className].filter(Boolean).join(' ');\n\n return <div className={classes} style={style} aria-hidden />;\n}\n\n// ============================================\n// Viewport\n// ============================================\n\nfunction NavigationMenuViewport({ className }: NavigationMenuViewportProps) {\n const ctx = useNavigationMenuContext();\n const { viewportSize, viewportRef, value, triggerRefs } = ctx;\n const isOpen = !!value;\n\n // Compute the active trigger's left offset relative to the nav root\n const [triggerLeft, setTriggerLeft] = React.useState(0);\n\n React.useEffect(() => {\n if (!isOpen || !value) return;\n const trigger = triggerRefs.current.get(value);\n if (!trigger || !viewportRef.current) return;\n\n const navRoot = viewportRef.current.parentElement;\n if (!navRoot) return;\n\n const navRect = navRoot.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setTriggerLeft(triggerRect.left - navRect.left);\n }, [isOpen, value, triggerRefs, viewportRef]);\n\n const cssVars = {\n '--fui-navmenu-viewport-width': isOpen ? `${viewportSize.width}px` : '0px',\n '--fui-navmenu-viewport-height': isOpen ? `${viewportSize.height}px` : '0px',\n '--fui-navmenu-viewport-left': `${triggerLeft}px`,\n } as React.CSSProperties;\n\n // Mark skip-delay state\n React.useEffect(() => {\n if (isOpen) {\n ctx.isRecentlyOpenRef.current = true;\n if (ctx.skipDelayTimerRef.current) {\n clearTimeout(ctx.skipDelayTimerRef.current);\n }\n } else {\n ctx.skipDelayTimerRef.current = setTimeout(() => {\n ctx.isRecentlyOpenRef.current = false;\n }, ctx.skipDelayDuration);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const classes = [styles.viewport, className].filter(Boolean).join(' ');\n\n return (\n <div\n ref={viewportRef}\n className={classes}\n style={cssVars}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"presentation\"\n />\n );\n}\n\n// ============================================\n// MobileContent (slot for extra mobile sections)\n// ============================================\n\nfunction NavigationMenuMobileContent({ children }: NavigationMenuMobileContentProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileContentChildren(children);\n return () => ctx.setMobileContentChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n // This component renders nothing visually on desktop or in the tree.\n // Its children are extracted into the mobile drawer via context.\n return null;\n}\n\n// ============================================\n// MobileBrand (slot for brand in mobile drawer header)\n// ============================================\n\nfunction NavigationMenuMobileBrand({ children }: NavigationMenuMobileBrandProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileBrandChildren(children);\n return () => ctx.setMobileBrandChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n return null;\n}\n\n// ============================================\n// MobileSection\n// ============================================\n\nfunction NavigationMenuMobileSection({ children, label }: NavigationMenuMobileSectionProps) {\n return (\n <div role=\"group\" aria-label={label}>\n {label && <div className={styles.drawerSectionLabel}>{label}</div>}\n <div className={styles.drawerNav}>{children}</div>\n </div>\n );\n}\n\n// ============================================\n// Mobile Hamburger Button\n// ============================================\n\nfunction MobileHamburger() {\n const { mobileOpen, setMobileOpen } = useNavigationMenuContext();\n\n return (\n <button\n type=\"button\"\n className={styles.hamburger}\n onClick={() => setMobileOpen(!mobileOpen)}\n aria-label=\"Toggle navigation\"\n aria-expanded={mobileOpen}\n >\n {mobileOpen ? <X size={24} aria-hidden /> : <List size={24} aria-hidden />}\n </button>\n );\n}\n\n// ============================================\n// Mobile Drawer\n// ============================================\n\nfunction MobileDrawer() {\n const ctx = useNavigationMenuContext();\n const drawerRef = React.useRef<HTMLDivElement>(null);\n\n useFocusTrap(drawerRef, true);\n\n // Lock body scroll\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle Escape\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n ctx.setMobileOpen(false);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [ctx]);\n\n // Build auto-converted nav items from item info registry\n const autoItems = React.useMemo(() => {\n const items: NavigationMenuItemInfo[] = [];\n for (const value of ctx.triggerOrder.current) {\n const info = ctx.itemInfoMap.current.get(value);\n if (info) items.push(info);\n }\n return items;\n }, [ctx.triggerOrder, ctx.itemInfoMap]);\n\n const handleLinkClick = () => {\n ctx.setMobileOpen(false);\n };\n\n const drawerContent = (\n <>\n <div\n className={styles.drawerBackdrop}\n onClick={() => ctx.setMobileOpen(false)}\n aria-hidden\n />\n <div\n ref={drawerRef}\n className={styles.drawer}\n role=\"dialog\"\n aria-modal\n aria-label=\"Navigation\"\n >\n <div className={styles.drawerHeader}>\n {ctx.mobileBrandChildren ?? <span />}\n <button\n type=\"button\"\n className={styles.drawerClose}\n onClick={() => ctx.setMobileOpen(false)}\n aria-label=\"Close navigation\"\n >\n <X size={20} aria-hidden />\n </button>\n </div>\n <ScrollArea orientation=\"vertical\" className={styles.drawerBody}>\n {/* When MobileContent is provided, it takes full control of the drawer nav.\n Otherwise, auto-convert registered Trigger+Content items. */}\n {ctx.mobileContentChildren ? (\n ctx.mobileContentChildren\n ) : (\n <div className={styles.drawerNav}>\n {autoItems.map((item) =>\n item.contentChildren ? (\n <MobileCollapsibleSection\n key={item.value}\n label={item.triggerLabel}\n onLinkClick={handleLinkClick}\n >\n {item.contentChildren}\n </MobileCollapsibleSection>\n ) : item.linkHref ? (\n <a\n key={item.value}\n className={styles.drawerLink}\n href={item.linkHref}\n onClick={handleLinkClick}\n >\n {item.triggerLabel}\n </a>\n ) : null\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n </>\n );\n\n if (typeof document === 'undefined') return null;\n return createPortal(drawerContent, document.body);\n}\n\n// ============================================\n// Mobile Collapsible Section (auto-converted)\n// ============================================\n\nfunction MobileCollapsibleSection({\n label,\n children,\n onLinkClick,\n}: {\n label: string;\n children: React.ReactNode;\n onLinkClick: () => void;\n}) {\n return (\n <Collapsible defaultOpen={false}>\n <Collapsible.Trigger className={styles.drawerCollapsibleTrigger}>\n {label}\n </Collapsible.Trigger>\n <Collapsible.Content>\n <div className={styles.drawerCollapsibleContent} onClick={onLinkClick}>\n {children}\n </div>\n </Collapsible.Content>\n </Collapsible>\n );\n}\n\n// ============================================\n// Export Compound Component\n// ============================================\n\nexport const NavigationMenu = Object.assign(NavigationMenuRoot, {\n List: NavigationMenuList,\n Item: NavigationMenuItem,\n Trigger: NavigationMenuTrigger,\n Content: NavigationMenuContent,\n Link: NavigationMenuLink,\n Indicator: NavigationMenuIndicator,\n Viewport: NavigationMenuViewport,\n MobileBrand: NavigationMenuMobileBrand,\n MobileContent: NavigationMenuMobileContent,\n MobileSection: NavigationMenuMobileSection,\n});\n\nexport {\n NavigationMenuRoot,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n NavigationMenuMobileBrand,\n NavigationMenuMobileContent,\n NavigationMenuMobileSection,\n};\n"],"names":["classes","linkProps"],"mappings":";;;;;;;;;;AAuGA,SAAS,cAAc;AACrB,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAS,KAAK;AAEpD,QAAM,UAAU,MAAM;AACpB,QAAI,OAAO,WAAW,YAAa;AAEnC,UAAM,KAAK,OAAO,WAAW,oBAAoB;AACjD,gBAAY,GAAG,OAAO;AAEtB,UAAM,UAAU,CAAC,MAA2B,YAAY,EAAE,OAAO;AACjE,OAAG,iBAAiB,UAAU,OAAO;AACrC,WAAO,MAAM,GAAG,oBAAoB,UAAU,OAAO;AAAA,EACvD,GAAG,CAAA,CAAE;AAEL,SAAO;AACT;AAMA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB;AAAA,EACA,cAAc,YAAY;AAAA,EAC1B,GAAG;AACL,GAAwB;AACtB,QAAM,SAAS,MAAM,MAAA;AACrB,QAAM,WAAW,YAAA;AAEjB,QAAM,QAAQ,kBAAkB;AAAA,IAC9B,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,IACP,gBAAgB,cAAc,OAAO;AAAA,IACrC;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,OAAO,aAAa,UAAU,MAAM;AAAA,EAAA;AAGvC,SACE,oBAAC,sBAAsB,UAAtB,EAA+B,OAAO,cACrC,UAAA,qBAAC,OAAA,EAAK,GAAG,WAAW,WAAW,SAAS,cAAY,WAAW,oBAAkB,aAC9E,UAAA;AAAA,IAAA;AAAA,IACA,gCAAa,iBAAA,EAAgB;AAAA,IAC7B,YAAY,MAAM,cAAc,oBAAC,cAAA,CAAA,CAAa;AAAA,EAAA,EAAA,CACjD,EAAA,CACF;AAEJ;AAMA,SAAS,mBAAmB,EAAE,UAAU,aAAsC;AAC5E,QAAM,EAAE,aAAa,cAAc,aAAa,MAAA,IAAU,yBAAA;AAE1D,QAAM,UAAU,MAAM,OAAyB,IAAI;AAEnD,QAAM,gBAAgB,CAAC,MAA2B;AAChD,UAAM,QAAQ,aAAa;AAC3B,UAAM,aAAa,MAAM,QAAQ,KAAK;AAEtC,UAAM,SAAS,sBAAsB,GAAG,OAAO,cAAc,IAAI,aAAa,GAAG;AAAA,MAC/E,aAAa,gBAAgB,eAAe,eAAe;AAAA,MAC3D,MAAM;AAAA,IAAA,CACP;AAED,QAAI,WAAW,QAAW;AACxB,YAAM,cAAc,MAAM,MAAM;AAChC,YAAM,UAAU,YAAY,QAAQ,IAAI,WAAW;AACnD,yCAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,IACP,gBAAgB,cAAc,OAAO;AAAA,IACrC;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,MACX,MAAK;AAAA,MACL,oBAAkB;AAAA,MAClB,WAAW;AAAA,MAEV;AAAA,IAAA;AAAA,EAAA;AAGP;AAMA,IAAI,cAAc;AAElB,SAAS,mBAAmB,EAAE,UAAU,OAAO,WAAW,aAAsC;AAC9F,QAAM,UAAU,yBAAA;AAChB,QAAM,CAAC,SAAS,IAAI,MAAM,SAAS,MAAM,aAAa,gBAAgB,EAAE,WAAW,EAAE;AACrF,QAAM,YAAY,GAAG,QAAQ,MAAM,YAAY,SAAS;AACxD,QAAM,YAAY,GAAG,QAAQ,MAAM,YAAY,SAAS;AAExD,QAAM,UAAU,MAAM;AAAA,IACpB,OAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,CAAC,WAAW,WAAW,SAAS;AAAA,EAAA;AAGlC,SACE,oBAAC,0BAA0B,UAA1B,EAAmC,OAAO,SACzC,UAAA,oBAAC,MAAA,EAAG,WAAuB,SAAA,CAAS,EAAA,CACtC;AAEJ;AAMA,SAAS,sBAAsB,EAAE,UAAU,aAAyC;AAClF,QAAM,MAAM,yBAAA;AACZ,QAAM,UAAU,6BAAA;AAChB,QAAM,SAAS,IAAI,UAAU,QAAQ;AAGrC,QAAM,aAAa,MAAM,OAA0B,IAAI;AAEvD,QAAM,UAAU,MAAM;AACpB,QAAI,WAAW,SAAS;AACtB,UAAI,YAAY,QAAQ,IAAI,QAAQ,OAAO,WAAW,OAAO;AAC7D,UAAI,CAAC,IAAI,aAAa,QAAQ,SAAS,QAAQ,KAAK,GAAG;AACrD,YAAI,aAAa,QAAQ,KAAK,QAAQ,KAAK;AAAA,MAC7C;AAAA,IACF;AACA,WAAO,MAAM;AACX,UAAI,YAAY,QAAQ,OAAO,QAAQ,KAAK;AAC5C,UAAI,aAAa,UAAU,IAAI,aAAa,QAAQ,OAAO,CAAA,MAAK,MAAM,QAAQ,KAAK;AAAA,IACrF;AAAA,EAGF,GAAG,CAAC,QAAQ,KAAK,CAAC;AAGlB,QAAM,UAAU,MAAM;AACpB,UAAM,QAAQ,OAAO,aAAa,WAAW,WAAW;AACxD,UAAM,WAAW,IAAI,YAAY,QAAQ,IAAI,QAAQ,KAAK;AAC1D,QAAI,YAAY,QAAQ,IAAI,QAAQ,OAAO;AAAA,MACzC,GAAG;AAAA,MACH,OAAO,QAAQ;AAAA,MACf,cAAc,UAAS,qCAAU,iBAAgB;AAAA,IAAA,CACxB;AAAA,EAE7B,GAAG,CAAC,QAAQ,OAAO,QAAQ,CAAC;AAE5B,QAAM,cAAc,MAAM;AACxB,QAAI,SAAS,SAAS,KAAK,QAAQ,KAAK;AAAA,EAC1C;AAEA,QAAM,qBAAqB,MAAM;AAC/B,QAAI,IAAI,cAAc,SAAS;AAC7B,mBAAa,IAAI,cAAc,OAAO;AACtC,UAAI,cAAc,UAAU;AAAA,IAC9B;AAGA,QAAI,IAAI,kBAAkB,SAAS;AACjC,UAAI,SAAS,QAAQ,KAAK;AAC1B;AAAA,IACF;AAEA,QAAI,aAAa,UAAU,WAAW,MAAM;AAC1C,UAAI,SAAS,QAAQ,KAAK;AAAA,IAC5B,GAAG,IAAI,aAAa;AAAA,EACtB;AAEA,QAAM,qBAAqB,MAAM;AAC/B,QAAI,IAAI,aAAa,SAAS;AAC5B,mBAAa,IAAI,aAAa,OAAO;AACrC,UAAI,aAAa,UAAU;AAAA,IAC7B;AAEA,QAAI,cAAc,UAAU,WAAW,MAAM;AAC3C,UAAI,SAAS,EAAE;AAAA,IACjB,GAAG,IAAI,aAAa;AAAA,EACtB;AAEA,QAAM,gBAAgB,CAAC,MAA2B;;AAChD,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,QAAE,eAAA;AACF,UAAI,SAAS,SAAS,KAAK,QAAQ,KAAK;AAAA,IAC1C;AACA,QAAI,EAAE,QAAQ,YAAY,QAAQ;AAChC,QAAE,eAAA;AACF,UAAI,SAAS,EAAE;AACf,uBAAW,YAAX,mBAAoB;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEpE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,MAAK;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,WAAW;AAAA,MACX,iBAAe;AAAA,MACf,iBAAe,QAAQ;AAAA,MACvB,cAAY,SAAS,SAAS;AAAA,MAC9B,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MAEV,UAAA;AAAA,QAAA;AAAA,QACD,oBAAC,aAAU,MAAM,IAAI,WAAW,OAAO,gBAAgB,eAAW,KAAA,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGzE;AAMA,SAAS,sBAAsB,EAAE,UAAU,aAAyC;AAClF,QAAM,MAAM,yBAAA;AACZ,QAAM,UAAU,6BAAA;AAChB,QAAM,SAAS,IAAI,UAAU,QAAQ;AACrC,QAAM,aAAa,MAAM,OAAuB,IAAI;AAGpD,QAAM,UAAU,MAAM;AACpB,UAAM,WAAW,IAAI,YAAY,QAAQ,IAAI,QAAQ,KAAK;AAC1D,QAAI,YAAY,QAAQ,IAAI,QAAQ,OAAO;AAAA,MACzC,GAAG;AAAA,MACH,OAAO,QAAQ;AAAA,MACf,eAAc,qCAAU,iBAAgB;AAAA,MACxC,iBAAiB;AAAA,IAAA,CACQ;AAAA,EAE7B,GAAG,CAAC,QAAQ,OAAO,QAAQ,CAAC;AAG5B,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,UAAU,CAAC,WAAW,QAAS;AAEpC,UAAM,KAAK,WAAW;AACtB,UAAM,WAAW,IAAI,eAAe,CAAC,CAAC,KAAK,MAAM;AAC/C,UAAI,OAAO;AACT,YAAI,gBAAgB;AAAA,UAClB,OAAO,MAAM,YAAY;AAAA,UACzB,QAAQ,MAAM,YAAY;AAAA,QAAA,CAC3B;AAAA,MACH;AAAA,IACF,CAAC;AACD,aAAS,QAAQ,EAAE;AAGnB,QAAI,gBAAgB;AAAA,MAClB,OAAO,GAAG;AAAA,MACV,QAAQ,GAAG;AAAA,IAAA,CACZ;AAED,WAAO,MAAM,SAAS,WAAA;AAAA,EAExB,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,YAAY,IAAI,cAAc;AACpC,QAAM,eAAe,IAAI,aAAa;AACtC,QAAM,UAAU,aAAa,QAAQ,SAAS;AAC9C,QAAM,aAAa,aAAa,QAAQ,QAAQ,KAAK;AACrD,MAAI;AACJ,MAAI,UAAU,aAAa,cAAc,QAAQ,OAAO;AACtD,aAAS,aAAa,UAAU,aAAa;AAAA,EAC/C;AAGA,QAAM,UAAU,MAAM;AACpB,QAAI,QAAQ;AACV,UAAI,cAAc,UAAU,QAAQ;AAAA,IACtC;AAAA,EAEF,GAAG,CAAC,QAAQ,QAAQ,KAAK,CAAC;AAE1B,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,UAAU,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEpE,QAAM,qBAAqB,MAAM;AAC/B,QAAI,IAAI,cAAc,SAAS;AAC7B,mBAAa,IAAI,cAAc,OAAO;AACtC,UAAI,cAAc,UAAU;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM;AAC/B,QAAI,cAAc,UAAU,WAAW,MAAM;AAC3C,UAAI,SAAS,EAAE;AAAA,IACjB,GAAG,IAAI,aAAa;AAAA,EACtB;AAEA,QAAM,iBACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,WAAW;AAAA,MACX,MAAK;AAAA,MACL,mBAAiB,QAAQ;AAAA,MACzB,eAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAEf;AAAA,IAAA;AAAA,EAAA;AAKL,MAAI,IAAI,YAAY,SAAS;AAC3B,WAAO,aAAa,gBAAgB,IAAI,YAAY,OAAO;AAAA,EAC7D;AAEA,SAAO;AACT;AAMA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA4B;AAC1B,QAAM,MAAM,MAAM,WAAW,qBAAqB;AAClD,QAAM,eAAe,CAAC,EAAE,SAAS,eAAe;AAEhD,QAAM,cAAc,CAAC,MAA2C;AAC9D,uCAAU;AAEV,SAAI,2BAAK,aAAY,IAAI,YAAY;AACnC,UAAI,cAAc,KAAK;AAAA,IACzB;AAEA,QAAI,KAAK;AACP,UAAI,SAAS,EAAE;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,cAAc;AAChB,UAAMA,WAAU;AAAA,MACd,OAAO;AAAA,MACP,OAAO;AAAA,MACP,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB;AAAA,IAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,UAAMC,aAAY;AAAA,MAChB,GAAG;AAAA,MACH,WAAWD;AAAAA,MACX;AAAA,MACA,gBAAgB,SAAU,SAAmB;AAAA,MAC7C,SAAS;AAAA,IAAA;AAGX,QAAI,WAAW,MAAM,eAAe,QAAQ,GAAG;AAC7C,aAAO,MAAM,aAAa,UAAU;AAAA,QAClC,GAAGC;AAAAA,QACH,WAAW,CAACD,UAAU,SAAS,MAAiC,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QACnG,UACE,qBAAA,UAAA,EACG,UAAA;AAAA,UAAA,QAAQ,oBAAC,QAAA,EAAK,WAAW,OAAO,UAAW,UAAA,MAAK;AAAA,UACjD,qBAAC,QAAA,EAAK,WAAW,OAAO,UACrB,UAAA;AAAA,YAAA,SAAS,oBAAC,QAAA,EAAK,WAAW,OAAO,WAAY,UAAA,OAAM;AAAA,YACnD,eAAe,oBAAC,QAAA,EAAK,WAAW,OAAO,iBAAkB,UAAA,YAAA,CAAY;AAAA,UAAA,EAAA,CACxE;AAAA,QAAA,EAAA,CACF;AAAA,MAAA,CAEkC;AAAA,IACxC;AAEA,WACE,qBAAC,KAAA,EAAG,GAAGC,YACJ,UAAA;AAAA,MAAA,QAAQ,oBAAC,QAAA,EAAK,WAAW,OAAO,UAAW,UAAA,MAAK;AAAA,MACjD,qBAAC,QAAA,EAAK,WAAW,OAAO,UACrB,UAAA;AAAA,QAAA,SAAS,oBAAC,QAAA,EAAK,WAAW,OAAO,WAAY,UAAA,OAAM;AAAA,QACnD,eAAe,oBAAC,QAAA,EAAK,WAAW,OAAO,iBAAkB,UAAA,YAAA,CAAY;AAAA,MAAA,EAAA,CACxE;AAAA,IAAA,GACF;AAAA,EAEJ;AAGA,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,IACP,UAAU,OAAO;AAAA,IACjB;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,QAAM,YAAY;AAAA,IAChB,GAAG;AAAA,IACH,WAAW;AAAA,IACX;AAAA,IACA,gBAAgB,SAAU,SAAmB;AAAA,IAC7C,SAAS;AAAA,EAAA;AAGX,MAAI,WAAW,MAAM,eAAe,QAAQ,GAAG;AAC7C,WAAO,MAAM,aAAa,UAAU;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,CAAC,SAAU,SAAS,MAAiC,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IAAA,CAC/D;AAAA,EACxC;AAEA,SAAO,oBAAC,KAAA,EAAG,GAAG,WAAY,SAAA,CAAS;AACrC;AAMA,SAAS,wBAAwB,EAAE,aAA2C;AAC5E,QAAM,EAAE,OAAO,YAAA,IAAgB,yBAAA;AAC/B,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAA8B,EAAE,SAAS,GAAG;AAE5E,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,OAAO;AACV,eAAS,EAAE,SAAS,GAAG;AACvB;AAAA,IACF;AACA,UAAM,UAAU,YAAY,QAAQ,IAAI,KAAK;AAC7C,QAAI,SAAS;AACX,YAAM,SAAS,QAAQ,QAAQ,IAAI;AACnC,UAAI,QAAQ;AACV,cAAM,aAAa,OAAO,sBAAA;AAC1B,cAAM,cAAc,QAAQ,sBAAA;AAC5B,iBAAS;AAAA,UACP,MAAM,YAAY,OAAO,WAAW;AAAA,UACpC,OAAO,YAAY;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,WAAW,CAAC;AAEvB,QAAM,UAAU,CAAC,OAAO,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEtE,6BAAQ,OAAA,EAAI,WAAW,SAAS,OAAc,eAAW,MAAC;AAC5D;AAMA,SAAS,uBAAuB,EAAE,aAA0C;AAC1E,QAAM,MAAM,yBAAA;AACZ,QAAM,EAAE,cAAc,aAAa,OAAO,gBAAgB;AAC1D,QAAM,SAAS,CAAC,CAAC;AAGjB,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AAEtD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,UAAU,CAAC,MAAO;AACvB,UAAM,UAAU,YAAY,QAAQ,IAAI,KAAK;AAC7C,QAAI,CAAC,WAAW,CAAC,YAAY,QAAS;AAEtC,UAAM,UAAU,YAAY,QAAQ;AACpC,QAAI,CAAC,QAAS;AAEd,UAAM,UAAU,QAAQ,sBAAA;AACxB,UAAM,cAAc,QAAQ,sBAAA;AAC5B,mBAAe,YAAY,OAAO,QAAQ,IAAI;AAAA,EAChD,GAAG,CAAC,QAAQ,OAAO,aAAa,WAAW,CAAC;AAE5C,QAAM,UAAU;AAAA,IACd,gCAAgC,SAAS,GAAG,aAAa,KAAK,OAAO;AAAA,IACrE,iCAAiC,SAAS,GAAG,aAAa,MAAM,OAAO;AAAA,IACvE,+BAA+B,GAAG,WAAW;AAAA,EAAA;AAI/C,QAAM,UAAU,MAAM;AACpB,QAAI,QAAQ;AACV,UAAI,kBAAkB,UAAU;AAChC,UAAI,IAAI,kBAAkB,SAAS;AACjC,qBAAa,IAAI,kBAAkB,OAAO;AAAA,MAC5C;AAAA,IACF,OAAO;AACL,UAAI,kBAAkB,UAAU,WAAW,MAAM;AAC/C,YAAI,kBAAkB,UAAU;AAAA,MAClC,GAAG,IAAI,iBAAiB;AAAA,IAC1B;AAAA,EAEF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,UAAU,CAAC,OAAO,UAAU,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAErE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,MACX,OAAO;AAAA,MACP,cAAY,SAAS,SAAS;AAAA,MAC9B,MAAK;AAAA,IAAA;AAAA,EAAA;AAGX;AAMA,SAAS,4BAA4B,EAAE,YAA8C;AACnF,QAAM,MAAM,yBAAA;AAEZ,QAAM,UAAU,MAAM;AACpB,QAAI,yBAAyB,QAAQ;AACrC,WAAO,MAAM,IAAI,yBAAyB,IAAI;AAAA,EAEhD,GAAG,CAAC,QAAQ,CAAC;AAIb,SAAO;AACT;AAMA,SAAS,0BAA0B,EAAE,YAA4C;AAC/E,QAAM,MAAM,yBAAA;AAEZ,QAAM,UAAU,MAAM;AACpB,QAAI,uBAAuB,QAAQ;AACnC,WAAO,MAAM,IAAI,uBAAuB,IAAI;AAAA,EAE9C,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AACT;AAMA,SAAS,4BAA4B,EAAE,UAAU,SAA2C;AAC1F,SACE,qBAAC,OAAA,EAAI,MAAK,SAAQ,cAAY,OAC3B,UAAA;AAAA,IAAA,SAAS,oBAAC,OAAA,EAAI,WAAW,OAAO,oBAAqB,UAAA,OAAM;AAAA,IAC5D,oBAAC,OAAA,EAAI,WAAW,OAAO,WAAY,SAAA,CAAS;AAAA,EAAA,GAC9C;AAEJ;AAMA,SAAS,kBAAkB;AACzB,QAAM,EAAE,YAAY,cAAA,IAAkB,yBAAA;AAEtC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW,OAAO;AAAA,MAClB,SAAS,MAAM,cAAc,CAAC,UAAU;AAAA,MACxC,cAAW;AAAA,MACX,iBAAe;AAAA,MAEd,UAAA,aAAa,oBAAC,GAAA,EAAE,MAAM,IAAI,eAAW,KAAA,CAAC,IAAK,oBAAC,MAAA,EAAK,MAAM,IAAI,eAAW,KAAA,CAAC;AAAA,IAAA;AAAA,EAAA;AAG9E;AAMA,SAAS,eAAe;AACtB,QAAM,MAAM,yBAAA;AACZ,QAAM,YAAY,MAAM,OAAuB,IAAI;AAEnD,eAAa,WAAW,IAAI;AAG5B,QAAM,UAAU,MAAM;AACpB,aAAS,KAAK,MAAM,WAAW;AAC/B,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAM,UAAU,MAAM;AACpB,UAAM,gBAAgB,CAAC,MAAqB;AAC1C,UAAI,EAAE,QAAQ,UAAU;AACtB,YAAI,cAAc,KAAK;AAAA,MACzB;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM,SAAS,oBAAoB,WAAW,aAAa;AAAA,EACpE,GAAG,CAAC,GAAG,CAAC;AAGR,QAAM,YAAY,MAAM,QAAQ,MAAM;AACpC,UAAM,QAAkC,CAAA;AACxC,eAAW,SAAS,IAAI,aAAa,SAAS;AAC5C,YAAM,OAAO,IAAI,YAAY,QAAQ,IAAI,KAAK;AAC9C,UAAI,KAAM,OAAM,KAAK,IAAI;AAAA,IAC3B;AACA,WAAO;AAAA,EACT,GAAG,CAAC,IAAI,cAAc,IAAI,WAAW,CAAC;AAEtC,QAAM,kBAAkB,MAAM;AAC5B,QAAI,cAAc,KAAK;AAAA,EACzB;AAEA,QAAM,gBACJ,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,OAAO;AAAA,QAClB,SAAS,MAAM,IAAI,cAAc,KAAK;AAAA,QACtC,eAAW;AAAA,MAAA;AAAA,IAAA;AAAA,IAEb;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAW,OAAO;AAAA,QAClB,MAAK;AAAA,QACL,cAAU;AAAA,QACV,cAAW;AAAA,QAEX,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAW,OAAO,cACpB,UAAA;AAAA,YAAA,IAAI,2CAAwB,QAAA,CAAA,CAAK;AAAA,YAClC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,WAAW,OAAO;AAAA,gBAClB,SAAS,MAAM,IAAI,cAAc,KAAK;AAAA,gBACtC,cAAW;AAAA,gBAEX,UAAA,oBAAC,GAAA,EAAE,MAAM,IAAI,eAAW,KAAA,CAAC;AAAA,cAAA;AAAA,YAAA;AAAA,UAC3B,GACF;AAAA,8BACC,YAAA,EAAW,aAAY,YAAW,WAAW,OAAO,YAGlD,UAAA,IAAI,wBACH,IAAI,wBAEJ,oBAAC,OAAA,EAAI,WAAW,OAAO,WACpB,UAAA,UAAU;AAAA,YAAI,CAAC,SACd,KAAK,kBACH;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,OAAO,KAAK;AAAA,gBACZ,aAAa;AAAA,gBAEZ,UAAA,KAAK;AAAA,cAAA;AAAA,cAJD,KAAK;AAAA,YAAA,IAMV,KAAK,WACP;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAW,OAAO;AAAA,gBAClB,MAAM,KAAK;AAAA,gBACX,SAAS;AAAA,gBAER,UAAA,KAAK;AAAA,cAAA;AAAA,cALD,KAAK;AAAA,YAAA,IAOV;AAAA,UAAA,GAER,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAGF,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,SAAO,aAAa,eAAe,SAAS,IAAI;AAClD;AAMA,SAAS,yBAAyB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE,qBAAC,aAAA,EAAY,aAAa,OACxB,UAAA;AAAA,IAAA,oBAAC,YAAY,SAAZ,EAAoB,WAAW,OAAO,0BACpC,UAAA,OACH;AAAA,IACA,oBAAC,YAAY,SAAZ,EACC,UAAA,oBAAC,OAAA,EAAI,WAAW,OAAO,0BAA0B,SAAS,aACvD,SAAA,CACH,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAMO,MAAM,iBAAiB,OAAO,OAAO,oBAAoB;AAAA,EAC9D,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AACjB,CAAC;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/NavigationMenu/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { CaretDown, CaretRight, List, X } from '@phosphor-icons/react';\nimport { handleArrowNavigation, useFocusTrap } from '../../utils/a11y';\nimport { Collapsible } from '../Collapsible';\nimport { ScrollArea } from '../ScrollArea';\nimport {\n NavigationMenuContext,\n NavigationMenuItemContext,\n useNavigationMenuContext,\n useNavigationMenuItemContext,\n type NavigationMenuItemInfo,\n} from './NavigationMenuContext';\nimport { useNavigationMenu } from './useNavigationMenu';\nimport styles from './NavigationMenu.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface NavigationMenuProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode;\n /** Controlled open item value */\n value?: string;\n /** Default open item value */\n defaultValue?: string;\n /** Callback when open item changes */\n onValueChange?: (value: string) => void;\n /** Menu orientation */\n orientation?: 'horizontal' | 'vertical';\n /** Delay before opening on hover (ms) */\n delayDuration?: number;\n /** Duration to skip delays between triggers (ms) */\n skipDelayDuration?: number;\n}\n\nexport interface NavigationMenuListProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuItemProps {\n children: React.ReactNode;\n /** Unique item value (required for items with Trigger+Content) */\n value?: string;\n className?: string;\n}\n\nexport interface NavigationMenuTriggerProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuContentProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport interface NavigationMenuLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Simple mode: children as text content */\n children?: React.ReactNode;\n /** Structured mode: title text */\n title?: string;\n /** Structured mode: description text */\n description?: string;\n /** Structured mode: icon element */\n icon?: React.ReactNode;\n /** Whether this link is the current page */\n active?: boolean;\n /** Highlighted card style */\n featured?: boolean;\n /** Render as child element (polymorphic) */\n asChild?: boolean;\n}\n\nexport interface NavigationMenuIndicatorProps {\n className?: string;\n}\n\nexport interface NavigationMenuViewportProps {\n className?: string;\n}\n\nexport interface NavigationMenuMobileContentProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileBrandProps {\n children: React.ReactNode;\n}\n\nexport interface NavigationMenuMobileSectionProps {\n children: React.ReactNode;\n /** Section heading label */\n label?: string;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mq = window.matchMedia('(max-width: 767px)');\n setIsMobile(mq.matches);\n\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener('change', handler);\n return () => mq.removeEventListener('change', handler);\n }, []);\n\n return isMobile;\n}\n\n// ============================================\n// Root\n// ============================================\n\nfunction NavigationMenuRoot({\n children,\n value: controlledValue,\n defaultValue,\n onValueChange,\n orientation = 'horizontal',\n delayDuration = 200,\n skipDelayDuration = 300,\n className,\n 'aria-label': ariaLabel = 'Main navigation',\n ...htmlProps\n}: NavigationMenuProps) {\n const rootId = React.useId();\n const isMobile = useIsMobile();\n\n const state = useNavigationMenu({\n value: controlledValue,\n defaultValue,\n onValueChange,\n delayDuration,\n skipDelayDuration,\n });\n\n const classes = [\n styles.root,\n orientation === 'vertical' && styles.rootVertical,\n className,\n ].filter(Boolean).join(' ');\n\n const contextValue = React.useMemo(\n () => ({\n ...state,\n orientation,\n isMobile,\n rootId,\n }),\n [state, orientation, isMobile, rootId]\n );\n\n return (\n <NavigationMenuContext.Provider value={contextValue}>\n <nav {...htmlProps} className={classes} aria-label={ariaLabel} data-orientation={orientation}>\n {children}\n {isMobile && <MobileHamburger />}\n {isMobile && state.mobileOpen && <MobileDrawer />}\n </nav>\n </NavigationMenuContext.Provider>\n );\n}\n\n// ============================================\n// List\n// ============================================\n\nfunction NavigationMenuList({ children, className }: NavigationMenuListProps) {\n const { orientation, triggerOrder, triggerRefs, value } = useNavigationMenuContext();\n\n const listRef = React.useRef<HTMLUListElement>(null);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n const order = triggerOrder.current;\n const currentIdx = order.indexOf(value);\n\n const newIdx = handleArrowNavigation(e, order, currentIdx >= 0 ? currentIdx : 0, {\n orientation: orientation === 'horizontal' ? 'horizontal' : 'vertical',\n loop: true,\n });\n\n if (newIdx !== undefined) {\n const targetValue = order[newIdx];\n const trigger = triggerRefs.current.get(targetValue);\n trigger?.focus();\n }\n };\n\n const classes = [\n styles.list,\n orientation === 'vertical' && styles.listVertical,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <ul\n ref={listRef}\n className={classes}\n role=\"list\"\n data-orientation={orientation}\n onKeyDown={handleKeyDown}\n >\n {children}\n </ul>\n );\n}\n\n// ============================================\n// Item\n// ============================================\n\nlet itemCounter = 0;\n\nfunction NavigationMenuItem({ children, value: valueProp, className }: NavigationMenuItemProps) {\n const rootCtx = useNavigationMenuContext();\n const [autoValue] = React.useState(() => valueProp || `navmenu-item-${++itemCounter}`);\n const triggerId = `${rootCtx.rootId}-trigger-${autoValue}`;\n const contentId = `${rootCtx.rootId}-content-${autoValue}`;\n\n const itemCtx = React.useMemo(\n () => ({\n value: autoValue,\n triggerId,\n contentId,\n }),\n [autoValue, triggerId, contentId]\n );\n\n return (\n <NavigationMenuItemContext.Provider value={itemCtx}>\n <li className={className}>{children}</li>\n </NavigationMenuItemContext.Provider>\n );\n}\n\n// ============================================\n// Trigger\n// ============================================\n\nfunction NavigationMenuTrigger({ children, className }: NavigationMenuTriggerProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n\n // Register trigger\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n React.useEffect(() => {\n if (triggerRef.current) {\n ctx.triggerRefs.current.set(itemCtx.value, triggerRef.current);\n if (!ctx.triggerOrder.current.includes(itemCtx.value)) {\n ctx.triggerOrder.current.push(itemCtx.value);\n }\n }\n return () => {\n ctx.triggerRefs.current.delete(itemCtx.value);\n ctx.triggerOrder.current = ctx.triggerOrder.current.filter(v => v !== itemCtx.value);\n };\n // Only register/unregister on mount/unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value]);\n\n // Register item info for mobile drawer\n React.useEffect(() => {\n const label = typeof children === 'string' ? children : '';\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: label || existing?.triggerLabel || '',\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n const handleClick = () => {\n ctx.setValue(isOpen ? '' : itemCtx.value);\n };\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n\n // Skip delay if recently open\n if (ctx.isRecentlyOpenRef.current) {\n ctx.setValue(itemCtx.value);\n return;\n }\n\n ctx.openTimerRef.current = setTimeout(() => {\n ctx.setValue(itemCtx.value);\n }, ctx.delayDuration);\n };\n\n const handlePointerLeave = () => {\n if (ctx.openTimerRef.current) {\n clearTimeout(ctx.openTimerRef.current);\n ctx.openTimerRef.current = null;\n }\n\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n ctx.setValue(isOpen ? '' : itemCtx.value);\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n ctx.setValue('');\n triggerRef.current?.focus();\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n return (\n <button\n ref={triggerRef}\n type=\"button\"\n id={itemCtx.triggerId}\n className={classes}\n aria-expanded={isOpen}\n aria-controls={itemCtx.contentId}\n data-state={isOpen ? 'open' : 'closed'}\n onClick={handleClick}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n onKeyDown={handleKeyDown}\n >\n {children}\n <CaretDown size={12} className={styles.triggerChevron} aria-hidden />\n </button>\n );\n}\n\n// ============================================\n// Content\n// ============================================\n\nfunction NavigationMenuContent({ children, className }: NavigationMenuContentProps) {\n const ctx = useNavigationMenuContext();\n const itemCtx = useNavigationMenuItemContext();\n const isOpen = ctx.value === itemCtx.value;\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // Register content children into item info (for mobile drawer)\n React.useEffect(() => {\n const existing = ctx.itemInfoMap.current.get(itemCtx.value);\n ctx.itemInfoMap.current.set(itemCtx.value, {\n ...existing,\n value: itemCtx.value,\n triggerLabel: existing?.triggerLabel || '',\n contentChildren: children,\n } as NavigationMenuItemInfo);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemCtx.value, children]);\n\n // Measure content for viewport animation\n React.useEffect(() => {\n if (!isOpen || !contentRef.current) return;\n\n const el = contentRef.current;\n const observer = new ResizeObserver(([entry]) => {\n if (entry) {\n ctx.setViewportSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n });\n observer.observe(el);\n\n // Initial measurement\n ctx.setViewportSize({\n width: el.scrollWidth,\n height: el.scrollHeight,\n });\n\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n // Determine motion direction\n const prevValue = ctx.previousValue.current;\n const triggerOrder = ctx.triggerOrder.current;\n const prevIdx = triggerOrder.indexOf(prevValue);\n const currentIdx = triggerOrder.indexOf(itemCtx.value);\n let motion: string | undefined;\n if (isOpen && prevValue && prevValue !== itemCtx.value) {\n motion = currentIdx > prevIdx ? 'from-end' : 'from-start';\n }\n\n // Update previousValue when this content becomes active\n React.useEffect(() => {\n if (isOpen) {\n ctx.previousValue.current = itemCtx.value;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, itemCtx.value]);\n\n if (!isOpen) return null;\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n const handlePointerEnter = () => {\n if (ctx.closeTimerRef.current) {\n clearTimeout(ctx.closeTimerRef.current);\n ctx.closeTimerRef.current = null;\n }\n };\n\n const handlePointerLeave = () => {\n ctx.closeTimerRef.current = setTimeout(() => {\n ctx.setValue('');\n }, ctx.delayDuration);\n };\n\n const contentElement = (\n <div\n ref={contentRef}\n id={itemCtx.contentId}\n className={classes}\n role=\"region\"\n aria-labelledby={itemCtx.triggerId}\n data-motion={motion}\n onPointerEnter={handlePointerEnter}\n onPointerLeave={handlePointerLeave}\n >\n {children}\n </div>\n );\n\n // Portal into viewport if it exists\n if (ctx.viewportRef.current) {\n return createPortal(contentElement, ctx.viewportRef.current);\n }\n\n return contentElement;\n}\n\n// ============================================\n// Link\n// ============================================\n\nfunction NavigationMenuLink({\n children,\n title,\n description,\n icon,\n active = false,\n featured = false,\n asChild = false,\n className,\n href,\n onClick,\n ...htmlProps\n}: NavigationMenuLinkProps) {\n const ctx = React.useContext(NavigationMenuContext);\n const isStructured = !!(title || description || icon);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n onClick?.(e);\n // Close mobile drawer on link click\n if (ctx?.isMobile && ctx.mobileOpen) {\n ctx.setMobileOpen(false);\n }\n // Close desktop menu\n if (ctx) {\n ctx.setValue('');\n }\n };\n\n // Structured mode (title + description + icon)\n if (isStructured) {\n const classes = [\n styles.link,\n styles.linkStructured,\n active && styles.linkActive,\n featured && styles.linkFeatured,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n children: (\n <>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </>\n ),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return (\n <a {...linkProps}>\n {icon && <span className={styles.linkIcon}>{icon}</span>}\n <span className={styles.linkBody}>\n {title && <span className={styles.linkTitle}>{title}</span>}\n {description && <span className={styles.linkDescription}>{description}</span>}\n </span>\n </a>\n );\n }\n\n // Simple link mode\n const classes = [\n styles.link,\n active && styles.linkActive,\n className,\n ].filter(Boolean).join(' ');\n\n const linkProps = {\n ...htmlProps,\n className: classes,\n href,\n 'aria-current': active ? ('page' as const) : undefined,\n onClick: handleClick,\n };\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ...linkProps,\n className: [classes, (children.props as { className?: string }).className].filter(Boolean).join(' '),\n } as React.HTMLAttributes<HTMLElement>);\n }\n\n return <a {...linkProps}>{children}</a>;\n}\n\n// ============================================\n// Indicator\n// ============================================\n\nfunction NavigationMenuIndicator({ className }: NavigationMenuIndicatorProps) {\n const { value, triggerRefs } = useNavigationMenuContext();\n const [style, setStyle] = React.useState<React.CSSProperties>({ opacity: 0 });\n\n React.useEffect(() => {\n if (!value) {\n setStyle({ opacity: 0 });\n return;\n }\n const trigger = triggerRefs.current.get(value);\n if (trigger) {\n const parent = trigger.closest('ul');\n if (parent) {\n const parentRect = parent.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setStyle({\n left: triggerRect.left - parentRect.left,\n width: triggerRect.width,\n opacity: 1,\n });\n }\n }\n }, [value, triggerRefs]);\n\n const classes = [styles.indicator, className].filter(Boolean).join(' ');\n\n return <div className={classes} style={style} aria-hidden />;\n}\n\n// ============================================\n// Viewport\n// ============================================\n\nfunction NavigationMenuViewport({ className }: NavigationMenuViewportProps) {\n const ctx = useNavigationMenuContext();\n const { viewportSize, viewportRef, value, triggerRefs } = ctx;\n const isOpen = !!value;\n\n // Compute the active trigger's left offset relative to the nav root\n const [triggerLeft, setTriggerLeft] = React.useState(0);\n\n React.useEffect(() => {\n if (!isOpen || !value) return;\n const trigger = triggerRefs.current.get(value);\n if (!trigger || !viewportRef.current) return;\n\n const navRoot = viewportRef.current.parentElement;\n if (!navRoot) return;\n\n const navRect = navRoot.getBoundingClientRect();\n const triggerRect = trigger.getBoundingClientRect();\n setTriggerLeft(triggerRect.left - navRect.left);\n }, [isOpen, value, triggerRefs, viewportRef]);\n\n const cssVars = {\n '--fui-navmenu-viewport-width': isOpen ? `${viewportSize.width}px` : '0px',\n '--fui-navmenu-viewport-height': isOpen ? `${viewportSize.height}px` : '0px',\n '--fui-navmenu-viewport-left': `${triggerLeft}px`,\n } as React.CSSProperties;\n\n // Mark skip-delay state\n React.useEffect(() => {\n if (isOpen) {\n ctx.isRecentlyOpenRef.current = true;\n if (ctx.skipDelayTimerRef.current) {\n clearTimeout(ctx.skipDelayTimerRef.current);\n }\n } else {\n ctx.skipDelayTimerRef.current = setTimeout(() => {\n ctx.isRecentlyOpenRef.current = false;\n }, ctx.skipDelayDuration);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const classes = [styles.viewport, className].filter(Boolean).join(' ');\n\n return (\n <div\n ref={viewportRef}\n className={classes}\n style={cssVars}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"presentation\"\n />\n );\n}\n\n// ============================================\n// MobileContent (slot for extra mobile sections)\n// ============================================\n\nfunction NavigationMenuMobileContent({ children }: NavigationMenuMobileContentProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileContentChildren(children);\n return () => ctx.setMobileContentChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n // This component renders nothing visually on desktop or in the tree.\n // Its children are extracted into the mobile drawer via context.\n return null;\n}\n\n// ============================================\n// MobileBrand (slot for brand in mobile drawer header)\n// ============================================\n\nfunction NavigationMenuMobileBrand({ children }: NavigationMenuMobileBrandProps) {\n const ctx = useNavigationMenuContext();\n\n React.useEffect(() => {\n ctx.setMobileBrandChildren(children);\n return () => ctx.setMobileBrandChildren(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [children]);\n\n return null;\n}\n\n// ============================================\n// MobileSection\n// ============================================\n\nfunction NavigationMenuMobileSection({ children, label }: NavigationMenuMobileSectionProps) {\n return (\n <div role=\"group\" aria-label={label}>\n {label && <div className={styles.drawerSectionLabel}>{label}</div>}\n <div className={styles.drawerNav}>{children}</div>\n </div>\n );\n}\n\n// ============================================\n// Mobile Hamburger Button\n// ============================================\n\nfunction MobileHamburger() {\n const { mobileOpen, setMobileOpen } = useNavigationMenuContext();\n\n return (\n <button\n type=\"button\"\n className={styles.hamburger}\n onClick={() => setMobileOpen(!mobileOpen)}\n aria-label=\"Toggle navigation\"\n aria-expanded={mobileOpen}\n >\n {mobileOpen ? <X size={24} aria-hidden /> : <List size={24} aria-hidden />}\n </button>\n );\n}\n\n// ============================================\n// Mobile Drawer\n// ============================================\n\nfunction MobileDrawer() {\n const ctx = useNavigationMenuContext();\n const drawerRef = React.useRef<HTMLDivElement>(null);\n\n useFocusTrap(drawerRef, true);\n\n // Lock body scroll\n React.useEffect(() => {\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle Escape\n React.useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n ctx.setMobileOpen(false);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [ctx]);\n\n // Build auto-converted nav items from item info registry\n const autoItems = React.useMemo(() => {\n const items: NavigationMenuItemInfo[] = [];\n for (const value of ctx.triggerOrder.current) {\n const info = ctx.itemInfoMap.current.get(value);\n if (info) items.push(info);\n }\n return items;\n }, [ctx.triggerOrder, ctx.itemInfoMap]);\n\n const handleLinkClick = () => {\n ctx.setMobileOpen(false);\n };\n\n const drawerContent = (\n <>\n <div\n className={styles.drawerBackdrop}\n onClick={() => ctx.setMobileOpen(false)}\n aria-hidden\n />\n <div\n ref={drawerRef}\n className={styles.drawer}\n role=\"dialog\"\n aria-modal\n aria-label=\"Navigation\"\n >\n <div className={styles.drawerHeader}>\n {ctx.mobileBrandChildren ?? <span />}\n <button\n type=\"button\"\n className={styles.drawerClose}\n onClick={() => ctx.setMobileOpen(false)}\n aria-label=\"Close navigation\"\n >\n <X size={20} aria-hidden />\n </button>\n </div>\n <ScrollArea orientation=\"vertical\" className={styles.drawerBody}>\n {/* When MobileContent is provided, it takes full control of the drawer nav.\n Otherwise, auto-convert registered Trigger+Content items. */}\n {ctx.mobileContentChildren ? (\n ctx.mobileContentChildren\n ) : (\n <div className={styles.drawerNav}>\n {autoItems.map((item) =>\n item.contentChildren ? (\n <MobileCollapsibleSection\n key={item.value}\n label={item.triggerLabel}\n onLinkClick={handleLinkClick}\n >\n {item.contentChildren}\n </MobileCollapsibleSection>\n ) : item.linkHref ? (\n <a\n key={item.value}\n className={styles.drawerLink}\n href={item.linkHref}\n onClick={handleLinkClick}\n >\n {item.triggerLabel}\n </a>\n ) : null\n )}\n </div>\n )}\n </ScrollArea>\n </div>\n </>\n );\n\n if (typeof document === 'undefined') return null;\n return createPortal(drawerContent, document.body);\n}\n\n// ============================================\n// Mobile Collapsible Section (auto-converted)\n// ============================================\n\nfunction MobileCollapsibleSection({\n label,\n children,\n onLinkClick,\n}: {\n label: string;\n children: React.ReactNode;\n onLinkClick: () => void;\n}) {\n return (\n <Collapsible defaultOpen={false}>\n <Collapsible.Trigger className={styles.drawerCollapsibleTrigger}>\n {label}\n </Collapsible.Trigger>\n <Collapsible.Content>\n <div\n className={styles.drawerCollapsibleContent}\n onClick={onLinkClick}\n onKeyDown={(e) => { if (e.key === 'Enter') onLinkClick(); }}\n role=\"group\"\n >\n {children}\n </div>\n </Collapsible.Content>\n </Collapsible>\n );\n}\n\n// ============================================\n// Export Compound Component\n// ============================================\n\nexport const NavigationMenu = Object.assign(NavigationMenuRoot, {\n List: NavigationMenuList,\n Item: NavigationMenuItem,\n Trigger: NavigationMenuTrigger,\n Content: NavigationMenuContent,\n Link: NavigationMenuLink,\n Indicator: NavigationMenuIndicator,\n Viewport: NavigationMenuViewport,\n MobileBrand: NavigationMenuMobileBrand,\n MobileContent: NavigationMenuMobileContent,\n MobileSection: NavigationMenuMobileSection,\n});\n\nexport {\n NavigationMenuRoot,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n NavigationMenuMobileBrand,\n NavigationMenuMobileContent,\n NavigationMenuMobileSection,\n};\n"],"names":["classes","linkProps"],"mappings":"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"}
|
|
@@ -70,15 +70,15 @@ function SkeletonText({
|
|
|
70
70
|
Skeleton_module.default[`gap-${gap}`],
|
|
71
71
|
className
|
|
72
72
|
].filter(Boolean).join(" ");
|
|
73
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: containerClasses, "aria-hidden": "true", children: Array.from({ length: lines }, (_,
|
|
74
|
-
const isLast =
|
|
73
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: containerClasses, "aria-hidden": "true", children: Array.from({ length: lines }, (_, lineIdx) => {
|
|
74
|
+
const isLast = lineIdx === lines - 1;
|
|
75
75
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
76
76
|
"div",
|
|
77
77
|
{
|
|
78
78
|
className: Skeleton_module.default.textLine,
|
|
79
79
|
style: isLast && lines > 1 ? { width: `${lastLineWidth}%` } : void 0
|
|
80
80
|
},
|
|
81
|
-
|
|
81
|
+
`line-${lineIdx}`
|
|
82
82
|
);
|
|
83
83
|
}) });
|
|
84
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/components/Skeleton/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport styles from './Skeleton.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type SkeletonVariant =\n | 'text' // Single line of text, height: 1em\n | 'heading' // Heading text, height: 1.5em\n | 'avatar' // Circular, uses size prop\n | 'button' // Button shape, uses size prop\n | 'input' // Form input height\n | 'rect'; // Rectangle, requires explicit dimensions or fill\n\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps {\n /**\n * Semantic variant that auto-sizes based on design tokens.\n * @default 'rect'\n */\n variant?: SkeletonVariant;\n /**\n * Size variant for avatar/button. Ignored for text/heading/input.\n * @default 'md'\n */\n size?: SkeletonSize;\n /**\n * Width in pixels or CSS value. Auto-determined for most variants.\n */\n width?: number | string;\n /**\n * Height in pixels or CSS value. Auto-determined for semantic variants.\n */\n height?: number | string;\n /**\n * Fill parent container (100% width and height).\n * Useful when parent has explicit dimensions.\n */\n fill?: boolean;\n /**\n * Border radius override. Auto-determined for most variants.\n */\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';\n /**\n * Disable animation for reduced motion preference.\n * @default false\n */\n static?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nexport interface SkeletonTextProps {\n /** Number of text lines to render */\n lines?: number;\n /**\n * Width of last line as percentage.\n * Creates natural paragraph appearance.\n * @default 80\n */\n lastLineWidth?: number;\n /** Gap between lines. Uses spacing tokens. */\n gap?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n}\n\n// ============================================\n// Component\n// ============================================\n\nconst SkeletonBase = React.forwardRef<HTMLDivElement, SkeletonProps>(\n function SkeletonBase(\n {\n variant = 'rect',\n size = 'md',\n width,\n height,\n fill = false,\n radius,\n static: isStatic = false,\n className,\n },\n ref\n ) {\n const classes = [\n styles.skeleton,\n styles[variant],\n variant === 'avatar' && styles[`avatar-${size}`],\n variant === 'button' && styles[`button-${size}`],\n fill && styles.fill,\n radius && styles[`radius-${radius}`],\n isStatic && styles.static,\n className,\n ].filter(Boolean).join(' ');\n\n const style: React.CSSProperties = {};\n\n if (width !== undefined) {\n style.width = typeof width === 'number' ? `${width}px` : width;\n }\n if (height !== undefined) {\n style.height = typeof height === 'number' ? `${height}px` : height;\n }\n\n return (\n <div\n ref={ref}\n className={classes}\n style={Object.keys(style).length > 0 ? style : undefined}\n aria-hidden=\"true\"\n />\n );\n }\n);\n\n// ============================================\n// Skeleton.Text - Multi-line text skeleton\n// ============================================\n\nfunction SkeletonText({\n lines = 3,\n lastLineWidth = 80,\n gap = 'sm',\n className,\n}: SkeletonTextProps) {\n const containerClasses = [\n styles.textContainer,\n styles[`gap-${gap}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div className={containerClasses} aria-hidden=\"true\">\n {Array.from({ length: lines }, (_,
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/components/Skeleton/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport styles from './Skeleton.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type SkeletonVariant =\n | 'text' // Single line of text, height: 1em\n | 'heading' // Heading text, height: 1.5em\n | 'avatar' // Circular, uses size prop\n | 'button' // Button shape, uses size prop\n | 'input' // Form input height\n | 'rect'; // Rectangle, requires explicit dimensions or fill\n\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps {\n /**\n * Semantic variant that auto-sizes based on design tokens.\n * @default 'rect'\n */\n variant?: SkeletonVariant;\n /**\n * Size variant for avatar/button. Ignored for text/heading/input.\n * @default 'md'\n */\n size?: SkeletonSize;\n /**\n * Width in pixels or CSS value. Auto-determined for most variants.\n */\n width?: number | string;\n /**\n * Height in pixels or CSS value. Auto-determined for semantic variants.\n */\n height?: number | string;\n /**\n * Fill parent container (100% width and height).\n * Useful when parent has explicit dimensions.\n */\n fill?: boolean;\n /**\n * Border radius override. Auto-determined for most variants.\n */\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';\n /**\n * Disable animation for reduced motion preference.\n * @default false\n */\n static?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nexport interface SkeletonTextProps {\n /** Number of text lines to render */\n lines?: number;\n /**\n * Width of last line as percentage.\n * Creates natural paragraph appearance.\n * @default 80\n */\n lastLineWidth?: number;\n /** Gap between lines. Uses spacing tokens. */\n gap?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n}\n\n// ============================================\n// Component\n// ============================================\n\nconst SkeletonBase = React.forwardRef<HTMLDivElement, SkeletonProps>(\n function SkeletonBase(\n {\n variant = 'rect',\n size = 'md',\n width,\n height,\n fill = false,\n radius,\n static: isStatic = false,\n className,\n },\n ref\n ) {\n const classes = [\n styles.skeleton,\n styles[variant],\n variant === 'avatar' && styles[`avatar-${size}`],\n variant === 'button' && styles[`button-${size}`],\n fill && styles.fill,\n radius && styles[`radius-${radius}`],\n isStatic && styles.static,\n className,\n ].filter(Boolean).join(' ');\n\n const style: React.CSSProperties = {};\n\n if (width !== undefined) {\n style.width = typeof width === 'number' ? `${width}px` : width;\n }\n if (height !== undefined) {\n style.height = typeof height === 'number' ? `${height}px` : height;\n }\n\n return (\n <div\n ref={ref}\n className={classes}\n style={Object.keys(style).length > 0 ? style : undefined}\n aria-hidden=\"true\"\n />\n );\n }\n);\n\n// ============================================\n// Skeleton.Text - Multi-line text skeleton\n// ============================================\n\nfunction SkeletonText({\n lines = 3,\n lastLineWidth = 80,\n gap = 'sm',\n className,\n}: SkeletonTextProps) {\n const containerClasses = [\n styles.textContainer,\n styles[`gap-${gap}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div className={containerClasses} aria-hidden=\"true\">\n {Array.from({ length: lines }, (_, lineIdx) => {\n const isLast = lineIdx === lines - 1;\n return (\n <div\n key={`line-${lineIdx}`}\n className={styles.textLine}\n style={isLast && lines > 1 ? { width: `${lastLineWidth}%` } : undefined}\n />\n );\n })}\n </div>\n );\n}\n\n// ============================================\n// Skeleton.Circle - Shorthand for avatar variant\n// ============================================\n\nfunction SkeletonCircle({\n size = 'md',\n className,\n}: {\n size?: SkeletonSize | number;\n className?: string;\n}) {\n if (typeof size === 'number') {\n return (\n <SkeletonBase\n variant=\"rect\"\n width={size}\n height={size}\n radius=\"full\"\n className={className}\n />\n );\n }\n return <SkeletonBase variant=\"avatar\" size={size} className={className} />;\n}\n\n// ============================================\n// Compound Component\n// ============================================\n\nexport const Skeleton = Object.assign(SkeletonBase, {\n Text: SkeletonText,\n Circle: SkeletonCircle,\n});\n"],"names":["React","SkeletonBase","styles","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyEA,MAAM,eAAeA,iBAAM;AAAA,EACzB,SAASC,cACP;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,QAAQ,WAAW;AAAA,IACnB;AAAA,EAAA,GAEF,KACA;AACA,UAAM,UAAU;AAAA,MACdC,gBAAAA,QAAO;AAAA,MACPA,gBAAAA,QAAO,OAAO;AAAA,MACd,YAAY,YAAYA,gBAAAA,QAAO,UAAU,IAAI,EAAE;AAAA,MAC/C,YAAY,YAAYA,gBAAAA,QAAO,UAAU,IAAI,EAAE;AAAA,MAC/C,QAAQA,gBAAAA,QAAO;AAAA,MACf,UAAUA,gBAAAA,QAAO,UAAU,MAAM,EAAE;AAAA,MACnC,YAAYA,gBAAAA,QAAO;AAAA,MACnB;AAAA,IAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,UAAM,QAA6B,CAAA;AAEnC,QAAI,UAAU,QAAW;AACvB,YAAM,QAAQ,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,IAC3D;AACA,QAAI,WAAW,QAAW;AACxB,YAAM,SAAS,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,IAC9D;AAEA,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,QACX,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AAAA,QAC/C,eAAY;AAAA,MAAA;AAAA,IAAA;AAAA,EAGlB;AACF;AAMA,SAAS,aAAa;AAAA,EACpB,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN;AACF,GAAsB;AACpB,QAAM,mBAAmB;AAAA,IACvBD,gBAAAA,QAAO;AAAA,IACPA,gBAAAA,QAAO,OAAO,GAAG,EAAE;AAAA,IACnB;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACEC,2BAAAA,IAAC,OAAA,EAAI,WAAW,kBAAkB,eAAY,QAC3C,UAAA,MAAM,KAAK,EAAE,QAAQ,MAAA,GAAS,CAAC,GAAG,YAAY;AAC7C,UAAM,SAAS,YAAY,QAAQ;AACnC,WACEA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAWD,gBAAAA,QAAO;AAAA,QAClB,OAAO,UAAU,QAAQ,IAAI,EAAE,OAAO,GAAG,aAAa,QAAQ;AAAA,MAAA;AAAA,MAFzD,QAAQ,OAAO;AAAA,IAAA;AAAA,EAK1B,CAAC,EAAA,CACH;AAEJ;AAMA,SAAS,eAAe;AAAA,EACtB,OAAO;AAAA,EACP;AACF,GAGG;AACD,MAAI,OAAO,SAAS,UAAU;AAC5B,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAO;AAAA,QACP;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACA,SAAOA,2BAAAA,IAAC,cAAA,EAAa,SAAQ,UAAS,MAAY,WAAsB;AAC1E;AAMO,MAAM,WAAW,OAAO,OAAO,cAAc;AAAA,EAClD,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;;"}
|
|
@@ -51,15 +51,15 @@ function SkeletonText({
|
|
|
51
51
|
styles[`gap-${gap}`],
|
|
52
52
|
className
|
|
53
53
|
].filter(Boolean).join(" ");
|
|
54
|
-
return /* @__PURE__ */ jsx("div", { className: containerClasses, "aria-hidden": "true", children: Array.from({ length: lines }, (_,
|
|
55
|
-
const isLast =
|
|
54
|
+
return /* @__PURE__ */ jsx("div", { className: containerClasses, "aria-hidden": "true", children: Array.from({ length: lines }, (_, lineIdx) => {
|
|
55
|
+
const isLast = lineIdx === lines - 1;
|
|
56
56
|
return /* @__PURE__ */ jsx(
|
|
57
57
|
"div",
|
|
58
58
|
{
|
|
59
59
|
className: styles.textLine,
|
|
60
60
|
style: isLast && lines > 1 ? { width: `${lastLineWidth}%` } : void 0
|
|
61
61
|
},
|
|
62
|
-
|
|
62
|
+
`line-${lineIdx}`
|
|
63
63
|
);
|
|
64
64
|
}) });
|
|
65
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/Skeleton/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport styles from './Skeleton.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type SkeletonVariant =\n | 'text' // Single line of text, height: 1em\n | 'heading' // Heading text, height: 1.5em\n | 'avatar' // Circular, uses size prop\n | 'button' // Button shape, uses size prop\n | 'input' // Form input height\n | 'rect'; // Rectangle, requires explicit dimensions or fill\n\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps {\n /**\n * Semantic variant that auto-sizes based on design tokens.\n * @default 'rect'\n */\n variant?: SkeletonVariant;\n /**\n * Size variant for avatar/button. Ignored for text/heading/input.\n * @default 'md'\n */\n size?: SkeletonSize;\n /**\n * Width in pixels or CSS value. Auto-determined for most variants.\n */\n width?: number | string;\n /**\n * Height in pixels or CSS value. Auto-determined for semantic variants.\n */\n height?: number | string;\n /**\n * Fill parent container (100% width and height).\n * Useful when parent has explicit dimensions.\n */\n fill?: boolean;\n /**\n * Border radius override. Auto-determined for most variants.\n */\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';\n /**\n * Disable animation for reduced motion preference.\n * @default false\n */\n static?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nexport interface SkeletonTextProps {\n /** Number of text lines to render */\n lines?: number;\n /**\n * Width of last line as percentage.\n * Creates natural paragraph appearance.\n * @default 80\n */\n lastLineWidth?: number;\n /** Gap between lines. Uses spacing tokens. */\n gap?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n}\n\n// ============================================\n// Component\n// ============================================\n\nconst SkeletonBase = React.forwardRef<HTMLDivElement, SkeletonProps>(\n function SkeletonBase(\n {\n variant = 'rect',\n size = 'md',\n width,\n height,\n fill = false,\n radius,\n static: isStatic = false,\n className,\n },\n ref\n ) {\n const classes = [\n styles.skeleton,\n styles[variant],\n variant === 'avatar' && styles[`avatar-${size}`],\n variant === 'button' && styles[`button-${size}`],\n fill && styles.fill,\n radius && styles[`radius-${radius}`],\n isStatic && styles.static,\n className,\n ].filter(Boolean).join(' ');\n\n const style: React.CSSProperties = {};\n\n if (width !== undefined) {\n style.width = typeof width === 'number' ? `${width}px` : width;\n }\n if (height !== undefined) {\n style.height = typeof height === 'number' ? `${height}px` : height;\n }\n\n return (\n <div\n ref={ref}\n className={classes}\n style={Object.keys(style).length > 0 ? style : undefined}\n aria-hidden=\"true\"\n />\n );\n }\n);\n\n// ============================================\n// Skeleton.Text - Multi-line text skeleton\n// ============================================\n\nfunction SkeletonText({\n lines = 3,\n lastLineWidth = 80,\n gap = 'sm',\n className,\n}: SkeletonTextProps) {\n const containerClasses = [\n styles.textContainer,\n styles[`gap-${gap}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div className={containerClasses} aria-hidden=\"true\">\n {Array.from({ length: lines }, (_,
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/Skeleton/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport styles from './Skeleton.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type SkeletonVariant =\n | 'text' // Single line of text, height: 1em\n | 'heading' // Heading text, height: 1.5em\n | 'avatar' // Circular, uses size prop\n | 'button' // Button shape, uses size prop\n | 'input' // Form input height\n | 'rect'; // Rectangle, requires explicit dimensions or fill\n\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps {\n /**\n * Semantic variant that auto-sizes based on design tokens.\n * @default 'rect'\n */\n variant?: SkeletonVariant;\n /**\n * Size variant for avatar/button. Ignored for text/heading/input.\n * @default 'md'\n */\n size?: SkeletonSize;\n /**\n * Width in pixels or CSS value. Auto-determined for most variants.\n */\n width?: number | string;\n /**\n * Height in pixels or CSS value. Auto-determined for semantic variants.\n */\n height?: number | string;\n /**\n * Fill parent container (100% width and height).\n * Useful when parent has explicit dimensions.\n */\n fill?: boolean;\n /**\n * Border radius override. Auto-determined for most variants.\n */\n radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';\n /**\n * Disable animation for reduced motion preference.\n * @default false\n */\n static?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nexport interface SkeletonTextProps {\n /** Number of text lines to render */\n lines?: number;\n /**\n * Width of last line as percentage.\n * Creates natural paragraph appearance.\n * @default 80\n */\n lastLineWidth?: number;\n /** Gap between lines. Uses spacing tokens. */\n gap?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n}\n\n// ============================================\n// Component\n// ============================================\n\nconst SkeletonBase = React.forwardRef<HTMLDivElement, SkeletonProps>(\n function SkeletonBase(\n {\n variant = 'rect',\n size = 'md',\n width,\n height,\n fill = false,\n radius,\n static: isStatic = false,\n className,\n },\n ref\n ) {\n const classes = [\n styles.skeleton,\n styles[variant],\n variant === 'avatar' && styles[`avatar-${size}`],\n variant === 'button' && styles[`button-${size}`],\n fill && styles.fill,\n radius && styles[`radius-${radius}`],\n isStatic && styles.static,\n className,\n ].filter(Boolean).join(' ');\n\n const style: React.CSSProperties = {};\n\n if (width !== undefined) {\n style.width = typeof width === 'number' ? `${width}px` : width;\n }\n if (height !== undefined) {\n style.height = typeof height === 'number' ? `${height}px` : height;\n }\n\n return (\n <div\n ref={ref}\n className={classes}\n style={Object.keys(style).length > 0 ? style : undefined}\n aria-hidden=\"true\"\n />\n );\n }\n);\n\n// ============================================\n// Skeleton.Text - Multi-line text skeleton\n// ============================================\n\nfunction SkeletonText({\n lines = 3,\n lastLineWidth = 80,\n gap = 'sm',\n className,\n}: SkeletonTextProps) {\n const containerClasses = [\n styles.textContainer,\n styles[`gap-${gap}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div className={containerClasses} aria-hidden=\"true\">\n {Array.from({ length: lines }, (_, lineIdx) => {\n const isLast = lineIdx === lines - 1;\n return (\n <div\n key={`line-${lineIdx}`}\n className={styles.textLine}\n style={isLast && lines > 1 ? { width: `${lastLineWidth}%` } : undefined}\n />\n );\n })}\n </div>\n );\n}\n\n// ============================================\n// Skeleton.Circle - Shorthand for avatar variant\n// ============================================\n\nfunction SkeletonCircle({\n size = 'md',\n className,\n}: {\n size?: SkeletonSize | number;\n className?: string;\n}) {\n if (typeof size === 'number') {\n return (\n <SkeletonBase\n variant=\"rect\"\n width={size}\n height={size}\n radius=\"full\"\n className={className}\n />\n );\n }\n return <SkeletonBase variant=\"avatar\" size={size} className={className} />;\n}\n\n// ============================================\n// Compound Component\n// ============================================\n\nexport const Skeleton = Object.assign(SkeletonBase, {\n Text: SkeletonText,\n Circle: SkeletonCircle,\n});\n"],"names":["SkeletonBase"],"mappings":";;;AAyEA,MAAM,eAAe,MAAM;AAAA,EACzB,SAASA,cACP;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,QAAQ,WAAW;AAAA,IACnB;AAAA,EAAA,GAEF,KACA;AACA,UAAM,UAAU;AAAA,MACd,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,MACd,YAAY,YAAY,OAAO,UAAU,IAAI,EAAE;AAAA,MAC/C,YAAY,YAAY,OAAO,UAAU,IAAI,EAAE;AAAA,MAC/C,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO,UAAU,MAAM,EAAE;AAAA,MACnC,YAAY,OAAO;AAAA,MACnB;AAAA,IAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,UAAM,QAA6B,CAAA;AAEnC,QAAI,UAAU,QAAW;AACvB,YAAM,QAAQ,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,IAC3D;AACA,QAAI,WAAW,QAAW;AACxB,YAAM,SAAS,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,IAC9D;AAEA,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,QACX,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AAAA,QAC/C,eAAY;AAAA,MAAA;AAAA,IAAA;AAAA,EAGlB;AACF;AAMA,SAAS,aAAa;AAAA,EACpB,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN;AACF,GAAsB;AACpB,QAAM,mBAAmB;AAAA,IACvB,OAAO;AAAA,IACP,OAAO,OAAO,GAAG,EAAE;AAAA,IACnB;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE,oBAAC,OAAA,EAAI,WAAW,kBAAkB,eAAY,QAC3C,UAAA,MAAM,KAAK,EAAE,QAAQ,MAAA,GAAS,CAAC,GAAG,YAAY;AAC7C,UAAM,SAAS,YAAY,QAAQ;AACnC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAW,OAAO;AAAA,QAClB,OAAO,UAAU,QAAQ,IAAI,EAAE,OAAO,GAAG,aAAa,QAAQ;AAAA,MAAA;AAAA,MAFzD,QAAQ,OAAO;AAAA,IAAA;AAAA,EAK1B,CAAC,EAAA,CACH;AAEJ;AAMA,SAAS,eAAe;AAAA,EACtB,OAAO;AAAA,EACP;AACF,GAGG;AACD,MAAI,OAAO,SAAS,UAAU;AAC5B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAO;AAAA,QACP;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACA,SAAO,oBAAC,cAAA,EAAa,SAAQ,UAAS,MAAY,WAAsB;AAC1E;AAMO,MAAM,WAAW,OAAO,OAAO,cAAc;AAAA,EAClD,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;"}
|
|
@@ -90,11 +90,12 @@ const StackRoot = React__namespace.forwardRef(
|
|
|
90
90
|
}
|
|
91
91
|
) : separator;
|
|
92
92
|
const items = [];
|
|
93
|
-
validChildren.forEach((child,
|
|
93
|
+
validChildren.forEach((child, idx) => {
|
|
94
94
|
items.push(child);
|
|
95
|
-
if (
|
|
95
|
+
if (idx < validChildren.length - 1) {
|
|
96
|
+
const childKey = React__namespace.isValidElement(child) && child.key != null ? child.key : `idx-${idx}`;
|
|
96
97
|
items.push(
|
|
97
|
-
/* @__PURE__ */ jsxRuntime.jsx(React__namespace.Fragment, { children: separatorEl }, `sep-${
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsx(React__namespace.Fragment, { children: separatorEl }, `sep-${childKey}`)
|
|
98
99
|
);
|
|
99
100
|
}
|
|
100
101
|
});
|