Skip to content
CraftDocs
GitHub
Home
Home
Changelog
What's New
Guide
Guide
Getting Started
Principles
Styling Components
Theme System
Foundations
All Tokens
Color
Elevation
Icons
Motion
Shape
Spacing
Typography
Libraries
Libraries
@xds/cli
@xds/core
Themes
Themes
Theme: daily
Default Theme
Theme: matcha
Neutral Theme
Components
Components
AppShell
AspectRatio
Avatar
Avatar
AvatarStatusDot
Badge
Banner
Breadcrumbs
BreadcrumbItem
Breadcrumbs
Button
Button
IconButton
ToggleButton
ToggleButtonGroup
Calendar
Card
Carousel
Chat
ChatComposer
ChatComposerDrawer
ChatComposerInput
ChatComposerTokenElement
ChatDictationButton
ChatLayout
ChatLayoutScrollButton
ChatMessage
ChatMessageBubble
ChatMessageList
ChatMessageMetadata
ChatSendButton
ChatSystemMessage
ChatTokenizedText
ChatToolCalls
Checkbox
CheckboxInput
CheckboxList
CheckboxListItem
ClickableCard
Code
CodeBlock
Collapsible
Collapsible
CollapsibleGroup
useXDSCollapsible
CommandPalette
CommandPalette
CommandPaletteEmpty
CommandPaletteFooter
CommandPaletteGroup
CommandPaletteInput
CommandPaletteItem
CommandPaletteList
DateInput
Dialog
AlertDialog
Dialog
DialogHeader
useXDSImperativeAlertDialog
useXDSImperativeDialog
Divider
DropdownMenu
DropdownMenu
DropdownMenuDivider
DropdownMenuItem
DropdownMenuItemData
DropdownMenuSection
EmptyState
Field
Field
FieldLabel
FieldStatus
Heading
HoverCard
Icon
Kbd
Layout
Center
FormLayout
Grid
GridSpan
HStack
Layout
LayoutContainer
LayoutContent
LayoutFooter
LayoutHeader
LayoutPanel
Section
StackItem
VStack
Link
List
List
ListItem
Markdown
MetadataList
MetadataList
MetadataListItem
MobileNav
MoreMenu
NavIcon
NavMenuItem
NumberInput
OverflowList
Pagination
Popover
PowerSearch
ProgressBar
Radio
RadioList
RadioListItem
Resizable
ResizeHandle
useXDSResizable
SegmentedControl
SegmentedControl
SegmentedControlItem
SelectableCard
Selector
MultiSelector
Selector
SelectorOption
SideNav
SideNav
SideNavCollapseButton
SideNavHeading
SideNavItem
SideNavSection
Skeleton
Slider
Spinner
StatusDot
Switch
Table
BaseTable
Table
TableCell
TableHeaderCell
TableRow
useXDSTableColumnSettings
useXDSTablePagination
useXDSTableSelection
useXDSTableSelectionState
useXDSTableSortable
Tabs
Tab
TabList
TabMenu
Text
TextArea
TextInput
Thumbnail
TimeInput
Timestamp
Toast
Toast
useXDSToast
Token
Tokenizer
Toolbar
Tooltip
TopNav
TopNav
TopNavHeading
TopNavItem
TopNavMegaMenu
TopNavMegaMenuFeaturedCard
TopNavMegaMenuItem
TopNavMenu
TreeList
Typeahead
BaseTypeahead
Typeahead
TypeaheadItem
useXDSHoverCard
useXDSPopover
useXDSTooltip
Utilities
Utilities
LinkProvider
MediaTheme
SyntaxTheme
Theme
useClickableContainer
useEntryAnimation
useFocusTrap
useGridFocus
useImageMode
useInputContainer
useListFocus
useMediaQuery
useOverflow
useScrollLock
useScrollOverflow
useXDSLayer
useXDSStreamingText
Terms of UsePrivacy Policy
Type to search
↑↓Navigate↵SelectEscClose
TopNav@xds/core · XDSTopNav v0.0.13

