Navigation
The <lt-nav> component renders a list of links either horizontally or vertically. Nest
<lt-nav-item> elements to create collapsible groups — in vertical mode they expand inline; in
horizontal mode they drop down as a panel.
Playground
Usage
import '@latty-ds/web';
<!-- Vertical navigation (default) -->
<lt-nav>
<lt-nav-item href="/dashboard" label="Dashboard" icon-start="home" active></lt-nav-item>
<lt-nav-item label="Settings" icon-start="settings">
<lt-nav-item href="/settings/profile" label="Profile"></lt-nav-item>
<lt-nav-item href="/settings/security" label="Security"></lt-nav-item>
</lt-nav-item>
<lt-nav-item href="/help" label="Help" icon-start="question-circle"></lt-nav-item>
</lt-nav>
<!-- Horizontal navigation with dropdown groups -->
<lt-nav orientation="horizontal">
<lt-nav-item href="/" label="Home"></lt-nav-item>
<lt-nav-item label="Products">
<lt-nav-item href="/products/a" label="Product A"></lt-nav-item>
<lt-nav-item href="/products/b" label="Product B"></lt-nav-item>
</lt-nav-item>
<lt-nav-item href="/about" label="About"></lt-nav-item>
</lt-nav>
import { Nav, NavItem } from '@latty-ds/react';
{/* Vertical navigation (default) */}
<Nav>
<NavItem href="/dashboard" label="Dashboard" iconStart="home" active />
<NavItem label="Settings" iconStart="settings">
<NavItem href="/settings/profile" label="Profile" />
<NavItem href="/settings/security" label="Security" />
</NavItem>
<NavItem href="/help" label="Help" iconStart="question-circle" />
</Nav>
{/* Horizontal navigation with dropdown groups */}
<Nav orientation="horizontal">
<NavItem href="/" label="Home" />
<NavItem label="Products">
<NavItem href="/products/a" label="Product A" />
<NavItem href="/products/b" label="Product B" />
</NavItem>
<NavItem href="/about" label="About" />
</Nav>
SPA router integration
Items use the native click. Listen for it on the nav, call preventDefault() to stop the anchor's full-page navigation and hand the URL to your router — event.target is the lt-nav-item, so its href and label are right there, and modifier keys (event.metaKey…) work as on any link. Drive the highlighted item with the active property — it also sets aria-current="page" on the internal trigger. A group that opens or closes fires the native-style toggle event with detail.open.
<lt-nav id="app-nav">
<lt-nav-item href="/dashboard" label="Dashboard" icon-start="home"></lt-nav-item>
<lt-nav-item href="/reviews" label="Reviews" icon-start="star"></lt-nav-item>
</lt-nav>
<script type="module">
import '@latty-ds/web';
const nav = document.getElementById('app-nav');
nav.addEventListener('click', (e) => {
const link = e.target.closest('lt-nav-item');
if (!link?.href || link.disabled) return; // group headers and disabled items
e.preventDefault(); // stop the full-page navigation
router.navigate(link.href); // your SPA router
nav.querySelectorAll('lt-nav-item').forEach((item) => {
item.active = item.href === link.href;
});
});
</script>
import { Nav, NavItem } from '@latty-ds/react';
import { useLocation, useNavigate } from 'react-router';
function AppNav() {
const navigate = useNavigate();
const { pathname } = useLocation();
const go = (to) => (e) => {
e.preventDefault(); // stop the full-page navigation
navigate(to);
};
return (
<Nav>
<NavItem
href="/dashboard"
label="Dashboard"
iconStart="home"
active={pathname === '/dashboard'}
onClick={go('/dashboard')}
/>
<NavItem
href="/reviews"
label="Reviews"
iconStart="star"
active={pathname === '/reviews'}
onClick={go('/reviews')}
/>
</Nav>
);
}