XDSMobileNav@xds/core · MobileNav
Usage
A slide-out drawer for mobile navigation. MobileNav is the mobile counterpart to SideNav and accepts the same children. Use it on narrow viewports where a persistent sidebar is not practical.Best practices
| Guidance | Practices |
|---|---|
| Do | Share the same nav items between MobileNav and SideNav by extracting them into a variable. |
| Do | Provide a title when the drawer's purpose is not obvious from its content. |
| Don't | Use MobileNav on desktop — use a persistent SideNav instead. |
Import
tsimport {XDSMobileNav} from '@xds/core/MobileNav'
Props
| Prop | Type | Description |
|---|---|---|
isOpenrequired | boolean | Whether the drawer is open. |
onOpenChangerequired | (isOpen: boolean) => void | Called when the drawer visibility changes (backdrop click, Escape key, or close button). |
childrenrequired | ReactNode | Drawer content — typically XDSSideNavSection/XDSSideNavItem, or any ReactNode. |
title | string | Optional title shown at the top of the drawer. |
width | number (default: 280) | Drawer width in pixels. Capped at 85vw to prevent overflow on small screens. |
side | 'start' | 'end' (default: 'start') | Which side the drawer slides from. Start is left in LTR, right in RTL. |
Examples
Common configurations, variations, and states.MobileNav — Basic DrawerMobile navigation drawer with sectioned nav items triggered by a menu button
tsx'use client';import {useState} from 'react';import {XDSMobileNav} from '@xds/core/MobileNav';import {XDSSideNavSection, XDSSideNavItem} from '@xds/core/SideNav';import {XDSButton} from '@xds/core/Button';import {XDSIcon} from '@xds/core/Icon';import {HomeIcon,FolderIcon,ChartBarIcon,Cog6ToothIcon,UsersIcon,} from '@heroicons/react/24/outline';export default function MobileNavBasicMobileNav() {const [isOpen, setIsOpen] = useState(false);return (<><XDSButtonlabel="Open Navigation"icon={<XDSIcon icon="menu" color="inherit" />}variant="ghost"onClick={() => setIsOpen(true)}isIconOnly/><XDSMobileNavisOpen={isOpen}onOpenChange={open => setIsOpen(open)}header="Navigation"><XDSSideNavSection title="Main"><XDSSideNavItemlabel="Dashboard"icon={HomeIcon}isSelectedhref="/dashboard"/><XDSSideNavItem label="Projects" icon={FolderIcon} href="/projects" /><XDSSideNavItemlabel="Analytics"icon={ChartBarIcon}href="/analytics"/></XDSSideNavSection><XDSSideNavSection title="Settings"><XDSSideNavItemlabel="General"icon={Cog6ToothIcon}href="/settings"/><XDSSideNavItem label="Team" icon={UsersIcon} href="/team" /></XDSSideNavSection></XDSMobileNav></>);}
MobileNav — End Side DrawerNavigation drawer that slides in from the right side of the screen
tsx'use client';import {useState} from 'react';import {XDSMobileNav} from '@xds/core/MobileNav';import {XDSSideNavSection, XDSSideNavItem} from '@xds/core/SideNav';import {XDSButton} from '@xds/core/Button';import {Cog6ToothIcon, UsersIcon} from '@heroicons/react/24/outline';export default function MobileNavEndSideMobileNav() {const [isOpen, setIsOpen] = useState(false);return (<><XDSButton label="Open from Right" onClick={() => setIsOpen(true)} /><XDSMobileNavisOpen={isOpen}onOpenChange={open => setIsOpen(open)}header="Settings"side="end"><XDSSideNavSection title="Settings"><XDSSideNavItemlabel="General"icon={Cog6ToothIcon}href="/settings"/><XDSSideNavItem label="Team" icon={UsersIcon} href="/team" /></XDSSideNavSection></XDSMobileNav></>);}
MobileNav — Without TitleMobile navigation drawer without a title header
tsx'use client';import {useState} from 'react';import {XDSMobileNav} from '@xds/core/MobileNav';import {XDSSideNavSection, XDSSideNavItem} from '@xds/core/SideNav';import {XDSButton} from '@xds/core/Button';import {XDSIcon} from '@xds/core/Icon';import {HomeIcon, FolderIcon} from '@heroicons/react/24/outline';export default function MobileNavWithoutTitleMobileNav() {const [isOpen, setIsOpen] = useState(false);return (<><XDSButtonlabel="Open Navigation"icon={<XDSIcon icon="menu" color="inherit" />}variant="ghost"onClick={() => setIsOpen(true)}isIconOnly/><XDSMobileNav isOpen={isOpen} onOpenChange={open => setIsOpen(open)}><XDSSideNavSection title="Main"><XDSSideNavItemlabel="Dashboard"icon={HomeIcon}isSelectedhref="/dashboard"/><XDSSideNavItem label="Projects" icon={FolderIcon} href="/projects" /></XDSSideNavSection></XDSMobileNav></>);}
Showcase source
tsx'use client';import {useState} from 'react';import {XDSMobileNav} from '@xds/core/MobileNav';import {XDSSideNavSection, XDSSideNavItem} from '@xds/core/SideNav';import {XDSButton} from '@xds/core/Button';import {XDSIcon} from '@xds/core/Icon';export default function MobileNavShowcase() {const [isOpen, setIsOpen] = useState(false);return (<><XDSButtonlabel="Open Navigation"icon={<XDSIcon icon="menu" color="inherit" />}variant="ghost"onClick={() => setIsOpen(true)}isIconOnly/><XDSMobileNavisOpen={isOpen}onOpenChange={setIsOpen}header="Navigation"><XDSSideNavSection title="Main"><XDSSideNavItem label="Dashboard" isSelected href="/dashboard" /><XDSSideNavItem label="Projects" href="/projects" /><XDSSideNavItem label="Analytics" href="/analytics" /></XDSSideNavSection><XDSSideNavSection title="Settings"><XDSSideNavItem label="General" href="/settings" /><XDSSideNavItem label="Team" href="/team" /></XDSSideNavSection></XDSMobileNav></>);}