Usage

TopNav is a horizontal navigation bar for product-level navigation in application headers. Use TopNav for 5 or fewer always-visible navigation items, or minimal navigation paired with search and controls. For complex navigation hierarchies, use a sidebar; to filter content, use tabs or filter buttons instead.
ts
import {XDSTopNav} from '@xds/core/TopNav'

Best practices

GuidancePractices
DoInclude a product logo and name in the heading slot to clearly identify the application.
DoLimit primary navigation items to 5 or fewer for quick scanning and minimal cognitive load.
Don'tAvoid using TopNav to filter page content — use Tabs or filter controls instead.
Don'tAvoid deeply nested navigation hierarchies — keep menus to one level of depth.

Sub-components

TopNav is a compound component with 7 sub-components.

XDSTopNav

Main navigation bar container with slot-based layout.
PropTypeDescription
heading
ReactNodeHeading slot content (logo, brand) — positioned at the left edge of the nav bar.
startContent
ReactNodeStart content slot for navigation items or breadcrumbs — positioned after the heading, left-aligned.
centerContent
ReactNodeCenter content slot (tabs, search bar, primary navigation) — when provided, switches the layout to a three-column CSS grid for true horizontal centering.
endContent
ReactNodeEnd content slot for search, icons, or user profile — positioned at the right edge.
label
stringAccessible label for the navigation landmark, applied as aria-label on the <nav> element.
xstyle
StyleXStylesStyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}.

XDSTopNavHeading

Product/suite/account heading for the XDSTopNav heading slot. Supports smart interaction boundary logic: logo, heading text, superheading/subheading with independent links, and an optional menu popover with automatic chevron indicator.
PropTypeDescription
logo
ReactNodeLogo element to display before the heading text. Can be an image, XDSNavIcon, or any ReactNode.
heading
stringProduct/app name displayed as the primary heading text.
headingHref
stringLink for the heading text (e.g. product home). When no menu is present and this is the only href, the whole heading becomes one clickable link.
href
stringDeprecated — use headingHref instead. URL to navigate to when clicked.
superheading
stringText above the heading (e.g. suite name). Rendered in a smaller secondary style.
superheadingHref
stringLink for the superheading text (e.g. suite home). When provided alongside a menu, renders as an independent inline link.
subheading
stringText below the heading (e.g. account context). Rendered in a smaller secondary style.
subheadingHref
stringLink for the subheading text. When provided alongside a menu, renders as an independent inline link.
headerEndContent
ReactNodeContent rendered at the trailing edge of the heading row (e.g. a badge or status indicator).
menu
ReactNodeMenu content shown in a popover dropdown. When provided, a chevron indicator appears automatically. Interaction boundary is determined by the presence of hrefs: no hrefs means the whole header is the trigger; with hrefs, links are independent and the chevron area is the trigger.
as
XDSLinkComponentTypeCustom component to render instead of <a>. Overrides the provider-level default set by XDSLinkProvider. Must accept href, className, style, and children props.
xstyle
StyleXStylesStyleX styles for layout customization. Must be a stylex.create() value.

XDSTopNavItem

Navigation link item for use in XDSTopNav startContent — renders as an anchor with hover and selected states.
PropTypeDescription
labelrequired
stringAccessible label for the nav item. Rendered as visible text by default. When isIconOnly is true, used as aria-label instead.
href
stringNavigation target URL.
isSelected
boolean (default: false)Whether this nav item is currently selected. Sets aria-current="page" and applies highlighted styles.
isDisabled
boolean (default: false)Whether the nav item is disabled. Sets aria-disabled and prevents interaction.
isIconOnly
boolean (default: false)Renders the item as a square icon-only element. When true, label becomes the aria-label and visible text is hidden. Requires icon to be set.
icon
ReactNodeOptional icon to display before the label.
children
ReactNodeCustom content to render instead of the label text.
as
XDSLinkComponentTypeCustom component to render instead of <a>. Overrides the provider-level default set by XDSLinkProvider. Must accept href, className, style, and children props.

XDSTopNavMegaMenu

Navigation item that displays a full-width mega menu panel on hover. Uses a slots API with items and featured props. XDSTopNavMegaMenuItem renders itself in both desktop and mobile drawer modes. Supports inline collapsible drawer via render mode context.
PropTypeDescription
labelrequired
stringVisible label for the trigger button.
items
ReactNodeMenu items slot — typically XDSTopNavMegaMenuItem components, but accepts any ReactNode.
featured
ReactNodeFeatured content slot — rendered in the right panel on desktop, below items in the mobile drawer.
delay
number (default: 150)Delay in milliseconds before showing the menu on hover.
hideDelay
number (default: 250)Delay in milliseconds before hiding the menu after the mouse leaves.
onOpenChange
(isOpen: boolean) => voidCallback fired when the mega menu opens or closes. Useful for coordinating wrapper styles.

XDSTopNavMegaMenuFeaturedCard

Standard featured card for the XDSTopNavMegaMenu featured slot. Provides a consistent card with optional image, title, description, and CTA link.
PropTypeDescription
titlerequired
stringCard title.
description
stringDescription text below the title.
image
stringOptional image URL displayed above the body.
imageAlt
stringAlt text for the image.
linkLabel
stringCTA link text.
linkHref
stringCTA link URL.
children
ReactNodeCustom content rendered below the standard body.

XDSTopNavMegaMenuItem

An individual item inside an XDSTopNavMegaMenu. Renders itself in both desktop (popover grid) and mobile drawer modes via render mode context.
PropTypeDescription
titlerequired
stringDisplay title for the menu item.
description
stringOptional description text displayed below the title.
icon
ReactNodeOptional icon element displayed to the left.
href
stringURL to navigate to when clicked.
onClick
() => voidCallback when item is clicked.
as
XDSLinkComponentTypeCustom component to render instead of <a> for link items. Overrides the provider-level default set by XDSLinkProvider.

XDSTopNavMenu

Navigation item that displays a hover-triggered popover menu with rich items containing an icon, title, and optional description.
PropTypeDescription
labelrequired
stringVisible label for the trigger button.
itemsrequired
XDSTopNavMenuItemData[]Menu items to display in the hover popover.
delay
number (default: 150)Delay in milliseconds before showing the menu on hover.
hideDelay
number (default: 200)Delay in milliseconds before hiding the menu after the mouse leaves.

Examples

Common configurations, variations, and states.
TopNav — Centered NavigationNavigation layout with center-aligned nav items flanked by a logo heading and end actions.
tsx
'use client';
​
import {XDSTopNav, XDSTopNavHeading, XDSTopNavItem} from '@xds/core/TopNav';
import {XDSNavIcon} from '@xds/core/NavIcon';
import {XDSButton} from '@xds/core/Button';
import {XDSIcon} from '@xds/core/Icon';
​
function CubeIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 16.5V7.914a1.5 1.5 0 0 0-.75-1.299l-7.5-4.329a1.5 1.5 0 0 0-1.5 0l-7.5 4.33A1.5 1.5 0 0 0 3 7.913V16.5a1.5 1.5 0 0 0 .75 1.3l7.5 4.328a1.5 1.5 0 0 0 1.5 0l7.5-4.329A1.5 1.5 0 0 0 21 16.5Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 7.5 8.25 4.764 8.25-4.764M12 22.089V12.264" />
</svg>
);
}
​
function UserIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
);
}
​
export default function TopNavCenteredNavigation() {
return (
<XDSTopNav
label="Main navigation"
heading={
<XDSTopNavHeading
heading="My App"
logo={<XDSNavIcon icon={<CubeIcon />} />}
href="#"
/>
}
centerContent={
<>
<XDSTopNavItem label="Home" href="#" isSelected />
<XDSTopNavItem label="Products" href="#" />
<XDSTopNavItem label="About" href="#" />
</>
}
endContent={
<>
<XDSButton
label="Search"
variant="ghost"
icon={<XDSIcon icon="search" color="inherit" />}
isIconOnly
/>
<XDSButton
label="Profile"
variant="ghost"
icon={<UserIcon />}
isIconOnly
/>
</>
}
/>
);
}
TopNav — Enterprise DashboardFull-featured navigation bar with icon-labeled nav items, search, notifications, and a primary CTA.
tsx
'use client';
​
import {XDSTopNav, XDSTopNavHeading, XDSTopNavItem} from '@xds/core/TopNav';
import {XDSNavIcon} from '@xds/core/NavIcon';
import {XDSButton} from '@xds/core/Button';
import {XDSIcon} from '@xds/core/Icon';
​
function ChartIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
</svg>
);
}
​
function HomeIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 12 8.955-8.955a1.126 1.126 0 0 1 1.59 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
</svg>
);
}
​
function DocumentIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
</svg>
);
}
​
function CogIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.646.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.333.183-.582.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
);
}
​
function BellIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
</svg>
);
}
​
export default function TopNavEnterpriseDashboard() {
return (
<XDSTopNav
label="Main navigation"
heading={
<XDSTopNavHeading
heading="Enterprise Dashboard"
logo={<XDSNavIcon icon={<ChartIcon />} />}
href="#"
/>
}
startContent={
<>
<XDSTopNavItem
label="Dashboard"
href="#"
isSelected
icon={<HomeIcon />}
/>
<XDSTopNavItem
label="Reports"
href="#"
icon={<DocumentIcon />}
/>
<XDSTopNavItem
label="Analytics"
href="#"
icon={<ChartIcon />}
/>
<XDSTopNavItem
label="Settings"
href="#"
icon={<CogIcon />}
/>
</>
}
endContent={
<>
<XDSButton
label="Search"
variant="ghost"
icon={<XDSIcon icon="search" color="inherit" />}
isIconOnly
/>
<XDSButton
label="Notifications"
variant="ghost"
icon={<BellIcon />}
isIconOnly
/>
<XDSButton label="Upgrade" variant="primary" />
</>
}
/>
);
}
TopNav — Hover MenuNavigation bar with a hover-triggered dropdown menu showing product items with icons and descriptions.
tsx
'use client';
​
import {
XDSTopNav,
XDSTopNavHeading,
XDSTopNavItem,
XDSTopNavMenu,
} from '@xds/core/TopNav';
import {XDSNavIcon} from '@xds/core/NavIcon';
import {XDSButton} from '@xds/core/Button';
​
function CubeIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 16.5V7.914a1.5 1.5 0 0 0-.75-1.299l-7.5-4.329a1.5 1.5 0 0 0-1.5 0l-7.5 4.33A1.5 1.5 0 0 0 3 7.913V16.5a1.5 1.5 0 0 0 .75 1.3l7.5 4.328a1.5 1.5 0 0 0 1.5 0l7.5-4.329A1.5 1.5 0 0 0 21 16.5Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 7.5 8.25 4.764 8.25-4.764M12 22.089V12.264" />
</svg>
);
}
​
function ChartIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
</svg>
);
}
​
function ShieldIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
</svg>
);
}
​
function BoltIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z" />
</svg>
);
}
​
function CodeIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" />
</svg>
);
}
​
function UserIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
);
}
​
export default function TopNavHoverMenu() {
return (
<XDSTopNav
label="Main navigation"
heading={
<XDSTopNavHeading
heading="My App"
logo={<XDSNavIcon icon={<CubeIcon />} />}
href="#"
/>
}
startContent={
<>
<XDSTopNavItem label="Home" href="#" isSelected />
<XDSTopNavMenu
label="Products"
items={[
{
title: 'Analytics',
description: 'Track and analyze user behavior',
icon: <ChartIcon />,
href: '#analytics',
},
{
title: 'Security',
description: 'Enterprise-grade protection',
icon: <ShieldIcon />,
href: '#security',
},
{
title: 'Automation',
description: 'Streamline your workflows',
icon: <BoltIcon />,
href: '#automation',
},
{
title: 'Developer Tools',
description: 'APIs, SDKs, and CLI tools',
icon: <CodeIcon />,
href: '#dev-tools',
},
]}
/>
<XDSTopNavItem label="Pricing" href="#" />
</>
}
endContent={
<XDSButton
label="Profile"
variant="ghost"
icon={<UserIcon />}
isIconOnly
/>
}
/>
);
}
TopNav — Mega MenuMarketing-style navigation with a full-width mega menu featuring product items and a promotional featured card.
tsx
'use client';
​
import {
XDSTopNav,
XDSTopNavHeading,
XDSTopNavItem,
XDSTopNavMegaMenu,
XDSTopNavMegaMenuItem,
XDSTopNavMegaMenuFeaturedCard,
} from '@xds/core/TopNav';
import {XDSNavIcon} from '@xds/core/NavIcon';
import {XDSButton} from '@xds/core/Button';
​
function CubeIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 16.5V7.914a1.5 1.5 0 0 0-.75-1.299l-7.5-4.329a1.5 1.5 0 0 0-1.5 0l-7.5 4.33A1.5 1.5 0 0 0 3 7.913V16.5a1.5 1.5 0 0 0 .75 1.3l7.5 4.328a1.5 1.5 0 0 0 1.5 0l7.5-4.329A1.5 1.5 0 0 0 21 16.5Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 7.5 8.25 4.764 8.25-4.764M12 22.089V12.264" />
</svg>
);
}
​
function ChartIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
</svg>
);
}
​
function ShieldIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
</svg>
);
}
​
function BoltIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z" />
</svg>
);
}
​
function CodeIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" />
</svg>
);
}
​
function GlobeIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
</svg>
);
}
​
export default function TopNavMegaMenu() {
return (
<XDSTopNav
label="Marketing navigation"
heading={
<XDSTopNavHeading
heading="Acme"
logo={<XDSNavIcon icon={<CubeIcon />} />}
href="#"
/>
}
startContent={
<>
<XDSTopNavMegaMenu
label="Products"
items={
<>
<XDSTopNavMegaMenuItem
title="Analytics"
description="Track and analyze user behavior across your apps"
icon={<ChartIcon />}
href="#analytics"
/>
<XDSTopNavMegaMenuItem
title="Security"
description="Enterprise-grade protection for your data"
icon={<ShieldIcon />}
href="#security"
/>
<XDSTopNavMegaMenuItem
title="Automation"
description="Streamline workflows with intelligent tools"
icon={<BoltIcon />}
href="#automation"
/>
<XDSTopNavMegaMenuItem
title="Developer Tools"
description="APIs, SDKs, and CLI for integration"
icon={<CodeIcon />}
href="#dev-tools"
/>
<XDSTopNavMegaMenuItem
title="Global Network"
description="Low-latency edge infra in 40+ regions"
icon={<GlobeIcon />}
href="#network"
/>
</>
}
featured={
<XDSTopNavMegaMenuFeaturedCard
title="What's new in v4.0"
description="AI-powered analytics and real-time collaboration."
image="https://lookaside.facebook.com/assets/xds_oss/light-working-horizontal-1.png"
imageAlt="Team collaboration"
linkLabel="Read the announcement"
linkHref="#announcement"
/>
}
/>
<XDSTopNavItem label="Pricing" href="#" />
<XDSTopNavItem label="Docs" href="#" />
</>
}
endContent={
<>
<XDSButton label="Sign in" variant="ghost" />
<XDSButton label="Get started" variant="primary" />
</>
}
/>
);
}
TopNav — Multiple DropdownsNavigation bar with multiple hover-triggered dropdown menus that auto-close when switching between them.
tsx
'use client';
​
import {
XDSTopNav,
XDSTopNavHeading,
XDSTopNavItem,
XDSTopNavMenu,
} from '@xds/core/TopNav';
​
function ChartIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
</svg>
);
}
​
function ShieldIcon() {
return (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
</svg>
);
}
​
export default function TopNavMultipleDropdowns() {
return (
<XDSTopNav
label="Main navigation"
heading={<XDSTopNavHeading heading="Platform" href="#" />}
startContent={
<>
<XDSTopNavMenu
label="Products"
items={[
{
title: 'Analytics',
description: 'Track behavior',
icon: <ChartIcon />,
href: '#',
},
{
title: 'Security',
description: 'Enterprise protection',
icon: <ShieldIcon />,
href: '#',
},
]}
/>
<XDSTopNavMenu
label="Resources"
items={[
{title: 'Documentation', href: '#'},
{title: 'API Reference', href: '#'},
{title: 'Community Forum', href: '#'},
]}
/>
<XDSTopNavItem label="Pricing" href="#" />
</>
}
/>
);
}
TopNav — With LogoNavigation bar with a branded logo icon, heading link, nav items, and a profile action.
tsx
'use client';
​
import {XDSTopNav, XDSTopNavHeading, XDSTopNavItem} from '@xds/core/TopNav';
import {XDSNavIcon} from '@xds/core/NavIcon';
import {XDSButton} from '@xds/core/Button';
​
function CubeIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 16.5V7.914a1.5 1.5 0 0 0-.75-1.299l-7.5-4.329a1.5 1.5 0 0 0-1.5 0l-7.5 4.33A1.5 1.5 0 0 0 3 7.913V16.5a1.5 1.5 0 0 0 .75 1.3l7.5 4.328a1.5 1.5 0 0 0 1.5 0l7.5-4.329A1.5 1.5 0 0 0 21 16.5Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 7.5 8.25 4.764 8.25-4.764M12 22.089V12.264" />
</svg>
);
}
​
function UserIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
);
}
​
export default function TopNavWithLogo() {
return (
<XDSTopNav
label="Main navigation"
heading={
<XDSTopNavHeading
heading="Dashboard"
logo={<XDSNavIcon icon={<CubeIcon />} />}
href="#"
/>
}
startContent={
<>
<XDSTopNavItem label="Overview" href="#" isSelected />
<XDSTopNavItem label="Analytics" href="#" />
<XDSTopNavItem label="Reports" href="#" />
</>
}
endContent={
<XDSButton
label="Profile"
variant="ghost"
icon={<UserIcon />}
isIconOnly
/>
}
/>
);
}

Showcase source

tsx
'use client';
​
import {XDSTopNav, XDSTopNavHeading, XDSTopNavItem} from '@xds/core/TopNav';
import {XDSButton} from '@xds/core/Button';
import {XDSIcon} from '@xds/core/Icon';
​
function BellIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
</svg>
);
}
​
function UserIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
);
}
​
export default function TopNavShowcase() {
return (
<XDSTopNav
label="Main navigation"
heading={<XDSTopNavHeading heading="My App" />}
startContent={
<>
<XDSTopNavItem label="Home" href="#" isSelected />
<XDSTopNavItem label="Products" href="#" />
<XDSTopNavItem label="About" href="#" />
</>
}
endContent={
<>
<XDSButton
label="Search"
variant="ghost"
icon={<XDSIcon icon="search" color="inherit" />}
isIconOnly
/>
<XDSButton
label="Notifications"
variant="ghost"
icon={<BellIcon />}
isIconOnly
/>
<XDSButton
label="Profile"
variant="ghost"
icon={<UserIcon />}
isIconOnly
/>
</>
}
/>
);
}